diff options
-rw-r--r-- | src/video_core/pica.h | 1 | ||||
-rw-r--r-- | src/video_core/rasterizer.cpp | 39 |
2 files changed, 34 insertions, 6 deletions
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 4afda7b4b..810a926c9 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -300,6 +300,7 @@ struct Regs { struct { enum DepthFunc : u32 { Always = 1, + LessThan = 4, GreaterThan = 6, }; diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 04ff68615..8dff2db27 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp @@ -396,12 +396,39 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, combiner_output = Math::MakeVec(color_output, alpha_output); } - // TODO: Not sure if the multiplication by 65535 has already been taken care - // of when transforming to screen coordinates or not. - u16 z = (u16)(((float)v0.screenpos[2].ToFloat32() * w0 + - (float)v1.screenpos[2].ToFloat32() * w1 + - (float)v2.screenpos[2].ToFloat32() * w2) * 65535.f / wsum); - SetDepth(x >> 4, y >> 4, z); + // TODO: Does depth indeed only get written even if depth testing is enabled? + if (registers.output_merger.depth_test_enable) { + u16 z = (u16)(-((float)v0.screenpos[2].ToFloat32() * w0 + + (float)v1.screenpos[2].ToFloat32() * w1 + + (float)v2.screenpos[2].ToFloat32() * w2) * 65535.f / wsum); + u16 ref_z = GetDepth(x >> 4, y >> 4); + + bool pass = false; + + switch (registers.output_merger.depth_test_func) { + case registers.output_merger.Always: + pass = true; + break; + + case registers.output_merger.LessThan: + pass = z < ref_z; + break; + + case registers.output_merger.GreaterThan: + pass = z > ref_z; + break; + + default: + LOG_ERROR(HW_GPU, "Unknown depth test function %x", registers.output_merger.depth_test_func.Value()); + break; + } + + if (!pass) + continue; + + if (registers.output_merger.depth_write_enable) + SetDepth(x >> 4, y >> 4, z); + } DrawPixel(x >> 4, y >> 4, combiner_output); } |