diff options
Diffstat (limited to 'src/video_core/rasterizer.cpp')
| -rw-r--r-- | src/video_core/rasterizer.cpp | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index df67b9081..80cad9056 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp | |||
| @@ -862,10 +862,30 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, | |||
| 862 | } | 862 | } |
| 863 | } | 863 | } |
| 864 | 864 | ||
| 865 | // interpolated_z = z / w | ||
| 866 | float interpolated_z_over_w = (v0.screenpos[2].ToFloat32() * w0 + | ||
| 867 | v1.screenpos[2].ToFloat32() * w1 + | ||
| 868 | v2.screenpos[2].ToFloat32() * w2) / wsum; | ||
| 869 | |||
| 870 | // Not fully accurate. About 3 bits in precision are missing. | ||
| 871 | // Z-Buffer (z / w * scale + offset) | ||
| 872 | float depth_scale = float24::FromRaw(regs.viewport_depth_range).ToFloat32(); | ||
| 873 | float depth_offset = float24::FromRaw(regs.viewport_depth_near_plane).ToFloat32(); | ||
| 874 | float depth = interpolated_z_over_w * depth_scale + depth_offset; | ||
| 875 | |||
| 876 | // Potentially switch to W-Buffer | ||
| 877 | if (regs.depthmap_enable == Pica::Regs::DepthBuffering::WBuffering) { | ||
| 878 | |||
| 879 | // W-Buffer (z * scale + w * offset = (z / w * scale + offset) * w) | ||
| 880 | depth *= interpolated_w_inverse.ToFloat32() * wsum; | ||
| 881 | } | ||
| 882 | |||
| 883 | // Clamp the result | ||
| 884 | depth = MathUtil::Clamp(depth, 0.0f, 1.0f); | ||
| 885 | |||
| 886 | // Convert float to integer | ||
| 865 | unsigned num_bits = Regs::DepthBitsPerPixel(regs.framebuffer.depth_format); | 887 | unsigned num_bits = Regs::DepthBitsPerPixel(regs.framebuffer.depth_format); |
| 866 | u32 z = (u32)((v0.screenpos[2].ToFloat32() * w0 + | 888 | u32 z = (u32)(depth * ((1 << num_bits) - 1)); |
| 867 | v1.screenpos[2].ToFloat32() * w1 + | ||
| 868 | v2.screenpos[2].ToFloat32() * w2) * ((1 << num_bits) - 1) / wsum); | ||
| 869 | 889 | ||
| 870 | if (output_merger.depth_test_enable) { | 890 | if (output_merger.depth_test_enable) { |
| 871 | u32 ref_z = GetDepth(x >> 4, y >> 4); | 891 | u32 ref_z = GetDepth(x >> 4, y >> 4); |