rsx: Fix decoding of some fixed point texture parameters

- Checked envydocs and found the correct format as fixed-point 4.8 with optional sign bit
This commit is contained in:
kd-11 2019-10-16 23:21:30 +03:00 committed by kd-11
parent a936e43ff6
commit 5af8a9fbbc
6 changed files with 49 additions and 28 deletions

View file

@ -49,8 +49,8 @@ D3D12_SAMPLER_DESC get_sampler_desc(const rsx::fragment_texture &texture)
samplerDesc.BorderColor[1] = (FLOAT)texture.border_color();
samplerDesc.BorderColor[2] = (FLOAT)texture.border_color();
samplerDesc.BorderColor[3] = (FLOAT)texture.border_color();
samplerDesc.MinLOD = (FLOAT)(texture.min_lod() >> 8);
samplerDesc.MaxLOD = (FLOAT)(texture.max_lod() >> 8);
samplerDesc.MinLOD = (FLOAT)(texture.min_lod());
samplerDesc.MaxLOD = (FLOAT)(texture.max_lod());
return samplerDesc;
}

View file

@ -259,8 +259,8 @@ namespace gl
{
set_parameteri(GL_TEXTURE_MIN_FILTER, tex_min_filter(tex.min_filter()));
set_parameterf(GL_TEXTURE_LOD_BIAS, tex.bias());
set_parameteri(GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8));
set_parameteri(GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8));
set_parameterf(GL_TEXTURE_MIN_LOD, tex.min_lod());
set_parameterf(GL_TEXTURE_MAX_LOD, tex.max_lod());
}
const bool aniso_override = !g_cfg.video.strict_rendering_mode && g_cfg.video.anisotropic_level_override > 0;
@ -307,8 +307,8 @@ namespace gl
set_parameteri(GL_TEXTURE_MIN_FILTER, GL_NEAREST);
set_parameteri(GL_TEXTURE_MAG_FILTER, GL_NEAREST);
set_parameterf(GL_TEXTURE_LOD_BIAS, tex.bias());
set_parameteri(GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8));
set_parameteri(GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8));
set_parameterf(GL_TEXTURE_MIN_LOD, tex.min_lod());
set_parameterf(GL_TEXTURE_MAX_LOD, tex.max_lod());
set_parameteri(GL_TEXTURE_COMPARE_MODE, GL_NONE);
}

View file

@ -123,14 +123,14 @@ namespace rsx
return ((registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 31) & 0x1);
}
u16 fragment_texture::min_lod() const
f32 fragment_texture::min_lod() const
{
return ((registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 19) & 0xfff);
return rsx::decode_fx13((registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 19) & 0xfff);
}
u16 fragment_texture::max_lod() const
f32 fragment_texture::max_lod() const
{
return ((registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 7) & 0xfff);
return rsx::decode_fx13((registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 7) & 0xfff);
}
rsx::texture_max_anisotropy fragment_texture::max_aniso() const
@ -211,9 +211,9 @@ namespace rsx
return std::make_pair(remap_inputs, remap_lookup);
}
float fragment_texture::bias() const
f32 fragment_texture::bias() const
{
return float(f16((registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff));
return rsx::decode_fx13((registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff);
}
rsx::texture_minify_filter fragment_texture::min_filter() const
@ -350,19 +350,19 @@ namespace rsx
return ((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 31) & 0x1);
}
u16 vertex_texture::min_lod() const
f32 vertex_texture::min_lod() const
{
return ((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 19) & 0xfff);
return rsx::decode_fx13((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 19) & 0xfff);
}
u16 vertex_texture::max_lod() const
f32 vertex_texture::max_lod() const
{
return ((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 7) & 0xfff);
return rsx::decode_fx13((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 7) & 0xfff);
}
u16 vertex_texture::bias() const
f32 vertex_texture::bias() const
{
return ((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff);
return rsx::decode_fx13((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff);
}
rsx::texture_minify_filter vertex_texture::min_filter() const

View file

@ -48,8 +48,8 @@ namespace rsx
// Control0
bool enabled() const;
u16 min_lod() const;
u16 max_lod() const;
f32 min_lod() const;
f32 max_lod() const;
rsx::texture_max_anisotropy max_aniso() const;
bool alpha_kill_enabled() const;
@ -65,7 +65,7 @@ namespace rsx
std::pair<std::array<u8, 4>, std::array<u8, 4>> decoded_remap() const;
// Filter
float bias() const;
f32 bias() const;
rsx::texture_minify_filter min_filter() const;
rsx::texture_magnify_filter mag_filter() const;
u8 convolution_filter() const;
@ -115,11 +115,11 @@ namespace rsx
// Control0
bool enabled() const;
u16 min_lod() const;
u16 max_lod() const;
f32 min_lod() const;
f32 max_lod() const;
// Filter
u16 bias() const;
f32 bias() const;
rsx::texture_minify_filter min_filter() const;
rsx::texture_magnify_filter mag_filter() const;

View file

@ -1348,8 +1348,8 @@ void VKGSRender::end()
if (rsx::method_registers.fragment_textures[i].get_exact_mipmap_count() > 1)
{
min_lod = (float)(rsx::method_registers.fragment_textures[i].min_lod() >> 8);
max_lod = (float)(rsx::method_registers.fragment_textures[i].max_lod() >> 8);
min_lod = rsx::method_registers.fragment_textures[i].min_lod();
max_lod = rsx::method_registers.fragment_textures[i].max_lod();
lod_bias = rsx::method_registers.fragment_textures[i].bias();
f32 actual_mipmaps;
@ -1425,8 +1425,8 @@ void VKGSRender::end()
bool replace = !vs_sampler_handles[i];
const VkBool32 unnormalized_coords = !!(rsx::method_registers.vertex_textures[i].format() & CELL_GCM_TEXTURE_UN);
const auto min_lod = (f32)rsx::method_registers.vertex_textures[i].min_lod();
const auto max_lod = (f32)rsx::method_registers.vertex_textures[i].max_lod();
const auto min_lod = rsx::method_registers.vertex_textures[i].min_lod();
const auto max_lod = rsx::method_registers.vertex_textures[i].max_lod();
const auto border_color = vk::get_border_color(rsx::method_registers.vertex_textures[i].border_color());
if (vs_sampler_handles[i])

View file

@ -752,6 +752,27 @@ namespace rsx
return result;
}
static inline f32 decode_fx13(u32 bits)
{
// 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)
{
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;
}
}
template <int N>
void unpack_bitset(std::bitset<N>& block, u64* values)
{