mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-12 22:14:58 +00:00
rsx/gl/vk/dx12: Add emulated texture fetch for depth read (#2173)
* rsx/gl/vk/dx12: Add emulated texture fetch for depth read gl/vk/dx12: Simplify reinterpretation equation * gl: Remove unnecessary re-swizzle * glsl: explicitly cast uint to float
This commit is contained in:
parent
9abb908226
commit
5430e1d310
@ -448,7 +448,10 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE1D));
|
||||
return true;
|
||||
case rsx::texture_dimension_extended::texture_dimension_2d:
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D));
|
||||
if (m_prog.redirected_textures & (1 << dst.tex_num))
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA));
|
||||
else
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D));
|
||||
return true;
|
||||
case rsx::texture_dimension_extended::texture_dimension_cubemap:
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE));
|
||||
|
@ -106,7 +106,7 @@ bool fragment_program_compare::operator()(const RSXFragmentProgram& binary1, con
|
||||
if (binary1.texture_dimensions != binary2.texture_dimensions || binary1.unnormalized_coords != binary2.unnormalized_coords ||
|
||||
binary1.height != binary2.height || binary1.origin_mode != binary2.origin_mode || binary1.pixel_center_mode != binary2.pixel_center_mode ||
|
||||
binary1.back_color_diffuse_output != binary2.back_color_diffuse_output || binary1.back_color_specular_output != binary2.back_color_specular_output ||
|
||||
binary1.front_back_color_enabled != binary2.front_back_color_enabled || binary1.alpha_func != binary2.alpha_func)
|
||||
binary1.front_back_color_enabled != binary2.front_back_color_enabled || binary1.alpha_func != binary2.alpha_func || binary1.redirected_textures != binary2.redirected_textures)
|
||||
return false;
|
||||
const qword *instBuffer1 = (const qword*)binary1.addr;
|
||||
const qword *instBuffer2 = (const qword*)binary2.addr;
|
||||
|
@ -37,6 +37,7 @@ enum class FUNCTION {
|
||||
FUNCTION_VERTEX_TEXTURE_FETCH2D,
|
||||
FUNCTION_VERTEX_TEXTURE_FETCH3D,
|
||||
FUNCTION_VERTEX_TEXTURE_FETCHCUBE,
|
||||
FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA
|
||||
};
|
||||
|
||||
enum class COMPARE {
|
||||
|
@ -80,6 +80,8 @@ std::string getFunctionImp(FUNCTION f)
|
||||
return "ddx($0)";
|
||||
case FUNCTION::FUNCTION_DFDY:
|
||||
return "ddy($0)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA:
|
||||
return "texture2DReconstruct($t.Sample($tsampler, $0.xy * $t_scale))";
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,5 +204,14 @@ void insert_d3d12_legacy_function(std::ostream& OS)
|
||||
OS << "{\n";
|
||||
OS << " return unpackSnorm2x16(val) * 6.1E+5;\n";
|
||||
OS << "}\n\n";
|
||||
|
||||
OS << "float4 texture2DReconstruct(float depth_value)\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., 1.);\n";
|
||||
OS << "}\n\n";
|
||||
}
|
||||
#endif
|
||||
|
@ -43,6 +43,23 @@ void D3D12GSRender::load_program()
|
||||
m_vertex_program = get_current_vertex_program();
|
||||
m_fragment_program = get_current_fragment_program();
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
auto &tex = rsx::method_registers.fragment_textures[i];
|
||||
if (tex.enabled())
|
||||
{
|
||||
const u32 texaddr = rsx::get_address(tex.offset(), tex.location());
|
||||
if (m_rtts.get_texture_from_depth_stencil_if_applicable(texaddr))
|
||||
{
|
||||
u32 format = tex.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
if (format == CELL_GCM_TEXTURE_A8R8G8B8 || format == CELL_GCM_TEXTURE_D8R8G8B8)
|
||||
{
|
||||
m_fragment_program.redirected_textures |= (1 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
D3D12PipelineProperties prop = {};
|
||||
prop.Topology = get_primitive_topology_type(rsx::method_registers.current_draw_clause.primitive);
|
||||
|
||||
|
@ -80,6 +80,8 @@ std::string getFunctionImpl(FUNCTION f)
|
||||
return "dFdy($0)";
|
||||
case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH2D:
|
||||
return "textureLod($t, $0.xy, 0)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA:
|
||||
return "texture2DReconstruct($t, $0.xy)";
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,4 +139,15 @@ void insert_glsl_legacy_function(std::ostream& OS)
|
||||
OS << " result.z = clamped_val.x > 0.0 ? exp(clamped_val.w * log(max(clamped_val.y, 1.E-10))) : 0.0;\n";
|
||||
OS << " return result;\n";
|
||||
OS << "}\n\n";
|
||||
|
||||
//NOTE: We lose precision if we just store depth value into 8-bit textures i.e (depth, 0, 0)
|
||||
OS << "vec4 texture2DReconstruct(sampler2D tex, vec2 coord)\n";
|
||||
OS << "{\n";
|
||||
OS << " float depth_value = texture(tex, coord.xy).r;\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., 1.);\n";
|
||||
OS << "}\n\n";
|
||||
}
|
||||
|
@ -653,6 +653,23 @@ bool GLGSRender::load_program()
|
||||
RSXVertexProgram vertex_program = get_current_vertex_program();
|
||||
RSXFragmentProgram fragment_program = get_current_fragment_program();
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
auto &tex = rsx::method_registers.fragment_textures[i];
|
||||
if (tex.enabled())
|
||||
{
|
||||
const u32 texaddr = rsx::get_address(tex.offset(), tex.location());
|
||||
if (m_rtts.get_texture_from_depth_stencil_if_applicable(texaddr))
|
||||
{
|
||||
u32 format = tex.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
if (format == CELL_GCM_TEXTURE_A8R8G8B8 || format == CELL_GCM_TEXTURE_D8R8G8B8)
|
||||
{
|
||||
fragment_program.redirected_textures |= (1 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_program = &m_prog_buffer.getGraphicPipelineState(vertex_program, fragment_program, nullptr);
|
||||
m_program->use();
|
||||
|
||||
|
@ -221,6 +221,7 @@ struct RSXFragmentProgram
|
||||
u32 offset;
|
||||
u32 ctrl;
|
||||
u16 unnormalized_coords;
|
||||
u16 redirected_textures;
|
||||
rsx::comparison_function alpha_func;
|
||||
bool front_back_color_enabled : 1;
|
||||
bool back_color_diffuse_output : 1;
|
||||
|
@ -828,6 +828,8 @@ namespace rsx
|
||||
result.origin_mode = rsx::method_registers.shader_window_origin();
|
||||
result.pixel_center_mode = rsx::method_registers.shader_window_pixel();
|
||||
result.height = rsx::method_registers.shader_window_height();
|
||||
result.redirected_textures = 0;
|
||||
|
||||
|
||||
std::array<texture_dimension_extended, 16> texture_dimensions;
|
||||
for (u32 i = 0; i < rsx::limits::fragment_textures_count; ++i)
|
||||
|
@ -75,6 +75,8 @@ namespace vk
|
||||
return "dFdy($0)";
|
||||
case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH2D:
|
||||
return "textureLod($t, $0.xy, 0)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA:
|
||||
return "texture2DReconstruct($t, $0.xy)";
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,6 +134,16 @@ namespace vk
|
||||
OS << " result.z = clamped_val.x > 0. ? exp(clamped_val.w * log(max(clamped_val.y, 1.E-10))) : 0.;\n";
|
||||
OS << " return result;\n";
|
||||
OS << "}\n\n";
|
||||
|
||||
OS << "vec4 texture2DReconstruct(sampler2D tex, vec2 coord)\n";
|
||||
OS << "{\n";
|
||||
OS << " float depth_value = texture(tex, coord.xy).r;\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., 1.);\n";
|
||||
OS << "}\n\n";
|
||||
}
|
||||
|
||||
void init_default_resources(TBuiltInResource &rsc)
|
||||
|
@ -975,6 +975,23 @@ bool VKGSRender::load_program()
|
||||
RSXVertexProgram vertex_program = get_current_vertex_program();
|
||||
RSXFragmentProgram fragment_program = get_current_fragment_program();
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
auto &tex = rsx::method_registers.fragment_textures[i];
|
||||
if (tex.enabled())
|
||||
{
|
||||
const u32 texaddr = rsx::get_address(tex.offset(), tex.location());
|
||||
if (m_rtts.get_texture_from_depth_stencil_if_applicable(texaddr))
|
||||
{
|
||||
u32 format = tex.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
if (format == CELL_GCM_TEXTURE_A8R8G8B8 || format == CELL_GCM_TEXTURE_D8R8G8B8)
|
||||
{
|
||||
fragment_program.redirected_textures |= (1 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vk::pipeline_props properties = {};
|
||||
|
||||
properties.ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
|
Loading…
x
Reference in New Issue
Block a user