From 0e7f3978632b7b68b675e0aee8ea167f2c4538d7 Mon Sep 17 00:00:00 2001 From: narzoul Date: Sat, 16 Jan 2021 12:42:56 +0100 Subject: [PATCH] Moved palettized presentation handling to driver level --- DDrawCompat/D3dDdi/Device.cpp | 6 -- DDrawCompat/D3dDdi/Device.h | 1 - DDrawCompat/D3dDdi/Resource.cpp | 63 ++++++++++++++++++--- DDrawCompat/DDraw/RealPrimarySurface.cpp | 72 ++---------------------- 4 files changed, 58 insertions(+), 84 deletions(-) diff --git a/DDrawCompat/D3dDdi/Device.cpp b/DDrawCompat/D3dDdi/Device.cpp index 8c155e6..bcba4a6 100644 --- a/DDrawCompat/D3dDdi/Device.cpp +++ b/DDrawCompat/D3dDdi/Device.cpp @@ -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 Device::s_devices; bool Device::s_isFlushEnabled = true; } diff --git a/DDrawCompat/D3dDdi/Device.h b/DDrawCompat/D3dDdi/Device.h index d5c1eae..3a72202 100644 --- a/DDrawCompat/D3dDdi/Device.h +++ b/DDrawCompat/D3dDdi/Device.h @@ -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(); diff --git a/DDrawCompat/D3dDdi/Resource.cpp b/DDrawCompat/D3dDdi/Resource.cpp index 158bc4d..288ae32 100644 --- a/DDrawCompat/D3dDdi/Resource.cpp +++ b/DDrawCompat/D3dDdi/Resource.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include 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(srcLockData.data) + y * srcLockData.pitch; + auto dst = reinterpret_cast(static_cast(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) diff --git a/DDrawCompat/DDraw/RealPrimarySurface.cpp b/DDrawCompat/DDraw/RealPrimarySurface.cpp index 9f62410..641d4ec 100644 --- a/DDrawCompat/DDraw/RealPrimarySurface.cpp +++ b/DDrawCompat/DDraw/RealPrimarySurface.cpp @@ -27,7 +27,6 @@ namespace void onRelease(); CompatWeakPtr g_frontBuffer; - CompatWeakPtr g_paletteConverter; CompatWeakPtr g_clipper; DDSURFACEDESC2 g_surfaceDesc = {}; DDraw::IReleaseNotifier g_releaseNotifier(onRelease); @@ -62,38 +61,6 @@ namespace } } - template - HRESULT createPaletteConverter(CompatRef dd) - { - auto dm = DDraw::getDisplayMode(*CompatPtr::from(&dd)); - if (dm.ddpfPixelFormat.dwRGBBitCount > 8) - { - return DD_OK; - } - - typename DDraw::Types::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::TCreatedSurface> paletteConverter; - HRESULT result = dd->CreateSurface(&dd, &desc, &paletteConverter.getRef(), nullptr); - if (SUCCEEDED(result)) - { - g_paletteConverter = Compat::queryInterface(paletteConverter.get()); - } - - return result; - } - CompatPtr 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 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::TSurfaceDesc desc = {}; desc.dwSize = sizeof(desc); @@ -323,7 +260,7 @@ namespace DDraw desc.dwBackBufferCount = 2; CompatPtr::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; }