mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-10-11 22:49:56 +00:00
GS/HW: Adjust line AA1 blur with upscaling.
This commit is contained in:
@@ -290,6 +290,12 @@ cbuffer cb1
|
||||
float4x4 DitherMatrix;
|
||||
float ScaledScaleFactor;
|
||||
float RcpScaleFactor;
|
||||
float _pad0_cb1;
|
||||
float _pad1_cb1;
|
||||
float LineCovScale;
|
||||
float _pad2_cb1;
|
||||
float _pad3_cb1;
|
||||
float _pad4_cb1;
|
||||
};
|
||||
|
||||
float4 RtLoad(int2 xy)
|
||||
@@ -1362,7 +1368,12 @@ void ps_main(PS_INPUT input)
|
||||
float4 C = ps_color(input);
|
||||
|
||||
#if PS_AA1
|
||||
float cov = clamp(1.0f - abs(input.inv_cov), 0.0f, 1.0f);
|
||||
#if PS_AA1 == PS_AA1_LINE
|
||||
// Blur only outer part of the line by scaling coverage.
|
||||
float cov = clamp(LineCovScale * (1.0f - abs(input.inv_cov)), 0.0f, 1.0f);
|
||||
#else
|
||||
float cov = clamp(1.0f - abs(input.inv_cov), 0.0f, 1.0f);
|
||||
#endif
|
||||
#if PS_ABE
|
||||
if (floor(C.a) == 128.0f) // The coverage is only used if the fragment alpha is 128.
|
||||
C.a = 128.0f * cov;
|
||||
@@ -1632,7 +1643,7 @@ cbuffer cb0
|
||||
float2 TextureOffset;
|
||||
float2 PointSize;
|
||||
uint MaxDepth;
|
||||
uint _cb0_pad0;
|
||||
float LineAA1Width;
|
||||
};
|
||||
|
||||
#ifdef DX12
|
||||
@@ -1875,11 +1886,9 @@ VS_OUTPUT vs_main_expand(uint vid : SV_VertexID)
|
||||
// Use bottom minus top for delta regardless of which vertex we are expanding.
|
||||
float2 line_delta = is_bottom ? (vtx.p.xy - other.p.xy) : (other.p.xy - vtx.p.xy);
|
||||
float2 line_vector = normalize(line_delta / VertexScale);
|
||||
#if VS_EXPAND == VS_EXPAND_LINE
|
||||
float2 line_expand = float2(line_vector.y, -line_vector.x);
|
||||
#elif VS_EXPAND == VS_EXPAND_LINE_AA1
|
||||
// Expand in y direction for shallow lines and x direction for steep lines.
|
||||
float2 line_expand = abs(line_vector.x) >= abs(line_vector.y) ? float2(0.0f, 2.0f) : float2(2.0f, 0.0f);
|
||||
#if VS_EXPAND == VS_EXPAND_LINE_AA1
|
||||
line_expand *= 2.0f * LineAA1Width;
|
||||
#endif
|
||||
float2 line_width = (line_expand * PointSize) / 2;
|
||||
float2 offset = is_right ? line_width : -line_width;
|
||||
|
||||
@@ -93,6 +93,13 @@ layout(std140, binding = 0) uniform cb21
|
||||
|
||||
float ScaledScaleFactor;
|
||||
float RcpScaleFactor;
|
||||
float _pad0_cb1;
|
||||
float _pad1_cb1;
|
||||
|
||||
float LineCovScale;
|
||||
float _pad2_cb1;
|
||||
float _pad3_cb1;
|
||||
float _pad4_cb1;
|
||||
};
|
||||
|
||||
in SHADER
|
||||
@@ -1250,7 +1257,12 @@ void ps_main()
|
||||
vec4 C = ps_color();
|
||||
|
||||
#if PS_AA1
|
||||
float cov = clamp(1.0f - abs(PSin.inv_cov), 0.0f, 1.0f);
|
||||
#if PS_AA1 == PS_AA1_LINE
|
||||
// Blur only outer part of the line by scaling coverage.
|
||||
float cov = clamp(LineCovScale * (1.0f - abs(PSin.inv_cov)), 0.0f, 1.0f);
|
||||
#else
|
||||
float cov = clamp(1.0f - abs(PSin.inv_cov), 0.0f, 1.0f);
|
||||
#endif
|
||||
#if PS_ABE
|
||||
if (floor(C.a) == 128.0f) // The coverage is only used if the fragment alpha is 128.
|
||||
C.a = 128.0f * cov;
|
||||
|
||||
@@ -12,8 +12,9 @@ layout(std140, binding = 1) uniform cb20
|
||||
vec2 TextureOffset;
|
||||
|
||||
vec2 PointSize;
|
||||
|
||||
uint MaxDepth;
|
||||
uint pad_cb20;
|
||||
float LineAA1Width;
|
||||
};
|
||||
|
||||
#ifdef VERTEX_SHADER
|
||||
@@ -323,11 +324,8 @@ void main()
|
||||
// Use bottom minus top for delta regardless of which vertex we are expanding.
|
||||
vec2 line_delta = is_bottom ? (vtx.p.xy - other.p.xy) : (other.p.xy - vtx.p.xy);
|
||||
vec2 line_vector = normalize(line_delta / VertexScale);
|
||||
#if VS_EXPAND == VS_EXPAND_LINE
|
||||
vec2 line_expand = vec2(line_vector.y, -line_vector.x);
|
||||
#elif VS_EXPAND == VS_EXPAND_LINE_AA1
|
||||
// Expand in y direction for shallow lines and x direction for steep lines.
|
||||
vec2 line_expand = abs(line_vector.x) >= abs(line_vector.y) ? vec2(0.0f, 2.0f) : vec2(2.0f, 0.0f);
|
||||
if VS_EXPAND == VS_EXPAND_LINE_AA1
|
||||
line_expand *= 2.0f * LineAA1Width;
|
||||
#endif
|
||||
vec2 line_width = (line_expand * PointSize) / 2;
|
||||
vec2 offset = is_right ? line_width : -line_width;
|
||||
|
||||
@@ -24,7 +24,7 @@ layout(std140, set = 0, binding = 0) uniform cb0
|
||||
vec2 TextureOffset;
|
||||
vec2 PointSize;
|
||||
uint MaxDepth;
|
||||
uint pad_cb0;
|
||||
float LineAA1Width;
|
||||
};
|
||||
|
||||
layout(location = 0) out VSOutput
|
||||
@@ -319,11 +319,9 @@ void main()
|
||||
// Use bottom minus top for delta regardless of which vertex we are expanding.
|
||||
vec2 line_delta = is_bottom ? (vtx.p.xy - other.p.xy) : (other.p.xy - vtx.p.xy);
|
||||
vec2 line_vector = normalize(line_delta / VertexScale);
|
||||
#if VS_EXPAND == VS_EXPAND_LINE
|
||||
vec2 line_expand = vec2(line_vector.y, -line_vector.x);
|
||||
#elif VS_EXPAND == VS_EXPAND_LINE_AA1
|
||||
// Expand in y direction for shallow lines and x direction for steep lines.
|
||||
vec2 line_expand = abs(line_vector.x) >= abs(line_vector.y) ? vec2(0.0f, 2.0f) : vec2(2.0f, 0.0f);
|
||||
#if VS_EXPAND == VS_EXPAND_LINE_AA1
|
||||
line_expand *= 2.0f * LineAA1Width;
|
||||
#endif
|
||||
vec2 line_width = (line_expand * PointSize) / 2;
|
||||
vec2 offset = is_right ? line_width : -line_width;
|
||||
@@ -624,6 +622,12 @@ layout(std140, set = 0, binding = 1) uniform cb1
|
||||
mat4 DitherMatrix;
|
||||
float ScaledScaleFactor;
|
||||
float RcpScaleFactor;
|
||||
float _pad0_cb1;
|
||||
float _pad1_cb1;
|
||||
float LineCovScale;
|
||||
float _pad2_cb1;
|
||||
float _pad3_cb1;
|
||||
float _pad4_cb1;
|
||||
};
|
||||
|
||||
layout(location = 0) in VSOutput
|
||||
@@ -1804,7 +1808,12 @@ void main()
|
||||
vec4 C = ps_color();
|
||||
|
||||
#if PS_AA1
|
||||
float cov = clamp(1.0f - abs(vsIn.inv_cov), 0.0f, 1.0f);
|
||||
#if PS_AA1 == PS_AA1_LINE
|
||||
// Blur only outer part of the line by scaling coverage.
|
||||
float cov = clamp(LineCovScale * (1.0f - abs(vsIn.inv_cov)), 0.0f, 1.0f);
|
||||
#else
|
||||
float cov = clamp(1.0f - abs(vsIn.inv_cov), 0.0f, 1.0f);
|
||||
#endif
|
||||
#if PS_ABE
|
||||
if (floor(C.a) == 128.0f) // The coverage is only used if the fragment alpha is 128.
|
||||
C.a = 128.0f * cov;
|
||||
|
||||
@@ -1705,6 +1705,7 @@ static void DumpPSConstantBuffer(DrawConfigWriter& out, const GSHWDrawConfig::PS
|
||||
DumpVector4(out, "DitherMatrix_2", cb.DitherMatrix[2]);
|
||||
DumpVector4(out, "DitherMatrix_3", cb.DitherMatrix[3]);
|
||||
DumpVector4(out, "ScaleFactor", cb.ScaleFactor);
|
||||
out.WriteLn("LineCovScale: {}", cb.LineCovScale);
|
||||
}
|
||||
|
||||
static void DumpVSConstantBuffer(DrawConfigWriter& out, const GSHWDrawConfig::VSConstantBuffer& cb)
|
||||
@@ -1714,7 +1715,8 @@ static void DumpVSConstantBuffer(DrawConfigWriter& out, const GSHWDrawConfig::VS
|
||||
DumpVector2(out, "texture_scale", cb.texture_scale);
|
||||
DumpVector2(out, "texture_offset", cb.texture_offset);
|
||||
DumpVector2(out, "point_size", cb.point_size);
|
||||
DumpVector2(out, "max_depth", cb.max_depth);
|
||||
out.WriteLn("max_depth: {}", cb.max_depth);
|
||||
out.WriteLn("line_aa1_width: {}", cb.line_aa1_width);
|
||||
}
|
||||
|
||||
static void DumpConfig(DrawConfigWriter& out, const GSHWDrawConfig& conf,
|
||||
|
||||
@@ -1027,7 +1027,8 @@ struct alignas(16) GSHWDrawConfig
|
||||
GSVector2 texture_scale;
|
||||
GSVector2 texture_offset;
|
||||
GSVector2 point_size;
|
||||
GSVector2i max_depth;
|
||||
u32 max_depth;
|
||||
float line_aa1_width;
|
||||
__fi VSConstantBuffer()
|
||||
{
|
||||
memset(static_cast<void*>(this), 0, sizeof(*this));
|
||||
@@ -1117,6 +1118,10 @@ struct alignas(16) GSHWDrawConfig
|
||||
GSVector4 DitherMatrix[4];
|
||||
|
||||
GSVector4 ScaleFactor;
|
||||
float LineCovScale;
|
||||
float _pad0;
|
||||
float _pad1;
|
||||
float _pad2;
|
||||
|
||||
__fi PSConstantBuffer()
|
||||
{
|
||||
|
||||
@@ -5442,6 +5442,25 @@ void GSRendererHW::SetupIA(float target_scale, float sx, float sy, bool req_vert
|
||||
GL_INS("HW: AA1 line expand.");
|
||||
m_conf.vs.expand = GSHWDrawConfig::VSExpand::LineAA1;
|
||||
m_conf.cb_vs.point_size = GSVector2(16.0f * sx, 16.0f * sy);
|
||||
|
||||
if (target_scale == 1.0f)
|
||||
{
|
||||
m_conf.cb_vs.line_aa1_width = 1.0f; // 1 native pixel on each side.
|
||||
m_conf.cb_ps.LineCovScale = 1.0f; // Linear falloff on both sides.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reduce the amount of blur with upscaling.
|
||||
constexpr float half_native_px = 0.5f;
|
||||
const float upscaled_px = 1.0f / target_scale;
|
||||
|
||||
// Half a native pixel + 1 upscaled pixel on both sides.
|
||||
m_conf.cb_vs.line_aa1_width = half_native_px + upscaled_px;
|
||||
|
||||
// Opaque in middle and linear falloff on last 2 upscaled pixels on each side.
|
||||
m_conf.cb_ps.LineCovScale = (half_native_px + upscaled_px) / (2 * upscaled_px);
|
||||
}
|
||||
|
||||
m_conf.topology = GSHWDrawConfig::Topology::Triangle;
|
||||
m_conf.indices_per_prim = 6;
|
||||
ExpandLineIndices();
|
||||
@@ -5583,7 +5602,7 @@ void GSRendererHW::EmulateZbuffer(const GSTextureCache::Target* ds)
|
||||
// No interpolation for flat Z so we can make some optimizations.
|
||||
const bool flat_z = m_vt.m_eq.z || m_vt.m_primclass == GS_POINT_CLASS || m_vt.m_primclass == GS_SPRITE_CLASS;
|
||||
|
||||
m_conf.cb_vs.max_depth = GSVector2i(0xFFFFFFFF);
|
||||
m_conf.cb_vs.max_depth = 0xFFFFFFFF;
|
||||
m_conf.cb_ps.TA_MaxDepth_Af.z = 0.0f;
|
||||
m_conf.ps.zclamp = false;
|
||||
|
||||
@@ -5597,7 +5616,7 @@ void GSRendererHW::EmulateZbuffer(const GSTextureCache::Target* ds)
|
||||
if (flat_z)
|
||||
{
|
||||
// Clamp in vertex shader.
|
||||
m_conf.cb_vs.max_depth = GSVector2i(max_z);
|
||||
m_conf.cb_vs.max_depth = max_z;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -98,7 +98,7 @@ struct GSMTLMainVSUniform
|
||||
vector_float2 texture_offset;
|
||||
vector_float2 point_size;
|
||||
uint max_depth;
|
||||
uint _pad0;
|
||||
float line_aa1_width;
|
||||
};
|
||||
|
||||
struct GSMTLMainPSUniform
|
||||
@@ -140,6 +140,11 @@ struct GSMTLMainPSUniform
|
||||
matrix_float4x4 dither_matrix;
|
||||
|
||||
vector_float4 scale_factor;
|
||||
|
||||
float line_cov_scale;
|
||||
float _pad0;
|
||||
float _pad1;
|
||||
float _pad2;
|
||||
};
|
||||
|
||||
enum GSMTLAttributes
|
||||
|
||||
@@ -398,16 +398,11 @@ vertex MainVSOut vs_main_expand(
|
||||
// Use bottom minus top for delta regardless of which vertex we are expanding.
|
||||
float2 line_delta = is_bottom ? point.p.xy - other.p.xy : other.p.xy - point.p.xy;
|
||||
float2 line_vector = normalize(line_delta / cb.vertex_scale);
|
||||
float2 line_expand;
|
||||
if (VS_EXPAND_TYPE == VSExpand::Line)
|
||||
{
|
||||
line_expand = float2(line_vector.y, -line_vector.x);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Expand in y direction for shallow lines and x direction for steep lines.
|
||||
line_expand = abs(line_vector.x) >= abs(line_vector.y) ? float2(0, 2) : float2(2, 0);
|
||||
}
|
||||
float2 line_expand = float2(line_vector.y, -line_vector.x);
|
||||
|
||||
if (VS_EXPAND_TYPE == VSExpand::LineAA1)
|
||||
line_expand *= 2.f * cb.line_aa1_width;
|
||||
|
||||
float2 line_width = (line_expand * cb.point_size) / 2;
|
||||
float2 offset = is_right ? line_width : -line_width;
|
||||
point.p.xy += offset;
|
||||
@@ -1507,7 +1502,9 @@ struct PSMain
|
||||
|
||||
if (PS_AA1 != AA1::NONE)
|
||||
{
|
||||
float cov = saturate(1.f - abs(in.inv_cov));
|
||||
float cov = PS_AA1 == AA1::LINE ?
|
||||
saturate(cb.line_cov_scale * (1.f - abs(in.inv_cov))) : // Blur only outer part of the line by scaling coverage.
|
||||
saturate(1.f - abs(in.inv_cov));
|
||||
if (!PS_ABE || floor(C.a) == 128.f) // The coverage is only used if the fragment alpha is 128.
|
||||
C.a = 128.f * cov;
|
||||
}
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
/// Version number for GS and other shaders. Increment whenever any of the contents of the
|
||||
/// shaders change, to invalidate the cache.
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 101; // Last changed in PR 14547
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 102; // Last changed in PR 14480
|
||||
|
||||
Reference in New Issue
Block a user