Better checks for smoothed depal

This commit is contained in:
Henrik Rydgård 2022-08-22 10:32:02 +02:00
parent 6558bde0f6
commit 2a6015c1e3
2 changed files with 30 additions and 1 deletions

View File

@ -602,6 +602,9 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
} else {
WRITE(p, " vec2 uv = %s.xy;\n vec2 uv_round;\n", texcoord);
}
// Restrictions on this are checked before setting the smoothed flag.
// Only RGB565 and RGBA5551 are supported, and only the specific shifts hitting the
// channels directly.
WRITE(p, " vec4 t = %s(tex, %s.xy);\n", compat.texture, texcoord);
WRITE(p, " uint depalShift = (u_depal_mask_shift_off_fmt >> 8) & 0xFFU;\n");
WRITE(p, " uint depalFmt = (u_depal_mask_shift_off_fmt >> 24) & 0x3U;\n");

View File

@ -1859,6 +1859,31 @@ bool CanDepalettize(GETextureFormat texFormat, GEBufferFormat bufferFormat) {
}
}
// If the palette is detected as a smooth ramp, we can interpolate for higher color precision.
// But we only do it if the mask/shift exactly matches a color channel, else something different might be going
// on and we definitely don't want to interpolate.
// Great enhancement for Test Drive.
static bool CanUseSmoothDepal(const GPUgstate &gstate, GEBufferFormat framebufferFormat, int rampLength) {
if (gstate.getClutIndexStartPos() == 0 &&
gstate.getClutIndexMask() <= rampLength) {
switch (framebufferFormat) {
case GE_FORMAT_565:
if (gstate.getClutIndexShift() == 0 || gstate.getClutIndexShift() == 11) {
return gstate.getClutIndexMask() == 0x1F;
} else if (gstate.getClutIndexShift() == 5) {
return gstate.getClutIndexMask() == 0x3F;
}
break;
case GE_FORMAT_5551:
if (gstate.getClutIndexShift() == 0 || gstate.getClutIndexShift() == 5 || gstate.getClutIndexShift() == 10) {
return gstate.getClutIndexMask() == 0x1F;
}
break;
}
}
return false;
}
void TextureCacheCommon::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, GETextureFormat texFormat, RasterChannel channel) {
TextureShader *textureShader = nullptr;
uint32_t clutMode = gstate.clutformat & 0xFFFFFF;
@ -1901,7 +1926,8 @@ void TextureCacheCommon::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer
// Since we started/ended render passes, might need these.
gstate_c.Dirty(DIRTY_DEPAL);
gstate_c.SetUseShaderDepal(true, gstate.getClutIndexStartPos() == 0 && gstate.getClutIndexMask() <= clutTexture.rampLength);
gstate_c.SetUseShaderDepal(true, CanUseSmoothDepal(gstate, framebuffer->drawnFormat, clutTexture.rampLength));
gstate_c.depalFramebufferFormat = framebuffer->drawnFormat;
const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16);
const u32 clutTotalColors = clutMaxBytes_ / bytesPerColor;