diff --git a/rpcs3/Emu/RSX/Common/GLSLCommon.h b/rpcs3/Emu/RSX/Common/GLSLCommon.h index e3232404ca..82e4136df4 100644 --- a/rpcs3/Emu/RSX/Common/GLSLCommon.h +++ b/rpcs3/Emu/RSX/Common/GLSLCommon.h @@ -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; diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index be3fe8b014..f046194e40 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -1057,7 +1057,9 @@ void GLGSRender::load_program(u32 vertex_base, u32 vertex_count) *(reinterpret_cast(buf + 128)) = rsx::method_registers.transform_branch_bits(); *(reinterpret_cast(buf + 132)) = vertex_base; *(reinterpret_cast(buf + 136)) = rsx::method_registers.point_size(); - fill_vertex_layout_state(m_vertex_layout, vertex_count, reinterpret_cast(buf + 144)); + *(reinterpret_cast(buf + 140)) = rsx::method_registers.clip_min(); + *(reinterpret_cast(buf + 144)) = rsx::method_registers.clip_max(); + fill_vertex_layout_state(m_vertex_layout, vertex_count, reinterpret_cast(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)) { diff --git a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp index 67f5ab6cd2..a1acc4c8f7 100644 --- a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp @@ -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 diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 04c4de0fc8..7f71b5ff36 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -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); diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index e86014be0c..58659b4006 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -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(buf + 128)) = rsx::method_registers.transform_branch_bits(); *(reinterpret_cast(buf + 132)) = vertex_base; *(reinterpret_cast(buf + 136)) = rsx::method_registers.point_size(); - fill_vertex_layout_state(m_vertex_layout, vertex_count, reinterpret_cast(buf + 144)); + *(reinterpret_cast(buf + 140)) = rsx::method_registers.clip_min(); + *(reinterpret_cast(buf + 144)) = rsx::method_registers.clip_max(); + fill_vertex_layout_state(m_vertex_layout, vertex_count, reinterpret_cast(buf + 160)); //Vertex constants buf = buf + 512; diff --git a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp index bfc357297b..bfa54106bb 100644 --- a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp @@ -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"; }