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

Extend lock surfaces to non-managed textures

Fixes issues with locked texture pitch. See issue #320.
This commit is contained in:
narzoul 2024-06-16 14:35:06 +02:00
parent 3d1197f863
commit 29a2b9246b
7 changed files with 68 additions and 3 deletions

View File

@ -486,6 +486,18 @@ namespace D3dDdi
return S_OK;
}
HRESULT Device::pfnTexBlt(const D3DDDIARG_TEXBLT* data)
{
prepareForTextureBlt(data->hDstResource, data->hSrcResource);
return m_origVtable.pfnTexBlt(m_device, data);
}
HRESULT Device::pfnTexBlt1(const D3DDDIARG_TEXBLT1* data)
{
prepareForTextureBlt(data->hDstResource, data->hSrcResource);
return m_origVtable.pfnTexBlt1(m_device, data);
}
HRESULT Device::pfnUnlock(const D3DDDIARG_UNLOCK* data)
{
flushPrimitives();
@ -532,6 +544,22 @@ namespace D3dDdi
return m_origVtable.pfnValidateDevice(m_device, data);
}
void Device::prepareForTextureBlt(HANDLE dstResource, HANDLE srcResource)
{
flushPrimitives();
auto it = m_resources.find(dstResource);
if (it != m_resources.end())
{
it->second->prepareForGpuWriteAll();
}
it = m_resources.find(srcResource);
if (it != m_resources.end())
{
it->second->prepareForGpuReadAll();
}
}
void Device::updateAllConfig()
{
g_isConfigUpdatePending = true;

View File

@ -50,6 +50,8 @@ namespace D3dDdi
HRESULT pfnPresent(const D3DDDIARG_PRESENT* data);
HRESULT pfnPresent1(D3DDDIARG_PRESENT1* data);
HRESULT pfnSetPalette(const D3DDDIARG_SETPALETTE* data);
HRESULT pfnTexBlt(const D3DDDIARG_TEXBLT* data);
HRESULT pfnTexBlt1(const D3DDDIARG_TEXBLT1* data);
HRESULT pfnUnlock(const D3DDDIARG_UNLOCK* data);
HRESULT pfnUpdatePalette(const D3DDDIARG_UPDATEPALETTE* data, const PALETTEENTRY* paletteData);
HRESULT pfnValidateDevice(D3DDDIARG_VALIDATETEXTURESTAGESTATE* data);
@ -85,6 +87,7 @@ namespace D3dDdi
private:
HRESULT clear(D3DDDIARG_CLEAR data, UINT numRect, const RECT* rect, Resource* resource, DWORD flags);
UINT detectColorKeyMethod();
void prepareForTextureBlt(HANDLE dstResource, HANDLE srcResource);
static void updateAllConfigNow();
D3DDDI_DEVICEFUNCS m_origVtable;

View File

@ -67,6 +67,8 @@ namespace
SET_DEVICE_FUNC(pfnPresent);
SET_DEVICE_FUNC(pfnPresent1);
SET_DEVICE_FUNC(pfnSetPalette);
SET_DEVICE_FUNC(pfnTexBlt);
SET_DEVICE_FUNC(pfnTexBlt1);
SET_DEVICE_FUNC(pfnUnlock);
SET_DEVICE_FUNC(pfnUpdatePalette);
SET_DEVICE_FUNC(pfnValidateDevice);
@ -103,8 +105,6 @@ namespace
SET_FLUSH_PRIMITIVES_FUNC(pfnSetClipPlane);
SET_FLUSH_PRIMITIVES_FUNC(pfnSetScissorRect);
SET_FLUSH_PRIMITIVES_FUNC(pfnStateSet);
SET_FLUSH_PRIMITIVES_FUNC(pfnTexBlt);
SET_FLUSH_PRIMITIVES_FUNC(pfnTexBlt1);
}
}

View File

@ -601,7 +601,7 @@ namespace D3dDdi
m_isSurfaceRepoResource ||
0 == m_formatInfo.bytesPerPixel ||
0 != (m_fixedData.Flags.Value & flags.Value) ||
m_fixedData.Flags.Texture && !m_origData.Flags.RenderTarget && !m_origData.Flags.ZBuffer)
m_fixedData.Flags.Texture && (DDraw::Surface::getCurrentSurfaceCaps().dwCaps2 & 0x100000)) // managed texture
{
return;
}
@ -1190,6 +1190,17 @@ namespace D3dDdi
return *this;
}
void Resource::prepareForGpuReadAll()
{
if (m_lockResource)
{
for (UINT i = 0; i < m_lockData.size(); ++i)
{
prepareForGpuRead(i);
}
}
}
Resource& Resource::prepareForGpuWrite(UINT subResourceIndex)
{
m_isColorKeyedSurfaceUpToDate = false;
@ -1219,6 +1230,17 @@ namespace D3dDdi
return *this;
}
void Resource::prepareForGpuWriteAll()
{
if (m_lockResource)
{
for (UINT i = 0; i < m_lockData.size(); ++i)
{
prepareForGpuWrite(i);
}
}
}
Resource& Resource::prepareForTextureRead(UINT stage)
{
if (m_lockResource)
@ -1817,6 +1839,7 @@ namespace D3dDdi
}
auto rect = getRect(0);
m_palettizedTexture->prepareForGpuReadAll();
m_device.getShaderBlitter().palettizedBlt(*this, 0, rect, *m_palettizedTexture, 0, rect, palettePtr);
m_palettizedTexture->m_isPalettizedTextureUpToDate = true;

View File

@ -53,7 +53,9 @@ namespace D3dDdi
void prepareForCpuRead(UINT subResourceIndex);
void prepareForCpuWrite(UINT subResourceIndex);
Resource& prepareForGpuRead(UINT subResourceIndex);
void prepareForGpuReadAll();
Resource& prepareForGpuWrite(UINT subResourceIndex);
void prepareForGpuWriteAll();
Resource& prepareForTextureRead(UINT stage);
HRESULT presentationBlt(D3DDDIARG_BLT data, Resource* srcResource);
void scaleRect(RECT& rect);

View File

@ -16,6 +16,7 @@ DEFINE_GUID(IID_CompatSurfacePrivateData,
namespace
{
DDSCAPS2 g_currentSurfaceCaps = {};
std::set<DDraw::Surface*> g_surfaces;
void heapFree(void* p)
@ -105,7 +106,9 @@ namespace DDraw
desc.ddsCaps.dwCaps &= ~(DDSCAPS_COMPLEX | DDSCAPS_MIPMAP);
}
memcpy(&g_currentSurfaceCaps, &desc.ddsCaps, sizeof(desc.ddsCaps));
HRESULT result = dd->CreateSurface(&dd, &desc, &surface, nullptr);
g_currentSurfaceCaps = {};
if (FAILED(result))
{
return result;
@ -189,6 +192,11 @@ namespace DDraw
}
}
DDSCAPS2 Surface::getCurrentSurfaceCaps()
{
return g_currentSurfaceCaps;
}
template <>
SurfaceImpl<IDirectDrawSurface>* Surface::getImpl<IDirectDrawSurface>() const { return m_impl.get(); }
template <>

View File

@ -33,6 +33,7 @@ namespace DDraw
CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface, std::unique_ptr<Surface> privateData);
static void enumSurfaces(const std::function<void(Surface&)>& callback);
static DDSCAPS2 getCurrentSurfaceCaps();
template <typename TSurface>
static Surface* getSurface(TSurface& dds);