summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/clipper.cpp4
-rw-r--r--src/video_core/pica.h20
-rw-r--r--src/video_core/rasterizer.cpp26
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp4
4 files changed, 43 insertions, 11 deletions
diff --git a/src/video_core/clipper.cpp b/src/video_core/clipper.cpp
index 2bc747102..db99ce666 100644
--- a/src/video_core/clipper.cpp
+++ b/src/video_core/clipper.cpp
@@ -75,8 +75,6 @@ static void InitScreenCoordinates(OutputVertex& vtx)
75 viewport.halfsize_y = float24::FromRaw(regs.viewport_size_y); 75 viewport.halfsize_y = float24::FromRaw(regs.viewport_size_y);
76 viewport.offset_x = float24::FromFloat32(static_cast<float>(regs.viewport_corner.x)); 76 viewport.offset_x = float24::FromFloat32(static_cast<float>(regs.viewport_corner.x));
77 viewport.offset_y = float24::FromFloat32(static_cast<float>(regs.viewport_corner.y)); 77 viewport.offset_y = float24::FromFloat32(static_cast<float>(regs.viewport_corner.y));
78 viewport.zscale = float24::FromRaw(regs.viewport_depth_range);
79 viewport.offset_z = float24::FromRaw(regs.viewport_depth_far_plane);
80 78
81 float24 inv_w = float24::FromFloat32(1.f) / vtx.pos.w; 79 float24 inv_w = float24::FromFloat32(1.f) / vtx.pos.w;
82 vtx.color *= inv_w; 80 vtx.color *= inv_w;
@@ -89,7 +87,7 @@ static void InitScreenCoordinates(OutputVertex& vtx)
89 87
90 vtx.screenpos[0] = (vtx.pos.x * inv_w + float24::FromFloat32(1.0)) * viewport.halfsize_x + viewport.offset_x; 88 vtx.screenpos[0] = (vtx.pos.x * inv_w + float24::FromFloat32(1.0)) * viewport.halfsize_x + viewport.offset_x;
91 vtx.screenpos[1] = (vtx.pos.y * inv_w + float24::FromFloat32(1.0)) * viewport.halfsize_y + viewport.offset_y; 89 vtx.screenpos[1] = (vtx.pos.y * inv_w + float24::FromFloat32(1.0)) * viewport.halfsize_y + viewport.offset_y;
92 vtx.screenpos[2] = viewport.offset_z + vtx.pos.z * inv_w * viewport.zscale; 90 vtx.screenpos[2] = vtx.pos.z * inv_w;
93} 91}
94 92
95void ProcessTriangle(const OutputVertex &v0, const OutputVertex &v1, const OutputVertex &v2) { 93void ProcessTriangle(const OutputVertex &v0, const OutputVertex &v1, const OutputVertex &v2) {
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index 5891fb72a..a81a7b984 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -70,7 +70,7 @@ struct Regs {
70 INSERT_PADDING_WORDS(0x9); 70 INSERT_PADDING_WORDS(0x9);
71 71
72 BitField<0, 24, u32> viewport_depth_range; // float24 72 BitField<0, 24, u32> viewport_depth_range; // float24
73 BitField<0, 24, u32> viewport_depth_far_plane; // float24 73 BitField<0, 24, u32> viewport_depth_near_plane; // float24
74 74
75 BitField<0, 3, u32> vs_output_total; 75 BitField<0, 3, u32> vs_output_total;
76 76
@@ -122,7 +122,20 @@ struct Regs {
122 BitField<16, 10, s32> y; 122 BitField<16, 10, s32> y;
123 } viewport_corner; 123 } viewport_corner;
124 124
125 INSERT_PADDING_WORDS(0x17); 125 INSERT_PADDING_WORDS(0x1);
126
127 //TODO: early depth
128 INSERT_PADDING_WORDS(0x1);
129
130 INSERT_PADDING_WORDS(0x2);
131
132 enum DepthBuffering : u32 {
133 WBuffering = 0,
134 ZBuffering = 1,
135 };
136 BitField< 0, 1, DepthBuffering> depthmap_enable;
137
138 INSERT_PADDING_WORDS(0x12);
126 139
127 struct TextureConfig { 140 struct TextureConfig {
128 enum WrapMode : u32 { 141 enum WrapMode : u32 {
@@ -1279,10 +1292,11 @@ ASSERT_REG_POSITION(cull_mode, 0x40);
1279ASSERT_REG_POSITION(viewport_size_x, 0x41); 1292ASSERT_REG_POSITION(viewport_size_x, 0x41);
1280ASSERT_REG_POSITION(viewport_size_y, 0x43); 1293ASSERT_REG_POSITION(viewport_size_y, 0x43);
1281ASSERT_REG_POSITION(viewport_depth_range, 0x4d); 1294ASSERT_REG_POSITION(viewport_depth_range, 0x4d);
1282ASSERT_REG_POSITION(viewport_depth_far_plane, 0x4e); 1295ASSERT_REG_POSITION(viewport_depth_near_plane, 0x4e);
1283ASSERT_REG_POSITION(vs_output_attributes[0], 0x50); 1296ASSERT_REG_POSITION(vs_output_attributes[0], 0x50);
1284ASSERT_REG_POSITION(vs_output_attributes[1], 0x51); 1297ASSERT_REG_POSITION(vs_output_attributes[1], 0x51);
1285ASSERT_REG_POSITION(viewport_corner, 0x68); 1298ASSERT_REG_POSITION(viewport_corner, 0x68);
1299ASSERT_REG_POSITION(depthmap_enable, 0x6D);
1286ASSERT_REG_POSITION(texture0_enable, 0x80); 1300ASSERT_REG_POSITION(texture0_enable, 0x80);
1287ASSERT_REG_POSITION(texture0, 0x81); 1301ASSERT_REG_POSITION(texture0, 0x81);
1288ASSERT_REG_POSITION(texture0_format, 0x8e); 1302ASSERT_REG_POSITION(texture0_format, 0x8e);
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);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 0b471dfd2..5fc885961 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -256,7 +256,7 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
256 256
257 // Depth modifiers 257 // Depth modifiers
258 case PICA_REG_INDEX(viewport_depth_range): 258 case PICA_REG_INDEX(viewport_depth_range):
259 case PICA_REG_INDEX(viewport_depth_far_plane): 259 case PICA_REG_INDEX(viewport_depth_near_plane):
260 SyncDepthModifiers(); 260 SyncDepthModifiers();
261 break; 261 break;
262 262
@@ -911,7 +911,7 @@ void RasterizerOpenGL::SyncCullMode() {
911 911
912void RasterizerOpenGL::SyncDepthModifiers() { 912void RasterizerOpenGL::SyncDepthModifiers() {
913 float depth_scale = -Pica::float24::FromRaw(Pica::g_state.regs.viewport_depth_range).ToFloat32(); 913 float depth_scale = -Pica::float24::FromRaw(Pica::g_state.regs.viewport_depth_range).ToFloat32();
914 float depth_offset = Pica::float24::FromRaw(Pica::g_state.regs.viewport_depth_far_plane).ToFloat32() / 2.0f; 914 float depth_offset = Pica::float24::FromRaw(Pica::g_state.regs.viewport_depth_near_plane).ToFloat32() / 2.0f;
915 915
916 // TODO: Implement scale modifier 916 // TODO: Implement scale modifier
917 uniform_block_data.data.depth_offset = depth_offset; 917 uniform_block_data.data.depth_offset = depth_offset;