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", {
|
: MappedSetting("DisplayFilter", "bilinear", {
|
||||||
{"point", POINT},
|
{"point", POINT},
|
||||||
{"bilinear", BILINEAR},
|
{"bilinear", BILINEAR},
|
||||||
|
{"bicubic", BICUBIC},
|
||||||
{"lanczos", LANCZOS},
|
{"lanczos", LANCZOS},
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
@ -18,6 +19,7 @@ namespace Config
|
|||||||
switch (m_value)
|
switch (m_value)
|
||||||
{
|
{
|
||||||
case BILINEAR:
|
case BILINEAR:
|
||||||
|
case BICUBIC:
|
||||||
return { "Blur", 0, 100, 0, m_param };
|
return { "Blur", 0, 100, 0, m_param };
|
||||||
case LANCZOS:
|
case LANCZOS:
|
||||||
return { "Lobes", 2, 4, 2, m_param };
|
return { "Lobes", 2, 4, 2, m_param };
|
||||||
|
@ -11,7 +11,8 @@ 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;
|
static const UINT BICUBIC = 2;
|
||||||
|
static const UINT LANCZOS = 3;
|
||||||
|
|
||||||
DisplayFilter();
|
DisplayFilter();
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <D3dDdi/ShaderBlitter.h>
|
#include <D3dDdi/ShaderBlitter.h>
|
||||||
#include <D3dDdi/SurfaceRepository.h>
|
#include <D3dDdi/SurfaceRepository.h>
|
||||||
#include <DDraw/Surfaces/PrimarySurface.h>
|
#include <DDraw/Surfaces/PrimarySurface.h>
|
||||||
|
#include <Shaders/Bicubic.h>
|
||||||
#include <Shaders/ColorKey.h>
|
#include <Shaders/ColorKey.h>
|
||||||
#include <Shaders/ColorKeyBlend.h>
|
#include <Shaders/ColorKeyBlend.h>
|
||||||
#include <Shaders/DepthBlt.h>
|
#include <Shaders/DepthBlt.h>
|
||||||
@ -57,6 +58,7 @@ namespace D3dDdi
|
|||||||
{
|
{
|
||||||
ShaderBlitter::ShaderBlitter(Device& device)
|
ShaderBlitter::ShaderBlitter(Device& device)
|
||||||
: m_device(device)
|
: m_device(device)
|
||||||
|
, m_psBicubic(createPixelShader(g_psBicubic))
|
||||||
, m_psColorKey(createPixelShader(g_psColorKey))
|
, m_psColorKey(createPixelShader(g_psColorKey))
|
||||||
, m_psColorKeyBlend(createPixelShader(g_psColorKeyBlend))
|
, m_psColorKeyBlend(createPixelShader(g_psColorKeyBlend))
|
||||||
, m_psDepthBlt(createPixelShader(g_psDepthBlt))
|
, m_psDepthBlt(createPixelShader(g_psDepthBlt))
|
||||||
@ -68,6 +70,8 @@ namespace D3dDdi
|
|||||||
, m_psPaletteLookup(createPixelShader(g_psPaletteLookup))
|
, m_psPaletteLookup(createPixelShader(g_psPaletteLookup))
|
||||||
, m_psTextureSampler(createPixelShader(g_psTextureSampler))
|
, m_psTextureSampler(createPixelShader(g_psTextureSampler))
|
||||||
, m_vertexShaderDecl(createVertexShaderDecl())
|
, m_vertexShaderDecl(createVertexShaderDecl())
|
||||||
|
, m_convolutionBaseParams{}
|
||||||
|
, m_convolutionExtraParams{}
|
||||||
, m_vertices{}
|
, m_vertices{}
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < m_vertices.size(); ++i)
|
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,
|
void ShaderBlitter::blt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect,
|
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect,
|
||||||
HANDLE pixelShader, UINT filter, UINT flags, const BYTE* alpha, const Gdi::Region& srcRgn)
|
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 firstKernelOffset = firstSampleOffset * kernelStep;
|
||||||
const float firstTextureOffset = firstSampleOffset * textureStep;
|
const float firstTextureOffset = firstSampleOffset * textureStep;
|
||||||
|
|
||||||
std::array<DeviceState::ShaderConstF, 5> reg = {};
|
m_convolutionBaseParams[0] = { textureSize.x, textureSize.y, textureSizeRcp.x, textureSizeRcp.y };
|
||||||
reg[0] = { textureSize.x, textureSize.y, textureSizeRcp.x, textureSizeRcp.y };
|
|
||||||
if (isHorizontal)
|
if (isHorizontal)
|
||||||
{
|
{
|
||||||
reg[1] = { firstTextureOffset, 0, firstKernelOffset, 0 };
|
m_convolutionBaseParams[1] = { firstTextureOffset, 0, firstKernelOffset, 0 };
|
||||||
reg[2] = { textureStep, 0, kernelStep, 0 };
|
m_convolutionBaseParams[2] = { textureStep, 0, kernelStep, 0 };
|
||||||
reg[3] = { -0.5f, 0, 0.5f * textureSizeRcp.x, 0.5f * textureSizeRcp.y };
|
m_convolutionBaseParams[3] = { -0.5f, 0, 0.5f * textureSizeRcp.x, 0.5f * textureSizeRcp.y };
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
reg[1] = { 0, firstTextureOffset, 0, firstKernelOffset };
|
m_convolutionBaseParams[1] = { 0, firstTextureOffset, 0, firstKernelOffset };
|
||||||
reg[2] = { 0, textureStep, 0, kernelStep };
|
m_convolutionBaseParams[2] = { 0, textureStep, 0, kernelStep };
|
||||||
reg[3] = { 0, -0.5f, 0.5f * textureSizeRcp.x, 0.5f * textureSizeRcp.y };
|
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,
|
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcSubResourceIndex, srcRect,
|
||||||
pixelShader, D3DTEXF_LINEAR | D3DTEXF_SRGB);
|
pixelShader, D3DTEXF_LINEAR | D3DTEXF_SRGB);
|
||||||
}
|
}
|
||||||
@ -470,6 +490,11 @@ namespace D3dDdi
|
|||||||
srcResource, srcSubResourceIndex, srcRect, Config::displayFilter.getParam());
|
srcResource, srcSubResourceIndex, srcRect, Config::displayFilter.getParam());
|
||||||
break;
|
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:
|
case Config::Settings::DisplayFilter::LANCZOS:
|
||||||
m_device.getShaderBlitter().lanczosBlt(rt, rtIndex, rtRect,
|
m_device.getShaderBlitter().lanczosBlt(rt, rtIndex, rtRect,
|
||||||
srcResource, srcSubResourceIndex, srcRect, Config::displayFilter.getParam());
|
srcResource, srcSubResourceIndex, srcRect, Config::displayFilter.getParam());
|
||||||
|
@ -25,6 +25,8 @@ namespace D3dDdi
|
|||||||
ShaderBlitter& operator=(const ShaderBlitter&) = delete;
|
ShaderBlitter& operator=(const ShaderBlitter&) = delete;
|
||||||
ShaderBlitter& operator=(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,
|
void colorKeyBlt(const Resource& dstResource, UINT dstSubResourceIndex,
|
||||||
const Resource& srcResource, UINT srcSubResourceIndex, DeviceState::ShaderConstF srcColorKey);
|
const Resource& srcResource, UINT srcSubResourceIndex, DeviceState::ShaderConstF srcColorKey);
|
||||||
void cursorBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
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);
|
void setTextureCoords(UINT stage, const RECT& rect, UINT width, UINT height);
|
||||||
|
|
||||||
Device& m_device;
|
Device& m_device;
|
||||||
|
std::unique_ptr<void, ResourceDeleter> m_psBicubic;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psColorKey;
|
std::unique_ptr<void, ResourceDeleter> m_psColorKey;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psColorKeyBlend;
|
std::unique_ptr<void, ResourceDeleter> m_psColorKeyBlend;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psDepthBlt;
|
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_psPaletteLookup;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psTextureSampler;
|
std::unique_ptr<void, ResourceDeleter> m_psTextureSampler;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_vertexShaderDecl;
|
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;
|
std::array<Vertex, 4> m_vertices;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -460,6 +460,7 @@
|
|||||||
<None Include="Shaders\Convolution.hlsli" />
|
<None Include="Shaders\Convolution.hlsli" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<FxCompile Include="Shaders\Bicubic.hlsl" />
|
||||||
<FxCompile Include="Shaders\ColorKey.hlsl" />
|
<FxCompile Include="Shaders\ColorKey.hlsl" />
|
||||||
<FxCompile Include="Shaders\ColorKeyBlend.hlsl" />
|
<FxCompile Include="Shaders\ColorKeyBlend.hlsl" />
|
||||||
<FxCompile Include="Shaders\DepthBlt.hlsl" />
|
<FxCompile Include="Shaders\DepthBlt.hlsl" />
|
||||||
|
@ -1103,6 +1103,9 @@
|
|||||||
<FxCompile Include="Shaders\Lanczos.hlsl">
|
<FxCompile Include="Shaders\Lanczos.hlsl">
|
||||||
<Filter>Shaders</Filter>
|
<Filter>Shaders</Filter>
|
||||||
</FxCompile>
|
</FxCompile>
|
||||||
|
<FxCompile Include="Shaders\Bicubic.hlsl">
|
||||||
|
<Filter>Shaders</Filter>
|
||||||
|
</FxCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="arrow.bmp">
|
<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);
|
int g_sampleCountY : register(i1);
|
||||||
|
|
||||||
float4 c[32] : register(c0);
|
float4 c[32] : register(c0);
|
||||||
|
float4 g_extraParams[2] : register(c5);
|
||||||
|
|
||||||
static const float2 g_textureSize = c[0].xy;
|
static const float2 g_textureSize = c[0].xy;
|
||||||
static const float2 g_textureSizeRcp = c[0].zw;
|
static const float2 g_textureSizeRcp = c[0].zw;
|
||||||
static const float4 g_firstCoordOffset = c[1];
|
static const float4 g_firstCoordOffset = c[1];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user