3
0
Fork 0
forked from suyu/suyu

Rasterizer: Implemented alpha testing.

This commit is contained in:
bunnei 2015-01-26 21:10:09 -05:00
parent b101e6312f
commit b2c55bf772
2 changed files with 52 additions and 7 deletions

View file

@ -310,7 +310,7 @@ struct Regs {
}; };
struct { struct {
enum DepthFunc : u32 { enum CompareFunc : u32 {
Never = 0, Never = 0,
Always = 1, Always = 1,
Equal = 2, Equal = 2,
@ -357,11 +357,19 @@ struct Regs {
BitField<0, 4, Op> op; BitField<0, 4, Op> op;
} logic_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 { union {
BitField< 0, 1, u32> depth_test_enable; 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; BitField<12, 1, u32> depth_write_enable;
}; };

View file

@ -431,6 +431,47 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
combiner_output = Math::MakeVec(color_output, alpha_output); 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? // TODO: Does depth indeed only get written even if depth testing is enabled?
if (registers.output_merger.depth_test_enable) { if (registers.output_merger.depth_test_enable) {
u16 z = (u16)(-(v0.screenpos[2].ToFloat32() * w0 + u16 z = (u16)(-(v0.screenpos[2].ToFloat32() * w0 +
@ -472,10 +513,6 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
case registers.output_merger.GreaterThanOrEqual: case registers.output_merger.GreaterThanOrEqual:
pass = z >= ref_z; pass = z >= ref_z;
break; break;
default:
LOG_ERROR(HW_GPU, "Unknown depth test function %x", registers.output_merger.depth_test_func.Value());
break;
} }
if (!pass) if (!pass)