GPU: Support emulating a depth buffer from PGXP depth values

This commit is contained in:
Connor McLaughlin
2020-12-23 01:10:49 +10:00
parent f393ea618e
commit aa1543271e
13 changed files with 242 additions and 47 deletions

View File

@ -5,10 +5,12 @@
GPU_HW_ShaderGen::GPU_HW_ShaderGen(HostDisplay::RenderAPI render_api, u32 resolution_scale, u32 multisamples,
bool per_sample_shading, bool true_color, bool scaled_dithering,
GPUTextureFilter texture_filtering, bool uv_limits, bool supports_dual_source_blend)
GPUTextureFilter texture_filtering, bool uv_limits, bool pgxp_depth,
bool supports_dual_source_blend)
: ShaderGen(render_api, supports_dual_source_blend), m_resolution_scale(resolution_scale),
m_multisamples(multisamples), m_true_color(true_color), m_per_sample_shading(per_sample_shading),
m_scaled_dithering(scaled_dithering), m_texture_filter(texture_filtering), m_uv_limits(uv_limits)
m_scaled_dithering(scaled_dithering), m_texture_filter(texture_filtering), m_uv_limits(uv_limits),
m_pgxp_depth(pgxp_depth)
{
}
@ -84,6 +86,7 @@ std::string GPU_HW_ShaderGen::GenerateBatchVertexShader(bool textured)
WriteHeader(ss);
DefineMacro(ss, "TEXTURED", textured);
DefineMacro(ss, "UV_LIMITS", m_uv_limits);
DefineMacro(ss, "PGXP_DEPTH", m_pgxp_depth);
WriteCommonFunctions(ss);
WriteBatchUniformBuffer(ss);
@ -135,8 +138,15 @@ CONSTANT float TEX_EPSILON = 0.00001;
// 0..+1023 -> -1..1
float pos_x = ((a_pos.x + vertex_offset) / 512.0) - 1.0;
float pos_y = ((a_pos.y + vertex_offset) / -256.0) + 1.0;
#if PGXP_DEPTH
// Ignore mask Z when using PGXP depth.
float pos_z = a_pos.w;
float pos_w = a_pos.w;
#else
float pos_z = a_pos.z;
float pos_w = a_pos.w;
#endif
#if API_OPENGL || API_OPENGL_ES
pos_y += POS_EPSILON;
@ -689,6 +699,7 @@ std::string GPU_HW_ShaderGen::GenerateBatchFragmentShader(GPU_HW::BatchRenderMod
DefineMacro(ss, "TEXTURE_FILTERING", m_texture_filter != GPUTextureFilter::Nearest);
DefineMacro(ss, "UV_LIMITS", m_uv_limits);
DefineMacro(ss, "USE_DUAL_SOURCE", use_dual_source);
DefineMacro(ss, "PGXP_DEPTH", m_pgxp_depth);
WriteCommonFunctions(ss);
WriteBatchUniformBuffer(ss);
@ -800,17 +811,18 @@ float4 SampleFromVRAM(uint4 texpage, float2 coords)
{
DeclareFragmentEntryPoint(ss, 1, 1,
{{"nointerpolation", "uint4 v_texpage"}, {"nointerpolation", "float4 v_uv_limits"}},
true, use_dual_source ? 2 : 1, true, UsingMSAA(), UsingPerSampleShading());
true, use_dual_source ? 2 : 1, !m_pgxp_depth, UsingMSAA(), UsingPerSampleShading());
}
else
{
DeclareFragmentEntryPoint(ss, 1, 1, {{"nointerpolation", "uint4 v_texpage"}}, true, use_dual_source ? 2 : 1, true,
UsingMSAA(), UsingPerSampleShading());
DeclareFragmentEntryPoint(ss, 1, 1, {{"nointerpolation", "uint4 v_texpage"}}, true, use_dual_source ? 2 : 1,
!m_pgxp_depth, UsingMSAA(), UsingPerSampleShading());
}
}
else
{
DeclareFragmentEntryPoint(ss, 1, 0, {}, true, use_dual_source ? 2 : 1, true, UsingMSAA(), UsingPerSampleShading());
DeclareFragmentEntryPoint(ss, 1, 0, {}, true, use_dual_source ? 2 : 1, !m_pgxp_depth, UsingMSAA(),
UsingPerSampleShading());
}
ss << R"(
@ -939,7 +951,9 @@ float4 SampleFromVRAM(uint4 texpage, float2 coords)
o_col0 = float4(color, u_dst_alpha_factor / ialpha);
#endif
#if !PGXP_DEPTH
o_depth = oalpha * v_pos.z;
#endif
}
else
{
@ -962,7 +976,9 @@ float4 SampleFromVRAM(uint4 texpage, float2 coords)
#endif
#endif
#if !PGXP_DEPTH
o_depth = oalpha * v_pos.z;
#endif
}
#else
// Non-transparency won't enable blending so we can write the mask here regardless.
@ -972,7 +988,9 @@ float4 SampleFromVRAM(uint4 texpage, float2 coords)
o_col1 = float4(0.0, 0.0, 0.0, 1.0 - ialpha);
#endif
#if !PGXP_DEPTH
o_depth = oalpha * v_pos.z;
#endif
#endif
}
)";
@ -1196,6 +1214,7 @@ std::string GPU_HW_ShaderGen::GenerateVRAMWriteFragmentShader(bool use_ssbo)
std::stringstream ss;
WriteHeader(ss);
WriteCommonFunctions(ss);
DefineMacro(ss, "PGXP_DEPTH", m_pgxp_depth);
DeclareUniformBuffer(ss,
{"uint2 u_base_coords", "uint2 u_end_coords", "uint2 u_size", "uint u_buffer_base_offset",
"uint u_mask_or_bits", "float u_depth_value"},
@ -1243,7 +1262,11 @@ std::string GPU_HW_ShaderGen::GenerateVRAMWriteFragmentShader(bool use_ssbo)
uint value = GET_VALUE(buffer_offset) | u_mask_or_bits;
o_col0 = RGBA5551ToRGBA8(value);
#if !PGXP_DEPTH
o_depth = (o_col0.a == 1.0) ? u_depth_value : 0.0;
#else
o_depth = 1.0;
#endif
})";
return ss.str();
@ -1257,6 +1280,7 @@ std::string GPU_HW_ShaderGen::GenerateVRAMCopyFragmentShader()
std::stringstream ss;
WriteHeader(ss);
WriteCommonFunctions(ss);
DefineMacro(ss, "PGXP_DEPTH", m_pgxp_depth);
DeclareUniformBuffer(ss,
{"uint2 u_src_coords", "uint2 u_dst_coords", "uint2 u_end_coords", "uint2 u_size",
"bool u_set_mask_bit", "float u_depth_value"},
@ -1291,7 +1315,11 @@ std::string GPU_HW_ShaderGen::GenerateVRAMCopyFragmentShader()
float4 color = LOAD_TEXTURE(samp0, int2(src_coords), 0);
#endif
o_col0 = float4(color.xyz, u_set_mask_bit ? 1.0 : color.a);
#if !PGXP_DEPTH
o_depth = (u_set_mask_bit ? 1.0f : ((o_col0.a == 1.0) ? u_depth_value : 0.0));
#else
o_depth = 1.0f;
#endif
})";
return ss.str();