From 49029c9b9810ef4118773c1ab108c86a867154a9 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Thu, 12 Feb 2026 02:22:34 +0300 Subject: [PATCH] rsx: Handle 16-bit format remapping --- rpcs3/Emu/RSX/Common/TextureUtils.cpp | 6 ++-- rpcs3/Emu/RSX/Common/TextureUtils.h | 1 + rpcs3/Emu/RSX/Program/GLSLCommon.cpp | 35 ++++++++++--------- rpcs3/Emu/RSX/Program/GLSLCommon.h | 1 + .../RSXProg/RSXFragmentTextureOps.glsl | 34 +++++++++++++----- 5 files changed, 49 insertions(+), 28 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.cpp b/rpcs3/Emu/RSX/Common/TextureUtils.cpp index ddfbb99b9b..7fe0431baf 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.cpp +++ b/rpcs3/Emu/RSX/Common/TextureUtils.cpp @@ -1231,9 +1231,11 @@ namespace rsx return RSX_FORMAT_FEATURE_BIASED_NORMALIZATION; case CELL_GCM_TEXTURE_X16: + // X16 - GAMMA causes hangs. ARGB8_SIGNED is ignored. UNSIGNED_REMAP=BIASED works. + return RSX_FORMAT_FEATURE_BIASED_NORMALIZATION | RSX_FORMAT_FEATURE_16BIT_CHANNELS; 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; + // X16 | Y16 - GAMMA causes hangs. ARGB8_SIGNED works. UNSIGNED_REMAP=BIASED also works. + return RSX_FORMAT_FEATURE_SIGNED_COMPONENTS | RSX_FORMAT_FEATURE_BIASED_NORMALIZATION | RSX_FORMAT_FEATURE_16BIT_CHANNELS; case CELL_GCM_TEXTURE_COMPRESSED_HILO8: // GAMMA causes GPU hangs. ARGB8_SIGNED is ignored. UNSIGNED_REMAP=BIASED works. diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.h b/rpcs3/Emu/RSX/Common/TextureUtils.h index 3928e22874..65f4ef5c6f 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.h +++ b/rpcs3/Emu/RSX/Common/TextureUtils.h @@ -132,6 +132,7 @@ namespace rsx RSX_FORMAT_FEATURE_SIGNED_COMPONENTS = (1 << 0), RSX_FORMAT_FEATURE_BIASED_NORMALIZATION = (1 << 1), RSX_FORMAT_FEATURE_GAMMA_CORRECTION = (1 << 2), + RSX_FORMAT_FEATURE_16BIT_CHANNELS = (1 << 3), // Complements RSX_FORMAT_FEATURE_SIGNED_COMPONENTS }; using enum format_features; diff --git a/rpcs3/Emu/RSX/Program/GLSLCommon.cpp b/rpcs3/Emu/RSX/Program/GLSLCommon.cpp index 8f7cc46e66..ebf73e935a 100644 --- a/rpcs3/Emu/RSX/Program/GLSLCommon.cpp +++ b/rpcs3/Emu/RSX/Program/GLSLCommon.cpp @@ -337,21 +337,21 @@ namespace glsl // Declare special texture control flags program_common::define_glsl_constants(OS, { - { "GAMMA_R_BIT " , rsx::texture_control_bits::GAMMA_R }, - { "GAMMA_G_BIT " , rsx::texture_control_bits::GAMMA_G }, - { "GAMMA_B_BIT " , rsx::texture_control_bits::GAMMA_B }, - { "GAMMA_A_BIT " , rsx::texture_control_bits::GAMMA_A }, - { "EXPAND_R_BIT" , rsx::texture_control_bits::EXPAND_R }, - { "EXPAND_G_BIT" , rsx::texture_control_bits::EXPAND_G }, - { "EXPAND_B_BIT" , rsx::texture_control_bits::EXPAND_B }, - { "EXPAND_A_BIT" , rsx::texture_control_bits::EXPAND_A }, - { "SEXT_R_BIT" , rsx::texture_control_bits::SEXT_R }, - { "SEXT_G_BIT" , rsx::texture_control_bits::SEXT_G }, - { "SEXT_B_BIT" , rsx::texture_control_bits::SEXT_B }, - { "SEXT_A_BIT" , rsx::texture_control_bits::SEXT_A }, - { "WRAP_S_BIT", rsx::texture_control_bits::WRAP_S }, - { "WRAP_T_BIT", rsx::texture_control_bits::WRAP_T }, - { "WRAP_R_BIT", rsx::texture_control_bits::WRAP_R }, + { "GAMMA_R_BIT ", rsx::texture_control_bits::GAMMA_R }, + { "GAMMA_G_BIT ", rsx::texture_control_bits::GAMMA_G }, + { "GAMMA_B_BIT ", rsx::texture_control_bits::GAMMA_B }, + { "GAMMA_A_BIT ", rsx::texture_control_bits::GAMMA_A }, + { "EXPAND_R_BIT", rsx::texture_control_bits::EXPAND_R }, + { "EXPAND_G_BIT", rsx::texture_control_bits::EXPAND_G }, + { "EXPAND_B_BIT", rsx::texture_control_bits::EXPAND_B }, + { "EXPAND_A_BIT", rsx::texture_control_bits::EXPAND_A }, + { "SEXT_R_BIT", rsx::texture_control_bits::SEXT_R }, + { "SEXT_G_BIT", rsx::texture_control_bits::SEXT_G }, + { "SEXT_B_BIT", rsx::texture_control_bits::SEXT_B }, + { "SEXT_A_BIT", rsx::texture_control_bits::SEXT_A }, + { "WRAP_S_BIT", rsx::texture_control_bits::WRAP_S }, + { "WRAP_T_BIT", rsx::texture_control_bits::WRAP_T }, + { "WRAP_R_BIT", rsx::texture_control_bits::WRAP_R }, { "ALPHAKILL ", rsx::texture_control_bits::ALPHAKILL }, { "RENORMALIZE ", rsx::texture_control_bits::RENORMALIZE }, @@ -363,8 +363,9 @@ namespace glsl { "CLAMP_COORDS_BIT", rsx::texture_control_bits::CLAMP_TEXCOORDS_BIT }, { "FORMAT_FEATURE_SIGNED_BIT", rsx::texture_control_bits::FF_SIGNED_BIT }, - { "FORMAT_FEATURE_GAMMA_BIT", rsx::texture_control_bits::FF_GAMMA_BIT }, - { "FORMAT_FEATURE_BIASED_RENORMALIZATION_BIT", rsx::texture_control_bits::FF_BIASED_RENORM_BIT } + { "FORMAT_FEATURE_GAMMA_BIT", rsx::texture_control_bits::FF_GAMMA_BIT }, + { "FORMAT_FEATURE_BIASED_RENORMALIZATION_BIT", rsx::texture_control_bits::FF_BIASED_RENORM_BIT }, + { "FORMAT_FEATURE_16BIT_CHANNELS_BIT", rsx::texture_control_bits::FF_16BIT_CHANNELS_BIT } }); if (props.require_texture_expand) diff --git a/rpcs3/Emu/RSX/Program/GLSLCommon.h b/rpcs3/Emu/RSX/Program/GLSLCommon.h index b417947002..ae22464f12 100644 --- a/rpcs3/Emu/RSX/Program/GLSLCommon.h +++ b/rpcs3/Emu/RSX/Program/GLSLCommon.h @@ -40,6 +40,7 @@ namespace rsx FF_SIGNED_BIT, FF_BIASED_RENORM_BIT, FF_GAMMA_BIT, + FF_16BIT_CHANNELS_BIT, GAMMA_CTRL_MASK = (1 << GAMMA_R) | (1 << GAMMA_G) | (1 << GAMMA_B) | (1 << GAMMA_A), EXPAND_MASK = (1 << EXPAND_R) | (1 << EXPAND_G) | (1 << EXPAND_B) | (1 << EXPAND_A), diff --git a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl index cb89f718bf..a59e8ae3a1 100644 --- a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl @@ -23,7 +23,8 @@ R"( #define FORMAT_FEATURE_SIGNED (1 << FORMAT_FEATURE_SIGNED_BIT) #define FORMAT_FEATURE_GAMMA (1 << FORMAT_FEATURE_GAMMA_BIT) #define FORMAT_FEATURE_BIASED_RENORMALIZATION (1 << FORMAT_FEATURE_BIASED_RENORMALIZATION_BIT) -#define FORMAT_FEATURE_MASK (FORMAT_FEATURE_SIGNED | FORMAT_FEATURE_GAMMA | FORMAT_FEATURE_BIASED_RENORMALIZATION) +#define FORMAT_FEATURE_16BIT_CHANNELS (1 << FORMAT_FEATURE_16BIT_CHANNELS_BIT) +#define FORMAT_FEATURE_MASK (FORMAT_FEATURE_SIGNED | FORMAT_FEATURE_GAMMA | FORMAT_FEATURE_BIASED_RENORMALIZATION | FORMAT_FEATURE_16BIT_CHANNELS) #ifdef _ENABLE_TEXTURE_EXPAND // NOTE: BX2 expansion overrides GAMMA correction @@ -44,9 +45,9 @@ R"( _texture_flag_erase = 0; \ _texture_bx2_active = false; \ } while (false) - #define TEX_FLAGS(index) ((TEX_PARAM(index).flags & ~(FORMAT_FEATURE_MASK | _texture_flag_erase)) | _texture_flag_override) + #define TEX_FLAGS(index) ((TEX_PARAM(index).flags & ~(_texture_flag_erase)) | _texture_flag_override) #else - #define TEX_FLAGS(index) (TEX_PARAM(index).flags & ~FORMAT_FEATURE_MASK) + #define TEX_FLAGS(index) (TEX_PARAM(index).flags) #endif #define TEX_NAME(index) tex##index @@ -195,10 +196,19 @@ vec4 _texcoord_xform_shadow(const in vec4 coord4, const in sampler_info params) vec4 _sext_unorm8x4(const in vec4 x) { // TODO: Handle clamped sign-extension - const vec4 bits = floor(fma(x, vec4(255.f), vec4(0.5f))); - const bvec4 sign_check = lessThan(bits, vec4(128.f)); - const vec4 ret = _select(bits - 256.f, bits, sign_check); - return ret / 127.f; + const uint shift = 32 - 8; // sext 8-bit value into 32-bit container + const uvec4 ubits = uvec4(floor(fma(x, vec4(255.f), vec4(0.5f)))); + const ivec4 ibits = ivec4(ubits << shift); + return (ibits >> shift) / 127.f; +} + +vec4 _sext_unorm16x4(const in vec4 x) +{ + // TODO: Handle clamped sign-extension + const uint shift = 32 - 16; // sext 16-bit value into 32-bit container + const uvec4 ubits = uvec4(floor(fma(x, vec4(65535.f), vec4(0.5f)))); + const ivec4 ibits = ivec4(ubits << shift); + return (ibits >> shift) / 32767.f; } vec4 _process_texel(in vec4 rgba, const in uint control_bits) @@ -237,7 +247,10 @@ vec4 _process_texel(in vec4 rgba, const in uint control_bits) { // Sign-extend the input signal mask = uvec4(op_mask) & uvec4(SEXT_R_MASK, SEXT_G_MASK, SEXT_B_MASK, SEXT_A_MASK); - convert = _sext_unorm8x4(rgba); + if (_test_bit(control_bits, FORMAT_FEATURE_16BIT_CHANNELS_BIT)) + convert = _sext_unorm16x4(rgba); + else + convert = _sext_unorm8x4(rgba); rgba = _select(rgba, convert, notEqual(mask, uvec4(0))); ch_mask &= ~(op_mask >> SEXT_A_BIT); } @@ -262,7 +275,10 @@ vec4 _process_texel(in vec4 rgba, const in uint control_bits) convert = (rgba * 2.f - 1.f); else #endif - convert = (floor(fma(rgba, vec4(255.f), vec4(0.5f))) - 128.f) / 127.f; + if (_test_bit(control_bits, FORMAT_FEATURE_16BIT_CHANNELS_BIT)) + convert = (floor(fma(rgba, vec4(65535.f), vec4(0.5f))) - 32768.f) / 32767.f; + else + convert = (floor(fma(rgba, vec4(255.f), vec4(0.5f))) - 128.f) / 127.f; rgba = _select(rgba, convert, notEqual(mask, uvec4(0))); }