From b2c55bf772f2436db04357c2689302b98d9f0b26 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 26 Jan 2015 21:10:09 -0500 Subject: Rasterizer: Implemented alpha testing. --- src/video_core/pica.h | 14 +++++++++++--- src/video_core/rasterizer.cpp | 45 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 7 deletions(-) (limited to 'src/video_core') diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 15850ba1..a19f4190 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -310,7 +310,7 @@ struct Regs { }; struct { - enum DepthFunc : u32 { + enum CompareFunc : u32 { Never = 0, Always = 1, Equal = 2, @@ -357,11 +357,19 @@ struct Regs { BitField<0, 4, Op> op; } logic_op; - INSERT_PADDING_WORDS(0x4); + INSERT_PADDING_WORDS(0x1); + + union { + BitField< 0, 1, u32> enable; + BitField< 4, 3, CompareFunc> func; + BitField< 8, 8, u32> ref; + } alpha_test; + + INSERT_PADDING_WORDS(0x2); union { BitField< 0, 1, u32> depth_test_enable; - BitField< 4, 3, DepthFunc> depth_test_func; + BitField< 4, 3, CompareFunc> depth_test_func; BitField<12, 1, u32> depth_write_enable; }; diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 219a1bbb..15715c43 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp @@ -431,6 +431,47 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, combiner_output = Math::MakeVec(color_output, alpha_output); } + if (registers.output_merger.alpha_test.enable) { + bool pass = false; + + switch (registers.output_merger.alpha_test.func) { + case registers.output_merger.Never: + pass = false; + break; + + case registers.output_merger.Always: + pass = true; + break; + + case registers.output_merger.Equal: + pass = combiner_output.a() == registers.output_merger.alpha_test.ref; + break; + + case registers.output_merger.NotEqual: + pass = combiner_output.a() != registers.output_merger.alpha_test.ref; + break; + + case registers.output_merger.LessThan: + pass = combiner_output.a() < registers.output_merger.alpha_test.ref; + break; + + case registers.output_merger.LessThanOrEqual: + pass = combiner_output.a() <= registers.output_merger.alpha_test.ref; + break; + + case registers.output_merger.GreaterThan: + pass = combiner_output.a() > registers.output_merger.alpha_test.ref; + break; + + case registers.output_merger.GreaterThanOrEqual: + pass = combiner_output.a() >= registers.output_merger.alpha_test.ref; + break; + } + + if (!pass) + continue; + } + // TODO: Does depth indeed only get written even if depth testing is enabled? if (registers.output_merger.depth_test_enable) { u16 z = (u16)(-(v0.screenpos[2].ToFloat32() * w0 + @@ -472,10 +513,6 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, case registers.output_merger.GreaterThanOrEqual: 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) -- cgit v1.2.3