diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 275e611cd5..b1d3d6d729 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -467,8 +467,8 @@ void D3D12GSRender::end() 0.f, (float)clip_w, (float)clip_h, - rsx::method_registers.clip_min(), - rsx::method_registers.clip_max(), + 0.f, + 1.f, }; get_current_resource_storage().command_list->RSSetViewports(1, &viewport); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp index fb90d1c609..c1b1ef7ab0 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp @@ -276,6 +276,7 @@ void D3D12GSRender::load_program() D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF, }; prop.Rasterization = CD3D12_RASTERIZER_DESC; + prop.Rasterization.DepthClipEnable = rsx::method_registers.depth_clip_enabled(); if (rsx::method_registers.cull_face_enabled()) { diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index d021a76052..7417ba8e81 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -1044,16 +1044,6 @@ void GLGSRender::update_draw_state() if (gl_state.enable(rsx::method_registers.depth_test_enabled(), GL_DEPTH_TEST)) { gl_state.depth_func(comparison_op(rsx::method_registers.depth_func())); - - float range_near = rsx::method_registers.clip_min(); - float range_far = rsx::method_registers.clip_max(); - - //Workaround to preserve depth precision but respect z direction - //Ni no Kuni sets a very restricted z range (0.9x - 1.) and depth reads / tests are broken - if (range_near <= range_far) - gl_state.depth_range(0.f, 1.f); - else - gl_state.depth_range(1.f, 0.f); } if (glDepthBoundsEXT && (gl_state.enable(rsx::method_registers.depth_bounds_test_enabled(), GL_DEPTH_BOUNDS_TEST_EXT))) diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index fd2b2189c5..fe1e7b1741 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -790,8 +790,14 @@ namespace rsx if (flip_y) scale_y *= -1; if (flip_y) offset_y *= -1; - float scale_z = rsx::method_registers.viewport_scale_z(); - float offset_z = rsx::method_registers.viewport_offset_z(); + 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 one = 1.f; stream_vector(buffer, (u32&)scale_x, 0, 0, (u32&)offset_x); diff --git a/rpcs3/Emu/RSX/rsx_decode.h b/rpcs3/Emu/RSX/rsx_decode.h index bc96cba982..89f64451d7 100644 --- a/rpcs3/Emu/RSX/rsx_decode.h +++ b/rpcs3/Emu/RSX/rsx_decode.h @@ -710,20 +710,34 @@ struct registers_decoder union { u32 raw_value; + bitfield_decoder_t<0, 4> depth_clip_enabled; bitfield_decoder_t<4, 4> depth_clamp_enabled; + bitfield_decoder_t<8, 4> depth_clip_ignore_w; } m_data; public: decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + bool depth_clip_enabled() const + { + return bool(m_data.depth_clip_enabled); + } + bool depth_clamp_enabled() const { return bool(m_data.depth_clamp_enabled); } + + bool depth_clip_ignore_w() const + { + return bool(m_data.depth_clip_ignore_w); + } }; static std::string dump(decoded_type &&decoded_values) { - return "Depth: clamp " + print_boolean(decoded_values.depth_clamp_enabled()); + return "Depth: clip_enabled " + print_boolean(decoded_values.depth_clip_enabled()) + + " clamp " + print_boolean(decoded_values.depth_clamp_enabled()) + + " ignore_w " + print_boolean(decoded_values.depth_clip_ignore_w()); } }; diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index a389fbb969..9cd69c8633 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -1159,6 +1159,7 @@ namespace rsx // Stencil bits init to 00 - Tested with NPEB90184 (never sets the depth_stencil clear values but uses stencil test) registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffff00; + registers[NV4097_SET_ZMIN_MAX_CONTROL] = 1; // CELL_GCM_SURFACE_A8R8G8B8, CELL_GCM_SURFACE_Z24S8 and CELL_GCM_SURFACE_CENTER_1 registers[NV4097_SET_SURFACE_FORMAT] = (8 << 0) | (2 << 5) | (0 << 12) | (1 << 16) | (1 << 24); diff --git a/rpcs3/Emu/RSX/rsx_methods.h b/rpcs3/Emu/RSX/rsx_methods.h index 1d9b8b0197..0969f9c349 100644 --- a/rpcs3/Emu/RSX/rsx_methods.h +++ b/rpcs3/Emu/RSX/rsx_methods.h @@ -387,24 +387,12 @@ namespace rsx f32 clip_min() const { - f32 depth_min = decode().clip_min(); - - //Clamp to [0, 1] - if (depth_min < 0.f) return 0.f; - if (depth_min > 1.f) return 1.f; - - return depth_min; + return decode().clip_min(); } f32 clip_max() const { - f32 depth_max = decode().clip_max(); - - //Clamp to [0, 1] - if (depth_max < 0.f) return 0.f; - if (depth_max > 1.f) return 1.f; - - return depth_max; + return decode().clip_max(); } bool logic_op_enabled() const @@ -1206,6 +1194,16 @@ namespace rsx { return decode().depth_clamp_enabled(); } + + bool depth_clip_enabled() + { + return decode().depth_clip_enabled(); + } + + bool depth_clip_ignore_w() + { + return decode().depth_clip_ignore_w(); + } }; extern rsx_state method_registers;