diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index 5b4762eb01..039fb45ebc 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -125,12 +125,12 @@ namespace rsx f32 fragment_texture::min_lod() const { - return rsx::decode_fx13((registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 19) & 0xfff); + return rsx::decode_fxp<4, 8, false>((registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 19) & 0xfff); } f32 fragment_texture::max_lod() const { - return rsx::decode_fx13((registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 7) & 0xfff); + return rsx::decode_fxp<4, 8, false>((registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 7) & 0xfff); } rsx::texture_max_anisotropy fragment_texture::max_aniso() const @@ -213,7 +213,7 @@ namespace rsx f32 fragment_texture::bias() const { - return rsx::decode_fx13((registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff); + return rsx::decode_fxp<4, 8>((registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff); } rsx::texture_minify_filter fragment_texture::min_filter() const @@ -352,17 +352,17 @@ namespace rsx f32 vertex_texture::min_lod() const { - return rsx::decode_fx13((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 19) & 0xfff); + return rsx::decode_fxp<4, 8, false>((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 19) & 0xfff); } f32 vertex_texture::max_lod() const { - return rsx::decode_fx13((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 7) & 0xfff); + return rsx::decode_fxp<4, 8, false>((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 7) & 0xfff); } f32 vertex_texture::bias() const { - return rsx::decode_fx13((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff); + return rsx::decode_fxp<4, 8>((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff); } rsx::texture_minify_filter vertex_texture::min_filter() const diff --git a/rpcs3/Emu/RSX/rsx_decode.h b/rpcs3/Emu/RSX/rsx_decode.h index 5b58bb8421..9d7997f638 100644 --- a/rpcs3/Emu/RSX/rsx_decode.h +++ b/rpcs3/Emu/RSX/rsx_decode.h @@ -5,6 +5,7 @@ #include #include #include "gcm_enums.h" +#include "rsx_utils.h" #pragma warning(disable:4503) namespace @@ -2027,17 +2028,13 @@ struct registers_decoder { const u32 val = value; - if ((val & ~(1<<31)) == 0) + if (val == 0) { + // Will get reported in image_in return 0; } - if ((s32)val < 0) - { - return 1.f / (((val & ~(1<<31)) / 1048576.f) - 2048.f); - } - - return 1048576.f / val; + return 1.f / rsx::decode_fxp<11, 20>(val); } }; @@ -2063,17 +2060,13 @@ struct registers_decoder { const u32 val = value; - if ((val & ~(1<<31)) == 0) + if (val == 0) { - return 0; + // Will get reported in image_in + return 0.f; } - if ((s32)val < 0) - { - return 1.f / (((val & ~(1<<31)) / 1048576.f) - 2048.f); - } - - return 1048576.f / val; + return 1.f / rsx::decode_fxp<11, 20>(val); } }; diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index e77d2b17dc..79d88c912c 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -752,25 +752,21 @@ namespace rsx return result; } - static inline f32 decode_fx13(u32 bits) + template + static inline To decode_fxp(u32 bits) { + static_assert(u64{sign} + integer + frac <= 32, "Invalid decode_fxp range"); + // Classic fixed point, see PGRAPH section of nouveau docs for TEX_FILTER (lod_bias) and TEX_CONTROL (min_lod, max_lod) // Technically min/max lod are fixed 4.8 but a 5.8 decoder should work just as well since sign bit is 0 - if ((bits & (1 << 12)) == 0) + if constexpr (sign) if (bits & (1 << (integer + frac))) { - const auto integral = f32(bits >> 8); - const auto fractional = (bits & 0xff) / 256.f; - return integral + fractional; - } - else - { - // Negative sign bit - bits = (~bits + 1) & 0x1fff; - const auto integral = -f32(bits >> 8); - const auto fractional = (bits & 0xff) / 256.f; - return integral - fractional; + bits = (0 - bits) & (~0u >> (31 - (integer + frac))); + return bits / (-To(1u << frac)); } + + return bits / To(1u << frac); } template