diff --git a/DDrawCompat/D3dDdi/Device.cpp b/DDrawCompat/D3dDdi/Device.cpp index 7ec10f5..6f0e245 100644 --- a/DDrawCompat/D3dDdi/Device.cpp +++ b/DDrawCompat/D3dDdi/Device.cpp @@ -586,33 +586,6 @@ namespace D3dDdi m_state.updateConfig(); } - void Device::waitForIdle() - { - D3dDdi::ScopedCriticalSection lock; - flushPrimitives(); - D3DDDIARG_ISSUEQUERY issueQuery = {}; - issueQuery.hQuery = m_eventQuery; - issueQuery.Flags.End = 1; - m_origVtable.pfnIssueQuery(m_device, &issueQuery); - - if (m_origVtable.pfnFlush1) - { - m_origVtable.pfnFlush1(m_device, 0); - } - else - { - m_origVtable.pfnFlush(m_device); - } - - BOOL result = FALSE; - D3DDDIARG_GETQUERYDATA getQueryData = {}; - getQueryData.hQuery = m_eventQuery; - getQueryData.pData = &result; - while (S_FALSE == m_origVtable.pfnGetQueryData(m_device, &getQueryData)) - { - } - } - std::map Device::s_devices; bool Device::s_isFlushEnabled = true; } diff --git a/DDrawCompat/D3dDdi/Device.h b/DDrawCompat/D3dDdi/Device.h index 4ddf9f9..d31883d 100644 --- a/DDrawCompat/D3dDdi/Device.h +++ b/DDrawCompat/D3dDdi/Device.h @@ -72,7 +72,6 @@ namespace D3dDdi void setDepthStencil(HANDLE resource); void setRenderTarget(const D3DDDIARG_SETRENDERTARGET& data); void updateConfig(); - void waitForIdle(); static void add(Adapter& adapter, HANDLE device); static Device& get(HANDLE device) { return s_devices.find(device)->second; } diff --git a/DDrawCompat/D3dDdi/Resource.cpp b/DDrawCompat/D3dDdi/Resource.cpp index ef5f9b7..6ef0593 100644 --- a/DDrawCompat/D3dDdi/Resource.cpp +++ b/DDrawCompat/D3dDdi/Resource.cpp @@ -1851,4 +1851,46 @@ namespace D3dDdi m_palettizedTexture->m_isPalettizedTextureUpToDate = true; m_paletteColorKeyIndex = paletteColorKeyIndex; } + + void Resource::waitForIdle(UINT subResourceIndex) + { + m_device.flushPrimitives(); + Resource* srcResource = this; + RECT rect = { 0, 0, 1, 1 }; + + if (m_lockResource) + { + if (m_lockData[subResourceIndex].isMsaaUpToDate || + m_lockData[subResourceIndex].isMsaaResolvedUpToDate) + { + if (!m_lockData[subResourceIndex].isMsaaResolvedUpToDate) + { + copySubResourceRegion(*m_msaaResolvedSurface.resource, subResourceIndex, rect, + *m_msaaSurface.resource, subResourceIndex, rect); + } + srcResource = m_msaaResolvedSurface.resource; + } + else if (!m_lockData[subResourceIndex].isVidMemUpToDate) + { + return; + } + } + + auto& syncSurface = m_device.getRepo().getSyncSurface(srcResource->m_fixedData.Format); + if (!syncSurface.resource) + { + return; + } + + copySubResourceRegion(*syncSurface.resource, 0, rect, *srcResource, subResourceIndex, rect); + + D3DDDIARG_LOCK lock = {}; + lock.hResource = *syncSurface.resource; + lock.Flags.ReadOnly = 1; + m_device.getOrigVtable().pfnLock(m_device, &lock); + + D3DDDIARG_UNLOCK unlock = {}; + unlock.hResource = *syncSurface.resource; + m_device.getOrigVtable().pfnUnlock(m_device, &unlock); + } } diff --git a/DDrawCompat/D3dDdi/Resource.h b/DDrawCompat/D3dDdi/Resource.h index 0379d30..f069ed7 100644 --- a/DDrawCompat/D3dDdi/Resource.h +++ b/DDrawCompat/D3dDdi/Resource.h @@ -66,6 +66,7 @@ namespace D3dDdi HRESULT unlock(const D3DDDIARG_UNLOCK& data); void updateConfig(); void updatePalettizedTexture(UINT stage); + void waitForIdle(UINT subResourceIndex); static void enableConfig(bool enable); static void setFormatOverride(D3DDDIFORMAT format); diff --git a/DDrawCompat/D3dDdi/SurfaceRepository.cpp b/DDrawCompat/D3dDdi/SurfaceRepository.cpp index d4210e7..990d2dd 100644 --- a/DDrawCompat/D3dDdi/SurfaceRepository.cpp +++ b/DDrawCompat/D3dDdi/SurfaceRepository.cpp @@ -333,6 +333,11 @@ namespace D3dDdi return surface; } + SurfaceRepository::Surface& SurfaceRepository::getSyncSurface(D3DDDIFORMAT format) + { + return getSurface(m_syncSurface[format], 16, 16, format, DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY); + } + SurfaceRepository::Surface& SurfaceRepository::getTempSurface(Surface& surface, DWORD width, DWORD height, D3DDDIFORMAT format, DWORD caps, UINT surfaceCount) { diff --git a/DDrawCompat/D3dDdi/SurfaceRepository.h b/DDrawCompat/D3dDdi/SurfaceRepository.h index 0f3d412..65e1f50 100644 --- a/DDrawCompat/D3dDdi/SurfaceRepository.h +++ b/DDrawCompat/D3dDdi/SurfaceRepository.h @@ -49,6 +49,7 @@ namespace D3dDdi const Resource* currentSrcRt = nullptr, const Resource* currentDstRt = nullptr); Surface& getSurface(Surface& surface, DWORD width, DWORD height, D3DDDIFORMAT format, DWORD caps, UINT surfaceCount = 1, DWORD caps2 = 0); + Surface& getSyncSurface(D3DDDIFORMAT format); Surface& getTempSysMemSurface(DWORD width, DWORD height); Surface& getTempSurface(Surface& surface, DWORD width, DWORD height, D3DDDIFORMAT format, DWORD caps, UINT surfaceCount = 1); @@ -89,6 +90,7 @@ namespace D3dDdi std::array m_hqRenderTargets; std::map m_textures; std::vector m_releasedSurfaces; + std::map m_syncSurface; Surface m_sysMemSurface; Surface m_windowedBackBuffer; CompatPtr m_windowedPrimary; diff --git a/DDrawCompat/DDraw/RealPrimarySurface.cpp b/DDrawCompat/DDraw/RealPrimarySurface.cpp index a170749..47840d8 100644 --- a/DDrawCompat/DDraw/RealPrimarySurface.cpp +++ b/DDrawCompat/DDraw/RealPrimarySurface.cpp @@ -509,10 +509,9 @@ namespace DDraw return DD_OK; } - HRESULT RealPrimarySurface::flip(CompatPtr surfaceTargetOverride, DWORD flags) + void RealPrimarySurface::flip(CompatPtr surfaceTargetOverride, DWORD flags) { const DWORD flipInterval = getFlipInterval(flags); - PrimarySurface::waitForIdle(); Compat::ScopedCriticalSection lock(g_presentCs); scheduleUpdate(); @@ -527,8 +526,6 @@ namespace DDraw { g_lastFlipSurface = nullptr; } - - return DD_OK; } int RealPrimarySurface::flush() diff --git a/DDrawCompat/DDraw/RealPrimarySurface.h b/DDrawCompat/DDraw/RealPrimarySurface.h index d885616..69f895a 100644 --- a/DDrawCompat/DDraw/RealPrimarySurface.h +++ b/DDrawCompat/DDraw/RealPrimarySurface.h @@ -13,7 +13,7 @@ namespace DDraw { public: static HRESULT create(CompatRef dd); - static HRESULT flip(CompatPtr surfaceTargetOverride, DWORD flags); + static void flip(CompatPtr surfaceTargetOverride, DWORD flags); static int flush(); static HRESULT getGammaRamp(DDGAMMARAMP* rampData); static HWND getPresentationWindow(); diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp index da1835a..812b41a 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -17,10 +18,10 @@ namespace { CompatWeakPtr g_primarySurface; - D3dDdi::Device* g_device = nullptr; HANDLE g_gdiDriverResource = nullptr; HANDLE g_gdiRuntimeResource = nullptr; - HANDLE g_frontResource = nullptr; + D3dDdi::Resource* g_frontResource = nullptr; + UINT g_frontResourceIndex = 0; DWORD g_origCaps = 0; HWND g_deviceWindow = nullptr; HPALETTE g_palette = nullptr; @@ -34,10 +35,10 @@ namespace DDraw { LOG_FUNC("PrimarySurface::~PrimarySurface"); - g_device = nullptr; g_gdiRuntimeResource = nullptr; g_gdiDriverResource = nullptr; g_frontResource = nullptr; + g_frontResourceIndex = 0; g_primarySurface = nullptr; g_origCaps = 0; g_deviceWindow = nullptr; @@ -111,7 +112,6 @@ namespace DDraw ResizePalette(g_palette, 256); } - g_device = D3dDdi::Device::findDeviceByResource(DirectDrawSurface::getDriverResourceHandle(*surface)); data->restore(); D3dDdi::Device::updateAllConfig(); return LOG_RESULT(DD_OK); @@ -215,7 +215,7 @@ namespace DDraw HANDLE PrimarySurface::getFrontResource() { - return g_frontResource; + return *g_frontResource; } HANDLE PrimarySurface::getGdiResource() @@ -260,7 +260,7 @@ namespace DDraw g_gdiRuntimeResource = DirectDrawSurface::getRuntimeResourceHandle(*g_primarySurface); updateFrontResource(); - g_gdiDriverResource = g_frontResource; + g_gdiDriverResource = *g_frontResource; D3dDdi::Device::setGdiResourceHandle(g_gdiDriverResource); DDSCAPS2 caps = {}; @@ -324,7 +324,8 @@ namespace DDraw void PrimarySurface::updateFrontResource() { - g_frontResource = DirectDrawSurface::getDriverResourceHandle(*g_primarySurface); + g_frontResource = D3dDdi::Device::findResource(DirectDrawSurface::getDriverResourceHandle(*g_primarySurface)); + g_frontResourceIndex = DirectDrawSurface::getSubResourceIndex(*g_primarySurface); } void PrimarySurface::updatePalette() @@ -360,10 +361,8 @@ namespace DDraw void PrimarySurface::waitForIdle() { - if (g_device) - { - g_device->waitForIdle(); - } + D3dDdi::ScopedCriticalSection lock; + g_frontResource->waitForIdle(g_frontResourceIndex); } CompatWeakPtr PrimarySurface::s_palette; diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp index 826339a..3c605fe 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp @@ -198,13 +198,14 @@ namespace DDraw } PrimarySurface::updateFrontResource(); - result = RealPrimarySurface::flip(surfaceTargetOverride, dwFlags); - if (SUCCEEDED(result) && Config::Settings::FpsLimiter::FLIPEND == Config::fpsLimiter.get()) + RealPrimarySurface::flip(surfaceTargetOverride, dwFlags); + PrimarySurface::waitForIdle(); + if (Config::Settings::FpsLimiter::FLIPEND == Config::fpsLimiter.get()) { DDraw::RealPrimarySurface::waitForFlip(m_data->getDDS()); RealPrimarySurface::waitForFlipFpsLimit(); } - return result; + return DD_OK; } template