mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Added Lanczos display filter
This commit is contained in:
parent
714c4f5337
commit
3627af8d37
@ -5,17 +5,25 @@ namespace Config
|
|||||||
namespace Settings
|
namespace Settings
|
||||||
{
|
{
|
||||||
DisplayFilter::DisplayFilter()
|
DisplayFilter::DisplayFilter()
|
||||||
: MappedSetting("DisplayFilter", "bilinear", { {"point", POINT}, {"bilinear", BILINEAR} })
|
: MappedSetting("DisplayFilter", "bilinear", {
|
||||||
|
{"point", POINT},
|
||||||
|
{"bilinear", BILINEAR},
|
||||||
|
{"lanczos", LANCZOS},
|
||||||
|
})
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Setting::ParamInfo DisplayFilter::getParamInfo() const
|
Setting::ParamInfo DisplayFilter::getParamInfo() const
|
||||||
{
|
{
|
||||||
if (BILINEAR == m_value)
|
switch (m_value)
|
||||||
{
|
{
|
||||||
|
case BILINEAR:
|
||||||
return { "Blur", 0, 100, 0, m_param };
|
return { "Blur", 0, 100, 0, m_param };
|
||||||
|
case LANCZOS:
|
||||||
|
return { "Lobes", 2, 4, 2, m_param };
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ namespace Config
|
|||||||
public:
|
public:
|
||||||
static const UINT POINT = 0;
|
static const UINT POINT = 0;
|
||||||
static const UINT BILINEAR = 1;
|
static const UINT BILINEAR = 1;
|
||||||
|
static const UINT LANCZOS = 2;
|
||||||
|
|
||||||
DisplayFilter();
|
DisplayFilter();
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <D3dDdi/DeviceState.h>
|
#include <D3dDdi/DeviceState.h>
|
||||||
#include <D3dDdi/DrawPrimitive.h>
|
#include <D3dDdi/DrawPrimitive.h>
|
||||||
#include <D3dDdi/ShaderBlitter.h>
|
#include <D3dDdi/ShaderBlitter.h>
|
||||||
|
#include <D3dDdi/SurfaceRepository.h>
|
||||||
|
|
||||||
namespace D3dDdi
|
namespace D3dDdi
|
||||||
{
|
{
|
||||||
@ -56,6 +57,7 @@ namespace D3dDdi
|
|||||||
DrawPrimitive& getDrawPrimitive() { return m_drawPrimitive; }
|
DrawPrimitive& getDrawPrimitive() { return m_drawPrimitive; }
|
||||||
const D3DDDI_DEVICEFUNCS& getOrigVtable() const { return m_origVtable; }
|
const D3DDDI_DEVICEFUNCS& getOrigVtable() const { return m_origVtable; }
|
||||||
RGBQUAD* getPalette(UINT paletteHandle) { return m_palettes[paletteHandle].data(); }
|
RGBQUAD* getPalette(UINT paletteHandle) { return m_palettes[paletteHandle].data(); }
|
||||||
|
SurfaceRepository& getRepo() const { return SurfaceRepository::get(m_adapter); }
|
||||||
Resource* getResource(HANDLE resource);
|
Resource* getResource(HANDLE resource);
|
||||||
DeviceState& getState() { return m_state; }
|
DeviceState& getState() { return m_state; }
|
||||||
ShaderBlitter& getShaderBlitter() { return m_shaderBlitter; }
|
ShaderBlitter& getShaderBlitter() { return m_shaderBlitter; }
|
||||||
|
@ -48,6 +48,20 @@ namespace D3dDdi
|
|||||||
m_state.m_device, &m_data, &m_state.m_pixelShaderConst[m_data.Register][0]);
|
m_state.m_device, &m_data, &m_state.m_pixelShaderConst[m_data.Register][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeviceState::TempPixelShaderConstI::TempPixelShaderConstI(
|
||||||
|
DeviceState& state, const D3DDDIARG_SETPIXELSHADERCONSTI& data, const ShaderConstI* registers)
|
||||||
|
: m_state(state)
|
||||||
|
, m_data(data)
|
||||||
|
{
|
||||||
|
state.m_device.getOrigVtable().pfnSetPixelShaderConstI(state.m_device, &data, ®isters[0][0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceState::TempPixelShaderConstI::~TempPixelShaderConstI()
|
||||||
|
{
|
||||||
|
m_state.m_device.getOrigVtable().pfnSetPixelShaderConstI(
|
||||||
|
m_state.m_device, &m_data, &m_state.m_pixelShaderConstI[m_data.Register][0]);
|
||||||
|
}
|
||||||
|
|
||||||
DeviceState::DeviceState(Device& device)
|
DeviceState::DeviceState(Device& device)
|
||||||
: m_device(device)
|
: m_device(device)
|
||||||
, m_app{}
|
, m_app{}
|
||||||
|
@ -59,6 +59,17 @@ namespace D3dDdi
|
|||||||
D3DDDIARG_SETPIXELSHADERCONST m_data;
|
D3DDDIARG_SETPIXELSHADERCONST m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TempPixelShaderConstI
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TempPixelShaderConstI(DeviceState& state, const D3DDDIARG_SETPIXELSHADERCONSTI& data, const ShaderConstI* registers);
|
||||||
|
~TempPixelShaderConstI();
|
||||||
|
|
||||||
|
private:
|
||||||
|
DeviceState& m_state;
|
||||||
|
D3DDDIARG_SETPIXELSHADERCONSTI m_data;
|
||||||
|
};
|
||||||
|
|
||||||
class TempStateLock
|
class TempStateLock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include <Config/Settings/BltFilter.h>
|
#include <Config/Settings/BltFilter.h>
|
||||||
#include <Config/Settings/ColorKeyMethod.h>
|
#include <Config/Settings/ColorKeyMethod.h>
|
||||||
#include <Config/Settings/DepthFormat.h>
|
#include <Config/Settings/DepthFormat.h>
|
||||||
#include <Config/Settings/DisplayFilter.h>
|
|
||||||
#include <Config/Settings/RenderColorDepth.h>
|
#include <Config/Settings/RenderColorDepth.h>
|
||||||
#include <Config/Settings/ResolutionScaleFilter.h>
|
#include <Config/Settings/ResolutionScaleFilter.h>
|
||||||
#include <D3dDdi/Adapter.h>
|
#include <D3dDdi/Adapter.h>
|
||||||
@ -212,7 +211,7 @@ namespace D3dDdi
|
|||||||
|
|
||||||
if (m_msaaSurface.surface || m_msaaResolvedSurface.surface || m_lockRefSurface.surface)
|
if (m_msaaSurface.surface || m_msaaResolvedSurface.surface || m_lockRefSurface.surface)
|
||||||
{
|
{
|
||||||
auto& repo = SurfaceRepository::get(m_device.getAdapter());
|
auto& repo = m_device.getRepo();
|
||||||
repo.release(m_msaaSurface);
|
repo.release(m_msaaSurface);
|
||||||
repo.release(m_msaaResolvedSurface);
|
repo.release(m_msaaResolvedSurface);
|
||||||
repo.release(m_lockRefSurface);
|
repo.release(m_lockRefSurface);
|
||||||
@ -669,11 +668,12 @@ namespace D3dDdi
|
|||||||
|
|
||||||
void Resource::downscale(Resource*& rt, LONG& srcWidth, LONG& srcHeight, LONG dstWidth, LONG dstHeight)
|
void Resource::downscale(Resource*& rt, LONG& srcWidth, LONG& srcHeight, LONG dstWidth, LONG dstHeight)
|
||||||
{
|
{
|
||||||
|
auto& repo = m_device.getRepo();
|
||||||
while (srcWidth > 2 * dstWidth || srcHeight > 2 * dstHeight)
|
while (srcWidth > 2 * dstWidth || srcHeight > 2 * dstHeight)
|
||||||
{
|
{
|
||||||
const LONG newSrcWidth = std::max(dstWidth, (srcWidth + 1) / 2);
|
const LONG newSrcWidth = std::max(dstWidth, (srcWidth + 1) / 2);
|
||||||
const LONG newSrcHeight = std::max(dstHeight, (srcHeight + 1) / 2);
|
const LONG newSrcHeight = std::max(dstHeight, (srcHeight + 1) / 2);
|
||||||
auto& nextRt = getNextRenderTarget(rt, newSrcWidth, newSrcHeight);
|
auto& nextRt = repo.getNextRenderTarget(newSrcWidth, newSrcHeight, rt);
|
||||||
if (!nextRt.resource)
|
if (!nextRt.resource)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -808,17 +808,6 @@ 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, 0);
|
|
||||||
if (nextRt->resource == currentRt)
|
|
||||||
{
|
|
||||||
nextRt = &repo.getTempRenderTarget(width, height, 1);
|
|
||||||
}
|
|
||||||
return *nextRt;
|
|
||||||
}
|
|
||||||
|
|
||||||
RECT Resource::getRect(UINT subResourceIndex) const
|
RECT Resource::getRect(UINT subResourceIndex) const
|
||||||
{
|
{
|
||||||
const auto& si = m_fixedData.pSurfList[subResourceIndex];
|
const auto& si = m_fixedData.pSurfList[subResourceIndex];
|
||||||
@ -855,8 +844,7 @@ namespace D3dDdi
|
|||||||
const RECT srcRect = { 0, 0, static_cast<LONG>(si.Width), static_cast<LONG>(si.Height) };
|
const RECT srcRect = { 0, 0, static_cast<LONG>(si.Width), static_cast<LONG>(si.Height) };
|
||||||
if (!m_fixedData.Flags.Texture)
|
if (!m_fixedData.Flags.Texture)
|
||||||
{
|
{
|
||||||
auto& repo = SurfaceRepository::get(m_device.getAdapter());
|
auto& texture = m_device.getRepo().getTempTexture(si.Width, si.Height, m_fixedData.Format);
|
||||||
auto& texture = repo.getTempTexture(si.Width, si.Height, m_fixedData.Format);
|
|
||||||
if (!texture.resource)
|
if (!texture.resource)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -1193,8 +1181,8 @@ namespace D3dDdi
|
|||||||
|
|
||||||
if (!m_colorKeyedSurface.surface)
|
if (!m_colorKeyedSurface.surface)
|
||||||
{
|
{
|
||||||
auto& repo = SurfaceRepository::get(m_device.getAdapter());
|
m_device.getRepo().getSurface(m_colorKeyedSurface,
|
||||||
repo.getSurface(m_colorKeyedSurface, m_fixedData.pSurfList[0].Width, m_fixedData.pSurfList[0].Height,
|
m_fixedData.pSurfList[0].Width, m_fixedData.pSurfList[0].Height,
|
||||||
D3DDDIFMT_A8R8G8B8, DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY |
|
D3DDDIFMT_A8R8G8B8, DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY |
|
||||||
(m_fixedData.MipLevels > 1 ? DDSCAPS_MIPMAP : 0),
|
(m_fixedData.MipLevels > 1 ? DDSCAPS_MIPMAP : 0),
|
||||||
m_fixedData.SurfCount,
|
m_fixedData.SurfCount,
|
||||||
@ -1244,8 +1232,8 @@ namespace D3dDdi
|
|||||||
data.DstRect = g_presentationRect;
|
data.DstRect = g_presentationRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& repo = SurfaceRepository::get(m_device.getAdapter());
|
auto& repo = m_device.getRepo();
|
||||||
const auto& rtSurface = repo.getTempRenderTarget(srcWidth, srcHeight);
|
const auto& rtSurface = repo.getNextRenderTarget(srcWidth, srcHeight);
|
||||||
auto rt = rtSurface.resource ? rtSurface.resource : this;
|
auto rt = rtSurface.resource ? rtSurface.resource : this;
|
||||||
auto rtIndex = rtSurface.resource ? 0 : data.DstSubResourceIndex;
|
auto rtIndex = rtSurface.resource ? 0 : data.DstSubResourceIndex;
|
||||||
auto rtRect = rtSurface.resource ? data.SrcRect : data.DstRect;
|
auto rtRect = rtSurface.resource ? data.SrcRect : data.DstRect;
|
||||||
@ -1300,39 +1288,7 @@ namespace D3dDdi
|
|||||||
const LONG dstHeight = data.DstRect.bottom - data.DstRect.top;
|
const LONG dstHeight = data.DstRect.bottom - data.DstRect.top;
|
||||||
downscale(rt, data.SrcRect.right, data.SrcRect.bottom, dstWidth, dstHeight);
|
downscale(rt, data.SrcRect.right, data.SrcRect.bottom, dstWidth, dstHeight);
|
||||||
|
|
||||||
const SurfaceRepository::Surface* rtGamma = nullptr;
|
m_device.getShaderBlitter().displayBlt(*this, data.DstSubResourceIndex, data.DstRect, *rt, 0, data.SrcRect);
|
||||||
if (!ShaderBlitter::isGammaRampDefault() &&
|
|
||||||
SurfaceRepository::get(m_device.getAdapter()).getGammaRampTexture())
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
clearRectExterior(data.DstSubResourceIndex, data.DstRect);
|
clearRectExterior(data.DstSubResourceIndex, data.DstRect);
|
||||||
|
|
||||||
@ -1351,7 +1307,7 @@ namespace D3dDdi
|
|||||||
std::vector<Gdi::Window::LayeredWindow> layeredWindows, const RECT& monitorRect)
|
std::vector<Gdi::Window::LayeredWindow> layeredWindows, const RECT& monitorRect)
|
||||||
{
|
{
|
||||||
auto& blitter = m_device.getShaderBlitter();
|
auto& blitter = m_device.getShaderBlitter();
|
||||||
auto& repo = SurfaceRepository::get(m_device.getAdapter());
|
auto& repo = m_device.getRepo();
|
||||||
|
|
||||||
for (auto& layeredWindow : layeredWindows)
|
for (auto& layeredWindow : layeredWindows)
|
||||||
{
|
{
|
||||||
@ -1513,7 +1469,7 @@ namespace D3dDdi
|
|||||||
return LOG_RESULT(m_device.getOrigVtable().pfnBlt(m_device, &data));
|
return LOG_RESULT(m_device.getOrigVtable().pfnBlt(m_device, &data));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& repo = SurfaceRepository::get(m_device.getAdapter());
|
auto& repo = m_device.getRepo();
|
||||||
|
|
||||||
Resource* srcRes = &srcResource;
|
Resource* srcRes = &srcResource;
|
||||||
UINT srcIndex = data.SrcSubResourceIndex;
|
UINT srcIndex = data.SrcSubResourceIndex;
|
||||||
@ -1574,7 +1530,7 @@ namespace D3dDdi
|
|||||||
{
|
{
|
||||||
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 = getNextRenderTarget(srcRes, width, height);
|
auto& rt = repo.getNextRenderTarget(width, height, srcRes);
|
||||||
if (!rt.resource)
|
if (!rt.resource)
|
||||||
{
|
{
|
||||||
return LOG_RESULT(E_OUTOFMEMORY);
|
return LOG_RESULT(E_OUTOFMEMORY);
|
||||||
@ -1716,39 +1672,36 @@ namespace D3dDdi
|
|||||||
static_cast<LONG>(m_fixedData.pSurfList[0].Height) != m_scaledSize.cy;
|
static_cast<LONG>(m_fixedData.pSurfList[0].Height) != m_scaledSize.cy;
|
||||||
if (D3DDDIMULTISAMPLE_NONE != msaa.first || m_fixedData.Format != formatConfig || isScaled)
|
if (D3DDDIMULTISAMPLE_NONE != msaa.first || m_fixedData.Format != formatConfig || isScaled)
|
||||||
{
|
{
|
||||||
|
auto& repo = m_device.getRepo();
|
||||||
const DWORD caps = (m_fixedData.Flags.ZBuffer ? DDSCAPS_ZBUFFER : DDSCAPS_3DDEVICE) | DDSCAPS_VIDEOMEMORY;
|
const DWORD caps = (m_fixedData.Flags.ZBuffer ? DDSCAPS_ZBUFFER : DDSCAPS_3DDEVICE) | DDSCAPS_VIDEOMEMORY;
|
||||||
if (D3DDDIMULTISAMPLE_NONE != msaa.first)
|
if (D3DDDIMULTISAMPLE_NONE != msaa.first)
|
||||||
{
|
{
|
||||||
g_msaaOverride = msaa;
|
g_msaaOverride = msaa;
|
||||||
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_msaaSurface,
|
repo.getSurface(m_msaaSurface, scaledSize.cx, scaledSize.cy, formatConfig, caps, m_fixedData.SurfCount);
|
||||||
scaledSize.cx, scaledSize.cy, formatConfig, caps, m_fixedData.SurfCount);
|
|
||||||
g_msaaOverride = {};
|
g_msaaOverride = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_fixedData.Flags.ZBuffer && m_msaaSurface.resource)
|
if (m_fixedData.Flags.ZBuffer && m_msaaSurface.resource)
|
||||||
{
|
{
|
||||||
g_msaaOverride = msaa;
|
g_msaaOverride = msaa;
|
||||||
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_nullSurface,
|
repo.getSurface(m_nullSurface, scaledSize.cx, scaledSize.cy, FOURCC_NULL,
|
||||||
scaledSize.cx, scaledSize.cy, FOURCC_NULL,
|
|
||||||
DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount);
|
DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount);
|
||||||
g_msaaOverride = {};
|
g_msaaOverride = {};
|
||||||
}
|
}
|
||||||
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_msaaResolvedSurface,
|
repo.getSurface(m_msaaResolvedSurface, scaledSize.cx, scaledSize.cy,
|
||||||
scaledSize.cx, scaledSize.cy, m_nullSurface.resource ? FOURCC_INTZ : formatConfig,
|
m_nullSurface.resource ? FOURCC_INTZ : formatConfig, caps, m_fixedData.SurfCount);
|
||||||
caps, m_fixedData.SurfCount);
|
|
||||||
|
|
||||||
if (!m_msaaResolvedSurface.resource && m_msaaSurface.resource)
|
if (!m_msaaResolvedSurface.resource && m_msaaSurface.resource)
|
||||||
{
|
{
|
||||||
m_msaaSurface = {};
|
m_msaaSurface = {};
|
||||||
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_msaaResolvedSurface,
|
repo.getSurface(m_msaaResolvedSurface, scaledSize.cx, scaledSize.cy,
|
||||||
scaledSize.cx, scaledSize.cy, formatConfig, caps, m_fixedData.SurfCount);
|
formatConfig, caps, m_fixedData.SurfCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_fixedData.Flags.ZBuffer && m_msaaResolvedSurface.resource)
|
if (!m_fixedData.Flags.ZBuffer && m_msaaResolvedSurface.resource)
|
||||||
{
|
{
|
||||||
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_lockRefSurface,
|
repo.getSurface(m_lockRefSurface, m_fixedData.pSurfList[0].Width, m_fixedData.pSurfList[0].Height,
|
||||||
m_fixedData.pSurfList[0].Width, m_fixedData.pSurfList[0].Height, m_fixedData.Format,
|
m_fixedData.Format, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount);
|
||||||
DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount);
|
|
||||||
|
|
||||||
if (isScaled && m_device.getGdiResource() == this)
|
if (isScaled && m_device.getGdiResource() == this)
|
||||||
{
|
{
|
||||||
|
@ -114,7 +114,6 @@ 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);
|
|
||||||
SIZE getScaledSize();
|
SIZE getScaledSize();
|
||||||
bool isValidRect(UINT subResourceIndex, const RECT& rect);
|
bool isValidRect(UINT subResourceIndex, const RECT& rect);
|
||||||
void loadFromLockRefResource(UINT subResourceIndex);
|
void loadFromLockRefResource(UINT subResourceIndex);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <Common/Log.h>
|
#include <Common/Log.h>
|
||||||
#include <Common/Rect.h>
|
#include <Common/Rect.h>
|
||||||
|
#include <Config/Settings/DisplayFilter.h>
|
||||||
#include <D3dDdi/Adapter.h>
|
#include <D3dDdi/Adapter.h>
|
||||||
#include <D3dDdi/Device.h>
|
#include <D3dDdi/Device.h>
|
||||||
#include <D3dDdi/Resource.h>
|
#include <D3dDdi/Resource.h>
|
||||||
@ -12,6 +13,7 @@
|
|||||||
#include <Shaders/DrawCursor.h>
|
#include <Shaders/DrawCursor.h>
|
||||||
#include <Shaders/Gamma.h>
|
#include <Shaders/Gamma.h>
|
||||||
#include <Shaders/GenBilinear.h>
|
#include <Shaders/GenBilinear.h>
|
||||||
|
#include <Shaders/Lanczos.h>
|
||||||
#include <Shaders/LockRef.h>
|
#include <Shaders/LockRef.h>
|
||||||
#include <Shaders/PaletteLookup.h>
|
#include <Shaders/PaletteLookup.h>
|
||||||
#include <Shaders/TextureSampler.h>
|
#include <Shaders/TextureSampler.h>
|
||||||
@ -61,6 +63,7 @@ namespace D3dDdi
|
|||||||
, m_psDrawCursor(createPixelShader(g_psDrawCursor))
|
, m_psDrawCursor(createPixelShader(g_psDrawCursor))
|
||||||
, m_psGamma(createPixelShader(g_psGamma))
|
, m_psGamma(createPixelShader(g_psGamma))
|
||||||
, m_psGenBilinear(createPixelShader(g_psGenBilinear))
|
, m_psGenBilinear(createPixelShader(g_psGenBilinear))
|
||||||
|
, m_psLanczos(createPixelShader(g_psLanczos))
|
||||||
, m_psLockRef(createPixelShader(g_psLockRef))
|
, m_psLockRef(createPixelShader(g_psLockRef))
|
||||||
, m_psPaletteLookup(createPixelShader(g_psPaletteLookup))
|
, m_psPaletteLookup(createPixelShader(g_psPaletteLookup))
|
||||||
, m_psTextureSampler(createPixelShader(g_psTextureSampler))
|
, m_psTextureSampler(createPixelShader(g_psTextureSampler))
|
||||||
@ -172,6 +175,108 @@ namespace D3dDdi
|
|||||||
m_psColorKeyBlend.get(), D3DTEXF_POINT);
|
m_psColorKeyBlend.get(), D3DTEXF_POINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderBlitter::convolution(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
|
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect,
|
||||||
|
bool isHorizontal, float kernelStep, int sampleCount, float support, HANDLE pixelShader)
|
||||||
|
{
|
||||||
|
LOG_FUNC("ShaderBlitter::convolution", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
||||||
|
static_cast<HANDLE>(srcResource), srcSubResourceIndex, srcRect,
|
||||||
|
isHorizontal, kernelStep, sampleCount, support, pixelShader);
|
||||||
|
|
||||||
|
const auto& srcDesc = srcResource.getFixedDesc().pSurfList[0];
|
||||||
|
const Float2 textureSize(srcDesc.Width, srcDesc.Height);
|
||||||
|
const Float2 textureSizeRcp = Float2(1) / textureSize;
|
||||||
|
const float textureStep = isHorizontal ? textureSizeRcp.x : textureSizeRcp.y;
|
||||||
|
|
||||||
|
const int firstSampleOffset = -sampleCount / 2 + 1;
|
||||||
|
const float firstKernelOffset = firstSampleOffset * kernelStep;
|
||||||
|
const float firstTextureOffset = firstSampleOffset * textureStep;
|
||||||
|
|
||||||
|
std::array<DeviceState::ShaderConstF, 5> reg = {};
|
||||||
|
reg[0] = { textureSize.x, textureSize.y, textureSizeRcp.x, textureSizeRcp.y };
|
||||||
|
if (isHorizontal)
|
||||||
|
{
|
||||||
|
reg[1] = { firstTextureOffset, 0, firstKernelOffset, 0 };
|
||||||
|
reg[2] = { textureStep, 0, kernelStep, 0 };
|
||||||
|
reg[3] = { -0.5f, 0, 0.5f * textureSizeRcp.x, 0.5f * textureSizeRcp.y };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reg[1] = { 0, firstTextureOffset, 0, firstKernelOffset };
|
||||||
|
reg[2] = { 0, textureStep, 0, kernelStep };
|
||||||
|
reg[3] = { 0, -0.5f, 0.5f * textureSizeRcp.x, 0.5f * textureSizeRcp.y };
|
||||||
|
}
|
||||||
|
reg[4] = { support, 1.0f / support, 0, 0 };
|
||||||
|
|
||||||
|
DeviceState::TempPixelShaderConst tempPsConst(m_device.getState(), { 0, reg.size() }, reg.data());
|
||||||
|
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcSubResourceIndex, srcRect,
|
||||||
|
pixelShader, D3DTEXF_LINEAR | D3DTEXF_SRGB);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderBlitter::convolutionBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
|
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect,
|
||||||
|
Float2 support, HANDLE pixelShader)
|
||||||
|
{
|
||||||
|
LOG_FUNC("ShaderBlitter::convolutionBlt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
||||||
|
static_cast<HANDLE>(srcResource), srcSubResourceIndex, srcRect, support, pixelShader);
|
||||||
|
|
||||||
|
const Int2 dstSize(dstRect.right - dstRect.left, dstRect.bottom - dstRect.top);
|
||||||
|
const Int2 srcSize(srcRect.right - srcRect.left, srcRect.bottom - srcRect.top);
|
||||||
|
const Float2 scale = Float2(dstSize) / Float2(srcSize);
|
||||||
|
const Float2 kernelStep = min(scale, Float2(1));
|
||||||
|
const Int2 sampleCount = min(Float2(2) * ceil(support / kernelStep), Float2(255));
|
||||||
|
|
||||||
|
if (srcSize.y == dstSize.y)
|
||||||
|
{
|
||||||
|
return convolution(dstResource, dstSubResourceIndex, dstRect, srcResource, srcSubResourceIndex, srcRect,
|
||||||
|
true, kernelStep.x, sampleCount.x, support.x, pixelShader);
|
||||||
|
}
|
||||||
|
else if (srcSize.x == dstSize.x)
|
||||||
|
{
|
||||||
|
return convolution(dstResource, dstSubResourceIndex, dstRect, srcResource, srcSubResourceIndex, srcRect,
|
||||||
|
false, kernelStep.y, sampleCount.y, support.y, pixelShader);
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool isHorizontalFirst = dstSize.x * srcSize.y <= srcSize.x * dstSize.y;
|
||||||
|
RECT rect = { 0, 0, srcSize.x, srcSize.y };
|
||||||
|
if (dstSize.x * srcSize.y <= srcSize.x * dstSize.y)
|
||||||
|
{
|
||||||
|
rect.right = dstSize.x;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rect.bottom = dstSize.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto rt = m_device.getRepo().getNextRenderTarget(rect.right, rect.bottom, &srcResource, &dstResource).resource;
|
||||||
|
if (!rt)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::array<DeviceState::ShaderConstI, 2> reg = { {
|
||||||
|
{ sampleCount.x },
|
||||||
|
{ sampleCount.y }
|
||||||
|
} };
|
||||||
|
|
||||||
|
DeviceState::TempPixelShaderConstI tempPsConstI(m_device.getState(), { 0, reg.size()}, reg.data());
|
||||||
|
|
||||||
|
if (isHorizontalFirst)
|
||||||
|
{
|
||||||
|
convolution(*rt, 0, rect, srcResource, srcSubResourceIndex, srcRect,
|
||||||
|
true, kernelStep.x, sampleCount.x, support.x, pixelShader);
|
||||||
|
convolution(dstResource, dstSubResourceIndex, dstRect, *rt, 0, rect,
|
||||||
|
false, kernelStep.y, sampleCount.y, support.y, pixelShader);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
convolution(*rt, 0, rect, srcResource, srcSubResourceIndex, srcRect,
|
||||||
|
false, kernelStep.y, sampleCount.y, support.y, pixelShader);
|
||||||
|
convolution(dstResource, dstSubResourceIndex, dstRect, *rt, 0, rect,
|
||||||
|
true, kernelStep.x, sampleCount.x, support.x, pixelShader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<void, ResourceDeleter> ShaderBlitter::createPixelShader(const BYTE* code, UINT size)
|
std::unique_ptr<void, ResourceDeleter> ShaderBlitter::createPixelShader(const BYTE* code, UINT size)
|
||||||
{
|
{
|
||||||
D3DDDIARG_CREATEPIXELSHADER data = {};
|
D3DDDIARG_CREATEPIXELSHADER data = {};
|
||||||
@ -214,7 +319,7 @@ namespace D3dDdi
|
|||||||
{
|
{
|
||||||
LOG_FUNC("ShaderBlitter::cursorBlt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect, cursor, pt);
|
LOG_FUNC("ShaderBlitter::cursorBlt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect, cursor, pt);
|
||||||
|
|
||||||
auto& repo = SurfaceRepository::get(m_device.getAdapter());
|
auto& repo = m_device.getRepo();
|
||||||
auto cur = repo.getCursor(cursor);
|
auto cur = repo.getCursor(cursor);
|
||||||
if (!cur.colorTexture)
|
if (!cur.colorTexture)
|
||||||
{
|
{
|
||||||
@ -316,6 +421,67 @@ namespace D3dDdi
|
|||||||
m_device.flushPrimitives();
|
m_device.flushPrimitives();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderBlitter::displayBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
|
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect)
|
||||||
|
{
|
||||||
|
auto& repo = m_device.getRepo();
|
||||||
|
const bool useGamma = !g_isGammaRampDefault && repo.getGammaRampTexture();
|
||||||
|
|
||||||
|
if (Rect::isEqualSize(dstRect, srcRect))
|
||||||
|
{
|
||||||
|
if (useGamma)
|
||||||
|
{
|
||||||
|
gammaBlt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcSubResourceIndex, srcRect);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3DDDIARG_BLT data = {};
|
||||||
|
data.hSrcResource = srcResource;
|
||||||
|
data.SrcSubResourceIndex = srcSubResourceIndex;
|
||||||
|
data.SrcRect = srcRect;
|
||||||
|
data.hDstResource = dstResource;
|
||||||
|
data.DstSubResourceIndex = dstSubResourceIndex;
|
||||||
|
data.DstRect = dstRect;
|
||||||
|
data.Flags.Point = 1;
|
||||||
|
m_device.getOrigVtable().pfnBlt(m_device, &data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT r = { 0, 0, dstRect.right - dstRect.left, dstRect.bottom - dstRect.top };
|
||||||
|
Resource* rtGamma = nullptr;
|
||||||
|
if (useGamma)
|
||||||
|
{
|
||||||
|
rtGamma = repo.getNextRenderTarget(r.right, r.bottom, &srcResource).resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& rt = rtGamma ? *rtGamma : dstResource;
|
||||||
|
const auto rtIndex = rtGamma ? 0 : dstSubResourceIndex;
|
||||||
|
const auto& rtRect = rtGamma ? r : dstRect;
|
||||||
|
|
||||||
|
switch (Config::displayFilter.get())
|
||||||
|
{
|
||||||
|
case Config::Settings::DisplayFilter::POINT:
|
||||||
|
m_device.getShaderBlitter().textureBlt(rt, rtIndex, rtRect,
|
||||||
|
srcResource, srcSubResourceIndex, srcRect, D3DTEXF_POINT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Config::Settings::DisplayFilter::BILINEAR:
|
||||||
|
m_device.getShaderBlitter().genBilinearBlt(rt, rtIndex, rtRect,
|
||||||
|
srcResource, srcSubResourceIndex, srcRect, Config::displayFilter.getParam());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Config::Settings::DisplayFilter::LANCZOS:
|
||||||
|
m_device.getShaderBlitter().lanczosBlt(rt, rtIndex, rtRect,
|
||||||
|
srcResource, srcSubResourceIndex, srcRect, Config::displayFilter.getParam());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtGamma)
|
||||||
|
{
|
||||||
|
gammaBlt(dstResource, dstSubResourceIndex, dstRect, rt, rtIndex, rtRect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderBlitter::drawRect(const RECT& srcRect, const RectF& dstRect, UINT srcWidth, UINT srcHeight)
|
void ShaderBlitter::drawRect(const RECT& srcRect, const RectF& dstRect, UINT srcWidth, UINT srcHeight)
|
||||||
{
|
{
|
||||||
m_vertices[0].xy = { dstRect.left - 0.5f, dstRect.top - 0.5f };
|
m_vertices[0].xy = { dstRect.left - 0.5f, dstRect.top - 0.5f };
|
||||||
@ -333,12 +499,12 @@ namespace D3dDdi
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ShaderBlitter::gammaBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
void ShaderBlitter::gammaBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
const Resource& srcResource, const RECT& srcRect)
|
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect)
|
||||||
{
|
{
|
||||||
LOG_FUNC("ShaderBlitter::gammaBlt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
LOG_FUNC("ShaderBlitter::gammaBlt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
||||||
static_cast<HANDLE>(srcResource), srcRect);
|
static_cast<HANDLE>(srcResource), srcSubResourceIndex, srcRect);
|
||||||
|
|
||||||
auto gammaRampTexture(SurfaceRepository::get(m_device.getAdapter()).getGammaRampTexture());
|
auto gammaRampTexture(m_device.getRepo().getGammaRampTexture());
|
||||||
if (!gammaRampTexture)
|
if (!gammaRampTexture)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -371,13 +537,13 @@ namespace D3dDdi
|
|||||||
}
|
}
|
||||||
|
|
||||||
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, UINT srcSubResourceIndex, const RECT& srcRect, UINT blurPercent)
|
||||||
{
|
{
|
||||||
LOG_FUNC("ShaderBlitter::genBilinearBlt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
LOG_FUNC("ShaderBlitter::genBilinearBlt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
||||||
static_cast<HANDLE>(srcResource), srcRect, blurPercent);
|
static_cast<HANDLE>(srcResource), srcSubResourceIndex, srcRect, blurPercent);
|
||||||
if (100 == blurPercent)
|
if (100 == blurPercent)
|
||||||
{
|
{
|
||||||
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, 0, srcRect,
|
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcSubResourceIndex, srcRect,
|
||||||
m_psTextureSampler.get(), D3DTEXF_LINEAR | D3DTEXF_SRGB);
|
m_psTextureSampler.get(), D3DTEXF_LINEAR | D3DTEXF_SRGB);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -396,13 +562,18 @@ 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(),
|
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcSubResourceIndex, srcRect, m_psGenBilinear.get(),
|
||||||
D3DTEXF_LINEAR | D3DTEXF_SRGB);
|
D3DTEXF_LINEAR | D3DTEXF_SRGB);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShaderBlitter::isGammaRampDefault()
|
void ShaderBlitter::lanczosBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
|
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect, UINT lobes)
|
||||||
{
|
{
|
||||||
return g_isGammaRampDefault;
|
LOG_FUNC("ShaderBlitter::lanczosBlt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
||||||
|
static_cast<HANDLE>(srcResource), srcSubResourceIndex, srcRect, lobes);
|
||||||
|
|
||||||
|
convolutionBlt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcSubResourceIndex, srcRect,
|
||||||
|
lobes, m_psLanczos.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderBlitter::lockRefBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
void ShaderBlitter::lockRefBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
@ -425,7 +596,7 @@ namespace D3dDdi
|
|||||||
static_cast<HANDLE>(srcResource), srcSubResourceIndex, srcRect,
|
static_cast<HANDLE>(srcResource), srcSubResourceIndex, srcRect,
|
||||||
Compat::array(reinterpret_cast<void**>(palette), 256));
|
Compat::array(reinterpret_cast<void**>(palette), 256));
|
||||||
|
|
||||||
auto paletteTexture(SurfaceRepository::get(m_device.getAdapter()).getPaletteTexture());
|
auto paletteTexture(m_device.getRepo().getPaletteTexture());
|
||||||
if (!paletteTexture)
|
if (!paletteTexture)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
|
#include <Common/Vector.h>
|
||||||
#include <D3dDdi/ResourceDeleter.h>
|
#include <D3dDdi/ResourceDeleter.h>
|
||||||
#include <Gdi/Region.h>
|
#include <Gdi/Region.h>
|
||||||
|
|
||||||
@ -30,10 +31,14 @@ namespace D3dDdi
|
|||||||
HCURSOR cursor, POINT pt);
|
HCURSOR cursor, POINT pt);
|
||||||
void depthBlt(const Resource& dstResource, const RECT& dstRect,
|
void depthBlt(const Resource& dstResource, const RECT& dstRect,
|
||||||
const Resource& srcResource, const RECT& srcRect, HANDLE nullResource);
|
const Resource& srcResource, const RECT& srcRect, HANDLE nullResource);
|
||||||
|
void displayBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
|
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect);
|
||||||
void gammaBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
void gammaBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
const Resource& srcResource, const RECT& srcRect);
|
const Resource& srcResource, UINT srcSubResourceIndex, 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, UINT srcSubResourceIndex, const RECT& srcRect, UINT blurPercent);
|
||||||
|
void lanczosBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
|
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect, UINT lobes);
|
||||||
void lockRefBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
void lockRefBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect,
|
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect,
|
||||||
const Resource& lockRefResource);
|
const Resource& lockRefResource);
|
||||||
@ -44,7 +49,6 @@ namespace D3dDdi
|
|||||||
UINT filter, const DeviceState::ShaderConstF* srcColorKey = nullptr, const BYTE* alpha = nullptr,
|
UINT filter, const DeviceState::ShaderConstF* srcColorKey = nullptr, const BYTE* alpha = nullptr,
|
||||||
const Gdi::Region& srcRgn = nullptr);
|
const Gdi::Region& srcRgn = nullptr);
|
||||||
|
|
||||||
static bool isGammaRampDefault();
|
|
||||||
static void resetGammaRamp();
|
static void resetGammaRamp();
|
||||||
static void setGammaRamp(const D3DDDI_GAMMA_RAMP_RGB256x3x16& ramp);
|
static void setGammaRamp(const D3DDDI_GAMMA_RAMP_RGB256x3x16& ramp);
|
||||||
|
|
||||||
@ -62,6 +66,12 @@ namespace D3dDdi
|
|||||||
void blt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
void blt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect, HANDLE pixelShader,
|
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect, HANDLE pixelShader,
|
||||||
UINT filter, UINT flags = 0, const BYTE* alpha = nullptr, const Gdi::Region& srcRgn = nullptr);
|
UINT filter, UINT flags = 0, const BYTE* alpha = nullptr, const Gdi::Region& srcRgn = nullptr);
|
||||||
|
void convolution(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
|
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect,
|
||||||
|
bool isHorizontal, float kernelStep, int sampleCount, float support, HANDLE pixelShader);
|
||||||
|
void convolutionBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
|
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect,
|
||||||
|
Float2 support, HANDLE pixelShader);
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
std::unique_ptr<void, ResourceDeleter> createPixelShader(const BYTE(&code)[N])
|
std::unique_ptr<void, ResourceDeleter> createPixelShader(const BYTE(&code)[N])
|
||||||
@ -82,6 +92,7 @@ namespace D3dDdi
|
|||||||
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_psGamma;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psGenBilinear;
|
std::unique_ptr<void, ResourceDeleter> m_psGenBilinear;
|
||||||
|
std::unique_ptr<void, ResourceDeleter> m_psLanczos;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psLockRef;
|
std::unique_ptr<void, ResourceDeleter> m_psLockRef;
|
||||||
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;
|
||||||
|
@ -229,6 +229,23 @@ namespace D3dDdi
|
|||||||
return surface.resource;
|
return surface.resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SurfaceRepository::Surface& SurfaceRepository::getNextRenderTarget(
|
||||||
|
DWORD width, DWORD height, const Resource* currentSrcRt, const Resource* currentDstRt)
|
||||||
|
{
|
||||||
|
std::size_t index = 0;
|
||||||
|
while (index < m_renderTargets.size())
|
||||||
|
{
|
||||||
|
auto rt = m_renderTargets[index].resource;
|
||||||
|
if (!rt || rt != currentSrcRt && rt != currentDstRt)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
return getTempSurface(m_renderTargets[index], width, height, D3DDDIFMT_A8R8G8B8,
|
||||||
|
DDSCAPS_3DDEVICE | DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
Resource* SurfaceRepository::getPaletteTexture()
|
Resource* SurfaceRepository::getPaletteTexture()
|
||||||
{
|
{
|
||||||
return getSurface(m_paletteTexture, 256, 1, D3DDDIFMT_A8R8G8B8, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY).resource;
|
return getSurface(m_paletteTexture, 256, 1, D3DDDIFMT_A8R8G8B8, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY).resource;
|
||||||
@ -263,16 +280,6 @@ namespace D3dDdi
|
|||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SurfaceRepository::Surface& SurfaceRepository::getTempRenderTarget(DWORD width, DWORD height, UINT index)
|
|
||||||
{
|
|
||||||
if (index >= m_renderTargets.size())
|
|
||||||
{
|
|
||||||
m_renderTargets.resize(index + 1);
|
|
||||||
}
|
|
||||||
return getTempSurface(m_renderTargets[index], width, height, D3DDDIFMT_A8R8G8B8,
|
|
||||||
DDSCAPS_3DDEVICE | DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
SurfaceRepository::Surface& SurfaceRepository::getTempSurface(Surface& surface, DWORD width, DWORD height,
|
SurfaceRepository::Surface& SurfaceRepository::getTempSurface(Surface& surface, DWORD width, DWORD height,
|
||||||
D3DDDIFORMAT format, DWORD caps, UINT surfaceCount)
|
D3DDDIFORMAT format, DWORD caps, UINT surfaceCount)
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <ddraw.h>
|
#include <ddraw.h>
|
||||||
|
|
||||||
@ -41,9 +43,10 @@ namespace D3dDdi
|
|||||||
Resource* getLogicalXorTexture();
|
Resource* getLogicalXorTexture();
|
||||||
Resource* getPaletteTexture();
|
Resource* getPaletteTexture();
|
||||||
Resource* getGammaRampTexture();
|
Resource* getGammaRampTexture();
|
||||||
|
const Surface& getNextRenderTarget(DWORD width, DWORD height,
|
||||||
|
const Resource* currentSrcRt = nullptr, const Resource* currentDstRt = nullptr);
|
||||||
Surface& getSurface(Surface& surface, DWORD width, DWORD height,
|
Surface& getSurface(Surface& surface, DWORD width, DWORD height,
|
||||||
D3DDDIFORMAT format, DWORD caps, UINT surfaceCount = 1, DWORD caps2 = 0);
|
D3DDDIFORMAT format, DWORD caps, UINT surfaceCount = 1, DWORD caps2 = 0);
|
||||||
const Surface& getTempRenderTarget(DWORD width, DWORD height, UINT index = 0);
|
|
||||||
Surface& getTempSysMemSurface(DWORD width, DWORD height);
|
Surface& getTempSysMemSurface(DWORD width, DWORD height);
|
||||||
Surface& getTempSurface(Surface& surface, DWORD width, DWORD height,
|
Surface& getTempSurface(Surface& surface, DWORD width, DWORD height,
|
||||||
D3DDDIFORMAT format, DWORD caps, UINT surfaceCount = 1);
|
D3DDDIFORMAT format, DWORD caps, UINT surfaceCount = 1);
|
||||||
@ -74,7 +77,7 @@ namespace D3dDdi
|
|||||||
Surface m_gammaRampTexture;
|
Surface m_gammaRampTexture;
|
||||||
Surface m_logicalXorTexture;
|
Surface m_logicalXorTexture;
|
||||||
Surface m_paletteTexture;
|
Surface m_paletteTexture;
|
||||||
std::vector<Surface> m_renderTargets;
|
std::array<Surface, 3> m_renderTargets;
|
||||||
std::map<D3DDDIFORMAT, Surface> m_textures;
|
std::map<D3DDDIFORMAT, Surface> m_textures;
|
||||||
std::vector<Surface> m_releasedSurfaces;
|
std::vector<Surface> m_releasedSurfaces;
|
||||||
Surface m_sysMemSurface;
|
Surface m_sysMemSurface;
|
||||||
|
@ -194,7 +194,7 @@ namespace
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& repo = D3dDdi::SurfaceRepository::get(device->getAdapter());
|
auto& repo = device->getRepo();
|
||||||
D3dDdi::SurfaceRepository::Surface surface = {};
|
D3dDdi::SurfaceRepository::Surface surface = {};
|
||||||
repo.getSurface(surface, width, height, D3DDDIFMT_X8R8G8B8,
|
repo.getSurface(surface, width, height, D3DDDIFMT_X8R8G8B8,
|
||||||
DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY);
|
DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY);
|
||||||
|
@ -51,7 +51,7 @@ namespace
|
|||||||
return LOG_RESULT(nullptr);
|
return LOG_RESULT(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& repo = D3dDdi::SurfaceRepository::get(device->getAdapter());
|
auto& repo = device->getRepo();
|
||||||
D3dDdi::SurfaceRepository::Surface surface = {};
|
D3dDdi::SurfaceRepository::Surface surface = {};
|
||||||
repo.getSurface(surface, 1, 1, D3DDDIFMT_X8R8G8B8, DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY);
|
repo.getSurface(surface, 1, 1, D3DDDIFMT_X8R8G8B8, DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY);
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ namespace
|
|||||||
return bltFunc(This, lpDDSrcSurface, lpSrcRect);
|
return bltFunc(This, lpDDSrcSurface, lpSrcRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& repo = D3dDdi::SurfaceRepository::get(srcResource->getDevice().getAdapter());
|
auto& repo = srcResource->getDevice().getRepo();
|
||||||
RECT srcRect = getRect(lpSrcRect, srcDesc);
|
RECT srcRect = getRect(lpSrcRect, srcDesc);
|
||||||
auto& tex = repo.getTempTexture(srcRect.right - srcRect.left, srcRect.bottom - srcRect.top,
|
auto& tex = repo.getTempTexture(srcRect.right - srcRect.left, srcRect.bottom - srcRect.top,
|
||||||
srcResource->getOrigDesc().Format);
|
srcResource->getOrigDesc().Format);
|
||||||
|
@ -91,7 +91,7 @@
|
|||||||
<FxCompile>
|
<FxCompile>
|
||||||
<HeaderFileOutput>$(IntDir)%(RelativeDir)%(Filename).h</HeaderFileOutput>
|
<HeaderFileOutput>$(IntDir)%(RelativeDir)%(Filename).h</HeaderFileOutput>
|
||||||
<ObjectFileOutput />
|
<ObjectFileOutput />
|
||||||
<ShaderModel>2.0</ShaderModel>
|
<ShaderModel>3.0</ShaderModel>
|
||||||
<ShaderType>Pixel</ShaderType>
|
<ShaderType>Pixel</ShaderType>
|
||||||
<DisableOptimizations>false</DisableOptimizations>
|
<DisableOptimizations>false</DisableOptimizations>
|
||||||
</FxCompile>
|
</FxCompile>
|
||||||
@ -128,7 +128,7 @@
|
|||||||
<FxCompile>
|
<FxCompile>
|
||||||
<HeaderFileOutput>$(IntDir)%(RelativeDir)%(Filename).h</HeaderFileOutput>
|
<HeaderFileOutput>$(IntDir)%(RelativeDir)%(Filename).h</HeaderFileOutput>
|
||||||
<ObjectFileOutput />
|
<ObjectFileOutput />
|
||||||
<ShaderModel>2.0</ShaderModel>
|
<ShaderModel>3.0</ShaderModel>
|
||||||
<ShaderType>Pixel</ShaderType>
|
<ShaderType>Pixel</ShaderType>
|
||||||
</FxCompile>
|
</FxCompile>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@ -457,6 +457,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="genversion.ps1" />
|
<None Include="genversion.ps1" />
|
||||||
|
<None Include="Shaders\Convolution.hlsli" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<FxCompile Include="Shaders\ColorKey.hlsl" />
|
<FxCompile Include="Shaders\ColorKey.hlsl" />
|
||||||
@ -465,6 +466,7 @@
|
|||||||
<FxCompile Include="Shaders\DrawCursor.hlsl" />
|
<FxCompile Include="Shaders\DrawCursor.hlsl" />
|
||||||
<FxCompile Include="Shaders\Gamma.hlsl" />
|
<FxCompile Include="Shaders\Gamma.hlsl" />
|
||||||
<FxCompile Include="Shaders\GenBilinear.hlsl" />
|
<FxCompile Include="Shaders\GenBilinear.hlsl" />
|
||||||
|
<FxCompile Include="Shaders\Lanczos.hlsl" />
|
||||||
<FxCompile Include="Shaders\LockRef.hlsl" />
|
<FxCompile Include="Shaders\LockRef.hlsl" />
|
||||||
<FxCompile Include="Shaders\PaletteLookup.hlsl" />
|
<FxCompile Include="Shaders\PaletteLookup.hlsl" />
|
||||||
<FxCompile Include="Shaders\TextureSampler.hlsl" />
|
<FxCompile Include="Shaders\TextureSampler.hlsl" />
|
||||||
@ -473,6 +475,8 @@
|
|||||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Vertex</ShaderType>
|
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Vertex</ShaderType>
|
||||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">g_vs%(Filename)</VariableName>
|
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">g_vs%(Filename)</VariableName>
|
||||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">g_vs%(Filename)</VariableName>
|
<VariableName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">g_vs%(Filename)</VariableName>
|
||||||
|
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">2.0</ShaderModel>
|
||||||
|
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">2.0</ShaderModel>
|
||||||
</FxCompile>
|
</FxCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -665,7 +665,7 @@
|
|||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Config\Settings\ColorKeyMethod.h">
|
<ClInclude Include="Config\Settings\ColorKeyMethod.h">
|
||||||
<Filter>Header Files\Config\Settings</Filter>
|
<Filter>Header Files\Config\Settings</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Gdi\Gdi.cpp">
|
<ClCompile Include="Gdi\Gdi.cpp">
|
||||||
@ -1055,7 +1055,7 @@
|
|||||||
<ClCompile Include="Config\Settings\ColorKeyMethod.cpp">
|
<ClCompile Include="Config\Settings\ColorKeyMethod.cpp">
|
||||||
<Filter>Source Files\Config\Settings</Filter>
|
<Filter>Source Files\Config\Settings</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="DDrawCompat.rc">
|
<ResourceCompile Include="DDrawCompat.rc">
|
||||||
<Filter>Resource Files</Filter>
|
<Filter>Resource Files</Filter>
|
||||||
@ -1065,6 +1065,9 @@
|
|||||||
<None Include="genversion.ps1">
|
<None Include="genversion.ps1">
|
||||||
<Filter>Resource Files</Filter>
|
<Filter>Resource Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="Shaders\Convolution.hlsli">
|
||||||
|
<Filter>Shaders</Filter>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<FxCompile Include="Shaders\PaletteLookup.hlsl">
|
<FxCompile Include="Shaders\PaletteLookup.hlsl">
|
||||||
@ -1097,10 +1100,13 @@
|
|||||||
<FxCompile Include="Shaders\ColorKeyBlend.hlsl">
|
<FxCompile Include="Shaders\ColorKeyBlend.hlsl">
|
||||||
<Filter>Shaders</Filter>
|
<Filter>Shaders</Filter>
|
||||||
</FxCompile>
|
</FxCompile>
|
||||||
|
<FxCompile Include="Shaders\Lanczos.hlsl">
|
||||||
|
<Filter>Shaders</Filter>
|
||||||
|
</FxCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="arrow.bmp">
|
<Image Include="arrow.bmp">
|
||||||
<Filter>Resource Files</Filter>
|
<Filter>Resource Files</Filter>
|
||||||
</Image>
|
</Image>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
50
DDrawCompat/Shaders/Convolution.hlsli
Normal file
50
DDrawCompat/Shaders/Convolution.hlsli
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
sampler2D s_texture : register(s0);
|
||||||
|
int g_sampleCountX : register(i0);
|
||||||
|
int g_sampleCountY : register(i1);
|
||||||
|
|
||||||
|
float4 c[32] : register(c0);
|
||||||
|
static const float2 g_textureSize = c[0].xy;
|
||||||
|
static const float2 g_textureSizeRcp = c[0].zw;
|
||||||
|
static const float4 g_firstCoordOffset = c[1];
|
||||||
|
static const float4 g_coordStep = c[2];
|
||||||
|
static const float2 g_sampleCoordOffset = c[3].xy;
|
||||||
|
static const float2 g_halfTexelOffset = c[3].zw;
|
||||||
|
static const float g_support = c[4].x;
|
||||||
|
static const float g_supportRcp = c[4].y;
|
||||||
|
|
||||||
|
float kernel(float x);
|
||||||
|
|
||||||
|
float4 main(float2 texCoord : TEXCOORD0) : COLOR0
|
||||||
|
{
|
||||||
|
const float2 sampleCoord = texCoord * g_textureSize + g_sampleCoordOffset;
|
||||||
|
const float2 sampleCoordFrac = frac(sampleCoord);
|
||||||
|
const float2 sampleCoordInt = sampleCoord - sampleCoordFrac;
|
||||||
|
const float2 centeredTexCoord = sampleCoordInt * g_textureSizeRcp + g_halfTexelOffset;
|
||||||
|
|
||||||
|
float4 coord = float4(centeredTexCoord, -sampleCoordFrac * g_coordStep.zw) + g_firstCoordOffset;
|
||||||
|
float4 coordStep = g_coordStep;
|
||||||
|
float4 colorSum = 0;
|
||||||
|
|
||||||
|
if (0 != coordStep.x)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < g_sampleCountX; ++i)
|
||||||
|
{
|
||||||
|
coordStep.w = kernel(coord.z);
|
||||||
|
float4 color = tex2Dlod(s_texture, coord);
|
||||||
|
colorSum += coordStep.w * color;
|
||||||
|
coord += coordStep;
|
||||||
|
}
|
||||||
|
return colorSum / coord.w;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < g_sampleCountY; ++i)
|
||||||
|
{
|
||||||
|
coordStep.z = kernel(coord.w);
|
||||||
|
float4 color = tex2Dlod(s_texture, coord);
|
||||||
|
colorSum += coordStep.z * color;
|
||||||
|
coord += coordStep;
|
||||||
|
}
|
||||||
|
return colorSum / coord.z;
|
||||||
|
}
|
||||||
|
}
|
10
DDrawCompat/Shaders/Lanczos.hlsl
Normal file
10
DDrawCompat/Shaders/Lanczos.hlsl
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "Convolution.hlsli"
|
||||||
|
|
||||||
|
float kernel(float x)
|
||||||
|
{
|
||||||
|
x = min(abs(x), g_support);
|
||||||
|
const float PI = radians(180);
|
||||||
|
const float pi_x = PI * x;
|
||||||
|
const float pi_x_2 = pi_x * pi_x;
|
||||||
|
return 0 == pi_x_2 ? 1 : (g_support * sin(pi_x) * sin(pi_x * g_supportRcp) / pi_x_2);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user