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

Fixed a potential GDI deadlock when using resolution scaling

See issue #197.
This commit is contained in:
narzoul 2023-02-25 19:26:27 +01:00
parent 21c52092b8
commit 841cf3307f
3 changed files with 11 additions and 20 deletions

View File

@ -673,7 +673,7 @@ namespace D3dDdi
m_isClampable = false;
}
void Resource::downscale(Resource*& rt, LONG& srcWidth, LONG& srcHeight, LONG dstWidth, LONG dstHeight, bool dryRun)
void Resource::downscale(Resource*& rt, LONG& srcWidth, LONG& srcHeight, LONG dstWidth, LONG dstHeight)
{
while (srcWidth > 2 * dstWidth || srcHeight > 2 * dstHeight)
{
@ -685,11 +685,8 @@ namespace D3dDdi
return;
}
if (!dryRun)
{
m_device.getShaderBlitter().textureBlt(*nextRt.resource, 0, { 0, 0, newSrcWidth, newSrcHeight },
*rt, 0, { 0, 0, srcWidth, srcHeight }, D3DTEXF_LINEAR);
}
m_device.getShaderBlitter().textureBlt(*nextRt.resource, 0, { 0, 0, newSrcWidth, newSrcHeight },
*rt, 0, { 0, 0, srcWidth, srcHeight }, D3DTEXF_LINEAR);
rt = nextRt.resource;
srcWidth = newSrcWidth;
srcHeight = newSrcHeight;
@ -1015,7 +1012,6 @@ namespace D3dDdi
auto srcRect = src->getRect(subResourceIndex);
auto dstRect = getRect(subResourceIndex);
SurfaceRepository::enableSurfaceCheck(false);
downscale(src, srcRect.right, srcRect.bottom, dstRect.right, dstRect.bottom);
auto srcIndex = src == m_msaaResolvedSurface.resource ? subResourceIndex : 0;
@ -1032,7 +1028,6 @@ namespace D3dDdi
srcIndex = 0;
}
}
SurfaceRepository::enableSurfaceCheck(true);
if (dstRect == srcRect)
{
@ -1786,18 +1781,11 @@ namespace D3dDdi
m_fixedData.pSurfList[0].Width, m_fixedData.pSurfList[0].Height, m_fixedData.Format,
DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount);
if (isScaled)
if (isScaled && m_device.getGdiResource() == this)
{
Resource* rt = m_msaaResolvedSurface.resource;
auto srcRect = rt->getRect(0);
auto dstRect = getRect(0);
const bool dryRun = true;
downscale(rt, srcRect.right, srcRect.bottom, dstRect.right, dstRect.bottom, dryRun);
if (dstRect != srcRect &&
!(m_device.getAdapter().getInfo().formatOps.at(m_fixedData.Format).Operations & FORMATOP_SRGBWRITE))
{
getNextRenderTarget(rt, dstRect.right, dstRect.bottom);
}
loadMsaaResolvedResource(0);
m_lockData[0].isVidMemUpToDate = false;
loadVidMemResource(0);
}
}
}

View File

@ -108,7 +108,7 @@ namespace D3dDdi
void createGdiLockResource();
void createLockResource();
void createSysMemResource(const std::vector<D3DDDI_SURFACEINFO>& surfaceInfo);
void downscale(Resource*& rt, LONG& srcWidth, LONG& srcHeight, LONG dstWidth, LONG dstHeight, bool dryRun = false);
void downscale(Resource*& rt, LONG& srcWidth, LONG& srcHeight, LONG dstWidth, LONG dstHeight);
void fixResourceData();
D3DDDIFORMAT getFormatConfig();
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> getMultisampleConfig();

View File

@ -1,6 +1,7 @@
#include <D3dDdi/Device.h>
#include <D3dDdi/Resource.h>
#include <D3dDdi/ScopedCriticalSection.h>
#include <D3dDdi/SurfaceRepository.h>
#include <DDraw/RealPrimarySurface.h>
#include <DDraw/Surfaces/PrimarySurface.h>
#include <Gdi/CompatDc.h>
@ -19,6 +20,7 @@ namespace Gdi
auto gdiResource = D3dDdi::Device::getGdiResource();
if (gdiResource)
{
D3dDdi::SurfaceRepository::enableSurfaceCheck(false);
if (isReadOnly)
{
gdiResource->prepareForCpuRead(0);
@ -27,6 +29,7 @@ namespace Gdi
{
gdiResource->prepareForCpuWrite(0);
}
D3dDdi::SurfaceRepository::enableSurfaceCheck(true);
}
}
else