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[1] = (FLOAT)texture.border_color();
samplerDesc.BorderColor[2] = (FLOAT)texture.border_color(); samplerDesc.BorderColor[2] = (FLOAT)texture.border_color();
samplerDesc.BorderColor[3] = (FLOAT)texture.border_color(); samplerDesc.BorderColor[3] = (FLOAT)texture.border_color();
samplerDesc.MinLOD = (FLOAT)(texture.min_lod() >> 8); samplerDesc.MinLOD = (FLOAT)(texture.min_lod());
samplerDesc.MaxLOD = (FLOAT)(texture.max_lod() >> 8); samplerDesc.MaxLOD = (FLOAT)(texture.max_lod());
return samplerDesc; return samplerDesc;
} }

View file

@ -259,8 +259,8 @@ namespace gl
{ {
set_parameteri(GL_TEXTURE_MIN_FILTER, tex_min_filter(tex.min_filter())); set_parameteri(GL_TEXTURE_MIN_FILTER, tex_min_filter(tex.min_filter()));
set_parameterf(GL_TEXTURE_LOD_BIAS, tex.bias()); set_parameterf(GL_TEXTURE_LOD_BIAS, tex.bias());
set_parameteri(GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8)); set_parameterf(GL_TEXTURE_MIN_LOD, tex.min_lod());
set_parameteri(GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8)); 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; 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_MIN_FILTER, GL_NEAREST);
set_parameteri(GL_TEXTURE_MAG_FILTER, GL_NEAREST); set_parameteri(GL_TEXTURE_MAG_FILTER, GL_NEAREST);
set_parameterf(GL_TEXTURE_LOD_BIAS, tex.bias()); set_parameterf(GL_TEXTURE_LOD_BIAS, tex.bias());
set_parameteri(GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8)); set_parameterf(GL_TEXTURE_MIN_LOD, tex.min_lod());
set_parameteri(GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8)); set_parameterf(GL_TEXTURE_MAX_LOD, tex.max_lod());
set_parameteri(GL_TEXTURE_COMPARE_MODE, GL_NONE); 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); 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 rsx::texture_max_anisotropy fragment_texture::max_aniso() const
@ -211,9 +211,9 @@ namespace rsx
return std::make_pair(remap_inputs, remap_lookup); 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 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); 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 rsx::texture_minify_filter vertex_texture::min_filter() const

View file

@ -48,8 +48,8 @@ namespace rsx
// Control0 // Control0
bool enabled() const; bool enabled() const;
u16 min_lod() const; f32 min_lod() const;
u16 max_lod() const; f32 max_lod() const;
rsx::texture_max_anisotropy max_aniso() const; rsx::texture_max_anisotropy max_aniso() const;
bool alpha_kill_enabled() 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; std::pair<std::array<u8, 4>, std::array<u8, 4>> decoded_remap() const;
// Filter // Filter
float bias() const; f32 bias() const;
rsx::texture_minify_filter min_filter() const; rsx::texture_minify_filter min_filter() const;
rsx::texture_magnify_filter mag_filter() const; rsx::texture_magnify_filter mag_filter() const;
u8 convolution_filter() const; u8 convolution_filter() const;
@ -115,11 +115,11 @@ namespace rsx
// Control0 // Control0
bool enabled() const; bool enabled() const;
u16 min_lod() const; f32 min_lod() const;
u16 max_lod() const; f32 max_lod() const;
// Filter // Filter
u16 bias() const; f32 bias() const;
rsx::texture_minify_filter min_filter() const; rsx::texture_minify_filter min_filter() const;
rsx::texture_magnify_filter mag_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) if (rsx::method_registers.fragment_textures[i].get_exact_mipmap_count() > 1)
{ {
min_lod = (float)(rsx::method_registers.fragment_textures[i].min_lod() >> 8); min_lod = rsx::method_registers.fragment_textures[i].min_lod();
max_lod = (float)(rsx::method_registers.fragment_textures[i].max_lod() >> 8); max_lod = rsx::method_registers.fragment_textures[i].max_lod();
lod_bias = rsx::method_registers.fragment_textures[i].bias(); lod_bias = rsx::method_registers.fragment_textures[i].bias();
f32 actual_mipmaps; f32 actual_mipmaps;
@ -1425,8 +1425,8 @@ void VKGSRender::end()
bool replace = !vs_sampler_handles[i]; bool replace = !vs_sampler_handles[i];
const VkBool32 unnormalized_coords = !!(rsx::method_registers.vertex_textures[i].format() & CELL_GCM_TEXTURE_UN); 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 min_lod = rsx::method_registers.vertex_textures[i].min_lod();
const auto max_lod = (f32)rsx::method_registers.vertex_textures[i].max_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()); const auto border_color = vk::get_border_color(rsx::method_registers.vertex_textures[i].border_color());
if (vs_sampler_handles[i]) if (vs_sampler_handles[i])

View file

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