rsx: Reimplement depth <-> RGBA reinterpretation code

- Implements proper channel order for fp24-ARGB8 conversion
- Takes swizzle remap into account when reconstructing source bytes
This commit is contained in:
kd-11 2017-11-18 16:10:54 +03:00
parent 5cf2d774f3
commit de5a4fe083
6 changed files with 70 additions and 20 deletions

View File

@ -320,20 +320,43 @@ namespace glsl
program_common::insert_compare_op(OS);
//NOTE: After testing with GOW, the w component is either the original depth or wraps around to the x component
//Since component.r == depth_value with some precision loss, just use the precise depth value for now (further testing needed)
//NOTE: Memory layout is fetched as byteswapped BGRA [GBAR] (GOW collection, DS2, DeS)
//The A component (Z) is useless (should contain stencil8 or just 1)
OS << "vec4 decodeLinearDepth(float depth_value)\n";
OS << "{\n";
OS << " uint value = uint(depth_value * 16777215);\n";
OS << " uint b = (value & 0xff);\n";
OS << " uint g = (value >> 8) & 0xff;\n";
OS << " uint r = (value >> 16) & 0xff;\n";
OS << " return vec4(float(r)/255., float(g)/255., float(b)/255., depth_value);\n";
OS << " return vec4(float(g)/255., float(b)/255., 1., float(r)/255.);\n";
OS << "}\n\n";
OS << "vec4 texture2DReconstruct(sampler2D tex, vec2 coord)\n";
OS << "float read_value(vec4 src, uint remap_index)\n";
OS << "{\n";
OS << " return decodeLinearDepth(texture(tex, coord.xy).r);\n";
OS << " switch (remap_index)\n";
OS << " {\n";
OS << " case 0: return src.a;\n";
OS << " case 1: return src.r;\n";
OS << " case 2: return src.g;\n";
OS << " case 3: return src.b;\n";
OS << " }\n";
OS << "}\n\n";
OS << "vec4 texture2DReconstruct(sampler2D tex, vec2 coord, float remap)\n";
OS << "{\n";
OS << " vec4 result = decodeLinearDepth(texture(tex, coord.xy).r);\n";
OS << " uint remap_vector = floatBitsToUint(remap) & 0xFF;\n";
OS << " if (remap_vector == 0xE4) return result;\n\n";
OS << " vec4 tmp;\n";
OS << " uint remap_a = remap_vector & 0x3;\n";
OS << " uint remap_r = (remap_vector >> 2) & 0x3;\n";
OS << " uint remap_g = (remap_vector >> 4) & 0x3;\n";
OS << " uint remap_b = (remap_vector >> 6) & 0x3;\n";
OS << " tmp.a = read_value(result, remap_a);\n";
OS << " tmp.r = read_value(result, remap_r);\n";
OS << " tmp.g = read_value(result, remap_g);\n";
OS << " tmp.b = read_value(result, remap_b);\n";
OS << " return tmp;\n";
OS << "}\n\n";
OS << "vec4 get_wpos()\n";
@ -415,7 +438,7 @@ namespace glsl
case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH2D:
return "textureLod($t, $0.xy, 0)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA:
return "texture2DReconstruct($t, $0.xy * texture_parameters[$_i].xy)";
return "texture2DReconstruct($t, $0.xy * texture_parameters[$_i].xy, texture_parameters[$_i].z)";
}
}
}

View File

@ -83,7 +83,7 @@ std::string getFunctionImp(FUNCTION f)
case FUNCTION::FUNCTION_DFDY:
return "ddy($0)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA:
return "texture2DReconstruct($t.Sample($tsampler, $0.xy * $t_scale))";
return "texture2DReconstruct($t.Sample($tsampler, $0.xy * $t_scale, texture_parameters[$_i].z))";
}
}
@ -192,16 +192,36 @@ void insert_d3d12_legacy_function(std::ostream& OS, bool is_fragment_program)
OS << " return unpackSnorm2x16(val) * 6.1E+5;\n";
OS << "}\n\n";
//NOTE: After testing with GOW, the w component is either the original depth or wraps around to the x component
//Since component.r == depth_value with some precision loss, just use the precise depth value for now (further testing needed)
//TODO: This function does not work as intended on DX12
OS << "float4 texture2DReconstruct(float depth_value)\n";
OS << "float read_value(float4 src, uint remap_index)\n";
OS << "{\n";
OS << " switch (remap_index)\n";
OS << " {\n";
OS << " case 0: return src.a;\n";
OS << " case 1: return src.r;\n";
OS << " case 2: return src.g;\n";
OS << " case 3: return src.b;\n";
OS << " }\n";
OS << "}\n\n";
OS << "float4 texture2DReconstruct(float depth_value, float remap)\n";
OS << "{\n";
OS << " uint value = round(depth_value * 16777215);\n";
OS << " uint b = (value & 0xff);\n";
OS << " uint g = (value >> 8) & 0xff;\n";
OS << " uint r = (value >> 16) & 0xff;\n";
OS << " return float4(r/255., g/255., b/255., depth_value);\n";
OS << " float4 result = float4(g/255., b/255., 1., r/255.);\n\n";
OS << " uint remap_vector = asuint(remap) & 0xFF;\n";
OS << " if (remap_vector == 0xE4) return result;\n\n";
OS << " float4 tmp;\n";
OS << " uint remap_a = remap_vector & 0x3;\n";
OS << " uint remap_r = (remap_vector >> 2) & 0x3;\n";
OS << " uint remap_g = (remap_vector >> 4) & 0x3;\n";
OS << " uint remap_b = (remap_vector >> 6) & 0x3;\n";
OS << " tmp.a = read_value(result, remap_a);\n";
OS << " tmp.r = read_value(result, remap_r);\n";
OS << " tmp.g = read_value(result, remap_g);\n";
OS << " tmp.b = read_value(result, remap_b);\n";
OS << " return tmp;\n";
OS << "}\n\n";
}
#endif

