summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/pica.h12
-rw-r--r--src/video_core/rasterizer.cpp8
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp61
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h9
4 files changed, 78 insertions, 12 deletions
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index 16f9e4006..4552ff81c 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -578,7 +578,17 @@ struct Regs {
578 } 578 }
579 579
580 struct { 580 struct {
581 INSERT_PADDING_WORDS(0x6); 581 INSERT_PADDING_WORDS(0x3);
582
583 union {
584 BitField<0, 4, u32> allow_color_write; // 0 = disable, else enable
585 };
586
587 INSERT_PADDING_WORDS(0x1);
588
589 union {
590 BitField<0, 2, u32> allow_depth_stencil_write; // 0 = disable, else enable
591 };
582 592
583 DepthFormat depth_format; // TODO: Should be a BitField! 593 DepthFormat depth_format; // TODO: Should be a BitField!
584 BitField<16, 3, ColorFormat> color_format; 594 BitField<16, 3, ColorFormat> color_format;
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp
index fd02aa652..5b9ed7c64 100644
--- a/src/video_core/rasterizer.cpp
+++ b/src/video_core/rasterizer.cpp
@@ -809,7 +809,8 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0,
809 809
810 auto UpdateStencil = [stencil_test, x, y, &old_stencil](Pica::Regs::StencilAction action) { 810 auto UpdateStencil = [stencil_test, x, y, &old_stencil](Pica::Regs::StencilAction action) {
811 u8 new_stencil = PerformStencilAction(action, old_stencil, stencil_test.reference_value); 811 u8 new_stencil = PerformStencilAction(action, old_stencil, stencil_test.reference_value);
812 SetStencil(x >> 4, y >> 4, (new_stencil & stencil_test.write_mask) | (old_stencil & ~stencil_test.write_mask)); 812 if (g_state.regs.framebuffer.allow_depth_stencil_write != 0)
813 SetStencil(x >> 4, y >> 4, (new_stencil & stencil_test.write_mask) | (old_stencil & ~stencil_test.write_mask));
813 }; 814 };
814 815
815 if (stencil_action_enable) { 816 if (stencil_action_enable) {
@@ -909,7 +910,7 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0,
909 } 910 }
910 } 911 }
911 912
912 if (output_merger.depth_write_enable) 913 if (regs.framebuffer.allow_depth_stencil_write != 0 && output_merger.depth_write_enable)
913 SetDepth(x >> 4, y >> 4, z); 914 SetDepth(x >> 4, y >> 4, z);
914 915
915 // The stencil depth_pass action is executed even if depth testing is disabled 916 // The stencil depth_pass action is executed even if depth testing is disabled
@@ -1133,7 +1134,8 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0,
1133 output_merger.alpha_enable ? blend_output.a() : dest.a() 1134 output_merger.alpha_enable ? blend_output.a() : dest.a()
1134 }; 1135 };
1135 1136
1136 DrawPixel(x >> 4, y >> 4, result); 1137 if (regs.framebuffer.allow_color_write != 0)
1138 DrawPixel(x >> 4, y >> 4, result);
1137 } 1139 }
1138 } 1140 }
1139} 1141}
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 4fdf93a3e..6ca9f45e2 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -153,6 +153,9 @@ void RasterizerOpenGL::Reset() {
153 SyncLogicOp(); 153 SyncLogicOp();
154 SyncStencilTest(); 154 SyncStencilTest();
155 SyncDepthTest(); 155 SyncDepthTest();
156 SyncColorWriteMask();
157 SyncStencilWriteMask();
158 SyncDepthWriteMask();
156 159
157 SetShader(); 160 SetShader();
158 161
@@ -268,15 +271,36 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
268 state.draw.shader_dirty = true; 271 state.draw.shader_dirty = true;
269 break; 272 break;
270 273
271 // Stencil test 274 // Sync GL stencil test + stencil write mask
275 // (Pica stencil test function register also contains a stencil write mask)
272 case PICA_REG_INDEX(output_merger.stencil_test.raw_func): 276 case PICA_REG_INDEX(output_merger.stencil_test.raw_func):
277 SyncStencilTest();
278 SyncStencilWriteMask();
279 break;
273 case PICA_REG_INDEX(output_merger.stencil_test.raw_op): 280 case PICA_REG_INDEX(output_merger.stencil_test.raw_op):
281 case PICA_REG_INDEX(framebuffer.depth_format):
274 SyncStencilTest(); 282 SyncStencilTest();
275 break; 283 break;
276 284
277 // Depth test 285 // Sync GL depth test + depth and color write mask
286 // (Pica depth test function register also contains a depth and color write mask)
278 case PICA_REG_INDEX(output_merger.depth_test_enable): 287 case PICA_REG_INDEX(output_merger.depth_test_enable):
279 SyncDepthTest(); 288 SyncDepthTest();
289 SyncDepthWriteMask();
290 SyncColorWriteMask();
291 break;
292
293 // Sync GL depth and stencil write mask
294 // (This is a dedicated combined depth / stencil write-enable register)
295 case PICA_REG_INDEX(framebuffer.allow_depth_stencil_write):
296 SyncDepthWriteMask();
297 SyncStencilWriteMask();
298 break;
299
300 // Sync GL color write mask
301 // (This is a dedicated color write-enable register)
302 case PICA_REG_INDEX(framebuffer.allow_color_write):
303 SyncColorWriteMask();
280 break; 304 break;
281 305
282 // Logic op 306 // Logic op
@@ -880,13 +904,39 @@ void RasterizerOpenGL::SyncLogicOp() {
880 state.logic_op = PicaToGL::LogicOp(Pica::g_state.regs.output_merger.logic_op); 904 state.logic_op = PicaToGL::LogicOp(Pica::g_state.regs.output_merger.logic_op);
881} 905}
882 906
907void RasterizerOpenGL::SyncColorWriteMask() {
908 const auto& regs = Pica::g_state.regs;
909
910 auto IsColorWriteEnabled = [&](u32 value) {
911 return (regs.framebuffer.allow_color_write != 0 && value != 0) ? GL_TRUE : GL_FALSE;
912 };
913
914 state.color_mask.red_enabled = IsColorWriteEnabled(regs.output_merger.red_enable);
915 state.color_mask.green_enabled = IsColorWriteEnabled(regs.output_merger.green_enable);
916 state.color_mask.blue_enabled = IsColorWriteEnabled(regs.output_merger.blue_enable);
917 state.color_mask.alpha_enabled = IsColorWriteEnabled(regs.output_merger.alpha_enable);
918}
919
920void RasterizerOpenGL::SyncStencilWriteMask() {
921 const auto& regs = Pica::g_state.regs;
922 state.stencil.write_mask = (regs.framebuffer.allow_depth_stencil_write != 0)
923 ? static_cast<GLuint>(regs.output_merger.stencil_test.write_mask)
924 : 0;
925}
926
927void RasterizerOpenGL::SyncDepthWriteMask() {
928 const auto& regs = Pica::g_state.regs;
929 state.depth.write_mask = (regs.framebuffer.allow_depth_stencil_write != 0 && regs.output_merger.depth_write_enable)
930 ? GL_TRUE
931 : GL_FALSE;
932}
933
883void RasterizerOpenGL::SyncStencilTest() { 934void RasterizerOpenGL::SyncStencilTest() {
884 const auto& regs = Pica::g_state.regs; 935 const auto& regs = Pica::g_state.regs;
885 state.stencil.test_enabled = regs.output_merger.stencil_test.enable && regs.framebuffer.depth_format == Pica::Regs::DepthFormat::D24S8; 936 state.stencil.test_enabled = regs.output_merger.stencil_test.enable && regs.framebuffer.depth_format == Pica::Regs::DepthFormat::D24S8;
886 state.stencil.test_func = PicaToGL::CompareFunc(regs.output_merger.stencil_test.func); 937 state.stencil.test_func = PicaToGL::CompareFunc(regs.output_merger.stencil_test.func);
887 state.stencil.test_ref = regs.output_merger.stencil_test.reference_value; 938 state.stencil.test_ref = regs.output_merger.stencil_test.reference_value;
888 state.stencil.test_mask = regs.output_merger.stencil_test.input_mask; 939 state.stencil.test_mask = regs.output_merger.stencil_test.input_mask;
889 state.stencil.write_mask = regs.output_merger.stencil_test.write_mask;
890 state.stencil.action_stencil_fail = PicaToGL::StencilOp(regs.output_merger.stencil_test.action_stencil_fail); 940 state.stencil.action_stencil_fail = PicaToGL::StencilOp(regs.output_merger.stencil_test.action_stencil_fail);
891 state.stencil.action_depth_fail = PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_fail); 941 state.stencil.action_depth_fail = PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_fail);
892 state.stencil.action_depth_pass = PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_pass); 942 state.stencil.action_depth_pass = PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_pass);
@@ -898,11 +948,6 @@ void RasterizerOpenGL::SyncDepthTest() {
898 regs.output_merger.depth_write_enable == 1; 948 regs.output_merger.depth_write_enable == 1;
899 state.depth.test_func = regs.output_merger.depth_test_enable == 1 ? 949 state.depth.test_func = regs.output_merger.depth_test_enable == 1 ?
900 PicaToGL::CompareFunc(regs.output_merger.depth_test_func) : GL_ALWAYS; 950 PicaToGL::CompareFunc(regs.output_merger.depth_test_func) : GL_ALWAYS;
901 state.color_mask.red_enabled = regs.output_merger.red_enable;
902 state.color_mask.green_enabled = regs.output_merger.green_enable;
903 state.color_mask.blue_enabled = regs.output_merger.blue_enable;
904 state.color_mask.alpha_enabled = regs.output_merger.alpha_enable;
905 state.depth.write_mask = regs.output_merger.depth_write_enable ? GL_TRUE : GL_FALSE;
906} 951}
907 952
908void RasterizerOpenGL::SyncCombinerColor() { 953void RasterizerOpenGL::SyncCombinerColor() {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index fc85aa3ff..390349a0c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -344,6 +344,15 @@ private:
344 /// Syncs the logic op states to match the PICA register 344 /// Syncs the logic op states to match the PICA register
345 void SyncLogicOp(); 345 void SyncLogicOp();
346 346
347 /// Syncs the color write mask to match the PICA register state
348 void SyncColorWriteMask();
349
350 /// Syncs the stencil write mask to match the PICA register state
351 void SyncStencilWriteMask();
352
353 /// Syncs the depth write mask to match the PICA register state
354 void SyncDepthWriteMask();
355
347 /// Syncs the stencil test states to match the PICA register 356 /// Syncs the stencil test states to match the PICA register
348 void SyncStencilTest(); 357 void SyncStencilTest();
349 358