1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Updated waitForIdle implementation

Fixes performance issues on old versions of igd9trinity32.dll.
This commit is contained in:
narzoul 2024-08-17 13:51:05 +02:00
parent 1c4445717a
commit c8c6bd0ce9
10 changed files with 66 additions and 47 deletions

View File

@ -586,33 +586,6 @@ namespace D3dDdi
m_state.updateConfig(); 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<HANDLE, Device> Device::s_devices; std::map<HANDLE, Device> Device::s_devices;
bool Device::s_isFlushEnabled = true; bool Device::s_isFlushEnabled = true;
} }

View File

@ -72,7 +72,6 @@ namespace D3dDdi
void setDepthStencil(HANDLE resource); void setDepthStencil(HANDLE resource);
void setRenderTarget(const D3DDDIARG_SETRENDERTARGET& data); void setRenderTarget(const D3DDDIARG_SETRENDERTARGET& data);
void updateConfig(); void updateConfig();
void waitForIdle();
static void add(Adapter& adapter, HANDLE device); static void add(Adapter& adapter, HANDLE device);
static Device& get(HANDLE device) { return s_devices.find(device)->second; } static Device& get(HANDLE device) { return s_devices.find(device)->second; }

View File

@ -1851,4 +1851,46 @@ namespace D3dDdi
m_palettizedTexture->m_isPalettizedTextureUpToDate = true; m_palettizedTexture->m_isPalettizedTextureUpToDate = true;
m_paletteColorKeyIndex = paletteColorKeyIndex; 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);
}
} }

View File

@ -66,6 +66,7 @@ namespace D3dDdi
HRESULT unlock(const D3DDDIARG_UNLOCK& data); HRESULT unlock(const D3DDDIARG_UNLOCK& data);
void updateConfig(); void updateConfig();
void updatePalettizedTexture(UINT stage); void updatePalettizedTexture(UINT stage);
void waitForIdle(UINT subResourceIndex);
static void enableConfig(bool enable); static void enableConfig(bool enable);
static void setFormatOverride(D3DDDIFORMAT format); static void setFormatOverride(D3DDDIFORMAT format);

View File

@ -333,6 +333,11 @@ namespace D3dDdi
return surface; 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, SurfaceRepository::Surface& SurfaceRepository::getTempSurface(Surface& surface, DWORD width, DWORD height,
D3DDDIFORMAT format, DWORD caps, UINT surfaceCount) D3DDDIFORMAT format, DWORD caps, UINT surfaceCount)
{ {

View File

@ -49,6 +49,7 @@ namespace D3dDdi
const Resource* currentSrcRt = nullptr, const Resource* currentDstRt = nullptr); const Resource* currentSrcRt = nullptr, const Resource* currentDstRt = nullptr);
Surface& getSurface(Surface& surface, DWORD width, DWORD height, Surface& getSurface(Surface& surface, DWORD width, DWORD height,
D3DDDIFORMAT format, DWORD caps, UINT surfaceCount = 1, DWORD caps2 = 0); D3DDDIFORMAT format, DWORD caps, UINT surfaceCount = 1, DWORD caps2 = 0);
Surface& getSyncSurface(D3DDDIFORMAT format);
Surface& getTempSysMemSurface(DWORD width, DWORD height); Surface& getTempSysMemSurface(DWORD width, DWORD height);
Surface& getTempSurface(Surface& surface, DWORD width, DWORD height, Surface& getTempSurface(Surface& surface, DWORD width, DWORD height,
D3DDDIFORMAT format, DWORD caps, UINT surfaceCount = 1); D3DDDIFORMAT format, DWORD caps, UINT surfaceCount = 1);
@ -89,6 +90,7 @@ namespace D3dDdi
std::array<Surface, 3> m_hqRenderTargets; std::array<Surface, 3> m_hqRenderTargets;
std::map<D3DDDIFORMAT, Surface> m_textures; std::map<D3DDDIFORMAT, Surface> m_textures;
std::vector<Surface> m_releasedSurfaces; std::vector<Surface> m_releasedSurfaces;
std::map<D3DDDIFORMAT, Surface> m_syncSurface;
Surface m_sysMemSurface; Surface m_sysMemSurface;
Surface m_windowedBackBuffer; Surface m_windowedBackBuffer;
CompatPtr<IDirectDrawSurface7> m_windowedPrimary; CompatPtr<IDirectDrawSurface7> m_windowedPrimary;

View File

@ -509,10 +509,9 @@ namespace DDraw
return DD_OK; return DD_OK;
} }
HRESULT RealPrimarySurface::flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags) void RealPrimarySurface::flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags)
{ {
const DWORD flipInterval = getFlipInterval(flags); const DWORD flipInterval = getFlipInterval(flags);
PrimarySurface::waitForIdle();
Compat::ScopedCriticalSection lock(g_presentCs); Compat::ScopedCriticalSection lock(g_presentCs);
scheduleUpdate(); scheduleUpdate();
@ -527,8 +526,6 @@ namespace DDraw
{ {
g_lastFlipSurface = nullptr; g_lastFlipSurface = nullptr;
} }
return DD_OK;
} }
int RealPrimarySurface::flush() int RealPrimarySurface::flush()

View File

@ -13,7 +13,7 @@ namespace DDraw
{ {
public: public:
static HRESULT create(CompatRef<IDirectDraw> dd); static HRESULT create(CompatRef<IDirectDraw> dd);
static HRESULT flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags); static void flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags);
static int flush(); static int flush();
static HRESULT getGammaRamp(DDGAMMARAMP* rampData); static HRESULT getGammaRamp(DDGAMMARAMP* rampData);
static HWND getPresentationWindow(); static HWND getPresentationWindow();

