rsx: Re-work value remapping capabilities to match real hardware

- Drop heurestics and use what real hardware is doing instead
This commit is contained in:
kd-11 2026-02-10 01:42:47 +03:00 committed by kd-11
parent 3df370a7e6
commit 6b272ed563
3 changed files with 75 additions and 12 deletions

View file

@ -1200,27 +1200,56 @@ namespace rsx
fmt::throw_exception("Unknown format 0x%x", texture_format);
}
bool is_int8_remapped_format(u32 format)
rsx::flags32_t get_format_features(u32 texture_format)
{
switch (format)
switch (texture_format)
{
case CELL_GCM_TEXTURE_B8:
case CELL_GCM_TEXTURE_A1R5G5B5:
case CELL_GCM_TEXTURE_A4R4G4B4:
case CELL_GCM_TEXTURE_R5G6B5:
case CELL_GCM_TEXTURE_A8R8G8B8:
case CELL_GCM_TEXTURE_COMPRESSED_DXT1:
case CELL_GCM_TEXTURE_COMPRESSED_DXT23:
case CELL_GCM_TEXTURE_COMPRESSED_DXT45:
case CELL_GCM_TEXTURE_G8B8:
case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8:
case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8:
case CELL_GCM_TEXTURE_R6G5B5:
case CELL_GCM_TEXTURE_R5G5B5A1:
case CELL_GCM_TEXTURE_D1R5G5B5:
case CELL_GCM_TEXTURE_D8R8G8B8:
// Base texture formats - everything is supported
return RSX_FORMAT_FEATURE_SIGNED_COMPONENTS | RSX_FORMAT_FEATURE_GAMMA_CORRECTION | RSX_FORMAT_FEATURE_BIASED_NORMALIZATION;
case CELL_GCM_TEXTURE_DEPTH24_D8:
case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT:
case CELL_GCM_TEXTURE_DEPTH16:
case CELL_GCM_TEXTURE_DEPTH16_FLOAT:
// Depth textures will hang the hardware if BX2 or GAMMA is active. ARGB8_SIGNED has no impact.
return 0;
case CELL_GCM_TEXTURE_X16:
case CELL_GCM_TEXTURE_Y16_X16:
// X16 | Y16 - GAMMA causes hangs. ARGB8_SIGNED is ignored. UNSIGNED_REMAP=BIASED works.
return RSX_FORMAT_FEATURE_BIASED_NORMALIZATION;
case CELL_GCM_TEXTURE_COMPRESSED_HILO8:
// GAMMA causes GPU hangs. ARGB8_SIGNED is ignored. UNSIGNED_REMAP=BIASED works.
return RSX_FORMAT_FEATURE_BIASED_NORMALIZATION;
case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8:
// GAMMA causes hangs. Other flags ignored.
return 0;
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT:
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT:
case CELL_GCM_TEXTURE_X32_FLOAT:
case CELL_GCM_TEXTURE_Y16_X16_FLOAT:
// NOTE: Special data formats (XY, HILO, DEPTH) are not RGB formats
return false;
default:
return true;
// Floating point textures. Nothing works.
return 0;
}
fmt::throw_exception("Unknown format 0x%x", texture_format);
}
/**

View file

@ -9,6 +9,8 @@
namespace rsx
{
using flags32_t = u32;
enum texture_upload_context : u32
{
shader_read = 1,
@ -125,6 +127,15 @@ namespace rsx
using namespace format_class_;
enum format_features : u8
{
RSX_FORMAT_FEATURE_SIGNED_COMPONENTS = (1 << 0),
RSX_FORMAT_FEATURE_BIASED_NORMALIZATION = (1 << 1),
RSX_FORMAT_FEATURE_GAMMA_CORRECTION = (1 << 2),
};
using enum format_features;
// Sampled image descriptor
class sampled_image_descriptor_base
{
@ -257,7 +268,12 @@ namespace rsx
u8 get_format_sample_count(rsx::surface_antialiasing antialias);
u32 get_max_depth_value(rsx::surface_depth_format2 format);
bool is_depth_stencil_format(rsx::surface_depth_format2 format);
bool is_int8_remapped_format(u32 format); // Returns true if the format is treated as INT8 by the RSX remapper.
/**
* Format feature support. There is not simple format to determine what is supported here, results are from hw tests
* Returns a bitmask of supported features.
*/
rsx::flags32_t get_format_features(u32 texture_format);
/**
* Returns number of texel rows encoded in one pitch-length line of bytes

View file

@ -2321,17 +2321,35 @@ namespace rsx
}
}
if (rsx::is_int8_remapped_format(format))
if (const auto format_features = rsx::get_format_features(format); format_features != 0)
{
// Special operations applied to 8-bit formats such as gamma correction and sign conversion
// NOTE: The unsigned_remap=bias flag being set flags the texture as being compressed normal (2n-1 / BX2) (UE3)
// NOTE: The ARGB8_signed flag means to reinterpret the raw bytes as signed. This is different than unsigned_remap=bias which does range decompression.
// This is a separate method of setting the format to signed mode without doing so per-channel
// Precedence = SNORM > GAMMA > UNSIGNED_REMAP (See Resistance 3 for GAMMA/BX2 relationship, UE3 for BX2 effect)
// Precedence = SNORM > GAMMA > UNSIGNED_REMAP/BX2
// Games using mixed flags: (See Resistance 3 for GAMMA/BX2 relationship, UE3 for BX2 effect)
u32 argb8_signed = 0;
u32 unsigned_remap = 0;
u32 gamma = 0;
if (format_features & RSX_FORMAT_FEATURE_SIGNED_COMPONENTS)
{
argb8_signed = tex.argb_signed();
}
if (format_features & RSX_FORMAT_FEATURE_GAMMA_CORRECTION)
{
gamma = tex.gamma() & ~(argb8_signed);
}
if (format_features & RSX_FORMAT_FEATURE_BIASED_NORMALIZATION)
{
// The renormalization flag applies to all channels
unsigned_remap = (tex.unsigned_remap() == CELL_GCM_TEXTURE_UNSIGNED_REMAP_NORMAL) ? 0u : 0xF;
unsigned_remap &= ~(argb8_signed | gamma);
}
const u32 argb8_signed = tex.argb_signed(); // _SNROM
const u32 gamma = tex.gamma() & ~argb8_signed; // _SRGB
const u32 unsigned_remap = (tex.unsigned_remap() == CELL_GCM_TEXTURE_UNSIGNED_REMAP_NORMAL)? 0u : (~(gamma | argb8_signed) & 0xF); // _BX2
u32 argb8_convert = gamma;
// The options are mutually exclusive