GS/HW: Allow conversion from 32bit to 24bit depth

This commit is contained in:
refractionpcsx2 2024-06-27 18:32:12 +01:00
parent faa54f6c14
commit a7047b605e
7 changed files with 49 additions and 0 deletions

View File

@ -237,6 +237,13 @@ float rgb5a1_to_depth16(float4 val)
return float(((c.r & 0xF8u) >> 3) | ((c.g & 0xF8u) << 2) | ((c.b & 0xF8u) << 7) | ((c.a & 0x80u) << 8)) * exp2(-32.0f); return float(((c.r & 0xF8u) >> 3) | ((c.g & 0xF8u) << 2) | ((c.b & 0xF8u) << 7) | ((c.a & 0x80u) << 8)) * exp2(-32.0f);
} }
float ps_convert_float32_float24(PS_INPUT input) : SV_Depth
{
// Truncates depth value to 24bits
uint d = uint(sample_c(input.t).r * exp2(32.0f)) & 0xFFFFFF;
return float(d) * exp2(-32.0f);
}
float ps_convert_rgba8_float32(PS_INPUT input) : SV_Depth float ps_convert_rgba8_float32(PS_INPUT input) : SV_Depth
{ {
// Convert an RGBA texture into a float depth texture // Convert an RGBA texture into a float depth texture

View File

@ -144,6 +144,15 @@ float rgb5a1_to_depth16(vec4 unorm)
return float(((c.r & 0xF8u) >> 3) | ((c.g & 0xF8u) << 2) | ((c.b & 0xF8u) << 7) | ((c.a & 0x80u) << 8)) * exp2(-32.0f); return float(((c.r & 0xF8u) >> 3) | ((c.g & 0xF8u) << 2) | ((c.b & 0xF8u) << 7) | ((c.a & 0x80u) << 8)) * exp2(-32.0f);
} }
#ifdef ps_convert_float32_float24
void ps_convert_float32_float24()
{
// Truncates depth value to 24bits
uint d = uint(sample_c().r * exp2(32.0f)) & 0xFFFFFF;
gl_FragDepth = float(d) * exp2(-32.0f);
}
#endif
#ifdef ps_convert_rgba8_float32 #ifdef ps_convert_rgba8_float32
void ps_convert_rgba8_float32() void ps_convert_rgba8_float32()
{ {

View File

@ -214,6 +214,15 @@ float rgb5a1_to_depth16(vec4 unorm)
return float(((c.r & 0xF8u) >> 3) | ((c.g & 0xF8u) << 2) | ((c.b & 0xF8u) << 7) | ((c.a & 0x80u) << 8)) * exp2(-32.0f); return float(((c.r & 0xF8u) >> 3) | ((c.g & 0xF8u) << 2) | ((c.b & 0xF8u) << 7) | ((c.a & 0x80u) << 8)) * exp2(-32.0f);
} }
#ifdef ps_convert_float32_float24
void ps_convert_float32_float24()
{
// Truncates depth value to 24bits
uint d = uint(sample_c(v_tex).r * exp2(32.0f)) & 0xFFFFFF;
gl_FragDepth = float(d) * exp2(-32.0f);
}
#endif
#ifdef ps_convert_rgba8_float32 #ifdef ps_convert_rgba8_float32
void ps_convert_rgba8_float32() void ps_convert_rgba8_float32()
{ {

View File

@ -64,6 +64,7 @@ const char* shaderName(ShaderConvert value)
case ShaderConvert::RGBA8_TO_FLOAT24_BILN: return "ps_convert_rgba8_float24_biln"; case ShaderConvert::RGBA8_TO_FLOAT24_BILN: return "ps_convert_rgba8_float24_biln";
case ShaderConvert::RGBA8_TO_FLOAT16_BILN: return "ps_convert_rgba8_float16_biln"; case ShaderConvert::RGBA8_TO_FLOAT16_BILN: return "ps_convert_rgba8_float16_biln";
case ShaderConvert::RGB5A1_TO_FLOAT16_BILN: return "ps_convert_rgb5a1_float16_biln"; case ShaderConvert::RGB5A1_TO_FLOAT16_BILN: return "ps_convert_rgb5a1_float16_biln";
case ShaderConvert::FLOAT32_TO_FLOAT24: return "ps_convert_float32_float24";
case ShaderConvert::DEPTH_COPY: return "ps_depth_copy"; case ShaderConvert::DEPTH_COPY: return "ps_depth_copy";
case ShaderConvert::DOWNSAMPLE_COPY: return "ps_downsample_copy"; case ShaderConvert::DOWNSAMPLE_COPY: return "ps_downsample_copy";
case ShaderConvert::RGBA_TO_8I: return "ps_convert_rgba_8i"; case ShaderConvert::RGBA_TO_8I: return "ps_convert_rgba_8i";

View File

@ -39,6 +39,7 @@ enum class ShaderConvert
RGBA8_TO_FLOAT24_BILN, RGBA8_TO_FLOAT24_BILN,
RGBA8_TO_FLOAT16_BILN, RGBA8_TO_FLOAT16_BILN,
RGB5A1_TO_FLOAT16_BILN, RGB5A1_TO_FLOAT16_BILN,
FLOAT32_TO_FLOAT24,
DEPTH_COPY, DEPTH_COPY,
DOWNSAMPLE_COPY, DOWNSAMPLE_COPY,
RGBA_TO_8I, RGBA_TO_8I,
@ -78,6 +79,7 @@ static inline bool HasDepthOutput(ShaderConvert shader)
case ShaderConvert::RGBA8_TO_FLOAT24_BILN: case ShaderConvert::RGBA8_TO_FLOAT24_BILN:
case ShaderConvert::RGBA8_TO_FLOAT16_BILN: case ShaderConvert::RGBA8_TO_FLOAT16_BILN:
case ShaderConvert::RGB5A1_TO_FLOAT16_BILN: case ShaderConvert::RGB5A1_TO_FLOAT16_BILN:
case ShaderConvert::FLOAT32_TO_FLOAT24:
case ShaderConvert::DEPTH_COPY: case ShaderConvert::DEPTH_COPY:
return true; return true;
default: default:

View File

@ -2026,6 +2026,20 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
else if (dst->m_scale != scale) else if (dst->m_scale != scale)
scale = dst->m_scale; scale = dst->m_scale;
// Game is changing from 32bit deptth to 24bit, meaning any top values in the depth will no longer be valid, I hope no games rely on these values being maintained, else we're screwed.
if (type == DepthStencil && dst->m_type == DepthStencil && GSLocalMemory::m_psm[dst->m_TEX0.PSM].trbpp == 32 && GSLocalMemory::m_psm[TEX0.PSM].trbpp == 24 && dst->m_alpha_max > 0)
{
calcRescale(dst);
GSTexture* tex = g_gs_device->CreateDepthStencil(new_scaled_size.x, new_scaled_size.y, GSTexture::Format::DepthStencil, false);
g_gs_device->StretchRect(dst->m_texture, sRect, tex, dRect, ShaderConvert::FLOAT32_TO_FLOAT24, false);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
g_gs_device->Recycle(dst->m_texture);
dst->m_texture = tex;
dst->m_alpha_min = 0;
dst->m_alpha_max = 0;
}
// If our RGB was invalidated, we need to pull it from depth. // If our RGB was invalidated, we need to pull it from depth.
// Terminator 3 will reuse our dst_matched target with the RGB masked, then later use the full ARGB area, so we need to update the depth. // Terminator 3 will reuse our dst_matched target with the RGB masked, then later use the full ARGB area, so we need to update the depth.
const bool preserve_target = preserve_rgb || preserve_alpha; const bool preserve_target = preserve_rgb || preserve_alpha;

View File

@ -249,6 +249,13 @@ struct ConvertToDepthRes
} }
}; };
fragment DepthOut ps_convert_float32_float24(ConvertShaderData data [[stage_in]], ConvertPSDepthRes res)
{
// Truncates depth value to 24bits
uint val = uint(res.sample(data.t) * 0x1p32) & 0xFFFFFF;
return float(val) * 0x1p-32f;
}
fragment DepthOut ps_convert_rgba8_float32(ConvertShaderData data [[stage_in]], ConvertToDepthRes res) fragment DepthOut ps_convert_rgba8_float32(ConvertShaderData data [[stage_in]], ConvertToDepthRes res)
{ {
return rgba8_to_depth32(res.sample(data.t)); return rgba8_to_depth32(res.sample(data.t));