mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Support gamma ramps in borderless fullscreen mode
This commit is contained in:
parent
9813e8b1b7
commit
31444c364a
@ -28,6 +28,7 @@ namespace
|
|||||||
D3dDdi::KernelModeThunks::AdapterInfo g_lastOpenAdapterInfo = {};
|
D3dDdi::KernelModeThunks::AdapterInfo g_lastOpenAdapterInfo = {};
|
||||||
Compat::SrwLock g_adapterInfoSrwLock;
|
Compat::SrwLock g_adapterInfoSrwLock;
|
||||||
std::string g_lastDDrawDeviceName;
|
std::string g_lastDDrawDeviceName;
|
||||||
|
bool g_isExclusiveFullscreen = false;
|
||||||
decltype(&D3DKMTSubmitPresentBltToHwQueue) g_origSubmitPresentBltToHwQueue = nullptr;
|
decltype(&D3DKMTSubmitPresentBltToHwQueue) g_origSubmitPresentBltToHwQueue = nullptr;
|
||||||
decltype(&D3DKMTSubmitPresentToHwQueue) g_origSubmitPresentToHwQueue = nullptr;
|
decltype(&D3DKMTSubmitPresentToHwQueue) g_origSubmitPresentToHwQueue = nullptr;
|
||||||
|
|
||||||
@ -249,13 +250,34 @@ namespace
|
|||||||
return LOG_RESULT(result);
|
return LOG_RESULT(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS APIENTRY releaseProcessVidPnSourceOwners(HANDLE hProcess)
|
||||||
|
{
|
||||||
|
LOG_FUNC("D3DKMTReleaseProcessVidPnSourceOwners", hProcess);
|
||||||
|
NTSTATUS result = D3DKMTReleaseProcessVidPnSourceOwners(hProcess);
|
||||||
|
if (SUCCEEDED(result))
|
||||||
|
{
|
||||||
|
g_isExclusiveFullscreen = false;
|
||||||
|
}
|
||||||
|
return LOG_RESULT(result);
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS APIENTRY setGammaRamp(const D3DKMT_SETGAMMARAMP* pData)
|
NTSTATUS APIENTRY setGammaRamp(const D3DKMT_SETGAMMARAMP* pData)
|
||||||
{
|
{
|
||||||
LOG_FUNC("D3DKMTSetGammaRamp", pData);
|
LOG_FUNC("D3DKMTSetGammaRamp", pData);
|
||||||
|
NTSTATUS result = 0;
|
||||||
UINT vsyncCounter = D3dDdi::KernelModeThunks::getVsyncCounter();
|
UINT vsyncCounter = D3dDdi::KernelModeThunks::getVsyncCounter();
|
||||||
DDraw::RealPrimarySurface::setUpdateReady();
|
DDraw::RealPrimarySurface::setUpdateReady();
|
||||||
DDraw::RealPrimarySurface::flush();
|
DDraw::RealPrimarySurface::flush();
|
||||||
HRESULT result = D3DKMTSetGammaRamp(pData);
|
if (g_isExclusiveFullscreen || D3DDDI_GAMMARAMP_RGB256x3x16 != pData->Type || !pData->pGammaRampRgb256x3x16)
|
||||||
|
{
|
||||||
|
D3dDdi::ShaderBlitter::resetGammaRamp();
|
||||||
|
result = D3DKMTSetGammaRamp(pData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D3dDdi::ShaderBlitter::setGammaRamp(*pData->pGammaRampRgb256x3x16);
|
||||||
|
DDraw::RealPrimarySurface::scheduleUpdate();
|
||||||
|
}
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
D3dDdi::KernelModeThunks::waitForVsyncCounter(vsyncCounter + 1);
|
D3dDdi::KernelModeThunks::waitForVsyncCounter(vsyncCounter + 1);
|
||||||
@ -263,6 +285,17 @@ namespace
|
|||||||
return LOG_RESULT(result);
|
return LOG_RESULT(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS APIENTRY setVidPnSourceOwner(const D3DKMT_SETVIDPNSOURCEOWNER* pData)
|
||||||
|
{
|
||||||
|
LOG_FUNC("D3DKMTSetVidPnSourceOwner", pData);
|
||||||
|
NTSTATUS result = D3DKMTSetVidPnSourceOwner(pData);
|
||||||
|
if (SUCCEEDED(result))
|
||||||
|
{
|
||||||
|
g_isExclusiveFullscreen = 0 != pData->VidPnSourceCount;
|
||||||
|
}
|
||||||
|
return LOG_RESULT(result);
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS APIENTRY submitPresentToHwQueue(D3DKMT_SUBMITPRESENTTOHWQUEUE* pData)
|
NTSTATUS APIENTRY submitPresentToHwQueue(D3DKMT_SUBMITPRESENTTOHWQUEUE* pData)
|
||||||
{
|
{
|
||||||
LOG_FUNC("D3DKMTSubmitPresentToHwQueue", pData);
|
LOG_FUNC("D3DKMTSubmitPresentToHwQueue", pData);
|
||||||
@ -412,7 +445,9 @@ namespace D3dDdi
|
|||||||
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTOpenAdapterFromHdc", openAdapterFromHdc);
|
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTOpenAdapterFromHdc", openAdapterFromHdc);
|
||||||
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTPresent", present);
|
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTPresent", present);
|
||||||
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTQueryAdapterInfo", queryAdapterInfo);
|
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTQueryAdapterInfo", queryAdapterInfo);
|
||||||
|
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTReleaseProcessVidPnSourceOwners", releaseProcessVidPnSourceOwners);
|
||||||
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTSetGammaRamp", setGammaRamp);
|
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTSetGammaRamp", setGammaRamp);
|
||||||
|
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTSetVidPnSourceOwner", setVidPnSourceOwner);
|
||||||
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTSubmitPresentToHwQueue", submitPresentToHwQueue);
|
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTSubmitPresentToHwQueue", submitPresentToHwQueue);
|
||||||
|
|
||||||
Dll::createThread(&vsyncThreadProc, nullptr, THREAD_PRIORITY_TIME_CRITICAL);
|
Dll::createThread(&vsyncThreadProc, nullptr, THREAD_PRIORITY_TIME_CRITICAL);
|
||||||
|
@ -10,6 +10,14 @@ std::ostream& operator<<(std::ostream& os, const D3DDDI_ALLOCATIONLIST& data)
|
|||||||
<< Compat::hex(data.Value);
|
<< Compat::hex(data.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const D3DDDI_GAMMA_RAMP_RGB256x3x16& data)
|
||||||
|
{
|
||||||
|
return Compat::LogStruct(os)
|
||||||
|
<< Compat::array(data.Red, 256)
|
||||||
|
<< Compat::array(data.Green, 256)
|
||||||
|
<< Compat::array(data.Blue, 256);
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const D3DDDI_PATCHLOCATIONLIST& data)
|
std::ostream& operator<<(std::ostream& os, const D3DDDI_PATCHLOCATIONLIST& data)
|
||||||
{
|
{
|
||||||
return Compat::LogStruct(os)
|
return Compat::LogStruct(os)
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <d3dumddi.h>
|
#include <d3dumddi.h>
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const D3DDDI_ALLOCATIONLIST& data);
|
std::ostream& operator<<(std::ostream& os, const D3DDDI_ALLOCATIONLIST& data);
|
||||||
|
std::ostream& operator<<(std::ostream& os, const D3DDDI_GAMMA_RAMP_RGB256x3x16& data);
|
||||||
std::ostream& operator<<(std::ostream& os, const D3DDDI_PATCHLOCATIONLIST& data);
|
std::ostream& operator<<(std::ostream& os, const D3DDDI_PATCHLOCATIONLIST& data);
|
||||||
std::ostream& operator<<(std::ostream& os, const D3DDDI_RATIONAL& val);
|
std::ostream& operator<<(std::ostream& os, const D3DDDI_RATIONAL& val);
|
||||||
std::ostream& operator<<(std::ostream& os, D3DDDIFORMAT val);
|
std::ostream& operator<<(std::ostream& os, D3DDDIFORMAT val);
|
||||||
|
@ -135,7 +135,7 @@ std::ostream& operator<<(std::ostream& os, const D3DKMT_SETGAMMARAMP& data)
|
|||||||
<< Compat::hex(data.hDevice)
|
<< Compat::hex(data.hDevice)
|
||||||
<< data.VidPnSourceId
|
<< data.VidPnSourceId
|
||||||
<< data.Type
|
<< data.Type
|
||||||
<< static_cast<const void*>(data.pGammaRampRgb256x3x16)
|
<< data.pGammaRampRgb256x3x16
|
||||||
<< data.Size;
|
<< data.Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,20 +465,15 @@ namespace D3dDdi
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& repo = SurfaceRepository::get(m_device.getAdapter());
|
auto& nextRt = getNextRenderTarget(rt, newSrcWidth, newSrcHeight);
|
||||||
auto newRt = &repo.getTempRenderTarget(newSrcWidth, newSrcHeight, 1);
|
if (!nextRt.resource)
|
||||||
if (newRt->resource == rt)
|
|
||||||
{
|
|
||||||
newRt = &repo.getTempRenderTarget(newSrcWidth, newSrcHeight, 0);
|
|
||||||
}
|
|
||||||
if (!newRt->resource)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_device.getShaderBlitter().textureBlt(*newRt->resource, 0, { 0, 0, newSrcWidth, newSrcHeight },
|
m_device.getShaderBlitter().textureBlt(*nextRt.resource, 0, { 0, 0, newSrcWidth, newSrcHeight },
|
||||||
*rt, 0, { 0, 0, srcWidth, srcHeight }, D3DTEXF_LINEAR);
|
*rt, 0, { 0, 0, srcWidth, srcHeight }, D3DTEXF_LINEAR);
|
||||||
rt = newRt->resource;
|
rt = nextRt.resource;
|
||||||
srcWidth = newSrcWidth;
|
srcWidth = newSrcWidth;
|
||||||
srcHeight = newSrcHeight;
|
srcHeight = newSrcHeight;
|
||||||
return true;
|
return true;
|
||||||
@ -531,11 +526,6 @@ namespace D3dDdi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void* Resource::getLockPtr(UINT subResourceIndex)
|
|
||||||
{
|
|
||||||
return m_lockData.empty() ? nullptr : m_lockData[subResourceIndex].data;
|
|
||||||
}
|
|
||||||
|
|
||||||
D3DDDIFORMAT Resource::getFormatConfig()
|
D3DDDIFORMAT Resource::getFormatConfig()
|
||||||
{
|
{
|
||||||
if (m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.MatchGdiPrimary && D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool &&
|
if (m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.MatchGdiPrimary && D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool &&
|
||||||
@ -550,6 +540,11 @@ namespace D3dDdi
|
|||||||
return m_fixedData.Format;
|
return m_fixedData.Format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* Resource::getLockPtr(UINT subResourceIndex)
|
||||||
|
{
|
||||||
|
return m_lockData.empty() ? nullptr : m_lockData[subResourceIndex].data;
|
||||||
|
}
|
||||||
|
|
||||||
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.RenderTarget && !m_fixedData.Flags.Texture && !m_fixedData.Flags.MatchGdiPrimary ||
|
||||||
@ -561,6 +556,17 @@ namespace D3dDdi
|
|||||||
return { D3DDDIMULTISAMPLE_NONE, 0 };
|
return { D3DDDIMULTISAMPLE_NONE, 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SurfaceRepository::Surface& Resource::getNextRenderTarget(Resource* currentRt, DWORD width, DWORD height)
|
||||||
|
{
|
||||||
|
auto& repo = SurfaceRepository::get(m_device.getAdapter());
|
||||||
|
auto nextRt = &repo.getTempRenderTarget(width, height, 1);
|
||||||
|
if (nextRt->resource == currentRt)
|
||||||
|
{
|
||||||
|
nextRt = &repo.getTempRenderTarget(width, height, 0);
|
||||||
|
}
|
||||||
|
return *nextRt;
|
||||||
|
}
|
||||||
|
|
||||||
RECT Resource::getRect(UINT subResourceIndex)
|
RECT Resource::getRect(UINT subResourceIndex)
|
||||||
{
|
{
|
||||||
const auto& si = m_fixedData.pSurfList[subResourceIndex];
|
const auto& si = m_fixedData.pSurfList[subResourceIndex];
|
||||||
@ -873,23 +879,46 @@ namespace D3dDdi
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config::Settings::DisplayFilter::BILINEAR == Config::displayFilter.get())
|
const LONG dstWidth = data.DstRect.right - data.DstRect.left;
|
||||||
|
const LONG dstHeight = data.DstRect.bottom - data.DstRect.top;
|
||||||
|
while (downscale(rt, data.SrcRect.right, data.SrcRect.bottom, dstWidth, dstHeight))
|
||||||
{
|
{
|
||||||
const LONG dstWidth = data.DstRect.right - data.DstRect.left;
|
|
||||||
const LONG dstHeight = data.DstRect.bottom - data.DstRect.top;
|
|
||||||
while (downscale(rt, data.SrcRect.right, data.SrcRect.bottom, dstWidth, dstHeight))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
m_device.getShaderBlitter().genBilinearBlt(*this, data.DstSubResourceIndex, data.DstRect,
|
|
||||||
*rt, data.SrcRect, Config::displayFilter.getParam());
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data.hSrcResource = *rt;
|
const SurfaceRepository::Surface* rtGamma = nullptr;
|
||||||
data.SrcSubResourceIndex = 0;
|
if (!ShaderBlitter::isGammaRampDefault() &&
|
||||||
data.Flags.Point = 1;
|
SurfaceRepository::get(m_device.getAdapter()).getGammaRampTexture())
|
||||||
return m_device.getOrigVtable().pfnBlt(m_device, &data);
|
{
|
||||||
|
rtGamma = &getNextRenderTarget(rt, dstWidth, dstHeight);
|
||||||
|
}
|
||||||
|
const bool useGamma = rtGamma && rtGamma->resource;
|
||||||
|
auto& rtNext = useGamma ? *rtGamma->resource : *this;
|
||||||
|
auto rtNextIndex = useGamma ? 0 : data.DstSubResourceIndex;
|
||||||
|
auto rtNextRect = useGamma ? RECT{ 0, 0, dstWidth, dstHeight } : data.DstRect;
|
||||||
|
|
||||||
|
if (Config::Settings::DisplayFilter::BILINEAR == Config::displayFilter.get())
|
||||||
|
{
|
||||||
|
m_device.getShaderBlitter().genBilinearBlt(rtNext, rtNextIndex, rtNextRect,
|
||||||
|
*rt, data.SrcRect, Config::displayFilter.getParam());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D3DDDIARG_BLT blt = {};
|
||||||
|
blt.hSrcResource = *rt;
|
||||||
|
blt.SrcSubResourceIndex = 0;
|
||||||
|
blt.SrcRect = data.SrcRect;
|
||||||
|
blt.hDstResource = rtNext;
|
||||||
|
blt.DstSubResourceIndex = rtNextIndex;
|
||||||
|
blt.DstRect = rtNextRect;
|
||||||
|
blt.Flags.Point = 1;
|
||||||
|
m_device.getOrigVtable().pfnBlt(m_device, &blt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useGamma)
|
||||||
|
{
|
||||||
|
m_device.getShaderBlitter().gammaBlt(*this, data.DstSubResourceIndex, data.DstRect, rtNext, rtNextRect);
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resource::presentLayeredWindows(Resource& dst, UINT dstSubResourceIndex, const RECT& dstRect)
|
void Resource::presentLayeredWindows(Resource& dst, UINT dstSubResourceIndex, const RECT& dstRect)
|
||||||
|
@ -90,6 +90,7 @@ namespace D3dDdi
|
|||||||
void fixResourceData();
|
void fixResourceData();
|
||||||
D3DDDIFORMAT getFormatConfig();
|
D3DDDIFORMAT getFormatConfig();
|
||||||
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> getMultisampleConfig();
|
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> getMultisampleConfig();
|
||||||
|
const SurfaceRepository::Surface& getNextRenderTarget(Resource* currentRt, DWORD width, DWORD height);
|
||||||
RECT getRect(UINT subResourceIndex);
|
RECT getRect(UINT subResourceIndex);
|
||||||
SIZE getScaledSize();
|
SIZE getScaledSize();
|
||||||
bool isValidRect(UINT subResourceIndex, const RECT& rect);
|
bool isValidRect(UINT subResourceIndex, const RECT& rect);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <D3dDdi/SurfaceRepository.h>
|
#include <D3dDdi/SurfaceRepository.h>
|
||||||
#include <DDraw/Surfaces/PrimarySurface.h>
|
#include <DDraw/Surfaces/PrimarySurface.h>
|
||||||
#include <Shaders/DrawCursor.h>
|
#include <Shaders/DrawCursor.h>
|
||||||
|
#include <Shaders/Gamma.h>
|
||||||
#include <Shaders/GenBilinear.h>
|
#include <Shaders/GenBilinear.h>
|
||||||
#include <Shaders/PaletteLookup.h>
|
#include <Shaders/PaletteLookup.h>
|
||||||
#include <Shaders/TextureSampler.h>
|
#include <Shaders/TextureSampler.h>
|
||||||
@ -15,11 +16,27 @@
|
|||||||
#define CONCAT(a, b) CONCAT_(a, b)
|
#define CONCAT(a, b) CONCAT_(a, b)
|
||||||
#define SCOPED_STATE(state, ...) DeviceState::Scoped##state CONCAT(scopedState, __LINE__)(m_device.getState(), __VA_ARGS__)
|
#define SCOPED_STATE(state, ...) DeviceState::Scoped##state CONCAT(scopedState, __LINE__)(m_device.getState(), __VA_ARGS__)
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
D3DDDI_GAMMA_RAMP_RGB256x3x16 g_gammaRamp;
|
||||||
|
bool g_isGammaRampDefault = true;
|
||||||
|
bool g_isGammaRampInvalidated = false;
|
||||||
|
|
||||||
|
void setGammaValues(BYTE* ptr, USHORT* ramp)
|
||||||
|
{
|
||||||
|
for (UINT i = 0; i < 256; ++i)
|
||||||
|
{
|
||||||
|
ptr[i] = static_cast<BYTE>(ramp[i] * 0xFF / 0xFFFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace D3dDdi
|
namespace D3dDdi
|
||||||
{
|
{
|
||||||
ShaderBlitter::ShaderBlitter(Device& device)
|
ShaderBlitter::ShaderBlitter(Device& device)
|
||||||
: m_device(device)
|
: m_device(device)
|
||||||
, m_psDrawCursor(createPixelShader(g_psDrawCursor))
|
, m_psDrawCursor(createPixelShader(g_psDrawCursor))
|
||||||
|
, m_psGamma(createPixelShader(g_psGamma))
|
||||||
, m_psGenBilinear(createPixelShader(g_psGenBilinear))
|
, m_psGenBilinear(createPixelShader(g_psGenBilinear))
|
||||||
, m_psPaletteLookup(createPixelShader(g_psPaletteLookup))
|
, m_psPaletteLookup(createPixelShader(g_psPaletteLookup))
|
||||||
, m_psTextureSampler(createPixelShader(g_psTextureSampler))
|
, m_psTextureSampler(createPixelShader(g_psTextureSampler))
|
||||||
@ -206,9 +223,49 @@ namespace D3dDdi
|
|||||||
m_device.pfnDrawPrimitive(&dp, nullptr);
|
m_device.pfnDrawPrimitive(&dp, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderBlitter::gammaBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
|
const Resource& srcResource, const RECT& srcRect)
|
||||||
|
{
|
||||||
|
LOG_FUNC("ShaderBlitter::gammaBlt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
||||||
|
static_cast<HANDLE>(srcResource), srcRect);
|
||||||
|
|
||||||
|
auto gammaRampTexture(SurfaceRepository::get(m_device.getAdapter()).getGammaRampTexture());
|
||||||
|
if (!gammaRampTexture)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_isGammaRampInvalidated)
|
||||||
|
{
|
||||||
|
D3DDDIARG_LOCK lock = {};
|
||||||
|
lock.hResource = *gammaRampTexture;
|
||||||
|
lock.Flags.Discard = 1;
|
||||||
|
m_device.getOrigVtable().pfnLock(m_device, &lock);
|
||||||
|
if (!lock.pSurfData)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ptr = static_cast<BYTE*>(lock.pSurfData);
|
||||||
|
setGammaValues(ptr, g_gammaRamp.Red);
|
||||||
|
setGammaValues(ptr + lock.Pitch, g_gammaRamp.Green);
|
||||||
|
setGammaValues(ptr + 2 * lock.Pitch, g_gammaRamp.Blue);
|
||||||
|
|
||||||
|
D3DDDIARG_UNLOCK unlock = {};
|
||||||
|
unlock.hResource = *gammaRampTexture;
|
||||||
|
m_device.getOrigVtable().pfnUnlock(m_device, &unlock);
|
||||||
|
g_isGammaRampInvalidated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTempTextureStage(1, *gammaRampTexture, D3DTEXF_POINT);
|
||||||
|
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, 0, srcRect, m_psGamma.get(), D3DTEXF_POINT);
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderBlitter::genBilinearBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
void ShaderBlitter::genBilinearBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
const Resource& srcResource, const RECT& srcRect, UINT blurPercent)
|
const Resource& srcResource, const RECT& srcRect, UINT blurPercent)
|
||||||
{
|
{
|
||||||
|
LOG_FUNC("ShaderBlitter::genBilinearBlt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
||||||
|
static_cast<HANDLE>(srcResource), srcRect, blurPercent);
|
||||||
if (100 == blurPercent)
|
if (100 == blurPercent)
|
||||||
{
|
{
|
||||||
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, 0, srcRect,
|
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, 0, srcRect,
|
||||||
@ -233,6 +290,11 @@ namespace D3dDdi
|
|||||||
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, 0, srcRect, m_psGenBilinear.get(), D3DTEXF_LINEAR);
|
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, 0, srcRect, m_psGenBilinear.get(), D3DTEXF_LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ShaderBlitter::isGammaRampDefault()
|
||||||
|
{
|
||||||
|
return g_isGammaRampDefault;
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderBlitter::palettizedBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
void ShaderBlitter::palettizedBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
const Resource& srcResource, const RECT& srcRect, RGBQUAD palette[256])
|
const Resource& srcResource, const RECT& srcRect, RGBQUAD palette[256])
|
||||||
{
|
{
|
||||||
@ -264,6 +326,24 @@ namespace D3dDdi
|
|||||||
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, 0, srcRect, m_psPaletteLookup.get(), D3DTEXF_POINT);
|
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, 0, srcRect, m_psPaletteLookup.get(), D3DTEXF_POINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderBlitter::resetGammaRamp()
|
||||||
|
{
|
||||||
|
g_isGammaRampDefault = true;
|
||||||
|
g_isGammaRampInvalidated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderBlitter::setGammaRamp(const D3DDDI_GAMMA_RAMP_RGB256x3x16& ramp)
|
||||||
|
{
|
||||||
|
g_gammaRamp = ramp;
|
||||||
|
g_isGammaRampDefault = true;
|
||||||
|
for (WORD i = 0; i < 256 && g_isGammaRampDefault; ++i)
|
||||||
|
{
|
||||||
|
const WORD defaultRamp = i * 0xFFFF / 0xFF;
|
||||||
|
g_isGammaRampDefault = defaultRamp == ramp.Red[i] && defaultRamp == ramp.Green[i] && defaultRamp == ramp.Blue[i];
|
||||||
|
}
|
||||||
|
g_isGammaRampInvalidated = !g_isGammaRampDefault;
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderBlitter::setTempTextureStage(UINT stage, HANDLE texture, UINT filter, const UINT* srcColorKey)
|
void ShaderBlitter::setTempTextureStage(UINT stage, HANDLE texture, UINT filter, const UINT* srcColorKey)
|
||||||
{
|
{
|
||||||
auto& state = m_device.getState();
|
auto& state = m_device.getState();
|
||||||
|
@ -25,6 +25,8 @@ namespace D3dDdi
|
|||||||
|
|
||||||
void cursorBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
void cursorBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
HCURSOR cursor, POINT pt);
|
HCURSOR cursor, POINT pt);
|
||||||
|
void gammaBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
|
const Resource& srcResource, const RECT& srcRect);
|
||||||
void genBilinearBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
void genBilinearBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
const Resource& srcResource, const RECT& srcRect, UINT blurPercent);
|
const Resource& srcResource, const RECT& srcRect, UINT blurPercent);
|
||||||
void palettizedBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
void palettizedBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
@ -34,6 +36,10 @@ namespace D3dDdi
|
|||||||
UINT filter, const UINT* srcColorKey = nullptr, const BYTE* alpha = nullptr,
|
UINT filter, const UINT* srcColorKey = nullptr, const BYTE* alpha = nullptr,
|
||||||
const Gdi::Region& srcRgn = nullptr);
|
const Gdi::Region& srcRgn = nullptr);
|
||||||
|
|
||||||
|
static bool isGammaRampDefault();
|
||||||
|
static void resetGammaRamp();
|
||||||
|
static void setGammaRamp(const D3DDDI_GAMMA_RAMP_RGB256x3x16& ramp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Vertex
|
struct Vertex
|
||||||
{
|
{
|
||||||
@ -63,6 +69,7 @@ namespace D3dDdi
|
|||||||
|
|
||||||
Device& m_device;
|
Device& m_device;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psDrawCursor;
|
std::unique_ptr<void, ResourceDeleter> m_psDrawCursor;
|
||||||
|
std::unique_ptr<void, ResourceDeleter> m_psGamma;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psGenBilinear;
|
std::unique_ptr<void, ResourceDeleter> m_psGenBilinear;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psPaletteLookup;
|
std::unique_ptr<void, ResourceDeleter> m_psPaletteLookup;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psTextureSampler;
|
std::unique_ptr<void, ResourceDeleter> m_psTextureSampler;
|
||||||
|
@ -169,6 +169,16 @@ namespace D3dDdi
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Resource* SurfaceRepository::getGammaRampTexture()
|
||||||
|
{
|
||||||
|
DDPIXELFORMAT pf = {};
|
||||||
|
pf.dwSize = sizeof(pf);
|
||||||
|
pf.dwFlags = DDPF_LUMINANCE;
|
||||||
|
pf.dwLuminanceBitCount = 8;
|
||||||
|
pf.dwLuminanceBitMask = 0xFF;
|
||||||
|
return getSurface(m_gammaRampTexture, 256, 3, pf, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY).resource;
|
||||||
|
}
|
||||||
|
|
||||||
Resource* SurfaceRepository::getLogicalXorTexture()
|
Resource* SurfaceRepository::getLogicalXorTexture()
|
||||||
{
|
{
|
||||||
return getInitializedResource(m_logicalXorTexture, 256, 256, DDraw::DirectDraw::getRgbPixelFormat(8),
|
return getInitializedResource(m_logicalXorTexture, 256, 256, DDraw::DirectDraw::getRgbPixelFormat(8),
|
||||||
|
@ -38,6 +38,7 @@ namespace D3dDdi
|
|||||||
Cursor getCursor(HCURSOR cursor);
|
Cursor getCursor(HCURSOR cursor);
|
||||||
Resource* getLogicalXorTexture();
|
Resource* getLogicalXorTexture();
|
||||||
Resource* getPaletteTexture();
|
Resource* getPaletteTexture();
|
||||||
|
Resource* getGammaRampTexture();
|
||||||
Surface& getSurface(Surface& surface, DWORD width, DWORD height,
|
Surface& getSurface(Surface& surface, DWORD width, DWORD height,
|
||||||
const DDPIXELFORMAT& pf, DWORD caps, UINT surfaceCount = 1);
|
const DDPIXELFORMAT& pf, DWORD caps, UINT surfaceCount = 1);
|
||||||
const Surface& getTempRenderTarget(DWORD width, DWORD height, UINT index = 0);
|
const Surface& getTempRenderTarget(DWORD width, DWORD height, UINT index = 0);
|
||||||
@ -67,6 +68,7 @@ namespace D3dDdi
|
|||||||
Surface m_cursorMaskTexture;
|
Surface m_cursorMaskTexture;
|
||||||
Surface m_cursorColorTexture;
|
Surface m_cursorColorTexture;
|
||||||
Surface m_cursorTempTexture;
|
Surface m_cursorTempTexture;
|
||||||
|
Surface m_gammaRampTexture;
|
||||||
Surface m_logicalXorTexture;
|
Surface m_logicalXorTexture;
|
||||||
Surface m_paletteTexture;
|
Surface m_paletteTexture;
|
||||||
std::vector<Surface> m_renderTargets;
|
std::vector<Surface> m_renderTargets;
|
||||||
|
@ -25,6 +25,14 @@ std::ostream& operator<<(std::ostream& os, const DDCOLORKEY& ck)
|
|||||||
<< Compat::hex(ck.dwColorSpaceHighValue);
|
<< Compat::hex(ck.dwColorSpaceHighValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const DDGAMMARAMP& ramp)
|
||||||
|
{
|
||||||
|
return Compat::LogStruct(os)
|
||||||
|
<< Compat::array(ramp.red, 256)
|
||||||
|
<< Compat::array(ramp.green, 256)
|
||||||
|
<< Compat::array(ramp.blue, 256);
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const DDSCAPS& caps)
|
std::ostream& operator<<(std::ostream& os, const DDSCAPS& caps)
|
||||||
{
|
{
|
||||||
return Compat::LogStruct(os)
|
return Compat::LogStruct(os)
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const DDBLTFX& fx);
|
std::ostream& operator<<(std::ostream& os, const DDBLTFX& fx);
|
||||||
std::ostream& operator<<(std::ostream& os, const DDCOLORKEY& ck);
|
std::ostream& operator<<(std::ostream& os, const DDCOLORKEY& ck);
|
||||||
|
std::ostream& operator<<(std::ostream& os, const DDGAMMARAMP& ramp);
|
||||||
std::ostream& operator<<(std::ostream& os, const DDSCAPS& caps);
|
std::ostream& operator<<(std::ostream& os, const DDSCAPS& caps);
|
||||||
std::ostream& operator<<(std::ostream& os, const DDSCAPS2& caps);
|
std::ostream& operator<<(std::ostream& os, const DDSCAPS2& caps);
|
||||||
std::ostream& operator<<(std::ostream& os, const DDPIXELFORMAT& pf);
|
std::ostream& operator<<(std::ostream& os, const DDPIXELFORMAT& pf);
|
||||||
|
@ -455,6 +455,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<FxCompile Include="Shaders\DrawCursor.hlsl" />
|
<FxCompile Include="Shaders\DrawCursor.hlsl" />
|
||||||
|
<FxCompile Include="Shaders\Gamma.hlsl" />
|
||||||
<FxCompile Include="Shaders\GenBilinear.hlsl" />
|
<FxCompile Include="Shaders\GenBilinear.hlsl" />
|
||||||
<FxCompile Include="Shaders\PaletteLookup.hlsl" />
|
<FxCompile Include="Shaders\PaletteLookup.hlsl" />
|
||||||
<FxCompile Include="Shaders\TextureSampler.hlsl" />
|
<FxCompile Include="Shaders\TextureSampler.hlsl" />
|
||||||
|
@ -890,6 +890,9 @@
|
|||||||
<FxCompile Include="Shaders\VertexFixup.hlsl">
|
<FxCompile Include="Shaders\VertexFixup.hlsl">
|
||||||
<Filter>Shaders</Filter>
|
<Filter>Shaders</Filter>
|
||||||
</FxCompile>
|
</FxCompile>
|
||||||
|
<FxCompile Include="Shaders\Gamma.hlsl">
|
||||||
|
<Filter>Shaders</Filter>
|
||||||
|
</FxCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="arrow.bmp">
|
<Image Include="arrow.bmp">
|
||||||
|
12
DDrawCompat/Shaders/Gamma.hlsl
Normal file
12
DDrawCompat/Shaders/Gamma.hlsl
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
sampler2D s_texture : register(s0);
|
||||||
|
sampler2D s_gammaRamp : register(s1);
|
||||||
|
|
||||||
|
float4 main(float2 texCoord : TEXCOORD0) : COLOR0
|
||||||
|
{
|
||||||
|
const float4 color = tex2D(s_texture, texCoord);
|
||||||
|
return float4(
|
||||||
|
tex2D(s_gammaRamp, float2(color.r, 0.0f)).r,
|
||||||
|
tex2D(s_gammaRamp, float2(color.g, 0.5f)).r,
|
||||||
|
tex2D(s_gammaRamp, float2(color.b, 1.0f)).r,
|
||||||
|
0);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user