mirror of https://github.com/RPCS3/rpcs3.git
rsx: Implement signed normalized texture formats
- Already partially supported via EXP option in the shader opcode, but format decoding was disabled. - Noticed in some UE3 games which use _SNORM variants on PC but _UNORM on rpcs3
This commit is contained in:
parent
6892399699
commit
ce587f43a0
|
@ -753,10 +753,28 @@ namespace glsl
|
|||
" rgba /= 255.;"
|
||||
" }\n"
|
||||
"\n"
|
||||
" //TODO: Verify gamma control bit ordering, looks to be 0x7 for rgb, 0xF for rgba\n"
|
||||
" uvec4 mask = uvec4(control_bits & 0xFu) & uvec4(0x1, 0x2, 0x4, 0x8);\n"
|
||||
" vec4 convert = srgb_to_linear(rgba);\n"
|
||||
" return _select(rgba, convert, notEqual(mask, uvec4(0)));\n"
|
||||
" uvec4 mask;\n"
|
||||
" vec4 convert;\n"
|
||||
" uint op_mask = control_bits & 0x3C0u;\n"
|
||||
"\n"
|
||||
" if (op_mask != 0)\n"
|
||||
" {\n"
|
||||
" // Expand to signed normalized\n"
|
||||
" mask = uvec4(op_mask) & uvec4(0x80, 0x100, 0x200, 0x40);\n"
|
||||
" convert = (rgba * 2.f - 1.f);\n"
|
||||
" rgba = _select(rgba, convert, notEqual(mask, uvec4(0)));\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" op_mask = control_bits & 0xFu;\n"
|
||||
" if (op_mask != 0u)\n"
|
||||
" {\n"
|
||||
" // Gamma correction\n"
|
||||
" mask = uvec4(op_mask) & uvec4(0x1, 0x2, 0x4, 0x8);\n"
|
||||
" convert = srgb_to_linear(rgba);\n"
|
||||
" return _select(rgba, convert, notEqual(mask, uvec4(0)));\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return rgba;\n"
|
||||
"}\n\n"
|
||||
|
||||
"#define TEX_NAME(index) tex##index\n"
|
||||
|
|
|
@ -267,6 +267,11 @@ namespace rsx
|
|||
return ((registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 13) & 0xf);
|
||||
}
|
||||
|
||||
u8 fragment_texture::argb_signed() const
|
||||
{
|
||||
return ((registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 28) & 0xf);
|
||||
}
|
||||
|
||||
bool fragment_texture::a_signed() const
|
||||
{
|
||||
return ((registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 28) & 0x1);
|
||||
|
|
|
@ -69,6 +69,7 @@ namespace rsx
|
|||
rsx::texture_minify_filter min_filter() const;
|
||||
rsx::texture_magnify_filter mag_filter() const;
|
||||
u8 convolution_filter() const;
|
||||
u8 argb_signed() const;
|
||||
bool a_signed() const;
|
||||
bool r_signed() const;
|
||||
bool g_signed() const;
|
||||
|
|
|
@ -1727,7 +1727,31 @@ namespace rsx
|
|||
}
|
||||
}
|
||||
|
||||
if (const auto srgb_mask = tex.gamma())
|
||||
// Special operations applied to 8-bit formats such as gamma correction and sign conversion
|
||||
// NOTE: The unsigned_remap being set to anything other than 0 flags the texture as being signed
|
||||
// This is a separate method of setting the format to signed mode without doing so per-channel
|
||||
// NOTE2: Modifier precedence is not respected here. This is another TODO (kd-11)
|
||||
u32 argb8_convert = tex.gamma();
|
||||
if (const u32 sign_convert = tex.unsigned_remap() ? 0xF : tex.argb_signed())
|
||||
{
|
||||
// Apply remap to avoid mapping 1 to -1. Only the sign conversion needs this check
|
||||
// TODO: Use actual remap mask to account for 0 and 1 overrides in default mapping
|
||||
// TODO: Replace this clusterfuck of texture control with matrix transformation
|
||||
const auto remap_ctrl = (tex.remap() >> 8) & 0xAA;
|
||||
if (remap_ctrl == 0xAA)
|
||||
{
|
||||
argb8_convert |= (sign_convert & 0xFu) << 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (remap_ctrl & 0x03) argb8_convert |= (sign_convert & 0x1u) << 6;
|
||||
if (remap_ctrl & 0x0C) argb8_convert |= (sign_convert & 0x2u) << 6;
|
||||
if (remap_ctrl & 0x30) argb8_convert |= (sign_convert & 0x4u) << 6;
|
||||
if (remap_ctrl & 0xC0) argb8_convert |= (sign_convert & 0x8u) << 6;
|
||||
}
|
||||
}
|
||||
|
||||
if (argb8_convert)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
|
@ -1743,11 +1767,11 @@ namespace rsx
|
|||
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT:
|
||||
case CELL_GCM_TEXTURE_X32_FLOAT:
|
||||
case CELL_GCM_TEXTURE_Y16_X16_FLOAT:
|
||||
//Special data formats (XY, HILO, DEPTH) are not RGB formats
|
||||
//Ignore gamma flags
|
||||
// Special data formats (XY, HILO, DEPTH) are not RGB formats
|
||||
// Ignore gamma flags
|
||||
break;
|
||||
default:
|
||||
texture_control |= srgb_mask;
|
||||
texture_control |= argb8_convert;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue