mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Emulate unsupported render target formats
Fixes Midtown Madness 2 rendering on NVIDIA. See issue #159.
This commit is contained in:
parent
b53678bfd4
commit
12c4f87cb6
@ -266,6 +266,26 @@ namespace D3dDdi
|
||||
return supportedZBufferBitDepths;
|
||||
}
|
||||
|
||||
bool Adapter::isEmulatedRenderTargetFormat(D3DDDIFORMAT format)
|
||||
{
|
||||
const auto& fi = getFormatInfo(format);
|
||||
if (0 == fi.red.bitCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& formatOps = getInfo().formatOps;
|
||||
auto it = formatOps.find(format);
|
||||
if (it == formatOps.end() || (it->second.Operations & FORMATOP_OFFSCREEN_RENDERTARGET))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto replacementFormat = 0 != fi.alpha.bitCount ? D3DDDIFMT_A8R8G8B8 : D3DDDIFMT_X8R8G8B8;
|
||||
it = formatOps.find(replacementFormat);
|
||||
return it != formatOps.end() && (it->second.Operations & FORMATOP_OFFSCREEN_RENDERTARGET);
|
||||
}
|
||||
|
||||
HRESULT Adapter::pfnCloseAdapter()
|
||||
{
|
||||
auto adapter = m_adapter;
|
||||
@ -325,10 +345,16 @@ namespace D3dDdi
|
||||
auto formatOp = static_cast<FORMATOP*>(pData->pData);
|
||||
for (UINT i = 0; i < count; ++i)
|
||||
{
|
||||
if (isEmulatedRenderTargetFormat(formatOp[i].Format))
|
||||
{
|
||||
formatOp[i].Operations |= FORMATOP_OFFSCREEN_RENDERTARGET;
|
||||
}
|
||||
|
||||
if (D3DDDIFMT_P8 == formatOp[i].Format && Config::palettizedTextures.get())
|
||||
{
|
||||
formatOp[i].Operations |= FORMATOP_TEXTURE | FORMATOP_CUBETEXTURE;
|
||||
}
|
||||
|
||||
if (D3DDDIFMT_D24X4S4 == formatOp[i].Format || D3DDDIFMT_X4S4D24 == formatOp[i].Format)
|
||||
{
|
||||
// If these formats are reported as depth buffers, then EnumZBufferFormats returns only D16
|
||||
|
@ -40,6 +40,7 @@ namespace D3dDdi
|
||||
const D3DDDI_ADAPTERFUNCS& getOrigVtable() const { return m_origVtable; }
|
||||
CompatWeakPtr<IDirectDraw7> getRepository() const { return m_repository; }
|
||||
SIZE getScaledSize(Int2 size) const;
|
||||
bool isEmulatedRenderTargetFormat(D3DDDIFORMAT format);
|
||||
|
||||
HRESULT pfnCloseAdapter();
|
||||
HRESULT pfnCreateDevice(D3DDDIARG_CREATEDEVICE* pCreateData);
|
||||
|
@ -587,7 +587,7 @@ namespace D3dDdi
|
||||
|
||||
void DeviceState::prepareTextures()
|
||||
{
|
||||
for (UINT stage = 0; stage < m_app.textures.size(); ++stage)
|
||||
for (UINT stage = 0; stage < getVertexDecl().textureStageCount; ++stage)
|
||||
{
|
||||
auto resource = getTextureResource(stage);
|
||||
if (resource)
|
||||
@ -1045,7 +1045,13 @@ namespace D3dDdi
|
||||
{
|
||||
for (UINT stage = 0; stage <= m_maxChangedTextureStage; ++stage)
|
||||
{
|
||||
if (setTexture(stage, m_app.textures[stage]) ||
|
||||
auto resource = getTextureResource(stage);
|
||||
if (resource)
|
||||
{
|
||||
resource = &resource->prepareForGpuRead(0);
|
||||
}
|
||||
|
||||
if (setTexture(stage, resource ? *resource : m_app.textures[stage]) ||
|
||||
m_changedTextureStageStates[stage].test(D3DDDITSS_DISABLETEXTURECOLORKEY) ||
|
||||
m_changedTextureStageStates[stage].test(D3DDDITSS_TEXTURECOLORKEYVAL))
|
||||
{
|
||||
|
@ -35,6 +35,7 @@ namespace
|
||||
const UINT g_resourceTypeFlags = getResourceTypeFlags().Value;
|
||||
RECT g_presentationRect = {};
|
||||
|
||||
bool g_enableConfig = true;
|
||||
D3DDDIFORMAT g_formatOverride = D3DDDIFMT_UNKNOWN;
|
||||
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> g_msaaOverride = {};
|
||||
|
||||
@ -128,7 +129,7 @@ namespace D3dDdi
|
||||
, m_paletteHandle(0)
|
||||
, m_paletteColorKeyIndex(-1)
|
||||
, m_isOversized(false)
|
||||
, m_isSurfaceRepoResource(SurfaceRepository::inCreateSurface())
|
||||
, m_isSurfaceRepoResource(SurfaceRepository::inCreateSurface() || !g_enableConfig)
|
||||
, m_isClampable(true)
|
||||
, m_isPrimary(false)
|
||||
, m_isPalettizedTextureUpToDate(false)
|
||||
@ -404,7 +405,7 @@ namespace D3dDdi
|
||||
|
||||
if (D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool &&
|
||||
(m_fixedData.Flags.ZBuffer && &dstRes == m_msaaSurface.resource && m_nullSurface.resource ||
|
||||
m_fixedData.Flags.RenderTarget ||
|
||||
dstRes.m_fixedData.Flags.RenderTarget ||
|
||||
!m_fixedData.Flags.ZBuffer && (
|
||||
data.Flags.SrcColorKey ||
|
||||
data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown ||
|
||||
@ -583,10 +584,12 @@ namespace D3dDdi
|
||||
D3DDDI_RESOURCEFLAGS flags = {};
|
||||
flags.Value = g_resourceTypeFlags;
|
||||
flags.RenderTarget = 0;
|
||||
flags.Texture = 0;
|
||||
if (D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool ||
|
||||
m_isSurfaceRepoResource ||
|
||||
0 == m_formatInfo.bytesPerPixel ||
|
||||
0 != (m_fixedData.Flags.Value & flags.Value))
|
||||
0 != (m_fixedData.Flags.Value & flags.Value) ||
|
||||
m_fixedData.Flags.Texture && !m_origData.Flags.RenderTarget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -683,6 +686,11 @@ namespace D3dDdi
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::enableConfig(bool enable)
|
||||
{
|
||||
g_enableConfig = enable;
|
||||
}
|
||||
|
||||
void Resource::fixResourceData()
|
||||
{
|
||||
if (m_fixedData.Flags.MatchGdiPrimary)
|
||||
@ -698,8 +706,7 @@ namespace D3dDdi
|
||||
}
|
||||
m_fixedData.Format = D3DDDIFMT_X8R8G8B8;
|
||||
}
|
||||
|
||||
if (D3DDDIFMT_UNKNOWN != g_formatOverride)
|
||||
else if (D3DDDIFMT_UNKNOWN != g_formatOverride)
|
||||
{
|
||||
m_fixedData.Format = g_formatOverride;
|
||||
if (FOURCC_INTZ == g_formatOverride)
|
||||
@ -707,6 +714,10 @@ namespace D3dDdi
|
||||
m_fixedData.Flags.Texture = 1;
|
||||
}
|
||||
}
|
||||
else if (m_fixedData.Flags.RenderTarget && m_device.getAdapter().isEmulatedRenderTargetFormat(m_fixedData.Format))
|
||||
{
|
||||
m_fixedData.Flags.RenderTarget = 0;
|
||||
}
|
||||
|
||||
if (D3DDDIMULTISAMPLE_NONE != g_msaaOverride.first)
|
||||
{
|
||||
@ -736,6 +747,11 @@ namespace D3dDdi
|
||||
|
||||
D3DDDIFORMAT Resource::getFormatConfig()
|
||||
{
|
||||
if (m_origData.Flags.RenderTarget && !m_fixedData.Flags.RenderTarget)
|
||||
{
|
||||
return 0 != m_formatInfo.alpha.bitCount ? D3DDDIFMT_A8R8G8B8 : D3DDDIFMT_X8R8G8B8;
|
||||
}
|
||||
|
||||
if (D3DDDIFMT_X8R8G8B8 == m_fixedData.Format || D3DDDIFMT_R5G6B5 == m_fixedData.Format)
|
||||
{
|
||||
switch (Config::renderColorDepth.get())
|
||||
@ -775,8 +791,7 @@ namespace D3dDdi
|
||||
|
||||
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> Resource::getMultisampleConfig()
|
||||
{
|
||||
if (!m_fixedData.Flags.Texture &&
|
||||
(!m_isPrimary || m_fixedData.Flags.RenderTarget))
|
||||
if (!m_isPrimary || m_origData.Flags.RenderTarget)
|
||||
{
|
||||
return m_device.getAdapter().getMultisampleConfig(m_fixedData.Format);
|
||||
}
|
||||
@ -803,7 +818,7 @@ namespace D3dDdi
|
||||
SIZE Resource::getScaledSize()
|
||||
{
|
||||
SIZE size = { static_cast<LONG>(m_fixedData.pSurfList[0].Width), static_cast<LONG>(m_fixedData.pSurfList[0].Height) };
|
||||
if (!m_fixedData.Flags.Texture)
|
||||
if (m_origData.Flags.RenderTarget || m_fixedData.Flags.ZBuffer)
|
||||
{
|
||||
return m_device.getAdapter().getScaledSize(size);
|
||||
}
|
||||
@ -951,7 +966,7 @@ namespace D3dDdi
|
||||
if (m_lockData[subResourceIndex].isMsaaUpToDate || m_lockData[subResourceIndex].isMsaaResolvedUpToDate)
|
||||
{
|
||||
loadMsaaResolvedResource(subResourceIndex);
|
||||
if (!m_fixedData.Flags.RenderTarget ||
|
||||
if (!m_origData.Flags.RenderTarget ||
|
||||
Config::Settings::ResolutionScaleFilter::POINT == Config::resolutionScaleFilter.get())
|
||||
{
|
||||
const bool isScaled = static_cast<LONG>(m_fixedData.pSurfList[0].Width) != m_scaledSize.cx ||
|
||||
@ -1199,7 +1214,7 @@ namespace D3dDdi
|
||||
if (srcResource->m_lockResource)
|
||||
{
|
||||
if (srcResource->m_lockData[data.SrcSubResourceIndex].isSysMemUpToDate &&
|
||||
!srcResource->m_fixedData.Flags.RenderTarget)
|
||||
!srcResource->m_origData.Flags.RenderTarget)
|
||||
{
|
||||
srcResource->m_lockData[data.SrcSubResourceIndex].isVidMemUpToDate = false;
|
||||
srcResource->m_lockData[data.SrcSubResourceIndex].isMsaaResolvedUpToDate = false;
|
||||
@ -1515,7 +1530,7 @@ namespace D3dDdi
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.ZBuffer)
|
||||
if (!dstResource.m_fixedData.Flags.RenderTarget && !dstResource.m_fixedData.Flags.ZBuffer)
|
||||
{
|
||||
LONG width = data.DstRect.right - data.DstRect.left;
|
||||
LONG height = data.DstRect.bottom - data.DstRect.top;
|
||||
@ -1563,7 +1578,7 @@ namespace D3dDdi
|
||||
data.Flags.Linear ? D3DTEXF_LINEAR : D3DTEXF_POINT, data.Flags.SrcColorKey ? &ck : nullptr);
|
||||
}
|
||||
|
||||
if (!m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.ZBuffer)
|
||||
if (!dstResource.m_fixedData.Flags.RenderTarget && !dstResource.m_fixedData.Flags.ZBuffer)
|
||||
{
|
||||
HRESULT result = copySubResourceRegion(data.hDstResource, data.DstSubResourceIndex, data.DstRect,
|
||||
*dstRes, dstIndex, dstRect);
|
||||
@ -1617,7 +1632,7 @@ namespace D3dDdi
|
||||
{
|
||||
if (m_isSurfaceRepoResource || D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool || D3DDDIFMT_P8 == m_fixedData.Format ||
|
||||
m_fixedData.Flags.MatchGdiPrimary ||
|
||||
!m_isPrimary && !m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.ZBuffer ||
|
||||
!m_isPrimary && !m_origData.Flags.RenderTarget && !m_fixedData.Flags.ZBuffer ||
|
||||
!m_fixedData.Flags.ZBuffer && !m_lockResource)
|
||||
{
|
||||
return;
|
||||
|
@ -60,6 +60,7 @@ namespace D3dDdi
|
||||
void updateConfig();
|
||||
void updatePalettizedTexture(UINT stage);
|
||||
|
||||
static void enableConfig(bool enable);
|
||||
static void setFormatOverride(D3DDDIFORMAT format);
|
||||
|
||||
private:
|
||||
|
@ -38,7 +38,9 @@ namespace DDraw
|
||||
auto data = privateData.get();
|
||||
data->m_palettizedSurface = palettizedSurface;
|
||||
|
||||
D3dDdi::Resource::enableConfig(false);
|
||||
result = Surface::create(dd, desc, surface, std::move(privateData));
|
||||
D3dDdi::Resource::enableConfig(true);
|
||||
if (FAILED(result))
|
||||
{
|
||||
return LOG_RESULT(result);
|
||||
|
Loading…
x
Reference in New Issue
Block a user