diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/pica.h | 12 | ||||
| -rw-r--r-- | src/video_core/rasterizer.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 61 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 9 |
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 | ||
| 907 | void 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 | |||
| 920 | void 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 | |||
| 927 | void 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 | |||
| 883 | void RasterizerOpenGL::SyncStencilTest() { | 934 | void 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 | ||
| 908 | void RasterizerOpenGL::SyncCombinerColor() { | 953 | void 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 | ||