rsx util: Implement decode_fxp<>

This commit is contained in:
Eladash 2019-10-17 23:39:11 +03:00 committed by kd-11
parent 299b98b30a
commit d4ba7f37b6
3 changed files with 23 additions and 34 deletions

View File

@ -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

View File

@ -5,6 +5,7 @@
#include <tuple>
#include <climits>
#include "gcm_enums.h"
#include "rsx_utils.h"
#pragma warning(disable:4503)
namespace
@ -2027,17 +2028,13 @@ struct registers_decoder<NV3089_DS_DX>
{
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<NV3089_DT_DY>
{
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);
}
};

View File

@ -752,25 +752,21 @@ namespace rsx
return result;
}
static inline f32 decode_fx13(u32 bits)
template <uint integer, uint frac, bool sign = true, typename To = f32>
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 <int N>