GPU/HW: Add 'True Color (Full)' dithering mode
This is equivalent to the old 'True Color' mode. The new 'True Color' mode truncates flat-shaded sprites/polygons to 16-bit color before drawing. Doing so fixes: - Menu background in Breath of Fire IV. - Loading background in JumpStart Wildlife Safari - Field Trip. - and other similar games.
This commit is contained in:
parent
2d477f80b0
commit
741e971681
|
@ -80,6 +80,7 @@ static constexpr const std::array<const char*, static_cast<size_t>(Trait::MaxCou
|
|||
"ForceSoftwareRendererForReadbacks",
|
||||
"ForceRoundTextureCoordinates",
|
||||
"ForceShaderBlending",
|
||||
"ForceFullTrueColor",
|
||||
"ForceDeinterlacing",
|
||||
"ForceFullBoot",
|
||||
"DisableAutoAnalogMode",
|
||||
|
@ -110,6 +111,7 @@ static constexpr const std::array<const char*, static_cast<size_t>(Trait::MaxCou
|
|||
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Software Renderer For Readbacks", "GameDatabase::Trait"),
|
||||
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Round Texture Coordinates", "GameDatabase::Trait"),
|
||||
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Shader Blending", "GameDatabase::Trait"),
|
||||
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Full True Color", "GameDatabase::Trait"),
|
||||
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Deinterlacing", "GameDatabase::Trait"),
|
||||
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Full Boot", "GameDatabase::Trait"),
|
||||
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Disable Automatic Analog Mode", "GameDatabase::Trait"),
|
||||
|
@ -520,7 +522,7 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes
|
|||
}
|
||||
|
||||
if (HasTrait(Trait::DisableTrueColor) || HasTrait(Trait::DisableScaledDithering) ||
|
||||
HasTrait(Trait::ForceShaderBlending))
|
||||
HasTrait(Trait::ForceShaderBlending) || HasTrait(Trait::ForceFullTrueColor))
|
||||
{
|
||||
// Note: The order these are applied matters.
|
||||
const GPUDitheringMode old_mode = settings.gpu_dithering_mode;
|
||||
|
@ -539,6 +541,10 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes
|
|||
GPUDitheringMode::ScaledShaderBlend :
|
||||
GPUDitheringMode::UnscaledShaderBlend;
|
||||
}
|
||||
if (HasTrait(Trait::ForceFullTrueColor) && settings.gpu_dithering_mode == GPUDitheringMode::TrueColor)
|
||||
{
|
||||
settings.gpu_dithering_mode = GPUDitheringMode::TrueColorFull;
|
||||
}
|
||||
|
||||
if (display_osd_messages && settings.gpu_dithering_mode != old_mode)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,7 @@ enum class Trait : u32
|
|||
ForceSoftwareRendererForReadbacks,
|
||||
ForceRoundUpscaledTextureCoordinates,
|
||||
ForceShaderBlending,
|
||||
ForceFullTrueColor,
|
||||
ForceDeinterlacing,
|
||||
ForceFullBoot,
|
||||
DisableAutoAnalogMode,
|
||||
|
|
|
@ -154,6 +154,21 @@ ALWAYS_INLINE_RELEASE static GSVector4i GetVRAMTransferBounds(u32 x, u32 y, u32
|
|||
return ret;
|
||||
}
|
||||
|
||||
/// Returns true if the below function should be applied.
|
||||
ALWAYS_INLINE static bool ShouldTruncate32To16(const GPUBackendDrawCommand* cmd)
|
||||
{
|
||||
return (!cmd->texture_enable && !cmd->shading_enable && !cmd->dither_enable &&
|
||||
g_gpu_settings.gpu_dithering_mode == GPUDitheringMode::TrueColor);
|
||||
}
|
||||
|
||||
/// Truncates a 32-bit colour to 16-bit.
|
||||
ALWAYS_INLINE static u32 Truncate32To16(u32 color)
|
||||
{
|
||||
return GSVector4i((GSVector4(GSVector4i::zext32(color).u8to32().srl32<3>()) / GSVector4::cxpr(31.0f)) *
|
||||
GSVector4::cxpr(255.0f))
|
||||
.rgba32();
|
||||
}
|
||||
|
||||
namespace {
|
||||
class ShaderCompileProgressTracker
|
||||
{
|
||||
|
@ -2525,7 +2540,7 @@ void GPU_HW::DrawLine(const GPUBackendDrawLineCommand* cmd)
|
|||
}
|
||||
|
||||
AddDrawnRectangle(clamped_rect);
|
||||
DrawLine(GSVector4(bounds), start_color, end_color, depth);
|
||||
DrawLine(cmd, GSVector4(bounds), start_color, end_color, depth);
|
||||
}
|
||||
|
||||
if (ShouldDrawWithSoftwareRenderer())
|
||||
|
@ -2568,7 +2583,7 @@ void GPU_HW::DrawPreciseLine(const GPUBackendDrawPreciseLineCommand* cmd)
|
|||
}
|
||||
|
||||
AddDrawnRectangle(clamped_rect);
|
||||
DrawLine(bounds, start_color, end_color, depth);
|
||||
DrawLine(cmd, bounds, start_color, end_color, depth);
|
||||
}
|
||||
|
||||
if (ShouldDrawWithSoftwareRenderer())
|
||||
|
@ -2590,10 +2605,16 @@ void GPU_HW::DrawPreciseLine(const GPUBackendDrawPreciseLineCommand* cmd)
|
|||
}
|
||||
}
|
||||
|
||||
void GPU_HW::DrawLine(const GSVector4 bounds, u32 col0, u32 col1, float depth)
|
||||
void GPU_HW::DrawLine(const GPUBackendDrawCommand* cmd, const GSVector4 bounds, u32 col0, u32 col1, float depth)
|
||||
{
|
||||
DebugAssert(m_batch_vertex_space >= 4 && m_batch_index_space >= 6);
|
||||
|
||||
if (ShouldTruncate32To16(cmd))
|
||||
{
|
||||
col0 = Truncate32To16(col0);
|
||||
col1 = Truncate32To16(col1);
|
||||
}
|
||||
|
||||
const float x0 = bounds.x;
|
||||
const float y0 = bounds.y;
|
||||
const float x1 = bounds.z;
|
||||
|
@ -2717,7 +2738,9 @@ void GPU_HW::DrawSprite(const GPUBackendDrawRectangleCommand* cmd)
|
|||
const s32 pos_x = cmd->x;
|
||||
const s32 pos_y = cmd->y;
|
||||
const u32 texpage = m_draw_mode.bits;
|
||||
const u32 color = (cmd->texture_enable && cmd->raw_texture_enable) ? UINT32_C(0x00808080) : cmd->color;
|
||||
const u32 color = (cmd->texture_enable && cmd->raw_texture_enable) ?
|
||||
UINT32_C(0x00808080) :
|
||||
(ShouldTruncate32To16(cmd) ? Truncate32To16(cmd->color) : cmd->color);
|
||||
const float depth = GetCurrentNormalizedVertexDepth();
|
||||
const u32 orig_tex_left = ZeroExtend32(Truncate8(cmd->texcoord));
|
||||
const u32 orig_tex_top = ZeroExtend32(cmd->texcoord) >> 8;
|
||||
|
@ -2980,6 +3003,12 @@ ALWAYS_INLINE_RELEASE bool GPU_HW::BeginPolygonDraw(const GPUBackendDrawCommand*
|
|||
}
|
||||
}
|
||||
|
||||
if (ShouldTruncate32To16(cmd))
|
||||
{
|
||||
for (u32 i = 0; i < 4; i++)
|
||||
vertices[i].color = Truncate32To16(vertices[i].color);
|
||||
}
|
||||
|
||||
PrepareDraw(cmd);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -242,7 +242,7 @@ private:
|
|||
bool BlitVRAMReplacementTexture(GPUTexture* tex, u32 dst_x, u32 dst_y, u32 width, u32 height);
|
||||
|
||||
/// Expands a line into two triangles.
|
||||
void DrawLine(const GSVector4 bounds, u32 col0, u32 col1, float depth);
|
||||
void DrawLine(const GPUBackendDrawCommand* cmd, const GSVector4 bounds, u32 col0, u32 col1, float depth);
|
||||
|
||||
/// Computes partial derivatives and area for the given triangle. Needed for sprite/line detection.
|
||||
static void ComputeUVPartialDerivatives(const BatchVertex* vertices, float* dudx, float* dudy, float* dvdx,
|
||||
|
|
|
@ -1557,7 +1557,7 @@ const char* Settings::GetTextureFilterDisplayName(GPUTextureFilter filter)
|
|||
}
|
||||
|
||||
static constexpr const std::array s_gpu_dithering_mode_names = {
|
||||
"Unscaled", "UnscaledShaderBlend", "Scaled", "ScaledShaderBlend", "TrueColor",
|
||||
"Unscaled", "UnscaledShaderBlend", "Scaled", "ScaledShaderBlend", "TrueColor", "TrueColorFull",
|
||||
};
|
||||
static constexpr const std::array s_gpu_dithering_mode_display_names = {
|
||||
TRANSLATE_DISAMBIG_NOOP("Settings", "Unscaled", "GPUDitheringMode"),
|
||||
|
@ -1565,6 +1565,7 @@ static constexpr const std::array s_gpu_dithering_mode_display_names = {
|
|||
TRANSLATE_DISAMBIG_NOOP("Settings", "Scaled", "GPUDitheringMode"),
|
||||
TRANSLATE_DISAMBIG_NOOP("Settings", "Scaled (Shader Blending)", "GPUDitheringMode"),
|
||||
TRANSLATE_DISAMBIG_NOOP("Settings", "True Color", "GPUDitheringMode"),
|
||||
TRANSLATE_DISAMBIG_NOOP("Settings", "True Color (Full)", "GPUDitheringMode"),
|
||||
};
|
||||
static_assert(s_gpu_dithering_mode_names.size() == static_cast<size_t>(GPUDitheringMode::MaxCount));
|
||||
static_assert(s_gpu_dithering_mode_display_names.size() == static_cast<size_t>(GPUDitheringMode::MaxCount));
|
||||
|
|
|
@ -212,7 +212,7 @@ struct GPUSettings
|
|||
void SetPGXPDepthClearThreshold(float value);
|
||||
|
||||
ALWAYS_INLINE bool IsUsingSoftwareRenderer() const { return (gpu_renderer == GPURenderer::Software); }
|
||||
ALWAYS_INLINE bool IsUsingTrueColor() const { return (gpu_dithering_mode == GPUDitheringMode::TrueColor); }
|
||||
ALWAYS_INLINE bool IsUsingTrueColor() const { return (gpu_dithering_mode >= GPUDitheringMode::TrueColor); }
|
||||
ALWAYS_INLINE bool IsUsingDithering() const { return (gpu_dithering_mode < GPUDitheringMode::TrueColor); }
|
||||
ALWAYS_INLINE bool IsUsingShaderBlending() const
|
||||
{
|
||||
|
|
|
@ -107,6 +107,7 @@ enum class GPUDitheringMode : u8
|
|||
Scaled,
|
||||
ScaledShaderBlend,
|
||||
TrueColor,
|
||||
TrueColorFull,
|
||||
|
||||
MaxCount,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue