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

Don't apply gamma correction to bilinear blits

See issue #208.
This commit is contained in:
narzoul 2023-03-04 13:26:05 +01:00
parent bbf926162b
commit 714c4f5337
6 changed files with 114 additions and 137 deletions

View File

@ -21,6 +21,12 @@ namespace
namespace Rect namespace Rect
{ {
bool isEqualSize(const RECT& rect1, const RECT& rect2)
{
return rect1.right - rect1.left == rect2.right - rect2.left &&
rect1.bottom - rect1.top == rect2.bottom - rect2.top;
}
RectF toRectF(const RECT& rect) RectF toRectF(const RECT& rect)
{ {
return { return {

View File

@ -13,6 +13,7 @@ struct RectF
namespace Rect namespace Rect
{ {
RectF toRectF(const RECT& rect); RectF toRectF(const RECT& rect);
bool isEqualSize(const RECT& rect1, const RECT& rect2);
void transform(RECT& rect, const RECT& srcView, const RECT& dstView); void transform(RECT& rect, const RECT& srcView, const RECT& dstView);
void transform(RectF& rect, const RECT& srcView, const RECT& dstView); void transform(RectF& rect, const RECT& srcView, const RECT& dstView);
} }

View File

@ -15,6 +15,7 @@ const UINT D3DTEXF_NONE = 0;
const UINT D3DTEXF_POINT = 1; const UINT D3DTEXF_POINT = 1;
const UINT D3DTEXF_LINEAR = 2; const UINT D3DTEXF_LINEAR = 2;
const UINT D3DTEXF_ANISOTROPIC = 3; const UINT D3DTEXF_ANISOTROPIC = 3;
const UINT D3DTEXF_SRGB = 0x10000;
namespace D3dDdi namespace D3dDdi
{ {

View File

@ -117,6 +117,8 @@ namespace D3dDdi
, m_handle(nullptr) , m_handle(nullptr)
, m_origData(data) , m_origData(data)
, m_fixedData(data) , m_fixedData(data)
, m_formatInfo{}
, m_formatOp{}
, m_lockBuffer(nullptr, &heapFree) , m_lockBuffer(nullptr, &heapFree)
, m_lockResource(nullptr, ResourceDeleter(device, device.getOrigVtable().pfnDestroyResource)) , m_lockResource(nullptr, ResourceDeleter(device, device.getOrigVtable().pfnDestroyResource))
, m_lockRefSurface{} , m_lockRefSurface{}
@ -155,6 +157,13 @@ namespace D3dDdi
m_formatConfig = m_fixedData.Format; m_formatConfig = m_fixedData.Format;
m_scaledSize = { static_cast<LONG>(m_fixedData.pSurfList[0].Width), static_cast<LONG>(m_fixedData.pSurfList[0].Height) }; m_scaledSize = { static_cast<LONG>(m_fixedData.pSurfList[0].Width), static_cast<LONG>(m_fixedData.pSurfList[0].Height) };
const auto& formatOps = m_device.getAdapter().getInfo().formatOps;
auto it = formatOps.find(m_fixedData.Format);
if (it != formatOps.end())
{
m_formatOp = it->second;
}
HRESULT result = m_device.createPrivateResource(m_fixedData); HRESULT result = m_device.createPrivateResource(m_fixedData);
if (FAILED(result)) if (FAILED(result))
{ {
@ -392,55 +401,40 @@ namespace D3dDdi
srcResource.prepareForBltSrc(data); srcResource.prepareForBltSrc(data);
} }
if (!m_fixedData.Flags.ZBuffer &&
(0 == m_formatInfo.bytesPerPixel || 0 == srcResource.m_formatInfo.bytesPerPixel))
{
if (m_lockResource)
{
loadVidMemResource(data.DstSubResourceIndex);
clearUpToDateFlags(data.DstSubResourceIndex);
m_lockData[data.DstSubResourceIndex].isVidMemUpToDate = true;
}
return m_device.getOrigVtable().pfnBlt(m_device, &data);
}
Resource& dstRes = prepareForBltDst(data); Resource& dstRes = prepareForBltDst(data);
return shaderBlt(data, dstRes, *srcRes,
Config::Settings::BltFilter::BILINEAR == Config::bltFilter.get() ? D3DTEXF_LINEAR : D3DTEXF_POINT);
}
if (!m_fixedData.Flags.ZBuffer) bool Resource::canCopySubResource(const D3DDDIARG_BLT& data, Resource& srcResource)
{
if (data.Flags.SrcColorKey ||
data.Flags.MirrorLeftRight ||
data.Flags.MirrorUpDown ||
D3DDDIMULTISAMPLE_NONE != m_fixedData.MultisampleType)
{ {
if (D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool && return false;
D3DDDIPOOL_SYSTEMMEM != srcResource.m_fixedData.Pool &&
Config::Settings::BltFilter::BILINEAR == Config::bltFilter.get())
{
data.Flags.Linear = 1;
}
else
{
data.Flags.Point = 1;
}
} }
if (D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool && if (m_fixedData.Flags.ZBuffer)
(m_fixedData.Flags.ZBuffer &&
(m_nullSurface.resource && &dstRes == m_msaaSurface.resource || m_device.getAdapter().getInfo().isD3D9On12) ||
dstRes.m_fixedData.Flags.RenderTarget ||
!m_fixedData.Flags.ZBuffer && (
data.Flags.SrcColorKey ||
data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown ||
data.DstRect.right - data.DstRect.left != data.SrcRect.right - data.SrcRect.left ||
data.DstRect.bottom - data.DstRect.top != data.SrcRect.bottom - data.SrcRect.top)) &&
SUCCEEDED(shaderBlt(data, dstRes, *srcRes)))
{ {
return S_OK; return !m_device.getAdapter().getInfo().isD3D9On12 ||
m_fixedData.Format == srcResource.m_fixedData.Format && Rect::isEqualSize(data.SrcRect, data.DstRect);
} }
if (&dstRes != this && D3DDDIPOOL_SYSTEMMEM == srcRes->m_fixedData.Pool) return Rect::isEqualSize(data.SrcRect, data.DstRect);
{
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;
}
HRESULT result = m_device.getOrigVtable().pfnBlt(m_device, &data);
if (D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool)
{
notifyLock(data.DstSubResourceIndex);
}
else if (D3DDDIPOOL_SYSTEMMEM == srcResource.m_fixedData.Pool)
{
srcResource.notifyLock(data.SrcSubResourceIndex);
}
return result;
} }
void Resource::clearRectExterior(UINT subResourceIndex, const RECT& rect) void Resource::clearRectExterior(UINT subResourceIndex, const RECT& rect)
@ -686,7 +680,7 @@ namespace D3dDdi
} }
m_device.getShaderBlitter().textureBlt(*nextRt.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 | D3DTEXF_SRGB);
rt = nextRt.resource; rt = nextRt.resource;
srcWidth = newSrcWidth; srcWidth = newSrcWidth;
srcHeight = newSrcHeight; srcHeight = newSrcHeight;
@ -941,23 +935,14 @@ namespace D3dDdi
else else
{ {
loadVidMemResource(subResourceIndex); loadVidMemResource(subResourceIndex);
const bool isScaled = static_cast<LONG>(m_fixedData.pSurfList[0].Width) != m_scaledSize.cx || D3DDDIARG_BLT blt = {};
static_cast<LONG>(m_fixedData.pSurfList[0].Height) != m_scaledSize.cy; blt.hSrcResource = *this;
if ((m_fixedData.Flags.ZBuffer || !isScaled) && !m_device.getAdapter().getInfo().isD3D9On12) blt.SrcSubResourceIndex = subResourceIndex;
{ blt.SrcRect = getRect(subResourceIndex);
copySubResource(*m_msaaResolvedSurface.resource, *this, subResourceIndex); blt.hDstResource = *m_msaaResolvedSurface.resource;
} blt.DstSubResourceIndex = subResourceIndex;
else blt.DstRect = m_msaaResolvedSurface.resource->getRect(subResourceIndex);
{ shaderBlt(blt, *m_msaaResolvedSurface.resource, *this, D3DTEXF_POINT);
D3DDDIARG_BLT blt = {};
blt.hSrcResource = *this;
blt.SrcSubResourceIndex = subResourceIndex;
blt.SrcRect = getRect(subResourceIndex);
blt.hDstResource = *m_msaaResolvedSurface.resource;
blt.DstSubResourceIndex = subResourceIndex;
blt.DstRect = m_msaaResolvedSurface.resource->getRect(subResourceIndex);
shaderBlt(blt, *m_msaaResolvedSurface.resource , *this);
}
} }
m_lockData[subResourceIndex].isMsaaResolvedUpToDate = true; m_lockData[subResourceIndex].isMsaaResolvedUpToDate = true;
} }
@ -984,60 +969,18 @@ namespace D3dDdi
if (m_lockData[subResourceIndex].isMsaaUpToDate || m_lockData[subResourceIndex].isMsaaResolvedUpToDate) if (m_lockData[subResourceIndex].isMsaaUpToDate || m_lockData[subResourceIndex].isMsaaResolvedUpToDate)
{ {
loadMsaaResolvedResource(subResourceIndex); loadMsaaResolvedResource(subResourceIndex);
if (!m_origData.Flags.RenderTarget ||
Config::Settings::ResolutionScaleFilter::POINT == Config::resolutionScaleFilter.get())
{
const bool isScaled = static_cast<LONG>(m_fixedData.pSurfList[0].Width) != m_scaledSize.cx ||
static_cast<LONG>(m_fixedData.pSurfList[0].Height) != m_scaledSize.cy;
if ((m_fixedData.Flags.ZBuffer || !isScaled) && !m_device.getAdapter().getInfo().isD3D9On12)
{
copySubResource(*this, *m_msaaResolvedSurface.resource, subResourceIndex);
}
else
{
D3DDDIARG_BLT blt = {};
blt.hSrcResource = *m_msaaResolvedSurface.resource;
blt.SrcSubResourceIndex = subResourceIndex;
blt.SrcRect = m_msaaResolvedSurface.resource->getRect(subResourceIndex);
blt.hDstResource = *this;
blt.DstSubResourceIndex = subResourceIndex;
blt.DstRect = getRect(subResourceIndex);
shaderBlt(blt, *this, *m_msaaResolvedSurface.resource);
}
m_lockData[subResourceIndex].isVidMemUpToDate = true;
return;
}
auto src = m_msaaResolvedSurface.resource; D3DDDIARG_BLT blt = {};
auto srcRect = src->getRect(subResourceIndex); blt.hSrcResource = *m_msaaResolvedSurface.resource;
auto dstRect = getRect(subResourceIndex); blt.SrcSubResourceIndex = subResourceIndex;
blt.SrcRect = m_msaaResolvedSurface.resource->getRect(subResourceIndex);
downscale(src, srcRect.right, srcRect.bottom, dstRect.right, dstRect.bottom); blt.hDstResource = *this;
auto srcIndex = src == m_msaaResolvedSurface.resource ? subResourceIndex : 0; blt.DstSubResourceIndex = subResourceIndex;
blt.DstRect = getRect(subResourceIndex);
if (dstRect != srcRect && shaderBlt(blt, *this, *m_msaaResolvedSurface.resource,
!(m_device.getAdapter().getInfo().formatOps.at(m_fixedData.Format).Operations & FORMATOP_SRGBWRITE)) Config::Settings::ResolutionScaleFilter::BILINEAR == Config::resolutionScaleFilter.get()
{ ? D3DTEXF_LINEAR | D3DTEXF_SRGB
auto nextRt = getNextRenderTarget(src, dstRect.right, dstRect.bottom).resource; : D3DTEXF_POINT);
if (nextRt)
{
m_device.getShaderBlitter().textureBlt(*nextRt, 0, dstRect,
*src, srcIndex, srcRect, D3DTEXF_LINEAR);
src = nextRt;
srcRect = dstRect;
srcIndex = 0;
}
}
if (dstRect == srcRect)
{
copySubResourceRegion(m_handle, subResourceIndex, dstRect, *src, srcIndex, srcRect);
}
else
{
m_device.getShaderBlitter().textureBlt(*this, subResourceIndex, dstRect,
*src, srcIndex, srcRect, D3DTEXF_LINEAR);
}
} }
else else
{ {
@ -1560,9 +1503,16 @@ namespace D3dDdi
resource.m_isPalettizedTextureUpToDate = false; resource.m_isPalettizedTextureUpToDate = false;
} }
HRESULT Resource::shaderBlt(D3DDDIARG_BLT& data, Resource& dstResource, Resource& srcResource) HRESULT Resource::shaderBlt(const D3DDDIARG_BLT& data, Resource& dstResource, Resource& srcResource, UINT filter)
{ {
LOG_FUNC("Resource::shaderBlt", data, srcResource); LOG_FUNC("Resource::shaderBlt", data, dstResource, srcResource);
if (D3DDDIPOOL_SYSTEMMEM == dstResource.m_fixedData.Pool ||
dstResource.canCopySubResource(data, srcResource))
{
return LOG_RESULT(m_device.getOrigVtable().pfnBlt(m_device, &data));
}
auto& repo = SurfaceRepository::get(m_device.getAdapter()); auto& repo = SurfaceRepository::get(m_device.getAdapter());
Resource* srcRes = &srcResource; Resource* srcRes = &srcResource;
@ -1573,7 +1523,15 @@ namespace D3dDdi
UINT dstIndex = data.DstSubResourceIndex; UINT dstIndex = data.DstSubResourceIndex;
RECT dstRect = data.DstRect; RECT dstRect = data.DstRect;
if (!srcResource.m_fixedData.Flags.Texture || D3DDDIPOOL_SYSTEMMEM == srcResource.m_fixedData.Pool) if (D3DTEXF_POINT != filter &&
(dstResource.m_fixedData.Flags.ZBuffer || Rect::isEqualSize(srcRect, dstRect)))
{
filter = D3DTEXF_POINT;
}
if (!srcResource.m_fixedData.Flags.Texture ||
D3DDDIPOOL_SYSTEMMEM == srcResource.m_fixedData.Pool ||
(filter & D3DTEXF_SRGB) && !(srcResource.m_formatOp.Operations & FORMATOP_SRGBREAD))
{ {
DWORD width = data.SrcRect.right - data.SrcRect.left; DWORD width = data.SrcRect.right - data.SrcRect.left;
DWORD height = data.SrcRect.bottom - data.SrcRect.top; DWORD height = data.SrcRect.bottom - data.SrcRect.top;
@ -1602,11 +1560,21 @@ namespace D3dDdi
} }
} }
if (!dstResource.m_fixedData.Flags.RenderTarget && !dstResource.m_fixedData.Flags.ZBuffer) if (filter & D3DTEXF_SRGB)
{
downscale(srcRes, srcRect.right, srcRect.bottom, dstRect.right, dstRect.bottom);
if (Rect::isEqualSize(srcRect, dstRect))
{
filter = D3DTEXF_POINT;
}
}
if (!dstResource.m_fixedData.Flags.RenderTarget && !dstResource.m_fixedData.Flags.ZBuffer ||
(filter & D3DTEXF_SRGB) && !(dstResource.m_formatOp.Operations & FORMATOP_SRGBWRITE))
{ {
LONG width = data.DstRect.right - data.DstRect.left; LONG width = data.DstRect.right - data.DstRect.left;
LONG height = data.DstRect.bottom - data.DstRect.top; LONG height = data.DstRect.bottom - data.DstRect.top;
auto& rt = repo.getTempRenderTarget(width, height); auto& rt = getNextRenderTarget(srcRes, width, height);
if (!rt.resource) if (!rt.resource)
{ {
return LOG_RESULT(E_OUTOFMEMORY); return LOG_RESULT(E_OUTOFMEMORY);
@ -1642,16 +1610,20 @@ namespace D3dDdi
: DeviceState::ShaderConstF{}; : DeviceState::ShaderConstF{};
if (m_fixedData.Flags.ZBuffer) if (m_fixedData.Flags.ZBuffer)
{ {
m_device.getShaderBlitter().depthBlt(*dstRes, dstRect, *srcRes, srcRect, const bool isD3D9On12 = m_device.getAdapter().getInfo().isD3D9On12;
m_device.getAdapter().getInfo().isD3D9On12 ? nullptr : static_cast<HANDLE>(*m_nullSurface.resource)); if (m_nullSurface.resource || isD3D9On12)
{
m_device.getShaderBlitter().depthBlt(*dstRes, dstRect, *srcRes, srcRect,
isD3D9On12 ? nullptr : static_cast<HANDLE>(*m_nullSurface.resource));
}
} }
else else
{ {
m_device.getShaderBlitter().textureBlt(*dstRes, dstIndex, dstRect, *srcRes, srcIndex, srcRect, m_device.getShaderBlitter().textureBlt(*dstRes, dstIndex, dstRect, *srcRes, srcIndex, srcRect,
data.Flags.Linear ? D3DTEXF_LINEAR : D3DTEXF_POINT, data.Flags.SrcColorKey ? &ck : nullptr); filter, data.Flags.SrcColorKey ? &ck : nullptr);
} }
if (!dstResource.m_fixedData.Flags.RenderTarget && !dstResource.m_fixedData.Flags.ZBuffer) if (*dstRes != data.hDstResource)
{ {
HRESULT result = copySubResourceRegion(data.hDstResource, data.DstSubResourceIndex, data.DstRect, HRESULT result = copySubResourceRegion(data.hDstResource, data.DstSubResourceIndex, data.DstRect,
*dstRes, dstIndex, dstRect); *dstRes, dstIndex, dstRect);
@ -1691,9 +1663,7 @@ namespace D3dDdi
return false; return false;
} }
return Config::Settings::BltFilter::POINT == Config::bltFilter.get() || return Config::Settings::BltFilter::POINT == Config::bltFilter.get() || Rect::isEqualSize(data.SrcRect, data.DstRect);
data.SrcRect.right - data.SrcRect.left == data.DstRect.right - data.DstRect.left &&
data.SrcRect.bottom - data.SrcRect.top == data.DstRect.bottom - data.DstRect.top;
} }
HRESULT Resource::unlock(const D3DDDIARG_UNLOCK& data) HRESULT Resource::unlock(const D3DDDIARG_UNLOCK& data)
@ -1755,8 +1725,7 @@ namespace D3dDdi
g_msaaOverride = {}; g_msaaOverride = {};
} }
auto& adapterInfo = m_device.getAdapter().getInfo(); if (m_fixedData.Flags.ZBuffer && m_msaaSurface.resource)
if (m_fixedData.Flags.ZBuffer && m_msaaSurface.resource && adapterInfo.isMsaaDepthResolveSupported)
{ {
g_msaaOverride = msaa; g_msaaOverride = msaa;
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_nullSurface, SurfaceRepository::get(m_device.getAdapter()).getSurface(m_nullSurface,

View File

@ -30,6 +30,7 @@ namespace D3dDdi
Resource* getCustomResource() const { return m_msaaSurface.resource ? m_msaaSurface.resource : m_msaaResolvedSurface.resource; } Resource* getCustomResource() const { return m_msaaSurface.resource ? m_msaaSurface.resource : m_msaaResolvedSurface.resource; }
Device& getDevice() const { return m_device; } Device& getDevice() const { return m_device; }
const D3DDDIARG_CREATERESOURCE2& getFixedDesc() const { return m_fixedData; } const D3DDDIARG_CREATERESOURCE2& getFixedDesc() const { return m_fixedData; }
FORMATOP getFormatOp() const { return m_formatOp; }
const D3DDDIARG_CREATERESOURCE2& getOrigDesc() const { return m_origData; } const D3DDDIARG_CREATERESOURCE2& getOrigDesc() const { return m_origData; }
UINT getPaletteHandle() const { return m_paletteHandle; } UINT getPaletteHandle() const { return m_paletteHandle; }
Resource* getPalettizedTexture() { return m_palettizedTexture; } Resource* getPalettizedTexture() { return m_palettizedTexture; }
@ -97,6 +98,7 @@ namespace D3dDdi
HRESULT bltLock(D3DDDIARG_LOCK& data); HRESULT bltLock(D3DDDIARG_LOCK& data);
HRESULT bltViaCpu(D3DDDIARG_BLT data, Resource& srcResource); HRESULT bltViaCpu(D3DDDIARG_BLT data, Resource& srcResource);
HRESULT bltViaGpu(D3DDDIARG_BLT data, Resource& srcResource); HRESULT bltViaGpu(D3DDDIARG_BLT data, Resource& srcResource);
bool canCopySubResource(const D3DDDIARG_BLT& data, Resource& srcResource);
void clearRectExterior(UINT subResourceIndex, const RECT& rect); void clearRectExterior(UINT subResourceIndex, const RECT& rect);
void clearRectInterior(UINT subResourceIndex, const RECT& rect); void clearRectInterior(UINT subResourceIndex, const RECT& rect);
void clearUpToDateFlags(UINT subResourceIndex); void clearUpToDateFlags(UINT subResourceIndex);
@ -124,7 +126,7 @@ namespace D3dDdi
void presentLayeredWindows(Resource& dst, UINT dstSubResourceIndex, const RECT& dstRect, void presentLayeredWindows(Resource& dst, UINT dstSubResourceIndex, const RECT& dstRect,
std::vector<Gdi::Window::LayeredWindow> layeredWindows, const RECT& monitorRect); std::vector<Gdi::Window::LayeredWindow> layeredWindows, const RECT& monitorRect);
void resolveMsaaDepthBuffer(); void resolveMsaaDepthBuffer();
HRESULT shaderBlt(D3DDDIARG_BLT& data, Resource& dstResource, Resource& srcResource); HRESULT shaderBlt(const D3DDDIARG_BLT& data, Resource& dstResource, Resource& srcResource, UINT filter);
bool shouldBltViaCpu(const D3DDDIARG_BLT &data, Resource& srcResource); bool shouldBltViaCpu(const D3DDDIARG_BLT &data, Resource& srcResource);
Device& m_device; Device& m_device;
@ -132,6 +134,7 @@ namespace D3dDdi
Data m_origData; Data m_origData;
Data m_fixedData; Data m_fixedData;
FormatInfo m_formatInfo; FormatInfo m_formatInfo;
FORMATOP m_formatOp;
std::unique_ptr<void, void(*)(void*)> m_lockBuffer; std::unique_ptr<void, void(*)(void*)> m_lockBuffer;
std::vector<LockData> m_lockData; std::vector<LockData> m_lockData;
std::unique_ptr<void, ResourceDeleter> m_lockResource; std::unique_ptr<void, ResourceDeleter> m_lockResource;

View File

@ -89,13 +89,9 @@ namespace D3dDdi
const auto& srcSurface = srcResource.getFixedDesc().pSurfList[srcSubResourceIndex]; const auto& srcSurface = srcResource.getFixedDesc().pSurfList[srcSubResourceIndex];
const auto& dstSurface = dstResource.getFixedDesc().pSurfList[dstSubResourceIndex]; const auto& dstSurface = dstResource.getFixedDesc().pSurfList[dstSubResourceIndex];
bool srgb = false; const bool srgb = (filter & D3DTEXF_SRGB) &&
if (D3DTEXF_LINEAR == filter) (srcResource.getFormatOp().Operations & FORMATOP_SRGBREAD) &&
{ (dstResource.getFormatOp().Operations & FORMATOP_SRGBWRITE);
const auto& formatOps = m_device.getAdapter().getInfo().formatOps;
srgb = (formatOps.at(srcResource.getFixedDesc().Format).Operations & FORMATOP_SRGBREAD) &&
(formatOps.at(dstResource.getFixedDesc().Format).Operations & FORMATOP_SRGBWRITE);
}
auto& state = m_device.getState(); auto& state = m_device.getState();
state.setSpriteMode(false); state.setSpriteMode(false);
@ -142,7 +138,7 @@ namespace D3dDdi
state.setTempRenderState({ D3DDDIRS_DESTBLEND, D3DBLEND_INVSRCALPHA }); state.setTempRenderState({ D3DDDIRS_DESTBLEND, D3DBLEND_INVSRCALPHA });
} }
setTempTextureStage(0, srcResource, srcRect, filter); setTempTextureStage(0, srcResource, srcRect, LOWORD(filter));
state.setTempTextureStageState({ 0, D3DDDITSS_SRGBTEXTURE, srgb }); state.setTempTextureStageState({ 0, D3DDDITSS_SRGBTEXTURE, srgb });
state.setTempStreamSourceUm({ 0, sizeof(Vertex) }, m_vertices.data()); state.setTempStreamSourceUm({ 0, sizeof(Vertex) }, m_vertices.data());
@ -382,7 +378,7 @@ namespace D3dDdi
if (100 == blurPercent) if (100 == blurPercent)
{ {
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, 0, srcRect, blt(dstResource, dstSubResourceIndex, dstRect, srcResource, 0, srcRect,
m_psTextureSampler.get(), D3DTEXF_LINEAR); m_psTextureSampler.get(), D3DTEXF_LINEAR | D3DTEXF_SRGB);
return; return;
} }
@ -400,7 +396,8 @@ namespace D3dDdi
} }; } };
DeviceState::TempPixelShaderConst tempPsConst(m_device.getState(), { 0, registers.size() }, registers.data()); DeviceState::TempPixelShaderConst tempPsConst(m_device.getState(), { 0, registers.size() }, registers.data());
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, 0, srcRect, m_psGenBilinear.get(), D3DTEXF_LINEAR); blt(dstResource, dstSubResourceIndex, dstRect, srcResource, 0, srcRect, m_psGenBilinear.get(),
D3DTEXF_LINEAR | D3DTEXF_SRGB);
} }
bool ShaderBlitter::isGammaRampDefault() bool ShaderBlitter::isGammaRampDefault()