mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-27 18:41:10 +00:00
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:
parent
5cf2d774f3
commit
de5a4fe083
@ -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)";
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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"
|
||||
};
|
||||
}
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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"
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user