View File

@ -3,6 +3,7 @@
#include <D3dDdi/Device.h> #include <D3dDdi/Device.h>
#include <D3dDdi/KernelModeThunks.h> #include <D3dDdi/KernelModeThunks.h>
#include <D3dDdi/Resource.h> #include <D3dDdi/Resource.h>
#include <D3dDdi/ScopedCriticalSection.h>
#include <D3dDdi/SurfaceRepository.h> #include <D3dDdi/SurfaceRepository.h>
#include <DDraw/DirectDraw.h> #include <DDraw/DirectDraw.h>
#include <DDraw/DirectDrawSurface.h> #include <DDraw/DirectDrawSurface.h>
@ -17,10 +18,10 @@
namespace namespace
{ {
CompatWeakPtr<IDirectDrawSurface7> g_primarySurface; CompatWeakPtr<IDirectDrawSurface7> g_primarySurface;
D3dDdi::Device* g_device = nullptr;
HANDLE g_gdiDriverResource = nullptr; HANDLE g_gdiDriverResource = nullptr;
HANDLE g_gdiRuntimeResource = nullptr; HANDLE g_gdiRuntimeResource = nullptr;
HANDLE g_frontResource = nullptr; D3dDdi::Resource* g_frontResource = nullptr;
UINT g_frontResourceIndex = 0;
DWORD g_origCaps = 0; DWORD g_origCaps = 0;
HWND g_deviceWindow = nullptr; HWND g_deviceWindow = nullptr;
HPALETTE g_palette = nullptr; HPALETTE g_palette = nullptr;
@ -34,10 +35,10 @@ namespace DDraw
{ {
LOG_FUNC("PrimarySurface::~PrimarySurface"); LOG_FUNC("PrimarySurface::~PrimarySurface");
g_device = nullptr;
g_gdiRuntimeResource = nullptr; g_gdiRuntimeResource = nullptr;
g_gdiDriverResource = nullptr; g_gdiDriverResource = nullptr;
g_frontResource = nullptr; g_frontResource = nullptr;
g_frontResourceIndex = 0;
g_primarySurface = nullptr; g_primarySurface = nullptr;
g_origCaps = 0; g_origCaps = 0;
g_deviceWindow = nullptr; g_deviceWindow = nullptr;
@ -111,7 +112,6 @@ namespace DDraw
ResizePalette(g_palette, 256); ResizePalette(g_palette, 256);
} }
g_device = D3dDdi::Device::findDeviceByResource(DirectDrawSurface::getDriverResourceHandle(*surface));
data->restore(); data->restore();
D3dDdi::Device::updateAllConfig(); D3dDdi::Device::updateAllConfig();
return LOG_RESULT(DD_OK); return LOG_RESULT(DD_OK);
@ -215,7 +215,7 @@ namespace DDraw
HANDLE PrimarySurface::getFrontResource() HANDLE PrimarySurface::getFrontResource()
{ {
return g_frontResource; return *g_frontResource;
} }
HANDLE PrimarySurface::getGdiResource() HANDLE PrimarySurface::getGdiResource()
@ -260,7 +260,7 @@ namespace DDraw
g_gdiRuntimeResource = DirectDrawSurface::getRuntimeResourceHandle(*g_primarySurface); g_gdiRuntimeResource = DirectDrawSurface::getRuntimeResourceHandle(*g_primarySurface);
updateFrontResource(); updateFrontResource();
g_gdiDriverResource = g_frontResource; g_gdiDriverResource = *g_frontResource;
D3dDdi::Device::setGdiResourceHandle(g_gdiDriverResource); D3dDdi::Device::setGdiResourceHandle(g_gdiDriverResource);
DDSCAPS2 caps = {}; DDSCAPS2 caps = {};
@ -324,7 +324,8 @@ namespace DDraw
void PrimarySurface::updateFrontResource() 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() void PrimarySurface::updatePalette()
@ -360,10 +361,8 @@ namespace DDraw
void PrimarySurface::waitForIdle() void PrimarySurface::waitForIdle()
{ {
if (g_device) D3dDdi::ScopedCriticalSection lock;
{ g_frontResource->waitForIdle(g_frontResourceIndex);
g_device->waitForIdle();
}
} }
CompatWeakPtr<IDirectDrawPalette> PrimarySurface::s_palette; CompatWeakPtr<IDirectDrawPalette> PrimarySurface::s_palette;

View File

@ -198,13 +198,14 @@ namespace DDraw
} }
PrimarySurface::updateFrontResource(); PrimarySurface::updateFrontResource();
result = RealPrimarySurface::flip(surfaceTargetOverride, dwFlags); RealPrimarySurface::flip(surfaceTargetOverride, dwFlags);
if (SUCCEEDED(result) && Config::Settings::FpsLimiter::FLIPEND == Config::fpsLimiter.get()) PrimarySurface::waitForIdle();
if (Config::Settings::FpsLimiter::FLIPEND == Config::fpsLimiter.get())
{ {
DDraw::RealPrimarySurface::waitForFlip(m_data->getDDS()); DDraw::RealPrimarySurface::waitForFlip(m_data->getDDS());
RealPrimarySurface::waitForFlipFpsLimit(); RealPrimarySurface::waitForFlipFpsLimit();
} }
return result; return DD_OK;
} }
template <typename TSurface> template <typename TSurface>