mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-16 23:17:29 +00:00
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:
parent
e992cbe01b
commit
7f917c8ba5
@ -568,6 +568,11 @@ void GLGSRender::clear_surface(u32 arg)
|
|||||||
|
|
||||||
if (auto colormask = (arg & 0xf0))
|
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())
|
switch (rsx::method_registers.surface_color())
|
||||||
{
|
{
|
||||||
case rsx::surface_color_format::x32:
|
case rsx::surface_color_format::x32:
|
||||||
@ -579,16 +584,22 @@ void GLGSRender::clear_surface(u32 arg)
|
|||||||
}
|
}
|
||||||
case rsx::surface_color_format::g8b8:
|
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);
|
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();
|
rsx::get_abgr8_clear_color(clear_r, clear_g, clear_b, clear_a);
|
||||||
u8 clear_r = rsx::method_registers.clear_color_r();
|
colormask = rsx::get_abgr8_colormask(colormask);
|
||||||
u8 clear_g = rsx::method_registers.clear_color_g();
|
break;
|
||||||
u8 clear_b = rsx::method_registers.clear_color_b();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colormask)
|
||||||
|
{
|
||||||
gl_state.clear_color(clear_r, clear_g, clear_b, clear_a);
|
gl_state.clear_color(clear_r, clear_g, clear_b, clear_a);
|
||||||
mask |= GLenum(gl::buffers::color);
|
mask |= GLenum(gl::buffers::color);
|
||||||
|
|
||||||
@ -601,8 +612,6 @@ void GLGSRender::clear_surface(u32 arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
update_color = true;
|
update_color = true;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1130,33 +1130,45 @@ void VKGSRender::clear_surface(u32 mask)
|
|||||||
if (!m_draw_buffers.empty())
|
if (!m_draw_buffers.empty())
|
||||||
{
|
{
|
||||||
bool use_fast_clear = false;
|
bool use_fast_clear = false;
|
||||||
bool ignore_clear = false;
|
|
||||||
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;
|
|
||||||
break;
|
|
||||||
case rsx::surface_color_format::g8b8:
|
|
||||||
colormask = rsx::get_g8b8_r8g8_colormask(colormask);
|
|
||||||
use_fast_clear = (colormask == (0x10 | 0x20));
|
|
||||||
ignore_clear = (colormask == 0);
|
|
||||||
colormask |= (0x40 | 0x80);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
use_fast_clear = (colormask == (0x10 | 0x20 | 0x40 | 0x80));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ignore_clear)
|
|
||||||
{
|
|
||||||
u8 clear_a = rsx::method_registers.clear_color_a();
|
u8 clear_a = rsx::method_registers.clear_color_a();
|
||||||
u8 clear_r = rsx::method_registers.clear_color_r();
|
u8 clear_r = rsx::method_registers.clear_color_r();
|
||||||
u8 clear_g = rsx::method_registers.clear_color_g();
|
u8 clear_g = rsx::method_registers.clear_color_g();
|
||||||
u8 clear_b = rsx::method_registers.clear_color_b();
|
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
|
||||||
|
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));
|
||||||
|
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 (colormask)
|
||||||
|
{
|
||||||
color_clear_values.color.float32[0] = static_cast<float>(clear_r) / 255;
|
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[1] = static_cast<float>(clear_g) / 255;
|
||||||
color_clear_values.color.float32[2] = static_cast<float>(clear_b) / 255;
|
color_clear_values.color.float32[2] = static_cast<float>(clear_b) / 255;
|
||||||
|
@ -737,14 +737,38 @@ namespace rsx
|
|||||||
return result;
|
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;
|
red = blue;
|
||||||
green = green;
|
|
||||||
blue = false;
|
blue = false;
|
||||||
alpha = 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)
|
static inline color4f decode_border_color(u32 colorref)
|
||||||
{
|
{
|
||||||
color4f result;
|
color4f result;
|
||||||
|
Loading…
Reference in New Issue
Block a user