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;
|
HANDLE g_gdiResourceHandle = nullptr;
|
||||||
D3dDdi::Resource* g_gdiResource = nullptr;
|
D3dDdi::Resource* g_gdiResource = nullptr;
|
||||||
bool g_isReadOnlyGdiLockEnabled = false;
|
|
||||||
|
|
||||||
void logSrcColorKeySupportFailure(const char* reason, UINT32 resultCode)
|
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;
|
std::map<HANDLE, Device> Device::s_devices;
|
||||||
bool Device::s_isFlushEnabled = true;
|
bool Device::s_isFlushEnabled = true;
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,6 @@ namespace D3dDdi
|
|||||||
static Resource* findResource(HANDLE resource);
|
static Resource* findResource(HANDLE resource);
|
||||||
static Resource* getGdiResource();
|
static Resource* getGdiResource();
|
||||||
static void setGdiResourceHandle(HANDLE resource);
|
static void setGdiResourceHandle(HANDLE resource);
|
||||||
static void setReadOnlyGdiLock(bool enable);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool checkSrcColorKeySupport();
|
bool checkSrcColorKeySupport();
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <D3dDdi/Log/DeviceFuncsLog.h>
|
#include <D3dDdi/Log/DeviceFuncsLog.h>
|
||||||
#include <D3dDdi/Resource.h>
|
#include <D3dDdi/Resource.h>
|
||||||
#include <DDraw/Blitter.h>
|
#include <DDraw/Blitter.h>
|
||||||
|
#include <Gdi/Palette.h>
|
||||||
#include <Gdi/VirtualScreen.h>
|
#include <Gdi/VirtualScreen.h>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -530,6 +531,43 @@ namespace D3dDdi
|
|||||||
|
|
||||||
HRESULT Resource::presentationBlt(const D3DDDIARG_BLT& data, Resource& srcResource)
|
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 &&
|
if (srcResource.m_lockResource &&
|
||||||
srcResource.m_lockData[data.SrcSubResourceIndex].isSysMemUpToDate)
|
srcResource.m_lockData[data.SrcSubResourceIndex].isSysMemUpToDate)
|
||||||
{
|
{
|
||||||
@ -547,6 +585,10 @@ namespace D3dDdi
|
|||||||
{
|
{
|
||||||
createGdiLockResource();
|
createGdiLockResource();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
createLockResource();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT Resource::splitBlt(D3DDDIARG_BLT& data, UINT& subResourceIndex, RECT& rect, RECT& otherRect)
|
HRESULT Resource::splitBlt(D3DDDIARG_BLT& data, UINT& subResourceIndex, RECT& rect, RECT& otherRect)
|
||||||
@ -621,16 +663,19 @@ namespace D3dDdi
|
|||||||
|
|
||||||
bool isSysMemBltPreferred = true;
|
bool isSysMemBltPreferred = true;
|
||||||
auto now = Time::queryPerformanceCounter();
|
auto now = Time::queryPerformanceCounter();
|
||||||
if (data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown ||
|
if (D3DDDIFMT_P8 != m_fixedData.Format)
|
||||||
(data.Flags.SrcColorKey && !m_device.isSrcColorKeySupported()))
|
|
||||||
{
|
{
|
||||||
dstLockData.qpcLastForcedLock = now;
|
if (data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown ||
|
||||||
srcLockData.qpcLastForcedLock = now;
|
(data.Flags.SrcColorKey && !m_device.isSrcColorKeySupported()))
|
||||||
}
|
{
|
||||||
else
|
dstLockData.qpcLastForcedLock = now;
|
||||||
{
|
srcLockData.qpcLastForcedLock = now;
|
||||||
isSysMemBltPreferred = dstLockData.isSysMemUpToDate &&
|
}
|
||||||
Time::qpcToMs(now - dstLockData.qpcLastForcedLock) <= Config::evictionTimeout;
|
else
|
||||||
|
{
|
||||||
|
isSysMemBltPreferred = dstLockData.isSysMemUpToDate &&
|
||||||
|
Time::qpcToMs(now - dstLockData.qpcLastForcedLock) <= Config::evictionTimeout;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSysMemBltPreferred)
|
if (isSysMemBltPreferred)
|
||||||
|
@ -27,7 +27,6 @@ namespace
|
|||||||
void onRelease();
|
void onRelease();
|
||||||
|
|
||||||
CompatWeakPtr<IDirectDrawSurface7> g_frontBuffer;
|
CompatWeakPtr<IDirectDrawSurface7> g_frontBuffer;
|
||||||
CompatWeakPtr<IDirectDrawSurface7> g_paletteConverter;
|
|
||||||
CompatWeakPtr<IDirectDrawClipper> g_clipper;
|
CompatWeakPtr<IDirectDrawClipper> g_clipper;
|
||||||
DDSURFACEDESC2 g_surfaceDesc = {};
|
DDSURFACEDESC2 g_surfaceDesc = {};
|
||||||
DDraw::IReleaseNotifier g_releaseNotifier(onRelease);
|
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()
|
CompatPtr<IDirectDrawSurface7> getBackBuffer()
|
||||||
{
|
{
|
||||||
DDSCAPS2 caps = {};
|
DDSCAPS2 caps = {};
|
||||||
@ -157,7 +124,6 @@ namespace
|
|||||||
g_clipper.release();
|
g_clipper.release();
|
||||||
g_isFullScreen = false;
|
g_isFullScreen = false;
|
||||||
g_waitingForPrimaryUnlock = false;
|
g_waitingForPrimaryUnlock = false;
|
||||||
g_paletteConverter.release();
|
|
||||||
g_surfaceDesc = {};
|
g_surfaceDesc = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,32 +172,9 @@ namespace
|
|||||||
Gdi::Region excludeRegion(monitorRect);
|
Gdi::Region excludeRegion(monitorRect);
|
||||||
Gdi::Window::present(excludeRegion);
|
Gdi::Window::present(excludeRegion);
|
||||||
|
|
||||||
if (Win32::DisplayMode::getBpp() <= 8)
|
D3dDdi::KernelModeThunks::setDcPaletteOverride(true);
|
||||||
{
|
bltToPrimaryChain(*src);
|
||||||
HDC paletteConverterDc = nullptr;
|
D3dDdi::KernelModeThunks::setDcPaletteOverride(false);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_isFullScreen && src == DDraw::PrimarySurface::getGdiSurface())
|
if (g_isFullScreen && src == DDraw::PrimarySurface::getGdiSurface())
|
||||||
{
|
{
|
||||||
@ -309,12 +252,6 @@ namespace DDraw
|
|||||||
HRESULT RealPrimarySurface::create(CompatRef<DirectDraw> dd)
|
HRESULT RealPrimarySurface::create(CompatRef<DirectDraw> dd)
|
||||||
{
|
{
|
||||||
DDraw::ScopedThreadLock lock;
|
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 = {};
|
typename Types<DirectDraw>::TSurfaceDesc desc = {};
|
||||||
desc.dwSize = sizeof(desc);
|
desc.dwSize = sizeof(desc);
|
||||||
@ -323,7 +260,7 @@ namespace DDraw
|
|||||||
desc.dwBackBufferCount = 2;
|
desc.dwBackBufferCount = 2;
|
||||||
|
|
||||||
CompatPtr<typename Types<DirectDraw>::TCreatedSurface> surface;
|
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)
|
if (DDERR_NOEXCLUSIVEMODE == result)
|
||||||
{
|
{
|
||||||
@ -336,7 +273,6 @@ namespace DDraw
|
|||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
Compat::Log() << "ERROR: Failed to create the real primary surface: " << Compat::hex(result);
|
Compat::Log() << "ERROR: Failed to create the real primary surface: " << Compat::hex(result);
|
||||||
g_paletteConverter.release();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user