Pica/Rasterizer: Implement depth testing.

This commit is contained in:
Tony Wasserka 2014-12-21 02:59:08 +01:00
parent 77bb58afeb
commit e229ff8c83
2 changed files with 34 additions and 6 deletions

View File

@ -300,6 +300,7 @@ struct Regs {
struct { struct {
enum DepthFunc : u32 { enum DepthFunc : u32 {
Always = 1, Always = 1,
LessThan = 4,
GreaterThan = 6, GreaterThan = 6,
}; };

View File

@ -396,12 +396,39 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
combiner_output = Math::MakeVec(color_output, alpha_output); combiner_output = Math::MakeVec(color_output, alpha_output);
} }
// TODO: Not sure if the multiplication by 65535 has already been taken care // TODO: Does depth indeed only get written even if depth testing is enabled?
// of when transforming to screen coordinates or not. if (registers.output_merger.depth_test_enable) {
u16 z = (u16)(((float)v0.screenpos[2].ToFloat32() * w0 + u16 z = (u16)(-((float)v0.screenpos[2].ToFloat32() * w0 +
(float)v1.screenpos[2].ToFloat32() * w1 + (float)v1.screenpos[2].ToFloat32() * w1 +
(float)v2.screenpos[2].ToFloat32() * w2) * 65535.f / wsum); (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); SetDepth(x >> 4, y >> 4, z);
}
DrawPixel(x >> 4, y >> 4, combiner_output); DrawPixel(x >> 4, y >> 4, combiner_output);
} }