diff --git a/DDrawCompat/D3dDdi/Adapter.cpp b/DDrawCompat/D3dDdi/Adapter.cpp index 5a562e6..5df18bb 100644 --- a/DDrawCompat/D3dDdi/Adapter.cpp +++ b/DDrawCompat/D3dDdi/Adapter.cpp @@ -58,6 +58,7 @@ namespace D3dDdi , m_luid(KernelModeThunks::getLastOpenAdapterInfo().luid) , m_deviceName(KernelModeThunks::getLastOpenAdapterInfo().deviceName) , m_repository{} + , m_info(findInfo()) { } @@ -80,7 +81,7 @@ namespace D3dDdi return getAspectRatio({}); } - const Adapter::AdapterInfo& Adapter::getInfo() const + const Adapter::AdapterInfo& Adapter::findInfo() const { auto it = s_adapterInfos.find(m_luid); if (it != s_adapterInfos.end()) @@ -91,12 +92,16 @@ namespace D3dDdi AdapterInfo& info = s_adapterInfos.insert({ m_luid, {} }).first->second; getCaps(D3DDDICAPS_GETD3D7CAPS, info.d3dExtendedCaps); info.formatOps = getFormatOps(); - info.supportedZBufferBitDepths = getSupportedZBufferBitDepths(info.formatOps); + auto d3d9on12 = GetModuleHandle("d3d9on12"); + info.isD3D9On12 = d3d9on12 && d3d9on12 == Compat::getModuleHandleFromAddress(m_origVtable.pfnGetCaps); info.isMsaaDepthResolveSupported = + !info.isD3D9On12 && info.formatOps.find(FOURCC_RESZ) != info.formatOps.end() && info.formatOps.find(FOURCC_INTZ) != info.formatOps.end() && info.formatOps.find(FOURCC_NULL) != info.formatOps.end(); + info.fixedFormatOps = getFixedFormatOps(info); + info.supportedZBufferBitDepths = getSupportedZBufferBitDepths(info.fixedFormatOps); LOG_INFO << "Supported z-buffer bit depths: " << bitDepthsToString(info.supportedZBufferBitDepths); LOG_INFO << "Supported MSAA modes: " << getSupportedMsaaModes(info.formatOps); @@ -117,6 +122,47 @@ namespace D3dDdi return info; } + std::map Adapter::getFixedFormatOps(const AdapterInfo& info) const + { + std::map fixedFormatOps; + + for (auto& formatOp : info.formatOps) + { + auto fixedFormatOp = formatOp.second; + if (isEmulatedRenderTargetFormat(formatOp.first, info.formatOps)) + { + fixedFormatOp.Operations |= FORMATOP_OFFSCREEN_RENDERTARGET; + } + + if (D3DDDIFMT_P8 == formatOp.first && Config::palettizedTextures.get()) + { + fixedFormatOp.Operations |= FORMATOP_TEXTURE | FORMATOP_CUBETEXTURE; + } + + if (D3DDDIFMT_D24X4S4 == formatOp.first || D3DDDIFMT_X4S4D24 == formatOp.first) + { + // If these formats are reported as depth buffers, then EnumZBufferFormats returns only D16 + fixedFormatOp.Operations &= ~(FORMATOP_ZSTENCIL | FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH); + } + + if (info.isD3D9On12) + { + if (D3DDDIFMT_D24X8 == formatOp.first) + { + fixedFormatOp.Format = D3DDDIFMT_X8D24; + } + else if (D3DDDIFMT_D24S8 == formatOp.first) + { + fixedFormatOp.Format = D3DDDIFMT_S8D24; + } + } + + fixedFormatOps[fixedFormatOp.Format] = fixedFormatOp; + } + + return fixedFormatOps; + } + template HRESULT Adapter::getCaps(D3DDDICAPS_TYPE type, Data& data, UINT size) const { @@ -266,7 +312,12 @@ namespace D3dDdi return supportedZBufferBitDepths; } - bool Adapter::isEmulatedRenderTargetFormat(D3DDDIFORMAT format) + bool Adapter::isEmulatedRenderTargetFormat(D3DDDIFORMAT format) const + { + return isEmulatedRenderTargetFormat(format, m_info.formatOps); + } + + bool Adapter::isEmulatedRenderTargetFormat(D3DDDIFORMAT format, const std::map& formatOps) const { const auto& fi = getFormatInfo(format); if (0 == fi.red.bitCount) @@ -274,7 +325,6 @@ namespace D3dDdi return false; } - const auto& formatOps = getInfo().formatOps; auto it = formatOps.find(format); if (it == formatOps.end() || (it->second.Operations & FORMATOP_OFFSCREEN_RENDERTARGET)) { @@ -339,27 +389,24 @@ namespace D3dDdi break; } + case D3DDDICAPS_GETFORMATCOUNT: + *static_cast(pData->pData) = m_info.fixedFormatOps.size(); + break; + case D3DDDICAPS_GETFORMATDATA: { UINT count = pData->DataSize / sizeof(FORMATOP); + if (count > m_info.fixedFormatOps.size()) + { + count = m_info.fixedFormatOps.size(); + } + auto formatOp = static_cast(pData->pData); + auto it = m_info.fixedFormatOps.begin(); 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 - formatOp[i].Operations &= ~(FORMATOP_ZSTENCIL | FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH); - } + formatOp[i] = it->second; + ++it; } break; } diff --git a/DDrawCompat/D3dDdi/Adapter.h b/DDrawCompat/D3dDdi/Adapter.h index 53930b8..ee0f342 100644 --- a/DDrawCompat/D3dDdi/Adapter.h +++ b/DDrawCompat/D3dDdi/Adapter.h @@ -21,8 +21,10 @@ namespace D3dDdi { D3DNTHAL_D3DEXTENDEDCAPS d3dExtendedCaps; std::map formatOps; + std::map fixedFormatOps; DWORD supportedZBufferBitDepths; bool isMsaaDepthResolveSupported; + bool isD3D9On12; }; Adapter(const D3DDDIARG_OPENADAPTER& data); @@ -34,13 +36,13 @@ namespace D3dDdi operator HANDLE() const { return m_adapter; } Int2 getAspectRatio() const; - const AdapterInfo& getInfo() const; + const AdapterInfo& getInfo() const { return m_info; } LUID getLuid() const { return m_luid; } std::pair getMultisampleConfig(D3DDDIFORMAT format) const; const D3DDDI_ADAPTERFUNCS& getOrigVtable() const { return m_origVtable; } CompatWeakPtr getRepository() const { return m_repository; } SIZE getScaledSize(Int2 size) const; - bool isEmulatedRenderTargetFormat(D3DDDIFORMAT format); + bool isEmulatedRenderTargetFormat(D3DDDIFORMAT format) const; HRESULT pfnCloseAdapter(); HRESULT pfnCreateDevice(D3DDDIARG_CREATEDEVICE* pCreateData); @@ -51,14 +53,18 @@ namespace D3dDdi static void setRepository(LUID luid, CompatWeakPtr repository); private: + const AdapterInfo& findInfo() const; + template HRESULT getCaps(D3DDDICAPS_TYPE type, Data& data, UINT size = sizeof(Data)) const; Int2 getAspectRatio(Win32::DisplayMode::Resolution res) const; + std::map getFixedFormatOps(const AdapterInfo& info) const; std::map getFormatOps() const; Float2 getScaleFactor() const; std::string getSupportedMsaaModes(const std::map& formatOps) const; DWORD getSupportedZBufferBitDepths(const std::map& formatOps) const; + bool isEmulatedRenderTargetFormat(D3DDDIFORMAT format, const std::map& formatOps) const; HANDLE m_adapter; D3DDDI_ADAPTERFUNCS m_origVtable; @@ -67,6 +73,7 @@ namespace D3dDdi LUID m_luid; std::wstring m_deviceName; CompatWeakPtr m_repository; + const AdapterInfo& m_info; static std::map s_adapters; static std::map s_adapterInfos; diff --git a/DDrawCompat/D3dDdi/Device.cpp b/DDrawCompat/D3dDdi/Device.cpp index f05d8ef..2a73649 100644 --- a/DDrawCompat/D3dDdi/Device.cpp +++ b/DDrawCompat/D3dDdi/Device.cpp @@ -73,25 +73,45 @@ namespace D3dDdi HRESULT Device::createPrivateResource(D3DDDIARG_CREATERESOURCE2& data) { - const bool isPalettized = D3DDDIFMT_P8 == data.Format; - const bool isTexture = data.Flags.Texture; - if (isPalettized) + LOG_FUNC("Device::createPrivateResource", data); + 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) { data.Format = D3DDDIFMT_L8; - data.Flags.Texture = 1; + if (!data.Flags.Texture) + { + data.Flags.Texture = 1; + 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) : m_origVtable.pfnCreateResource(m_device, reinterpret_cast(&data)); - if (isPalettized) - { - data.Format = D3DDDIFMT_P8; - data.Flags.Texture = isTexture; - } - - return result; + data.Format = origFormat; + data.MipLevels = origMipLevels; + data.Flags.Value = origFlags; + return LOG_RESULT(result); } Device* Device::findDeviceByResource(HANDLE resource) diff --git a/DDrawCompat/D3dDdi/FormatInfo.h b/DDrawCompat/D3dDdi/FormatInfo.h index 90ac9af..3c6e6c6 100644 --- a/DDrawCompat/D3dDdi/FormatInfo.h +++ b/DDrawCompat/D3dDdi/FormatInfo.h @@ -7,9 +7,11 @@ namespace D3dDdi { - static const auto FOURCC_RESZ = static_cast(MAKEFOURCC('R', 'E', 'S', 'Z')); + static const auto FOURCC_DF16 = static_cast(MAKEFOURCC('D', 'F', '1', '6')); + static const auto FOURCC_DF24 = static_cast(MAKEFOURCC('D', 'F', '2', '4')); static const auto FOURCC_INTZ = static_cast(MAKEFOURCC('I', 'N', 'T', 'Z')); static const auto FOURCC_NULL = static_cast(MAKEFOURCC('N', 'U', 'L', 'L')); + static const auto FOURCC_RESZ = static_cast(MAKEFOURCC('R', 'E', 'S', 'Z')); struct FormatInfo { diff --git a/DDrawCompat/D3dDdi/Resource.cpp b/DDrawCompat/D3dDdi/Resource.cpp index a409a98..5c171ac 100644 --- a/DDrawCompat/D3dDdi/Resource.cpp +++ b/DDrawCompat/D3dDdi/Resource.cpp @@ -97,7 +97,7 @@ namespace void logUnsupportedMsaaDepthBufferResolve() { - LOG_ONCE("Warning: Resolving multisampled depth buffers is not supported by the GPU. " + LOG_ONCE("Warning: Resolving multisampled depth buffers is not supported by the GPU driver. " "Disable antialiasing if experiencing visual glitches."); } } @@ -158,7 +158,8 @@ namespace D3dDdi } m_handle = m_fixedData.hResource; - if (D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool && m_origData.Flags.ZBuffer) + if (D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool && m_origData.Flags.ZBuffer && + !m_device.getAdapter().getInfo().isD3D9On12) { m_lockData.resize(m_origData.SurfCount); for (UINT i = 0; i < m_origData.SurfCount; ++i) @@ -207,13 +208,6 @@ namespace D3dDdi HRESULT Resource::blt(D3DDDIARG_BLT data) { - if (m_fixedData.Flags.ZBuffer && m_msaaSurface.resource && - !m_device.getAdapter().getInfo().isMsaaDepthResolveSupported) - { - logUnsupportedMsaaDepthBufferResolve(); - return S_OK; - } - if (!m_fixedData.Flags.MatchGdiPrimary && !isValidRect(data.DstSubResourceIndex, data.DstRect)) { return S_OK; @@ -243,6 +237,13 @@ namespace D3dDdi return m_device.getOrigVtable().pfnBlt(m_device, &data); } + if (srcResource->m_fixedData.Flags.ZBuffer && srcResource->m_msaaSurface.resource && + !m_device.getAdapter().getInfo().isMsaaDepthResolveSupported) + { + logUnsupportedMsaaDepthBufferResolve(); + return S_OK; + } + if (shouldBltViaCpu(data, *srcResource)) { return bltViaCpu(data, *srcResource); @@ -404,7 +405,8 @@ namespace D3dDdi } if (D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool && - (m_fixedData.Flags.ZBuffer && &dstRes == m_msaaSurface.resource && m_nullSurface.resource || + (m_fixedData.Flags.ZBuffer && + (m_nullSurface.resource && &dstRes == m_msaaSurface.resource || m_device.getAdapter().getInfo().isD3D9On12) || dstRes.m_fixedData.Flags.RenderTarget || !m_fixedData.Flags.ZBuffer && ( data.Flags.SrcColorKey || @@ -585,11 +587,15 @@ namespace D3dDdi flags.Value = g_resourceTypeFlags; flags.RenderTarget = 0; flags.Texture = 0; + if (m_device.getAdapter().getInfo().isD3D9On12) + { + flags.ZBuffer = 0; + } if (D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool || m_isSurfaceRepoResource || 0 == m_formatInfo.bytesPerPixel || 0 != (m_fixedData.Flags.Value & flags.Value) || - m_fixedData.Flags.Texture && !m_origData.Flags.RenderTarget) + m_fixedData.Flags.Texture && !m_origData.Flags.RenderTarget && !m_origData.Flags.ZBuffer) { return; } @@ -709,10 +715,6 @@ namespace D3dDdi else if (D3DDDIFMT_UNKNOWN != g_formatOverride) { m_fixedData.Format = g_formatOverride; - if (FOURCC_INTZ == g_formatOverride) - { - m_fixedData.Flags.Texture = 1; - } } else if (m_fixedData.Flags.RenderTarget && m_device.getAdapter().isEmulatedRenderTargetFormat(m_fixedData.Format)) { @@ -724,6 +726,19 @@ namespace D3dDdi m_fixedData.MultisampleType = g_msaaOverride.first; m_fixedData.MultisampleQuality = g_msaaOverride.second; } + else if (!m_fixedData.Flags.Texture && + !m_fixedData.Flags.MatchGdiPrimary && + 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)) + { + m_fixedData.Flags.Texture = 1; + m_fixedData.MipLevels = 1; + } + } if (D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool && 1 == m_fixedData.SurfCount && @@ -763,7 +778,7 @@ namespace D3dDdi else if (m_fixedData.Flags.ZBuffer && Config::Settings::DepthFormat::APP != Config::depthFormat.get() && getFormatInfo(m_fixedData.Format).depth.bitCount != Config::depthFormat.get()) { - auto& formatOps = m_device.getAdapter().getInfo().formatOps; + auto& formatOps = m_device.getAdapter().getInfo().fixedFormatOps; switch (Config::depthFormat.get()) { #define USE_FORMAT(format) if (formatOps.find(format) != formatOps.end()) return format @@ -873,11 +888,13 @@ namespace D3dDdi loadMsaaResolvedResource(subResourceIndex); if (m_fixedData.Flags.ZBuffer) { - if (m_nullSurface.resource) + bool isD3D9On12 = m_device.getAdapter().getInfo().isD3D9On12; + if (m_nullSurface.resource || isD3D9On12) { RECT r = m_msaaResolvedSurface.resource->getRect(0); m_device.getShaderBlitter().depthBlt( - *m_msaaSurface.resource, r, *m_msaaResolvedSurface.resource, r, *m_nullSurface.resource); + *m_msaaSurface.resource, r, *m_msaaResolvedSurface.resource, r, + isD3D9On12 ? nullptr : static_cast(*m_nullSurface.resource)); } } else @@ -925,7 +942,7 @@ namespace D3dDdi loadVidMemResource(subResourceIndex); const bool isScaled = static_cast(m_fixedData.pSurfList[0].Width) != m_scaledSize.cx || static_cast(m_fixedData.pSurfList[0].Height) != m_scaledSize.cy; - if (m_fixedData.Flags.ZBuffer || !isScaled) + if ((m_fixedData.Flags.ZBuffer || !isScaled) && !m_device.getAdapter().getInfo().isD3D9On12) { copySubResource(*m_msaaResolvedSurface.resource, *this, subResourceIndex); } @@ -971,7 +988,7 @@ namespace D3dDdi { const bool isScaled = static_cast(m_fixedData.pSurfList[0].Width) != m_scaledSize.cx || static_cast(m_fixedData.pSurfList[0].Height) != m_scaledSize.cy; - if (m_fixedData.Flags.ZBuffer || !isScaled) + if ((m_fixedData.Flags.ZBuffer || !isScaled) && !m_device.getAdapter().getInfo().isD3D9On12) { copySubResource(*this, *m_msaaResolvedSurface.resource, subResourceIndex); } @@ -1570,7 +1587,8 @@ namespace D3dDdi : DeviceState::ShaderConstF{}; if (m_fixedData.Flags.ZBuffer) { - m_device.getShaderBlitter().depthBlt(*dstRes, dstRect, *srcRes, srcRect, *m_nullSurface.resource); + m_device.getShaderBlitter().depthBlt(*dstRes, dstRect, *srcRes, srcRect, + m_device.getAdapter().getInfo().isD3D9On12 ? nullptr : static_cast(*m_nullSurface.resource)); } else { @@ -1682,8 +1700,8 @@ namespace D3dDdi g_msaaOverride = {}; } - if (m_fixedData.Flags.ZBuffer && m_msaaSurface.resource && - m_device.getAdapter().getInfo().isMsaaDepthResolveSupported) + auto& adapterInfo = m_device.getAdapter().getInfo(); + if (m_fixedData.Flags.ZBuffer && m_msaaSurface.resource && adapterInfo.isMsaaDepthResolveSupported) { g_msaaOverride = msaa; SurfaceRepository::get(m_device.getAdapter()).getSurface(m_nullSurface, @@ -1691,16 +1709,15 @@ namespace D3dDdi DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount); g_msaaOverride = {}; } - auto msaaResolvedSurfaceCaps = caps | ((m_fixedData.Flags.ZBuffer || !isScaled) ? 0 : DDSCAPS_TEXTURE); SurfaceRepository::get(m_device.getAdapter()).getSurface(m_msaaResolvedSurface, scaledSize.cx, scaledSize.cy, m_nullSurface.resource ? FOURCC_INTZ : formatConfig, - msaaResolvedSurfaceCaps, m_fixedData.SurfCount); + caps, m_fixedData.SurfCount); if (!m_msaaResolvedSurface.resource && m_msaaSurface.resource) { m_msaaSurface = {}; SurfaceRepository::get(m_device.getAdapter()).getSurface(m_msaaResolvedSurface, - scaledSize.cx, scaledSize.cy, formatConfig, msaaResolvedSurfaceCaps, m_fixedData.SurfCount); + scaledSize.cx, scaledSize.cy, formatConfig, caps, m_fixedData.SurfCount); } if (!m_fixedData.Flags.ZBuffer && m_msaaResolvedSurface.resource) diff --git a/DDrawCompat/D3dDdi/ShaderBlitter.cpp b/DDrawCompat/D3dDdi/ShaderBlitter.cpp index 7014494..1245103 100644 --- a/DDrawCompat/D3dDdi/ShaderBlitter.cpp +++ b/DDrawCompat/D3dDdi/ShaderBlitter.cpp @@ -264,10 +264,10 @@ namespace D3dDdi } void ShaderBlitter::depthBlt(const Resource& dstResource, const RECT& dstRect, - const Resource& srcResource, const RECT& srcRect, const Resource& nullResource) + const Resource& srcResource, const RECT& srcRect, HANDLE nullResource) { LOG_FUNC("ShaderBlitter::depthBlt", static_cast(dstResource), dstRect, - static_cast(srcResource), srcRect, static_cast(nullResource)); + static_cast(srcResource), srcRect, nullResource); const auto& srcSurface = srcResource.getFixedDesc().pSurfList[0]; const auto& dstSurface = dstResource.getFixedDesc().pSurfList[0]; @@ -289,7 +289,7 @@ namespace D3dDdi state.setTempRenderState({ D3DDDIRS_ALPHATESTENABLE, FALSE }); state.setTempRenderState({ D3DDDIRS_CULLMODE, D3DCULL_NONE }); state.setTempRenderState({ D3DDDIRS_DITHERENABLE, FALSE }); - state.setTempRenderState({ D3DDDIRS_ALPHABLENDENABLE, TRUE }); + state.setTempRenderState({ D3DDDIRS_ALPHABLENDENABLE, FALSE }); state.setTempRenderState({ D3DDDIRS_FOGENABLE, FALSE }); state.setTempRenderState({ D3DDDIRS_COLORKEYENABLE, FALSE }); state.setTempRenderState({ D3DDDIRS_STENCILENABLE, FALSE }); @@ -298,11 +298,6 @@ namespace D3dDdi state.setTempRenderState({ D3DDDIRS_MULTISAMPLEANTIALIAS, FALSE }); state.setTempRenderState({ D3DDDIRS_COLORWRITEENABLE, 0 }); - const UINT D3DBLEND_ZERO = 1; - const UINT D3DBLEND_ONE = 2; - state.setTempRenderState({ D3DDDIRS_SRCBLEND, D3DBLEND_ZERO }); - state.setTempRenderState({ D3DDDIRS_DESTBLEND, D3DBLEND_ONE }); - setTempTextureStage(0, srcResource, srcRect, D3DTEXF_POINT); state.setTempTextureStageState({ 0, D3DDDITSS_SRGBTEXTURE, FALSE }); diff --git a/DDrawCompat/D3dDdi/ShaderBlitter.h b/DDrawCompat/D3dDdi/ShaderBlitter.h index 8be90a5..00c62b2 100644 --- a/DDrawCompat/D3dDdi/ShaderBlitter.h +++ b/DDrawCompat/D3dDdi/ShaderBlitter.h @@ -27,7 +27,7 @@ namespace D3dDdi void cursorBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect, HCURSOR cursor, POINT pt); void depthBlt(const Resource& dstResource, const RECT& dstRect, - const Resource& srcResource, const RECT& srcRect, const Resource& nullResource); + const Resource& srcResource, const RECT& srcRect, HANDLE nullResource); void gammaBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect, const Resource& srcResource, const RECT& srcRect); void genBilinearBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect, diff --git a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp index 445dfec..ecc816e 100644 --- a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp +++ b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp @@ -25,6 +25,14 @@ namespace UINT g_bltSrcSubResourceIndex = 0; RECT g_bltSrcRect = {}; + template + typename DDraw::Types::TDdsCaps getCaps(TSurface* This) + { + DDraw::Types::TDdsCaps caps = {}; + getOrigVtable(This).GetCaps(This, &caps); + return caps; + } + template typename DDraw::Types::TSurfaceDesc getDesc(TSurface* This) { @@ -54,8 +62,8 @@ namespace lpDDSrcSurface = srcSurface->getImpl()->getBltSrc(lpDDSrcSurface); } - auto dstDesc = getDesc(This); - if (!(dstDesc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) || !(dstDesc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + auto dstCaps = getCaps(This); + if (!(dstCaps.dwCaps & DDSCAPS_3DDEVICE) || !(dstCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) { return bltFunc(This, lpDDSrcSurface, lpSrcRect); }