summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/citra_qt/main.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp42
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp9
4 files changed, 28 insertions, 31 deletions
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index 82667446b..0c7bedfcf 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -286,7 +286,6 @@ bool GMainWindow::LoadROM(const std::string& filename) {
286 Loader::ResultStatus result = app_loader->Load(); 286 Loader::ResultStatus result = app_loader->Load();
287 if (Loader::ResultStatus::Success != result) { 287 if (Loader::ResultStatus::Success != result) {
288 LOG_CRITICAL(Frontend, "Failed to load ROM!"); 288 LOG_CRITICAL(Frontend, "Failed to load ROM!");
289 System::Shutdown();
290 289
291 switch (result) { 290 switch (result) {
292 case Loader::ResultStatus::ErrorEncrypted: { 291 case Loader::ResultStatus::ErrorEncrypted: {
@@ -326,8 +325,10 @@ void GMainWindow::BootGame(const std::string& filename) {
326 if (!InitializeSystem()) 325 if (!InitializeSystem())
327 return; 326 return;
328 327
329 if (!LoadROM(filename)) 328 if (!LoadROM(filename)) {
329 System::Shutdown();
330 return; 330 return;
331 }
331 332
332 // Create and start the emulation thread 333 // Create and start the emulation thread
333 emu_thread = std::make_unique<EmuThread>(render_window); 334 emu_thread = std::make_unique<EmuThread>(render_window);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index e7ad85bf3..7cc3b407a 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
1239void 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
1255void RasterizerOpenGL::SyncCombinerColor() { 1255void 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 d9b027305..e1a9cb361 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -394,9 +394,6 @@ private:
394 /// Syncs the depth test states to match the PICA register 394 /// Syncs the depth test states to match the PICA register
395 void SyncDepthTest(); 395 void SyncDepthTest();
396 396
397 /// Syncs the scissor test state to match the PICA register
398 void SyncScissorTest();
399
400 /// Syncs the TEV combiner color buffer to match the PICA register 397 /// Syncs the TEV combiner color buffer to match the PICA register
401 void SyncCombinerColor(); 398 void SyncCombinerColor();
402 399
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";