diff options
| author | 2016-09-29 21:08:32 -0700 | |
|---|---|---|
| committer | 2016-09-29 21:08:32 -0700 | |
| commit | 4b14e17b18e20f7f8077f0c7efc0e3a44ca8ca2a (patch) | |
| tree | f8a9a0ec07221758b50b952ba58ab0ea28b459a2 /src | |
| parent | Merge pull request #2100 from wwylele/fix-load-assert (diff) | |
| parent | OpenGL: Take cached viewport sub-rect into account for scissor (diff) | |
| download | yuzu-4b14e17b18e20f7f8077f0c7efc0e3a44ca8ca2a.tar.gz yuzu-4b14e17b18e20f7f8077f0c7efc0e3a44ca8ca2a.tar.xz yuzu-4b14e17b18e20f7f8077f0c7efc0e3a44ca8ca2a.zip | |
Merge pull request #2083 from yuriks/opengl-scissor-cached-rect
OpenGL: Take cached viewport sub-rect into account for scissor
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 42 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 9 |
3 files changed, 25 insertions, 29 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 60c9d9180..62c9af28c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -211,6 +211,27 @@ void RasterizerOpenGL::DrawTriangles() { | |||
| 211 | uniform_block_data.dirty = true; | 211 | uniform_block_data.dirty = true; |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | // Scissor checks are window-, not viewport-relative, which means that if the cached texture | ||
| 215 | // sub-rect changes, the scissor bounds also need to be updated. | ||
| 216 | GLint scissor_x1 = rect.left + regs.scissor_test.x1 * color_surface->res_scale_width; | ||
| 217 | GLint scissor_y1 = rect.bottom + regs.scissor_test.y1 * color_surface->res_scale_height; | ||
| 218 | // x2, y2 have +1 added to cover the entire pixel area, otherwise you might get cracks when | ||
| 219 | // scaling or doing multisampling. | ||
| 220 | GLint scissor_x2 = rect.left + (regs.scissor_test.x2 + 1) * color_surface->res_scale_width; | ||
| 221 | GLint scissor_y2 = rect.bottom + (regs.scissor_test.y2 + 1) * color_surface->res_scale_height; | ||
| 222 | |||
| 223 | if (uniform_block_data.data.scissor_x1 != scissor_x1 || | ||
| 224 | uniform_block_data.data.scissor_x2 != scissor_x2 || | ||
| 225 | uniform_block_data.data.scissor_y1 != scissor_y1 || | ||
| 226 | uniform_block_data.data.scissor_y2 != scissor_y2) { | ||
| 227 | |||
| 228 | uniform_block_data.data.scissor_x1 = scissor_x1; | ||
| 229 | uniform_block_data.data.scissor_x2 = scissor_x2; | ||
| 230 | uniform_block_data.data.scissor_y1 = scissor_y1; | ||
| 231 | uniform_block_data.data.scissor_y2 = scissor_y2; | ||
| 232 | uniform_block_data.dirty = true; | ||
| 233 | } | ||
| 234 | |||
| 214 | // Sync and bind the texture surfaces | 235 | // Sync and bind the texture surfaces |
| 215 | const auto pica_textures = regs.GetTextures(); | 236 | const auto pica_textures = regs.GetTextures(); |
| 216 | for (unsigned texture_index = 0; texture_index < pica_textures.size(); ++texture_index) { | 237 | for (unsigned texture_index = 0; texture_index < pica_textures.size(); ++texture_index) { |
| @@ -374,10 +395,6 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { | |||
| 374 | case PICA_REG_INDEX(scissor_test.mode): | 395 | case PICA_REG_INDEX(scissor_test.mode): |
| 375 | shader_dirty = true; | 396 | shader_dirty = true; |
| 376 | break; | 397 | break; |
| 377 | case PICA_REG_INDEX(scissor_test.x1): // and y1 | ||
| 378 | case PICA_REG_INDEX(scissor_test.x2): // and y2 | ||
| 379 | SyncScissorTest(); | ||
| 380 | break; | ||
| 381 | 398 | ||
| 382 | // Logic op | 399 | // Logic op |
| 383 | case PICA_REG_INDEX(output_merger.logic_op): | 400 | case PICA_REG_INDEX(output_merger.logic_op): |
| @@ -1061,7 +1078,6 @@ void RasterizerOpenGL::SetShader() { | |||
| 1061 | SyncDepthOffset(); | 1078 | SyncDepthOffset(); |
| 1062 | SyncAlphaTest(); | 1079 | SyncAlphaTest(); |
| 1063 | SyncCombinerColor(); | 1080 | SyncCombinerColor(); |
| 1064 | SyncScissorTest(); | ||
| 1065 | auto& tev_stages = Pica::g_state.regs.GetTevStages(); | 1081 | auto& tev_stages = Pica::g_state.regs.GetTevStages(); |
| 1066 | for (int index = 0; index < tev_stages.size(); ++index) | 1082 | for (int index = 0; index < tev_stages.size(); ++index) |
| 1067 | SyncTevConstColor(index, tev_stages[index]); | 1083 | SyncTevConstColor(index, tev_stages[index]); |
| @@ -1236,22 +1252,6 @@ void RasterizerOpenGL::SyncDepthTest() { | |||
| 1236 | : GL_ALWAYS; | 1252 | : GL_ALWAYS; |
| 1237 | } | 1253 | } |
| 1238 | 1254 | ||
| 1239 | void RasterizerOpenGL::SyncScissorTest() { | ||
| 1240 | const auto& regs = Pica::g_state.regs; | ||
| 1241 | |||
| 1242 | if (uniform_block_data.data.scissor_x1 != regs.scissor_test.x1 || | ||
| 1243 | uniform_block_data.data.scissor_y1 != regs.scissor_test.y1 || | ||
| 1244 | uniform_block_data.data.scissor_x2 != regs.scissor_test.x2 || | ||
| 1245 | uniform_block_data.data.scissor_y2 != regs.scissor_test.y2) { | ||
| 1246 | |||
| 1247 | uniform_block_data.data.scissor_x1 = regs.scissor_test.x1; | ||
| 1248 | uniform_block_data.data.scissor_y1 = regs.scissor_test.y1; | ||
| 1249 | uniform_block_data.data.scissor_x2 = regs.scissor_test.x2; | ||
| 1250 | uniform_block_data.data.scissor_y2 = regs.scissor_test.y2; | ||
| 1251 | uniform_block_data.dirty = true; | ||
| 1252 | } | ||
| 1253 | } | ||
| 1254 | |||
| 1255 | void RasterizerOpenGL::SyncCombinerColor() { | 1255 | void RasterizerOpenGL::SyncCombinerColor() { |
| 1256 | auto combiner_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.tev_combiner_buffer_color.raw); | 1256 | auto combiner_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.tev_combiner_buffer_color.raw); |
| 1257 | if (combiner_color != uniform_block_data.data.tev_combiner_buffer_color) { | 1257 | if (combiner_color != uniform_block_data.data.tev_combiner_buffer_color) { |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 24fefed1b..7b4ce2ac5 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -393,9 +393,6 @@ private: | |||
| 393 | /// Syncs the depth test states to match the PICA register | 393 | /// Syncs the depth test states to match the PICA register |
| 394 | void SyncDepthTest(); | 394 | void SyncDepthTest(); |
| 395 | 395 | ||
| 396 | /// Syncs the scissor test state to match the PICA register | ||
| 397 | void SyncScissorTest(); | ||
| 398 | |||
| 399 | /// Syncs the TEV combiner color buffer to match the PICA register | 396 | /// Syncs the TEV combiner color buffer to match the PICA register |
| 400 | void SyncCombinerColor(); | 397 | void SyncCombinerColor(); |
| 401 | 398 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 1808ee0a9..8f278722d 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp | |||
| @@ -645,11 +645,10 @@ vec4 secondary_fragment_color = vec4(0.0); | |||
| 645 | // Negate the condition if we have to keep only the pixels outside the scissor box | 645 | // Negate the condition if we have to keep only the pixels outside the scissor box |
| 646 | if (state.scissor_test_mode == Regs::ScissorMode::Include) | 646 | if (state.scissor_test_mode == Regs::ScissorMode::Include) |
| 647 | out += "!"; | 647 | out += "!"; |
| 648 | // x2,y2 have +1 added to cover the entire pixel area | 648 | out += "(gl_FragCoord.x >= scissor_x1 && " |
| 649 | out += "(gl_FragCoord.x >= scissor_x1 * framebuffer_scale.x && " | 649 | "gl_FragCoord.y >= scissor_y1 && " |
| 650 | "gl_FragCoord.y >= scissor_y1 * framebuffer_scale.y && " | 650 | "gl_FragCoord.x < scissor_x2 && " |
| 651 | "gl_FragCoord.x < (scissor_x2 + 1) * framebuffer_scale.x && " | 651 | "gl_FragCoord.y < scissor_y2)) discard;\n"; |
| 652 | "gl_FragCoord.y < (scissor_y2 + 1) * framebuffer_scale.y)) discard;\n"; | ||
| 653 | } | 652 | } |
| 654 | 653 | ||
| 655 | out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n"; | 654 | out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n"; |