mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Moved palettized presentation handling to driver level
This commit is contained in:
parent
affc5ab17e
commit
0e7f397863
@ -15,7 +15,6 @@ namespace
|
||||
{
|
||||
HANDLE g_gdiResourceHandle = nullptr;
|
||||
D3dDdi::Resource* g_gdiResource = nullptr;
|
||||
bool g_isReadOnlyGdiLockEnabled = false;
|
||||
|
||||
void logSrcColorKeySupportFailure(const char* reason, UINT32 resultCode)
|
||||
{
|
||||
@ -453,11 +452,6 @@ namespace D3dDdi
|
||||
}
|
||||
}
|
||||
|
||||
void Device::setReadOnlyGdiLock(bool enable)
|
||||
{
|
||||
g_isReadOnlyGdiLockEnabled = enable;
|
||||
}
|
||||
|
||||
std::map<HANDLE, Device> Device::s_devices;
|
||||
bool Device::s_isFlushEnabled = true;
|
||||
}
|
||||
|
@ -68,7 +68,6 @@ namespace D3dDdi
|
||||
static Resource* findResource(HANDLE resource);
|
||||
static Resource* getGdiResource();
|
||||
static void setGdiResourceHandle(HANDLE resource);
|
||||
static void setReadOnlyGdiLock(bool enable);
|
||||
|
||||
private:
|
||||
bool checkSrcColorKeySupport();
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <D3dDdi/Log/DeviceFuncsLog.h>
|
||||
#include <D3dDdi/Resource.h>
|
||||
#include <DDraw/Blitter.h>
|
||||
#include <Gdi/Palette.h>
|
||||
#include <Gdi/VirtualScreen.h>
|
||||
|
||||
namespace
|
||||
@ -530,6 +531,43 @@ namespace D3dDdi
|
||||
|
||||
HRESULT Resource::presentationBlt(const D3DDDIARG_BLT& data, Resource& srcResource)
|
||||
{
|
||||
if (D3DDDIFMT_P8 == srcResource.m_origData.Format)
|
||||
{
|
||||
D3DDDIARG_LOCK lock = {};
|
||||
lock.hResource = m_handle;
|
||||
lock.SubResourceIndex = data.DstSubResourceIndex;
|
||||
lock.Flags.Discard = 1;
|
||||
HRESULT result = m_device.getOrigVtable().pfnLock(m_device, &lock);
|
||||
if (FAILED(result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
auto entries(Gdi::Palette::getHardwarePalette());
|
||||
DWORD pal[256] = {};
|
||||
for (UINT i = 0; i < 256; ++i)
|
||||
{
|
||||
pal[i] = (entries[i].peRed << 16) | (entries[i].peGreen << 8) | entries[i].peBlue;
|
||||
}
|
||||
|
||||
auto& srcLockData = srcResource.m_lockData[data.SrcSubResourceIndex];
|
||||
for (UINT y = 0; y < srcResource.m_fixedData.surfaceData[data.SrcSubResourceIndex].Height; ++y)
|
||||
{
|
||||
auto src = static_cast<const BYTE*>(srcLockData.data) + y * srcLockData.pitch;
|
||||
auto dst = reinterpret_cast<DWORD*>(static_cast<BYTE*>(lock.pSurfData) + y * lock.Pitch);
|
||||
for (UINT x = 0; x < srcResource.m_fixedData.surfaceData[data.SrcSubResourceIndex].Width; ++x)
|
||||
{
|
||||
dst[x] = pal[*src];
|
||||
++src;
|
||||
}
|
||||
}
|
||||
|
||||
D3DDDIARG_UNLOCK unlock = {};
|
||||
unlock.hResource = m_handle;
|
||||
unlock.SubResourceIndex = data.DstSubResourceIndex;
|
||||
return m_device.getOrigVtable().pfnUnlock(m_device, &unlock);
|
||||
}
|
||||
|
||||
if (srcResource.m_lockResource &&
|
||||
srcResource.m_lockData[data.SrcSubResourceIndex].isSysMemUpToDate)
|
||||
{
|
||||
@ -547,6 +585,10 @@ namespace D3dDdi
|
||||
{
|
||||
createGdiLockResource();
|
||||
}
|
||||
else
|
||||
{
|
||||
createLockResource();
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT Resource::splitBlt(D3DDDIARG_BLT& data, UINT& subResourceIndex, RECT& rect, RECT& otherRect)
|
||||
@ -621,16 +663,19 @@ namespace D3dDdi
|
||||
|
||||
bool isSysMemBltPreferred = true;
|
||||
auto now = Time::queryPerformanceCounter();
|
||||
if (data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown ||
|
||||
(data.Flags.SrcColorKey && !m_device.isSrcColorKeySupported()))
|
||||
if (D3DDDIFMT_P8 != m_fixedData.Format)
|
||||
{
|
||||
dstLockData.qpcLastForcedLock = now;
|
||||
srcLockData.qpcLastForcedLock = now;
|
||||
}
|
||||
else
|
||||
{
|
||||
isSysMemBltPreferred = dstLockData.isSysMemUpToDate &&
|
||||
Time::qpcToMs(now - dstLockData.qpcLastForcedLock) <= Config::evictionTimeout;
|
||||
if (data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown ||
|
||||
(data.Flags.SrcColorKey && !m_device.isSrcColorKeySupported()))
|
||||
{
|
||||
dstLockData.qpcLastForcedLock = now;
|
||||
srcLockData.qpcLastForcedLock = now;
|
||||
}
|
||||
else
|
||||
{
|
||||
isSysMemBltPreferred = dstLockData.isSysMemUpToDate &&
|
||||
Time::qpcToMs(now - dstLockData.qpcLastForcedLock) <= Config::evictionTimeout;
|
||||
}
|
||||
}
|
||||
|
||||
if (isSysMemBltPreferred)
|
||||
|
@ -27,7 +27,6 @@ namespace
|
||||
void onRelease();
|
||||
|
||||
CompatWeakPtr<IDirectDrawSurface7> g_frontBuffer;
|
||||
CompatWeakPtr<IDirectDrawSurface7> g_paletteConverter;
|
||||
CompatWeakPtr<IDirectDrawClipper> g_clipper;
|
||||
DDSURFACEDESC2 g_surfaceDesc = {};
|
||||
DDraw::IReleaseNotifier g_releaseNotifier(onRelease);
|
||||
@ -62,38 +61,6 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT createPaletteConverter(CompatRef<TDirectDraw> dd)
|
||||
{
|
||||
auto dm = DDraw::getDisplayMode(*CompatPtr<IDirectDraw7>::from(&dd));
|
||||
if (dm.ddpfPixelFormat.dwRGBBitCount > 8)
|
||||
{
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
typename DDraw::Types<TDirectDraw>::TSurfaceDesc desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
|
||||
desc.dwWidth = dm.dwWidth;
|
||||
desc.dwHeight = dm.dwHeight;
|
||||
desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat);
|
||||
desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
|
||||
desc.ddpfPixelFormat.dwRGBBitCount = 32;
|
||||
desc.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
|
||||
desc.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
|
||||
desc.ddpfPixelFormat.dwBBitMask = 0x000000FF;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
|
||||
CompatPtr<DDraw::Types<TDirectDraw>::TCreatedSurface> paletteConverter;
|
||||
HRESULT result = dd->CreateSurface(&dd, &desc, &paletteConverter.getRef(), nullptr);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
g_paletteConverter = Compat::queryInterface<IDirectDrawSurface7>(paletteConverter.get());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> getBackBuffer()
|
||||
{
|
||||
DDSCAPS2 caps = {};
|
||||
@ -157,7 +124,6 @@ namespace
|
||||
g_clipper.release();
|
||||
g_isFullScreen = false;
|
||||
g_waitingForPrimaryUnlock = false;
|
||||
g_paletteConverter.release();
|
||||
g_surfaceDesc = {};
|
||||
}
|
||||
|
||||
@ -206,32 +172,9 @@ namespace
|
||||
Gdi::Region excludeRegion(monitorRect);
|
||||
Gdi::Window::present(excludeRegion);
|
||||
|
||||
if (Win32::DisplayMode::getBpp() <= 8)
|
||||
{
|
||||
HDC paletteConverterDc = nullptr;
|
||||
g_paletteConverter->GetDC(g_paletteConverter, &paletteConverterDc);
|
||||
HDC srcDc = nullptr;
|
||||
D3dDdi::Device::setReadOnlyGdiLock(true);
|
||||
D3dDdi::KernelModeThunks::setDcPaletteOverride(true);
|
||||
src->GetDC(src, &srcDc);
|
||||
D3dDdi::KernelModeThunks::setDcPaletteOverride(false);
|
||||
D3dDdi::Device::setReadOnlyGdiLock(false);
|
||||
|
||||
if (paletteConverterDc && srcDc)
|
||||
{
|
||||
CALL_ORIG_FUNC(BitBlt)(paletteConverterDc,
|
||||
0, 0, g_surfaceDesc.dwWidth, g_surfaceDesc.dwHeight, srcDc, 0, 0, SRCCOPY);
|
||||
}
|
||||
|
||||
src->ReleaseDC(src, srcDc);
|
||||
g_paletteConverter->ReleaseDC(g_paletteConverter, paletteConverterDc);
|
||||
|
||||
bltToPrimaryChain(*g_paletteConverter);
|
||||
}
|
||||
else
|
||||
{
|
||||
bltToPrimaryChain(*src);
|
||||
}
|
||||
D3dDdi::KernelModeThunks::setDcPaletteOverride(true);
|
||||
bltToPrimaryChain(*src);
|
||||
D3dDdi::KernelModeThunks::setDcPaletteOverride(false);
|
||||
|
||||
if (g_isFullScreen && src == DDraw::PrimarySurface::getGdiSurface())
|
||||
{
|
||||
@ -309,12 +252,6 @@ namespace DDraw
|
||||
HRESULT RealPrimarySurface::create(CompatRef<DirectDraw> dd)
|
||||
{
|
||||
DDraw::ScopedThreadLock lock;
|
||||
HRESULT result = createPaletteConverter(dd);
|
||||
if (FAILED(result))
|
||||
{
|
||||
Compat::Log() << "ERROR: Failed to create the palette converter surface: " << Compat::hex(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
typename Types<DirectDraw>::TSurfaceDesc desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
@ -323,7 +260,7 @@ namespace DDraw
|
||||
desc.dwBackBufferCount = 2;
|
||||
|
||||
CompatPtr<typename Types<DirectDraw>::TCreatedSurface> surface;
|
||||
result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr);
|
||||
HRESULT result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr);
|
||||
|
||||
if (DDERR_NOEXCLUSIVEMODE == result)
|
||||
{
|
||||
@ -336,7 +273,6 @@ namespace DDraw
|
||||
if (FAILED(result))
|
||||
{
|
||||
Compat::Log() << "ERROR: Failed to create the real primary surface: " << Compat::hex(result);
|
||||
g_paletteConverter.release();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user