diff --git a/DDrawCompat/D3dDdi/Adapter.cpp b/DDrawCompat/D3dDdi/Adapter.cpp index 2c8472c..c7ae81d 100644 --- a/DDrawCompat/D3dDdi/Adapter.cpp +++ b/DDrawCompat/D3dDdi/Adapter.cpp @@ -195,7 +195,15 @@ namespace D3dDdi if (D3DDDIFMT_UNKNOWN != formatOps[i].Format) { LOG_INFO << " " << formatOps[i]; - result[formatOps[i].Format] = formatOps[i]; + auto& formatOp = result[formatOps[i].Format]; + formatOp.Format = formatOps[i].Format; + formatOp.Operations |= formatOps[i].Operations; + formatOp.FlipMsTypes |= formatOps[i].FlipMsTypes; + formatOp.BltMsTypes |= formatOps[i].BltMsTypes; + if (formatOps[i].PrivateFormatBitCount > formatOp.PrivateFormatBitCount) + { + formatOp.PrivateFormatBitCount = formatOps[i].PrivateFormatBitCount; + } } } return result; @@ -211,16 +219,31 @@ namespace D3dDdi const auto& info(getInfo()); auto it = info.formatOps.find(format); - if (it == info.formatOps.end() || 0 == it->second.BltMsTypes) + if (it == info.formatOps.end()) { return { D3DDDIMULTISAMPLE_NONE, 0 }; } - while (samples > D3DDDIMULTISAMPLE_NONMASKABLE && !(it->second.BltMsTypes & (1 << (samples - 1)))) + auto msTypes = it->second.BltMsTypes; + if (0 == msTypes && (FOURCC_DF16 == it->first || FOURCC_INTZ == it->first)) + { + auto replacement = info.formatOps.find(FOURCC_DF16 == it->first ? D3DDDIFMT_D16 : D3DDDIFMT_S8D24); + if (replacement != info.formatOps.end()) + { + msTypes = replacement->second.BltMsTypes; + } + } + + while (samples > 0 && !(msTypes & (1 << (samples - 1)))) { --samples; } + if (0 == samples) + { + return { D3DDDIMULTISAMPLE_NONE, 0 }; + } + DDIMULTISAMPLEQUALITYLEVELSDATA levels = {}; levels.Format = D3DDDIFMT_X8R8G8B8; levels.MsType = static_cast(samples); diff --git a/DDrawCompat/D3dDdi/Device.cpp b/DDrawCompat/D3dDdi/Device.cpp index 73629f7..db10ca0 100644 --- a/DDrawCompat/D3dDdi/Device.cpp +++ b/DDrawCompat/D3dDdi/Device.cpp @@ -80,7 +80,6 @@ namespace D3dDdi const auto origFormat = data.Format; const auto origMipLevels = data.MipLevels; const auto origFlags = data.Flags.Value; - auto& adapterInfo = m_adapter.getInfo(); if (D3DDDIFMT_P8 == data.Format) { @@ -91,21 +90,6 @@ namespace D3dDdi data.MipLevels = 1; } } - else if (adapterInfo.isD3D9On12) - { - if (D3DDDIFMT_D16 == data.Format) - { - data.Format = FOURCC_DF16; - } - else if (D3DDDIFMT_X8D24 == data.Format) - { - data.Format = FOURCC_DF24; - } - else if (D3DDDIFMT_S8D24 == data.Format) - { - data.Format = FOURCC_INTZ; - } - } HRESULT result = m_origVtable.pfnCreateResource2 ? m_origVtable.pfnCreateResource2(m_device, &data) diff --git a/DDrawCompat/D3dDdi/DeviceState.cpp b/DDrawCompat/D3dDdi/DeviceState.cpp index 4d7cec2..9f16e0c 100644 --- a/DDrawCompat/D3dDdi/DeviceState.cpp +++ b/DDrawCompat/D3dDdi/DeviceState.cpp @@ -1103,7 +1103,7 @@ namespace D3dDdi m_changedRenderStates.forEach([&](UINT stateIndex) { const auto state = static_cast(stateIndex); - setRenderState({ state, mapRsValue(state, m_app.renderState[state]) }); + setRenderState({ state, mapRsValue(state, m_app.renderState[state]) }); }); m_changedRenderStates.reset(); } diff --git a/DDrawCompat/D3dDdi/FormatInfo.cpp b/DDrawCompat/D3dDdi/FormatInfo.cpp index 3988187..b39c5a4 100644 --- a/DDrawCompat/D3dDdi/FormatInfo.cpp +++ b/DDrawCompat/D3dDdi/FormatInfo.cpp @@ -131,9 +131,11 @@ namespace { D3DDDIFMT_D24X8, FormatInfoDXS(24, 8, 0) }, { D3DDDIFMT_D16, FormatInfoDXS(16, 0, 0) }, - { D3DDDIFMT_S1D15, FormatInfoXSD(0, 1, 15) }, - { D3DDDIFMT_S8D24, FormatInfoXSD(0, 8, 24) }, - { D3DDDIFMT_X8D24, FormatInfoXSD(8, 0, 24) }, + { D3DDDIFMT_S1D15, FormatInfoXSD(0, 1, 15) }, + { D3DDDIFMT_S8D24, FormatInfoXSD(0, 8, 24) }, + { D3DDDIFMT_X8D24, FormatInfoXSD(8, 0, 24) }, + { D3dDdi::FOURCC_DF16, FormatInfoXSD(0, 0, 16) }, + { D3dDdi::FOURCC_INTZ, FormatInfoXSD(0, 8, 24) } }; DWORD getMask(const D3dDdi::FormatInfo::Component& component) diff --git a/DDrawCompat/D3dDdi/Hooks.cpp b/DDrawCompat/D3dDdi/Hooks.cpp index 23dba9f..5a796f0 100644 --- a/DDrawCompat/D3dDdi/Hooks.cpp +++ b/DDrawCompat/D3dDdi/Hooks.cpp @@ -115,7 +115,10 @@ namespace D3dDdi::ScopedCriticalSection lock; D3dDdi::AdapterCallbacks::hookVtable(*pOpenData->pAdapterCallbacks, pOpenData->Version); + auto origInterface = pOpenData->Interface; + pOpenData->Interface = 9; HRESULT result = origOpenAdapter(); + pOpenData->Interface = origInterface; if (SUCCEEDED(result)) { D3dDdi::AdapterFuncs::hookVtable(*pOpenData->pAdapterFuncs, pOpenData->DriverVersion); diff --git a/DDrawCompat/D3dDdi/Resource.cpp b/DDrawCompat/D3dDdi/Resource.cpp index f43bd47..bf9c167 100644 --- a/DDrawCompat/D3dDdi/Resource.cpp +++ b/DDrawCompat/D3dDdi/Resource.cpp @@ -94,6 +94,11 @@ namespace HeapFree(GetProcessHeap(), 0, p); } + bool isDepthTexture(D3DDDIFORMAT format) + { + return D3dDdi::FOURCC_INTZ == format || D3dDdi::FOURCC_DF16 == format; + } + void logUnsupportedMsaaDepthBufferResolve() { LOG_ONCE("Warning: Resolving multisampled depth buffers is not supported by the GPU driver. " @@ -435,8 +440,8 @@ namespace D3dDdi if (m_fixedData.Flags.ZBuffer) { - return !m_device.getAdapter().getInfo().isD3D9On12 || - m_fixedData.Format == srcResource.m_fixedData.Format && Rect::isEqualSize(data.SrcRect, data.DstRect); + return m_fixedData.Format == srcResource.m_fixedData.Format && + (!m_device.getAdapter().getInfo().isD3D9On12 || Rect::isEqualSize(data.SrcRect, data.DstRect)); } return Rect::isEqualSize(data.SrcRect, data.DstRect); @@ -731,6 +736,27 @@ namespace D3dDdi m_fixedData.Flags.RenderTarget = 0; } + const auto& formatOps = m_device.getAdapter().getInfo().fixedFormatOps; + switch (m_fixedData.Format) + { + case D3DDDIFMT_D16: + if (formatOps.find(FOURCC_DF16) != formatOps.end()) + { + m_fixedData.Format = FOURCC_DF16; + } + break; + + case D3DDDIFMT_S8D24: + case D3DDDIFMT_D24S8: + case D3DDDIFMT_X8D24: + case D3DDDIFMT_D24X8: + if (formatOps.find(FOURCC_INTZ) != formatOps.end()) + { + m_fixedData.Format = FOURCC_INTZ; + } + break; + } + if (D3DDDIMULTISAMPLE_NONE != g_msaaOverride.first) { m_fixedData.MultisampleType = g_msaaOverride.first; @@ -741,7 +767,6 @@ namespace D3dDdi D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool && (m_origData.Flags.RenderTarget || m_fixedData.Flags.ZBuffer)) { - const auto& formatOps = m_device.getAdapter().getInfo().fixedFormatOps; auto it = formatOps.find(m_fixedData.Format); if (it != formatOps.end() && (it->second.Operations & FORMATOP_TEXTURE)) { @@ -895,7 +920,8 @@ namespace D3dDdi if (m_fixedData.Flags.ZBuffer) { bool isD3D9On12 = m_device.getAdapter().getInfo().isD3D9On12; - if (m_nullSurface.resource || isD3D9On12) + if (isD3D9On12 || + m_nullSurface.resource && isDepthTexture(m_msaaResolvedSurface.resource->m_fixedData.Format)) { RECT r = m_msaaResolvedSurface.resource->getRect(0); m_device.getShaderBlitter().depthBlt( @@ -1616,7 +1642,8 @@ namespace D3dDdi if (m_fixedData.Flags.ZBuffer) { const bool isD3D9On12 = m_device.getAdapter().getInfo().isD3D9On12; - if (m_nullSurface.resource || isD3D9On12) + if (isD3D9On12 || + m_nullSurface.resource && isDepthTexture(srcRes->m_fixedData.Format)) { m_device.getShaderBlitter().depthBlt(*dstRes, dstRect, *srcRes, srcRect, isD3D9On12 ? nullptr : static_cast(*m_nullSurface.resource)); @@ -1738,7 +1765,7 @@ namespace D3dDdi g_msaaOverride = {}; } - if (m_fixedData.Flags.ZBuffer && m_msaaSurface.resource) + if (m_fixedData.Flags.ZBuffer && (m_msaaSurface.resource || m_fixedData.Format != formatConfig)) { g_msaaOverride = msaa; repo.getSurface(m_nullSurface, scaledSize.cx, scaledSize.cy, FOURCC_NULL, @@ -1746,7 +1773,7 @@ namespace D3dDdi g_msaaOverride = {}; } repo.getSurface(m_msaaResolvedSurface, scaledSize.cx, scaledSize.cy, - m_nullSurface.resource ? FOURCC_INTZ : formatConfig, caps, m_fixedData.SurfCount); + formatConfig, caps, m_fixedData.SurfCount); if (!m_msaaResolvedSurface.resource && m_msaaSurface.resource) {