mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Added bicubic display filter
This commit is contained in:
parent
3627af8d37
commit
b377102d8d
@ -8,6 +8,7 @@ namespace Config
|
||||
: MappedSetting("DisplayFilter", "bilinear", {
|
||||
{"point", POINT},
|
||||
{"bilinear", BILINEAR},
|
||||
{"bicubic", BICUBIC},
|
||||
{"lanczos", LANCZOS},
|
||||
})
|
||||
{
|
||||
@ -18,6 +19,7 @@ namespace Config
|
||||
switch (m_value)
|
||||
{
|
||||
case BILINEAR:
|
||||
case BICUBIC:
|
||||
return { "Blur", 0, 100, 0, m_param };
|
||||
case LANCZOS:
|
||||
return { "Lobes", 2, 4, 2, m_param };
|
||||
|
@ -11,7 +11,8 @@ namespace Config
|
||||
public:
|
||||
static const UINT POINT = 0;
|
||||
static const UINT BILINEAR = 1;
|
||||
static const UINT LANCZOS = 2;
|
||||
static const UINT BICUBIC = 2;
|
||||
static const UINT LANCZOS = 3;
|
||||
|
||||
DisplayFilter();
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <D3dDdi/ShaderBlitter.h>
|
||||
#include <D3dDdi/SurfaceRepository.h>
|
||||
#include <DDraw/Surfaces/PrimarySurface.h>
|
||||
#include <Shaders/Bicubic.h>
|
||||
#include <Shaders/ColorKey.h>
|
||||
#include <Shaders/ColorKeyBlend.h>
|
||||
#include <Shaders/DepthBlt.h>
|
||||
@ -57,6 +58,7 @@ namespace D3dDdi
|
||||
{
|
||||
ShaderBlitter::ShaderBlitter(Device& device)
|
||||
: m_device(device)
|
||||
, m_psBicubic(createPixelShader(g_psBicubic))
|
||||
, m_psColorKey(createPixelShader(g_psColorKey))
|
||||
, m_psColorKeyBlend(createPixelShader(g_psColorKeyBlend))
|
||||
, m_psDepthBlt(createPixelShader(g_psDepthBlt))
|
||||
@ -68,6 +70,8 @@ namespace D3dDdi
|
||||
, m_psPaletteLookup(createPixelShader(g_psPaletteLookup))
|
||||
, m_psTextureSampler(createPixelShader(g_psTextureSampler))
|
||||
, m_vertexShaderDecl(createVertexShaderDecl())
|
||||
, m_convolutionBaseParams{}
|
||||
, m_convolutionExtraParams{}
|
||||
, m_vertices{}
|
||||
{
|
||||
for (std::size_t i = 0; i < m_vertices.size(); ++i)
|
||||
@ -76,6 +80,22 @@ namespace D3dDdi
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderBlitter::bicubicBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect, UINT blurPercent)
|
||||
{
|
||||
LOG_FUNC("ShaderBlitter::bicubicBlt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
||||
static_cast<HANDLE>(srcResource), srcSubResourceIndex, srcRect, blurPercent);
|
||||
|
||||
const float B = blurPercent / 100.0f;
|
||||
const float C = (1 - B) / 2;
|
||||
|
||||
m_convolutionExtraParams[0] = { (12 - 9 * B - 6 * C) / 6, (-18 + 12 * B + 6 * C) / 6, 0, (6 - 2 * B) / 6 };
|
||||
m_convolutionExtraParams[1] = { (-B - 6 * C) / 6, (6 * B + 30 * C) / 6, (-12 * B - 48 * C) / 6, (8 * B + 24 * C) / 6 };
|
||||
|
||||
convolutionBlt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcSubResourceIndex, srcRect,
|
||||
2, m_psBicubic.get());
|
||||
}
|
||||
|
||||
void ShaderBlitter::blt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect,
|
||||
HANDLE pixelShader, UINT filter, UINT flags, const BYTE* alpha, const Gdi::Region& srcRgn)
|
||||
@ -192,23 +212,23 @@ namespace D3dDdi
|
||||
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 };
|
||||
m_convolutionBaseParams[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 };
|
||||
m_convolutionBaseParams[1] = { firstTextureOffset, 0, firstKernelOffset, 0 };
|
||||
m_convolutionBaseParams[2] = { textureStep, 0, kernelStep, 0 };
|
||||
m_convolutionBaseParams[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 };
|
||||
m_convolutionBaseParams[1] = { 0, firstTextureOffset, 0, firstKernelOffset };
|
||||
m_convolutionBaseParams[2] = { 0, textureStep, 0, kernelStep };
|
||||
m_convolutionBaseParams[3] = { 0, -0.5f, 0.5f * textureSizeRcp.x, 0.5f * textureSizeRcp.y };
|
||||
}
|
||||
reg[4] = { support, 1.0f / support, 0, 0 };
|
||||
m_convolutionBaseParams[4] = { support, 1.0f / support, 0, 0 };
|
||||
|
||||
DeviceState::TempPixelShaderConst tempPsConst(m_device.getState(), { 0, reg.size() }, reg.data());
|
||||
DeviceState::TempPixelShaderConst tempPsConst(m_device.getState(),
|
||||
{ 0, m_convolutionBaseParams.size() + m_convolutionExtraParams.size()}, m_convolutionBaseParams.data());
|
||||
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcSubResourceIndex, srcRect,
|
||||
pixelShader, D3DTEXF_LINEAR | D3DTEXF_SRGB);
|
||||
}
|
||||
@ -470,6 +490,11 @@ namespace D3dDdi
|
||||
srcResource, srcSubResourceIndex, srcRect, Config::displayFilter.getParam());
|
||||
break;
|
||||
|
||||
case Config::Settings::DisplayFilter::BICUBIC:
|
||||
m_device.getShaderBlitter().bicubicBlt(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());
|
||||
|
@ -25,6 +25,8 @@ namespace D3dDdi
|
||||
ShaderBlitter& operator=(const ShaderBlitter&) = delete;
|
||||
ShaderBlitter& operator=(ShaderBlitter&&) = delete;
|
||||
|
||||
void bicubicBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect, UINT blurPercent);
|
||||
void colorKeyBlt(const Resource& dstResource, UINT dstSubResourceIndex,
|
||||
const Resource& srcResource, UINT srcSubResourceIndex, DeviceState::ShaderConstF srcColorKey);
|
||||
void cursorBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||
@ -86,6 +88,7 @@ namespace D3dDdi
|
||||
void setTextureCoords(UINT stage, const RECT& rect, UINT width, UINT height);
|
||||
|
||||
Device& m_device;
|
||||
std::unique_ptr<void, ResourceDeleter> m_psBicubic;
|
||||
std::unique_ptr<void, ResourceDeleter> m_psColorKey;
|
||||
std::unique_ptr<void, ResourceDeleter> m_psColorKeyBlend;
|
||||
std::unique_ptr<void, ResourceDeleter> m_psDepthBlt;
|
||||
@ -97,6 +100,8 @@ namespace D3dDdi
|
||||
std::unique_ptr<void, ResourceDeleter> m_psPaletteLookup;
|
||||
std::unique_ptr<void, ResourceDeleter> m_psTextureSampler;
|
||||
std::unique_ptr<void, ResourceDeleter> m_vertexShaderDecl;
|
||||
std::array<DeviceState::ShaderConstF, 5> m_convolutionBaseParams;
|
||||
std::array<DeviceState::ShaderConstF, 2> m_convolutionExtraParams;
|
||||
std::array<Vertex, 4> m_vertices;
|
||||
};
|
||||
}
|
||||
|
@ -460,6 +460,7 @@
|
||||
<None Include="Shaders\Convolution.hlsli" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<FxCompile Include="Shaders\Bicubic.hlsl" />
|
||||
<FxCompile Include="Shaders\ColorKey.hlsl" />
|
||||
<FxCompile Include="Shaders\ColorKeyBlend.hlsl" />
|
||||
<FxCompile Include="Shaders\DepthBlt.hlsl" />
|
||||
|
@ -1103,6 +1103,9 @@
|
||||
<FxCompile Include="Shaders\Lanczos.hlsl">
|
||||
<Filter>Shaders</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="Shaders\Bicubic.hlsl">
|
||||
<Filter>Shaders</Filter>
|
||||
</FxCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="arrow.bmp">
|
||||
|
9
DDrawCompat/Shaders/Bicubic.hlsl
Normal file
9
DDrawCompat/Shaders/Bicubic.hlsl
Normal file
@ -0,0 +1,9 @@
|
||||
#include "Convolution.hlsli"
|
||||
|
||||
float kernel(float x)
|
||||
{
|
||||
x = min(abs(x), g_support);
|
||||
const float4 weights = x < 1 ? g_extraParams[0] : g_extraParams[1];
|
||||
const float4 powers = float4(pow(x, 3), pow(x, 2), x, 1);
|
||||
return dot(weights, powers);
|
||||
}
|
@ -3,6 +3,8 @@ int g_sampleCountX : register(i0);
|
||||
int g_sampleCountY : register(i1);
|
||||
|
||||
float4 c[32] : register(c0);
|
||||
float4 g_extraParams[2] : register(c5);
|
||||
|
||||
static const float2 g_textureSize = c[0].xy;
|
||||
static const float2 g_textureSizeRcp = c[0].zw;
|
||||
static const float4 g_firstCoordOffset = c[1];
|
||||
|
Loading…
x
Reference in New Issue
Block a user