mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-06 09:39:55 +00:00
rsx: Fix clear color for formats with less than 32-bit width
This commit is contained in:
parent
8d5a9dc722
commit
b156b40f8f
@ -503,7 +503,7 @@ void GLGSRender::clear_surface(u32 arg)
|
||||
if ((arg & RSX_GCM_CLEAR_ANY_MASK) == 0) return;
|
||||
|
||||
u8 ctx = rsx::framebuffer_creation_context::context_draw;
|
||||
if (arg & RSX_GCM_CLEAR_COLOR_MASK) ctx |= rsx::framebuffer_creation_context::context_clear_color;
|
||||
if (arg & RSX_GCM_CLEAR_COLOR_RGBA_MASK) ctx |= rsx::framebuffer_creation_context::context_clear_color;
|
||||
if (arg & RSX_GCM_CLEAR_DEPTH_STENCIL_MASK) ctx |= rsx::framebuffer_creation_context::context_clear_depth;
|
||||
|
||||
init_buffers(static_cast<rsx::framebuffer_creation_context>(ctx), true);
|
||||
@ -612,6 +612,21 @@ void GLGSRender::clear_surface(u32 arg)
|
||||
colormask = rsx::get_g8b8_r8g8_clearmask(colormask);
|
||||
break;
|
||||
}
|
||||
case rsx::surface_color_format::r5g6b5:
|
||||
{
|
||||
rsx::get_rgb565_clear_color(clear_r, clear_g, clear_b, clear_a);
|
||||
break;
|
||||
}
|
||||
case rsx::surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
{
|
||||
rsx::get_a1rgb555_clear_color(clear_r, clear_g, clear_b, clear_a, 255);
|
||||
break;
|
||||
}
|
||||
case rsx::surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
{
|
||||
rsx::get_a1rgb555_clear_color(clear_r, clear_g, clear_b, clear_a, 0);
|
||||
break;
|
||||
}
|
||||
case rsx::surface_color_format::a8b8g8r8:
|
||||
case rsx::surface_color_format::x8b8g8r8_o8b8g8r8:
|
||||
case rsx::surface_color_format::x8b8g8r8_z8b8g8r8:
|
||||
|
@ -1246,7 +1246,7 @@ void VKGSRender::clear_surface(u32 mask)
|
||||
if (!(mask & RSX_GCM_CLEAR_ANY_MASK)) return;
|
||||
|
||||
u8 ctx = rsx::framebuffer_creation_context::context_draw;
|
||||
if (mask & RSX_GCM_CLEAR_COLOR_MASK) ctx |= rsx::framebuffer_creation_context::context_clear_color;
|
||||
if (mask & RSX_GCM_CLEAR_COLOR_RGBA_MASK) ctx |= rsx::framebuffer_creation_context::context_clear_color;
|
||||
if (mask & RSX_GCM_CLEAR_DEPTH_STENCIL_MASK) ctx |= rsx::framebuffer_creation_context::context_clear_depth;
|
||||
init_buffers(rsx::framebuffer_creation_context{ctx});
|
||||
|
||||
@ -1338,11 +1338,11 @@ void VKGSRender::clear_surface(u32 mask)
|
||||
}
|
||||
}
|
||||
|
||||
if (auto colormask = (mask & RSX_GCM_CLEAR_COLOR_MASK))
|
||||
if (auto colormask = (mask & RSX_GCM_CLEAR_COLOR_RGBA_MASK))
|
||||
{
|
||||
if (!m_draw_buffers.empty())
|
||||
{
|
||||
bool use_fast_clear = false;
|
||||
bool use_fast_clear = (colormask == RSX_GCM_CLEAR_COLOR_RGBA_MASK);;
|
||||
u8 clear_a = rsx::method_registers.clear_color_a();
|
||||
u8 clear_r = rsx::method_registers.clear_color_r();
|
||||
u8 clear_g = rsx::method_registers.clear_color_g();
|
||||
@ -1362,14 +1362,30 @@ void VKGSRender::clear_surface(u32 mask)
|
||||
{
|
||||
rsx::get_b8_clear_color(clear_r, clear_g, clear_b, clear_a);
|
||||
colormask = rsx::get_b8_clearmask(colormask);
|
||||
use_fast_clear = (colormask == RSX_GCM_CLEAR_RED_BIT);
|
||||
use_fast_clear = (colormask & RSX_GCM_CLEAR_RED_BIT);
|
||||
break;
|
||||
}
|
||||
case rsx::surface_color_format::g8b8:
|
||||
{
|
||||
rsx::get_g8b8_clear_color(clear_r, clear_g, clear_b, clear_a);
|
||||
colormask = rsx::get_g8b8_r8g8_clearmask(colormask);
|
||||
use_fast_clear = (colormask == (RSX_GCM_CLEAR_RED_BIT | RSX_GCM_CLEAR_GREEN_BIT));
|
||||
use_fast_clear = ((colormask & RSX_GCM_CLEAR_COLOR_RG_MASK) == RSX_GCM_CLEAR_COLOR_RG_MASK);
|
||||
break;
|
||||
}
|
||||
case rsx::surface_color_format::r5g6b5:
|
||||
{
|
||||
rsx::get_rgb565_clear_color(clear_r, clear_g, clear_b, clear_a);
|
||||
use_fast_clear = ((colormask & RSX_GCM_CLEAR_COLOR_RGB_MASK) == RSX_GCM_CLEAR_COLOR_RGB_MASK);
|
||||
break;
|
||||
}
|
||||
case rsx::surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
{
|
||||
rsx::get_a1rgb555_clear_color(clear_r, clear_g, clear_b, clear_a, 255);
|
||||
break;
|
||||
}
|
||||
case rsx::surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
{
|
||||
rsx::get_a1rgb555_clear_color(clear_r, clear_g, clear_b, clear_a, 0);
|
||||
break;
|
||||
}
|
||||
case rsx::surface_color_format::a8b8g8r8:
|
||||
@ -1378,11 +1394,10 @@ void VKGSRender::clear_surface(u32 mask)
|
||||
{
|
||||
rsx::get_abgr8_clear_color(clear_r, clear_g, clear_b, clear_a);
|
||||
colormask = rsx::get_abgr8_clearmask(colormask);
|
||||
[[fallthrough]];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
use_fast_clear = (colormask == RSX_GCM_CLEAR_COLOR_MASK);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1188,7 +1188,9 @@ enum
|
||||
RSX_GCM_CLEAR_BLUE_BIT = 0x40,
|
||||
RSX_GCM_CLEAR_ALPHA_BIT = 0x80,
|
||||
|
||||
RSX_GCM_CLEAR_COLOR_MASK = 0xF0,
|
||||
RSX_GCM_CLEAR_COLOR_RG_MASK = (RSX_GCM_CLEAR_RED_BIT | RSX_GCM_CLEAR_GREEN_BIT),
|
||||
RSX_GCM_CLEAR_COLOR_RGB_MASK = (RSX_GCM_CLEAR_RED_BIT | RSX_GCM_CLEAR_GREEN_BIT | RSX_GCM_CLEAR_BLUE_BIT),
|
||||
RSX_GCM_CLEAR_COLOR_RGBA_MASK = (RSX_GCM_CLEAR_COLOR_RGB_MASK | RSX_GCM_CLEAR_ALPHA_BIT),
|
||||
RSX_GCM_CLEAR_DEPTH_STENCIL_MASK = (RSX_GCM_CLEAR_DEPTH_BIT | RSX_GCM_CLEAR_STENCIL_BIT),
|
||||
RSX_GCM_CLEAR_ANY_MASK = (RSX_GCM_CLEAR_COLOR_MASK | RSX_GCM_CLEAR_DEPTH_STENCIL_MASK)
|
||||
RSX_GCM_CLEAR_ANY_MASK = (RSX_GCM_CLEAR_COLOR_RGBA_MASK | RSX_GCM_CLEAR_DEPTH_STENCIL_MASK)
|
||||
};
|
||||
|
@ -798,6 +798,38 @@ namespace rsx
|
||||
std::swap(red, blue);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
requires std::is_integral_v<T> && std::is_integral_v<U>
|
||||
u8 renormalize_color8(T input, U base)
|
||||
{
|
||||
// Base will be some POT-1 value
|
||||
const int value = static_cast<u8>(input & base);
|
||||
return static_cast<u8>((value * 255) / base);
|
||||
}
|
||||
|
||||
static inline void get_rgb565_clear_color(u8& red, u8& green, u8& blue, u8& /*alpha*/)
|
||||
{
|
||||
// RSX clear color is just a memcpy, so in this case the input is ARGB8 so only BG have the 16-bit input
|
||||
const u16 raw_value = static_cast<u16>(green) << 8 | blue;
|
||||
blue = renormalize_color8(raw_value, 0x1f);
|
||||
green = renormalize_color8(raw_value >> 5, 0x3f);
|
||||
red = renormalize_color8(raw_value >> 11, 0x1f);
|
||||
}
|
||||
|
||||
static inline void get_a1rgb555_clear_color(u8& red, u8& green, u8& blue, u8& alpha, u8 alpha_override)
|
||||
{
|
||||
// RSX clear color is just a memcpy, so in this case the input is ARGB8 so only BG have the 16-bit input
|
||||
const u16 raw_value = static_cast<u16>(green) << 8 | blue;
|
||||
blue = renormalize_color8(raw_value, 0x1f);
|
||||
green = renormalize_color8(raw_value >> 5, 0x1f);
|
||||
red = renormalize_color8(raw_value >> 10, 0x1f);
|
||||
|
||||
// Alpha can technically be encoded into the clear but the format normally just injects constants.
|
||||
// Will require hardware tests when possible to determine which approach makes more sense.
|
||||
// alpha = static_cast<u8>((raw_value & (1 << 15)) ? 255 : 0);
|
||||
alpha = alpha_override;
|
||||
}
|
||||
|
||||
static inline u32 get_b8_clearmask(u32 mask)
|
||||
{
|
||||
u32 result = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user