rsx: Fix ABGR decoding for colormask and clear color

- The bytes in these values are based on the format according to hw tests
- G8B8 is unaffected as the first two bytes are already G8B8 for A8R8G8B8 standard layout (BGRA)
- A8B8G8R8 and its derivatives have words 0 and 2 exchanged.
This commit is contained in:
kd-11 2020-06-22 19:13:11 +03:00 committed by kd-11
parent e992cbe01b
commit 7f917c8ba5
3 changed files with 65 additions and 20 deletions

View File

@ -568,6 +568,11 @@ void GLGSRender::clear_surface(u32 arg)
if (auto colormask = (arg & 0xf0))
{
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();
u8 clear_b = rsx::method_registers.clear_color_b();
switch (rsx::method_registers.surface_color())
{
case rsx::surface_color_format::x32:
@ -579,16 +584,22 @@ void GLGSRender::clear_surface(u32 arg)
}
case rsx::surface_color_format::g8b8:
{
rsx::get_g8b8_clear_color(clear_r, clear_g, clear_b, clear_a);
colormask = rsx::get_g8b8_r8g8_colormask(colormask);
[[fallthrough]];
break;
}
default:
case rsx::surface_color_format::a8b8g8r8:
case rsx::surface_color_format::x8b8g8r8_o8b8g8r8:
case rsx::surface_color_format::x8b8g8r8_z8b8g8r8:
{
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();
u8 clear_b = rsx::method_registers.clear_color_b();
rsx::get_abgr8_clear_color(clear_r, clear_g, clear_b, clear_a);
colormask = rsx::get_abgr8_colormask(colormask);
break;
}
}
if (colormask)
{
gl_state.clear_color(clear_r, clear_g, clear_b, clear_a);
mask |= GLenum(gl::buffers::color);
@ -601,8 +612,6 @@ void GLGSRender::clear_surface(u32 arg)
}
update_color = true;
break;
}
}
}

View File

@ -1130,33 +1130,45 @@ void VKGSRender::clear_surface(u32 mask)
if (!m_draw_buffers.empty())
{
bool use_fast_clear = false;
bool ignore_clear = false;
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();
u8 clear_b = rsx::method_registers.clear_color_b();
switch (rsx::method_registers.surface_color())
{
case rsx::surface_color_format::x32:
case rsx::surface_color_format::w16z16y16x16:
case rsx::surface_color_format::w32z32y32x32:
{
//NOP
ignore_clear = true;
colormask = 0;
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_colormask(colormask);
use_fast_clear = (colormask == (0x10 | 0x20));
ignore_clear = (colormask == 0);
colormask |= (0x40 | 0x80);
break;
}
case rsx::surface_color_format::a8b8g8r8:
case rsx::surface_color_format::x8b8g8r8_o8b8g8r8:
case rsx::surface_color_format::x8b8g8r8_z8b8g8r8:
{
rsx::get_abgr8_clear_color(clear_r, clear_g, clear_b, clear_a);
colormask = rsx::get_abgr8_colormask(colormask);
break;
}
default:
{
use_fast_clear = (colormask == (0x10 | 0x20 | 0x40 | 0x80));
break;
}
}
if (!ignore_clear)
if (colormask)
{
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();
u8 clear_b = rsx::method_registers.clear_color_b();
color_clear_values.color.float32[0] = static_cast<float>(clear_r) / 255;
color_clear_values.color.float32[1] = static_cast<float>(clear_g) / 255;
color_clear_values.color.float32[2] = static_cast<float>(clear_b) / 255;

View File

@ -737,14 +737,38 @@ namespace rsx
return result;
}
static inline void get_g8b8_r8g8_colormask(bool &red, bool &green, bool &blue, bool &alpha)
static inline void get_g8b8_r8g8_colormask(bool &red, bool &/*green*/, bool &blue, bool &alpha)
{
red = blue;
green = green;
blue = false;
alpha = false;
}
static inline void get_g8b8_clear_color(u8& red, u8& /*green*/, u8& blue, u8& /*alpha*/)
{
red = blue;
}
static inline u32 get_abgr8_colormask(u32 mask)
{
u32 result = 0;
if (mask & 0x10) result |= 0x40;
if (mask & 0x20) result |= 0x20;
if (mask & 0x40) result |= 0x10;
if (mask & 0x80) result |= 0x80;
return result;
}
static inline void get_abgr8_colormask(bool& red, bool& /*green*/, bool& blue, bool& /*alpha*/)
{
std::swap(red, blue);
}
static inline void get_abgr8_clear_color(u8& red, u8& /*green*/, u8& blue, u8& /*alpha*/)
{
std::swap(red, blue);
}
static inline color4f decode_border_color(u32 colorref)
{
color4f result;