1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2025-01-31 20:41:45 +01:00

rsx/gl/vk: Simulate z clipping with selective depth clamp

- The scale offset matrix is fine but on real hardware the z results seem to be independent of near/far clipping distances
-- If depth falls within near/far, clamp depth value to [0,1]
This commit is contained in:
kd-11 2018-01-18 15:06:28 +03:00
parent 1a6e53ec98
commit 0a2992839b
6 changed files with 30 additions and 12 deletions

View File

@ -341,6 +341,20 @@ namespace glsl
OS << " return result;\n";
OS << "}\n\n";
OS << "vec4 apply_zclip_xform(vec4 pos, float near_plane, float far_plane)\n";
OS << "{\n";
OS << " float d = pos.z / pos.w;\n";
OS << " if (d < 0.f && d >= near_plane)\n";
OS << " d = 0.f;\n";
OS << " else if (d > 1.f && d <= far_plane)\n";
OS << " d = 1.f;\n";
OS << " else\n";
OS << " return pos;\n";
OS << "\n";
OS << " pos.z = d * pos.w;\n";
OS << " return pos;\n";
OS << "}\n\n";
if (domain == glsl::program_domain::glsl_vertex_program)
return;

View File

@ -1057,7 +1057,9 @@ void GLGSRender::load_program(u32 vertex_base, u32 vertex_count)
*(reinterpret_cast<u32*>(buf + 128)) = rsx::method_registers.transform_branch_bits();
*(reinterpret_cast<u32*>(buf + 132)) = vertex_base;
*(reinterpret_cast<f32*>(buf + 136)) = rsx::method_registers.point_size();
fill_vertex_layout_state(m_vertex_layout, vertex_count, reinterpret_cast<s32*>(buf + 144));
*(reinterpret_cast<f32*>(buf + 140)) = rsx::method_registers.clip_min();
*(reinterpret_cast<f32*>(buf + 144)) = rsx::method_registers.clip_max();
fill_vertex_layout_state(m_vertex_layout, vertex_count, reinterpret_cast<s32*>(buf + 160));
if (m_transform_constants_dirty)
{
@ -1107,7 +1109,7 @@ void GLGSRender::update_draw_state()
gl_state.depth_mask(rsx::method_registers.depth_write_enabled());
gl_state.stencil_mask(rsx::method_registers.stencil_mask());
gl_state.enable(rsx::method_registers.depth_clamp_enabled(), GL_DEPTH_CLAMP);
gl_state.enable(rsx::method_registers.depth_clamp_enabled() || !rsx::method_registers.depth_clip_enabled(), GL_DEPTH_CLAMP);
if (gl_state.enable(rsx::method_registers.depth_test_enabled(), GL_DEPTH_TEST))
{

View File

@ -39,6 +39,8 @@ void GLVertexDecompilerThread::insertHeader(std::stringstream &OS)
OS << " uint transform_branch_bits;\n";
OS << " uint vertex_base_index;\n";
OS << " float point_size;\n";
OS << " float z_near;\n";
OS << " float z_far;\n";
OS << " ivec4 input_attributes[16];\n";
OS << "};\n\n";
}
@ -297,6 +299,7 @@ void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS)
OS << " gl_PointSize = point_size;\n";
OS << " gl_Position = gl_Position * scale_offset_mat;\n";
OS << " gl_Position = apply_zclip_xform(gl_Position, z_near, z_far);\n";
//Since our clip_space is symetrical [-1, 1] we map it to linear space using the eqn:
//ln = (clip * 2) - 1 to fully utilize the 0-1 range of the depth buffer

View File

@ -799,14 +799,8 @@ namespace rsx
if (flip_y) scale_y *= -1;
if (flip_y) offset_y *= -1;
float clip_min = rsx::method_registers.clip_min();
float clip_max = rsx::method_registers.clip_max();
float z_clip_scale = (clip_max + clip_min) == 0.f ? 1.f : (clip_max + clip_min);
float z_offset_scale = (clip_max - clip_min) == 0.f ? 1.f : (clip_max - clip_min);
float scale_z = rsx::method_registers.viewport_scale_z() / z_clip_scale;
float offset_z = rsx::method_registers.viewport_offset_z() / z_offset_scale;
float scale_z = rsx::method_registers.viewport_scale_z();
float offset_z = rsx::method_registers.viewport_offset_z();
float one = 1.f;
stream_vector(buffer, (u32&)scale_x, 0, 0, (u32&)offset_x);

View File

@ -2277,7 +2277,7 @@ void VKGSRender::load_program(u32 vertex_count, u32 vertex_base)
properties.rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
properties.rs.polygonMode = VK_POLYGON_MODE_FILL;
properties.rs.depthClampEnable = rsx::method_registers.depth_clamp_enabled();
properties.rs.depthClampEnable = rsx::method_registers.depth_clamp_enabled() || !rsx::method_registers.depth_clip_enabled();
properties.rs.rasterizerDiscardEnable = VK_FALSE;
//Disabled by setting factors to 0 as needed
@ -2338,7 +2338,9 @@ void VKGSRender::load_program(u32 vertex_count, u32 vertex_base)
*(reinterpret_cast<u32*>(buf + 128)) = rsx::method_registers.transform_branch_bits();
*(reinterpret_cast<u32*>(buf + 132)) = vertex_base;
*(reinterpret_cast<f32*>(buf + 136)) = rsx::method_registers.point_size();
fill_vertex_layout_state(m_vertex_layout, vertex_count, reinterpret_cast<s32*>(buf + 144));
*(reinterpret_cast<f32*>(buf + 140)) = rsx::method_registers.clip_min();
*(reinterpret_cast<f32*>(buf + 144)) = rsx::method_registers.clip_max();
fill_vertex_layout_state(m_vertex_layout, vertex_count, reinterpret_cast<s32*>(buf + 160));
//Vertex constants
buf = buf + 512;

View File

@ -37,6 +37,8 @@ void VKVertexDecompilerThread::insertHeader(std::stringstream &OS)
OS << " uint transform_branch_bits;\n";
OS << " uint vertex_base_index;\n";
OS << " float point_size;\n";
OS << " float z_near;\n";
OS << " float z_far;\n";
OS << " ivec4 input_attributes[16];\n";
OS << "};\n";
@ -312,6 +314,7 @@ void VKVertexDecompilerThread::insertMainEnd(std::stringstream & OS)
OS << " gl_PointSize = point_size;\n";
OS << " gl_Position = gl_Position * scale_offset_mat;\n";
OS << " gl_Position = apply_zclip_xform(gl_Position, z_near, z_far);\n";
OS << "}\n";
}