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

Force resolution scaling on primary surface

This commit is contained in:
narzoul 2022-05-18 23:07:08 +02:00
parent 22c61dc115
commit 0bc2694cce
3 changed files with 69 additions and 21 deletions

View File

@ -11,6 +11,7 @@
#include <D3dDdi/KernelModeThunks.h> #include <D3dDdi/KernelModeThunks.h>
#include <D3dDdi/Log/DeviceFuncsLog.h> #include <D3dDdi/Log/DeviceFuncsLog.h>
#include <D3dDdi/Resource.h> #include <D3dDdi/Resource.h>
#include <D3dDdi/ScopedCriticalSection.h>
#include <D3dDdi/SurfaceRepository.h> #include <D3dDdi/SurfaceRepository.h>
#include <DDraw/Blitter.h> #include <DDraw/Blitter.h>
#include <DDraw/RealPrimarySurface.h> #include <DDraw/RealPrimarySurface.h>
@ -118,6 +119,7 @@ namespace D3dDdi
, m_isOversized(false) , m_isOversized(false)
, m_isSurfaceRepoResource(SurfaceRepository::inCreateSurface()) , m_isSurfaceRepoResource(SurfaceRepository::inCreateSurface())
, m_isClampable(true) , m_isClampable(true)
, m_isPrimary(false)
{ {
if (m_origData.Flags.VertexBuffer && if (m_origData.Flags.VertexBuffer &&
m_origData.Flags.MightDrawFromLocked && m_origData.Flags.MightDrawFromLocked &&
@ -352,18 +354,38 @@ namespace D3dDdi
HRESULT Resource::bltViaGpu(D3DDDIARG_BLT data, Resource& srcResource) HRESULT Resource::bltViaGpu(D3DDDIARG_BLT data, Resource& srcResource)
{ {
if (D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool && Resource* srcRes = &srcResource;
(m_fixedData.Flags.RenderTarget || data.Flags.SrcColorKey || data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown)) if (m_msaaResolvedSurface.resource && srcResource.m_msaaResolvedSurface.resource &&
(srcResource.m_lockData[data.SrcSubResourceIndex].isMsaaResolvedUpToDate ||
srcResource.m_lockData[data.SrcSubResourceIndex].isMsaaUpToDate))
{ {
if (SUCCEEDED(shaderBlt(data, srcResource))) srcResource.loadMsaaResolvedResource(data.SrcSubResourceIndex);
{ srcRes = srcResource.m_msaaResolvedSurface.resource;
return S_OK; data.hSrcResource = *srcRes;
} srcResource.scaleRect(data.SrcRect);
loadMsaaResolvedResource(data.DstSubResourceIndex);
} }
else else
{ {
srcResource.prepareForBltSrc(data); srcResource.prepareForBltSrc(data);
prepareForBltDst(data); }
Resource& dstRes = prepareForBltDst(data);
if (D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool &&
(m_fixedData.Flags.RenderTarget || data.Flags.SrcColorKey || data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown) &&
SUCCEEDED(shaderBlt(data, dstRes, *srcRes)))
{
return S_OK;
}
if (&dstRes != this && D3DDDIPOOL_SYSTEMMEM == srcRes->m_fixedData.Pool)
{
RECT r = { 0, 0, data.SrcRect.right - data.SrcRect.left, data.SrcRect.bottom - data.SrcRect.top };
copySubResourceRegion(*this, data.DstSubResourceIndex, r, *srcRes, data.SrcSubResourceIndex, data.SrcRect);
data.hSrcResource = *this;
data.SrcSubResourceIndex = data.DstSubResourceIndex;
data.SrcRect = r;
} }
auto bltFilter = Config::bltFilter.get(); auto bltFilter = Config::bltFilter.get();
@ -666,8 +688,7 @@ namespace D3dDdi
D3DDDIFORMAT Resource::getFormatConfig() D3DDDIFORMAT Resource::getFormatConfig()
{ {
if (m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.MatchGdiPrimary && D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool && if (D3DDDIFMT_X8R8G8B8 == m_fixedData.Format || D3DDDIFMT_R5G6B5 == m_fixedData.Format)
(D3DDDIFMT_X8R8G8B8 == m_fixedData.Format || D3DDDIFMT_R5G6B5 == m_fixedData.Format))
{ {
switch (Config::renderColorDepth.get()) switch (Config::renderColorDepth.get())
{ {
@ -685,9 +706,7 @@ namespace D3dDdi
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> Resource::getMultisampleConfig() std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> Resource::getMultisampleConfig()
{ {
if ((m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.Texture && !m_fixedData.Flags.MatchGdiPrimary || if (!m_fixedData.Flags.Texture)
m_fixedData.Flags.ZBuffer) &&
D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool)
{ {
return m_device.getAdapter().getMultisampleConfig(m_fixedData.Format); return m_device.getAdapter().getMultisampleConfig(m_fixedData.Format);
} }
@ -714,9 +733,7 @@ namespace D3dDdi
SIZE Resource::getScaledSize() SIZE Resource::getScaledSize()
{ {
SIZE size = { static_cast<LONG>(m_fixedData.pSurfList[0].Width), static_cast<LONG>(m_fixedData.pSurfList[0].Height) }; SIZE size = { static_cast<LONG>(m_fixedData.pSurfList[0].Width), static_cast<LONG>(m_fixedData.pSurfList[0].Height) };
if ((m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.Texture && !m_fixedData.Flags.MatchGdiPrimary || if (!m_fixedData.Flags.Texture)
m_fixedData.Flags.ZBuffer) &&
D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool)
{ {
return m_device.getAdapter().getScaledSize(size); return m_device.getAdapter().getScaledSize(size);
} }
@ -1143,16 +1160,26 @@ namespace D3dDdi
} }
} }
HRESULT Resource::shaderBlt(D3DDDIARG_BLT& data, Resource& srcResource) void Resource::setAsPrimary()
{
D3dDdi::ScopedCriticalSection lock;
if (!m_isPrimary)
{
m_isPrimary = true;
updateConfig();
}
}
HRESULT Resource::shaderBlt(D3DDDIARG_BLT& data, Resource& dstResource, Resource& srcResource)
{ {
LOG_FUNC("Resource::shaderBlt", data, srcResource); LOG_FUNC("Resource::shaderBlt", data, srcResource);
auto& repo = SurfaceRepository::get(m_device.getAdapter()); auto& repo = SurfaceRepository::get(m_device.getAdapter());
Resource* srcRes = &srcResource.prepareForBltSrc(data); Resource* srcRes = &srcResource;
UINT srcIndex = data.SrcSubResourceIndex; UINT srcIndex = data.SrcSubResourceIndex;
RECT srcRect = data.SrcRect; RECT srcRect = data.SrcRect;
Resource* dstRes = &prepareForBltDst(data); Resource* dstRes = &dstResource;
UINT dstIndex = data.DstSubResourceIndex; UINT dstIndex = data.DstSubResourceIndex;
RECT dstRect = data.DstRect; RECT dstRect = data.DstRect;
@ -1241,7 +1268,9 @@ namespace D3dDdi
void Resource::updateConfig() void Resource::updateConfig()
{ {
if (m_isSurfaceRepoResource) if (m_isSurfaceRepoResource || D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool || D3DDDIFMT_P8 == m_fixedData.Format ||
m_fixedData.Flags.MatchGdiPrimary ||
!m_isPrimary && !m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.ZBuffer)
{ {
return; return;
} }
@ -1257,7 +1286,7 @@ namespace D3dDdi
m_formatConfig = formatConfig; m_formatConfig = formatConfig;
m_scaledSize = scaledSize; m_scaledSize = scaledSize;
if (m_fixedData.Flags.RenderTarget && if ((m_fixedData.Flags.RenderTarget || m_isPrimary) &&
(m_msaaSurface.resource || m_msaaResolvedSurface.resource)) (m_msaaSurface.resource || m_msaaResolvedSurface.resource))
{ {
for (UINT i = 0; i < m_lockData.size(); ++i) for (UINT i = 0; i < m_lockData.size(); ++i)

View File

@ -47,6 +47,7 @@ namespace D3dDdi
void prepareForGpuWrite(UINT subResourceIndex); void prepareForGpuWrite(UINT subResourceIndex);
void scaleRect(RECT& rect); void scaleRect(RECT& rect);
void setAsGdiResource(bool isGdiResource); void setAsGdiResource(bool isGdiResource);
void setAsPrimary();
HRESULT unlock(const D3DDDIARG_UNLOCK& data); HRESULT unlock(const D3DDDIARG_UNLOCK& data);
void updateConfig(); void updateConfig();
@ -103,7 +104,7 @@ namespace D3dDdi
void notifyLock(UINT subResourceIndex); void notifyLock(UINT subResourceIndex);
HRESULT presentationBlt(D3DDDIARG_BLT data, Resource* srcResource); HRESULT presentationBlt(D3DDDIARG_BLT data, Resource* srcResource);
void presentLayeredWindows(Resource& dst, UINT dstSubResourceIndex, const RECT& dstRect); void presentLayeredWindows(Resource& dst, UINT dstSubResourceIndex, const RECT& dstRect);
HRESULT shaderBlt(D3DDDIARG_BLT& data, Resource& srcResource); HRESULT shaderBlt(D3DDDIARG_BLT& data, Resource& dstResource, Resource& srcResource);
Device& m_device; Device& m_device;
HANDLE m_handle; HANDLE m_handle;
@ -121,5 +122,6 @@ namespace D3dDdi
bool m_isOversized; bool m_isOversized;
bool m_isSurfaceRepoResource; bool m_isSurfaceRepoResource;
bool m_isClampable; bool m_isClampable;
bool m_isPrimary;
}; };
} }

View File

@ -3,6 +3,7 @@
#include <Config/Config.h> #include <Config/Config.h>
#include <D3dDdi/Device.h> #include <D3dDdi/Device.h>
#include <D3dDdi/KernelModeThunks.h> #include <D3dDdi/KernelModeThunks.h>
#include <D3dDdi/Resource.h>
#include <DDraw/DirectDraw.h> #include <DDraw/DirectDraw.h>
#include <DDraw/DirectDrawSurface.h> #include <DDraw/DirectDrawSurface.h>
#include <DDraw/RealPrimarySurface.h> #include <DDraw/RealPrimarySurface.h>
@ -236,6 +237,22 @@ namespace DDraw
updateFrontResource(); updateFrontResource();
D3dDdi::Device::setGdiResourceHandle(g_frontResource); D3dDdi::Device::setGdiResourceHandle(g_frontResource);
DDSCAPS2 caps = {};
caps.dwCaps = DDSCAPS_FLIP;
auto surface(CompatPtr<IDirectDrawSurface7>::from(m_surface.get()));
HRESULT result = S_OK;
do
{
auto resource = D3dDdi::Device::findResource(DDraw::DirectDrawSurface::getDriverResourceHandle(*surface));
if (resource)
{
resource->setAsPrimary();
}
CompatPtr<IDirectDrawSurface7> next;
result = surface->GetAttachedSurface(surface, &caps, &next.getRef());
next.swap(surface);
} while (SUCCEEDED(result) && surface != m_surface);
Surface::restore(); Surface::restore();
} }