View File

@ -185,9 +185,7 @@ namespace gl
"void main()\n"
"{\n"
" vec4 rgba_in = texture(fs0, tc0);\n"
" uint raw_value = uint(rgba_in.b * 255.) | (uint(rgba_in.g * 255.) << 8) | (uint(rgba_in.r * 255.) << 16);\n"
" gl_FragDepth = float(raw_value) / 16777215.;\n"
" //gl_FragDepth = rgba_in.r * 0.99609 + rgba_in.g * 0.00389 + rgba_in.b * 0.00002;\n"
" gl_FragDepth = rgba_in.w * 0.99609 + rgba_in.x * 0.00389 + rgba_in.y * 0.00002;\n"
"}\n"
};
}

View File

@ -230,7 +230,7 @@ struct RSXFragmentProgram
bool front_color_specular_output : 1;
u32 texture_dimensions;
std::array<float, 2> texture_scale[16];
std::array<float, 4> texture_scale[16];
u8 textures_alpha_kill[16];
u8 textures_zfunc[16];

View File

@ -854,7 +854,10 @@ namespace rsx
size_t offset = 8;
for (int index = 0; index < 16; ++index)
{
stream_vector(&dst[offset], (u32&)fragment_program.texture_scale[index][0], (u32&)fragment_program.texture_scale[index][1], 0U, 0U);
stream_vector(&dst[offset],
(u32&)fragment_program.texture_scale[index][0], (u32&)fragment_program.texture_scale[index][1],
(u32&)fragment_program.texture_scale[index][2], (u32&)fragment_program.texture_scale[index][3]);
offset += 4;
}
}
@ -1396,8 +1399,12 @@ namespace rsx
case CELL_GCM_TEXTURE_D8R8G8B8:
case CELL_GCM_TEXTURE_A4R4G4B4:
case CELL_GCM_TEXTURE_R5G6B5:
{
u32 remap = tex.remap();
result.redirected_textures |= (1 << i);
result.texture_scale[i][2] = (f32&)remap;
break;
}
case CELL_GCM_TEXTURE_DEPTH16:
case CELL_GCM_TEXTURE_DEPTH24_D8:
case CELL_GCM_TEXTURE_DEPTH16_FLOAT:
@ -1520,8 +1527,12 @@ namespace rsx
case CELL_GCM_TEXTURE_D8R8G8B8:
case CELL_GCM_TEXTURE_A4R4G4B4:
case CELL_GCM_TEXTURE_R5G6B5:
{
u32 remap = tex.remap();
result.redirected_textures |= (1 << i);
result.texture_scale[i][2] = (f32&)remap;
break;
}
case CELL_GCM_TEXTURE_DEPTH16:
case CELL_GCM_TEXTURE_DEPTH24_D8:
case CELL_GCM_TEXTURE_DEPTH16_FLOAT:

View File

@ -334,9 +334,7 @@ namespace vk
"void main()\n"
"{\n"
" vec4 rgba_in = texture(fs0, tc0);\n"
" uint raw_value = uint(rgba_in.b * 255.) | (uint(rgba_in.g * 255.) << 8) | (uint(rgba_in.r * 255.) << 16);\n"
" gl_FragDepth = float(raw_value) / 16777215.;\n"
" //gl_FragDepth = rgba_in.r * 0.99609 + rgba_in.g * 0.00389 + rgba_in.b * 0.00002;\n"
" gl_FragDepth = rgba_in.w * 0.99609 + rgba_in.x * 0.00389 + rgba_in.y * 0.00002;\n"
"}\n"
};