mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-16 11:48:36 +12:00
rsx: Use a proper struct to wrap around channel remap operations
This commit is contained in:
parent
b1b0ac4433
commit
826f805902
30 changed files with 317 additions and 308 deletions
|
@ -216,36 +216,6 @@ namespace rsx
|
|||
bool swizzled;
|
||||
};
|
||||
|
||||
static const std::pair<std::array<u8, 4>, std::array<u8, 4>> default_remap_vector =
|
||||
{
|
||||
{ CELL_GCM_TEXTURE_REMAP_FROM_A, CELL_GCM_TEXTURE_REMAP_FROM_R, CELL_GCM_TEXTURE_REMAP_FROM_G, CELL_GCM_TEXTURE_REMAP_FROM_B },
|
||||
{ CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP }
|
||||
};
|
||||
|
||||
static inline std::pair<std::array<u8, 4>, std::array<u8, 4>> decode_remap_encoding(u32 remap_ctl)
|
||||
{
|
||||
// Remapping tables; format is A-R-G-B
|
||||
// Remap input table. Contains channel index to read color from
|
||||
const std::array<u8, 4> remap_inputs =
|
||||
{
|
||||
static_cast<u8>(remap_ctl & 0x3),
|
||||
static_cast<u8>((remap_ctl >> 2) & 0x3),
|
||||
static_cast<u8>((remap_ctl >> 4) & 0x3),
|
||||
static_cast<u8>((remap_ctl >> 6) & 0x3),
|
||||
};
|
||||
|
||||
// Remap control table. Controls whether the remap value is used, or force either 0 or 1
|
||||
const std::array<u8, 4> remap_lookup =
|
||||
{
|
||||
static_cast<u8>((remap_ctl >> 8) & 0x3),
|
||||
static_cast<u8>((remap_ctl >> 10) & 0x3),
|
||||
static_cast<u8>((remap_ctl >> 12) & 0x3),
|
||||
static_cast<u8>((remap_ctl >> 14) & 0x3),
|
||||
};
|
||||
|
||||
return std::make_pair(remap_inputs, remap_lookup);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void pad_texture(void* input_pixels, void* output_pixels, u16 input_width, u16 input_height, u16 output_width, u16 /*output_height*/)
|
||||
{
|
||||
|
@ -774,142 +744,6 @@ namespace rsx
|
|||
return (index + index_base) & 0x000FFFFF;
|
||||
}
|
||||
|
||||
// Convert color write mask for G8B8 to R8G8
|
||||
static inline u32 get_g8b8_r8g8_clearmask(u32 mask)
|
||||
{
|
||||
u32 result = 0;
|
||||
if (mask & RSX_GCM_CLEAR_GREEN_BIT) result |= RSX_GCM_CLEAR_GREEN_BIT;
|
||||
if (mask & RSX_GCM_CLEAR_BLUE_BIT) result |= RSX_GCM_CLEAR_RED_BIT;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void get_g8b8_r8g8_colormask(bool &red, bool &/*green*/, bool &blue, bool &alpha)
|
||||
{
|
||||
red = blue;
|
||||
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_clearmask(u32 mask)
|
||||
{
|
||||
u32 result = 0;
|
||||
if (mask & RSX_GCM_CLEAR_RED_BIT) result |= RSX_GCM_CLEAR_BLUE_BIT;
|
||||
if (mask & RSX_GCM_CLEAR_GREEN_BIT) result |= RSX_GCM_CLEAR_GREEN_BIT;
|
||||
if (mask & RSX_GCM_CLEAR_BLUE_BIT) result |= RSX_GCM_CLEAR_RED_BIT;
|
||||
if (mask & RSX_GCM_CLEAR_ALPHA_BIT) result |= RSX_GCM_CLEAR_ALPHA_BIT;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
if (mask & RSX_GCM_CLEAR_BLUE_BIT) result |= RSX_GCM_CLEAR_RED_BIT;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void get_b8_colormask(bool& red, bool& green, bool& blue, bool& alpha)
|
||||
{
|
||||
red = blue;
|
||||
green = false;
|
||||
blue = false;
|
||||
alpha = false;
|
||||
}
|
||||
|
||||
static inline void get_b8_clear_color(u8& red, u8& /*green*/, u8& blue, u8& /*alpha*/)
|
||||
{
|
||||
std::swap(red, blue);
|
||||
}
|
||||
|
||||
static inline color4f decode_border_color(u32 colorref)
|
||||
{
|
||||
color4f result;
|
||||
result.b = (colorref & 0xFF) / 255.f;
|
||||
result.g = ((colorref >> 8) & 0xFF) / 255.f;
|
||||
result.r = ((colorref >> 16) & 0xFF) / 255.f;
|
||||
result.a = ((colorref >> 24) & 0xFF) / 255.f;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline const std::array<bool, 4> get_write_output_mask(rsx::surface_color_format format)
|
||||
{
|
||||
constexpr std::array<bool, 4> rgba = { true, true, true, true };
|
||||
constexpr std::array<bool, 4> rgb = { true, true, true, false };
|
||||
constexpr std::array<bool, 4> rg = { true, true, false, false };
|
||||
constexpr std::array<bool, 4> r = { true, false, false, false };
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case rsx::surface_color_format::a8r8g8b8:
|
||||
case rsx::surface_color_format::a8b8g8r8:
|
||||
case rsx::surface_color_format::w16z16y16x16:
|
||||
case rsx::surface_color_format::w32z32y32x32:
|
||||
return rgba;
|
||||
case rsx::surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
case rsx::surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
case rsx::surface_color_format::r5g6b5:
|
||||
case rsx::surface_color_format::x8r8g8b8_z8r8g8b8:
|
||||
case rsx::surface_color_format::x8r8g8b8_o8r8g8b8:
|
||||
case rsx::surface_color_format::x8b8g8r8_z8b8g8r8:
|
||||
case rsx::surface_color_format::x8b8g8r8_o8b8g8r8:
|
||||
return rgb;
|
||||
case rsx::surface_color_format::g8b8:
|
||||
return rg;
|
||||
case rsx::surface_color_format::b8:
|
||||
case rsx::surface_color_format::x32:
|
||||
return r;
|
||||
default:
|
||||
fmt::throw_exception("Unknown surface format 0x%x", static_cast<int>(format));
|
||||
}
|
||||
}
|
||||
|
||||
template <uint integer, uint frac, bool sign = true, typename To = f32>
|
||||
static inline To decode_fxp(u32 bits)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue