summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp54
1 files changed, 42 insertions, 12 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 516e1b50f..954ec10ca 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -14,6 +14,7 @@
14#include "common/logging/log.h" 14#include "common/logging/log.h"
15#include "common/math_util.h" 15#include "common/math_util.h"
16#include "common/microprofile.h" 16#include "common/microprofile.h"
17#include "common/scope_exit.h"
17#include "core/core.h" 18#include "core/core.h"
18#include "core/frontend/emu_window.h" 19#include "core/frontend/emu_window.h"
19#include "core/hle/kernel/process.h" 20#include "core/hle/kernel/process.h"
@@ -364,41 +365,70 @@ std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_c
364} 365}
365 366
366void RasterizerOpenGL::Clear() { 367void RasterizerOpenGL::Clear() {
367 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 368 const auto prev_state{state};
369 SCOPE_EXIT({ prev_state.Apply(); });
368 370
371 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
369 bool use_color_fb = false; 372 bool use_color_fb = false;
370 bool use_depth_fb = false; 373 bool use_depth_fb = false;
371 374
372 GLbitfield clear_mask = 0; 375 OpenGLState clear_state;
373 if (regs.clear_buffers.R && regs.clear_buffers.G && regs.clear_buffers.B && 376 clear_state.draw.draw_framebuffer = state.draw.draw_framebuffer;
377 clear_state.color_mask.red_enabled = regs.clear_buffers.R ? GL_TRUE : GL_FALSE;
378 clear_state.color_mask.green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE;
379 clear_state.color_mask.blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE;
380 clear_state.color_mask.alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE;
381
382 GLbitfield clear_mask{};
383 if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
374 regs.clear_buffers.A) { 384 regs.clear_buffers.A) {
375 clear_mask |= GL_COLOR_BUFFER_BIT; 385 if (regs.clear_buffers.RT == 0) {
376 use_color_fb = true; 386 // We only support clearing the first color attachment for now
387 clear_mask |= GL_COLOR_BUFFER_BIT;
388 use_color_fb = true;
389 } else {
390 // TODO(subv): Add support for the other color attachments
391 LOG_CRITICAL(HW_GPU, "Clear unimplemented for RT {}", regs.clear_buffers.RT);
392 }
377 } 393 }
378 if (regs.clear_buffers.Z) { 394 if (regs.clear_buffers.Z) {
395 ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!");
396 use_depth_fb = true;
379 clear_mask |= GL_DEPTH_BUFFER_BIT; 397 clear_mask |= GL_DEPTH_BUFFER_BIT;
380 use_depth_fb = regs.zeta_enable != 0;
381 398
382 // Always enable the depth write when clearing the depth buffer. The depth write mask is 399 // Always enable the depth write when clearing the depth buffer. The depth write mask is
383 // ignored when clearing the buffer in the Switch, but OpenGL obeys it so we set it to true. 400 // ignored when clearing the buffer in the Switch, but OpenGL obeys it so we set it to true.
384 state.depth.test_enabled = true; 401 clear_state.depth.test_enabled = true;
385 state.depth.write_mask = GL_TRUE; 402 clear_state.depth.test_func = GL_ALWAYS;
386 state.depth.test_func = GL_ALWAYS; 403 }
387 state.Apply(); 404 if (regs.clear_buffers.S) {
405 ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear stencil but buffer is not enabled!");
406 use_depth_fb = true;
407 clear_mask |= GL_STENCIL_BUFFER_BIT;
408 clear_state.stencil.test_enabled = true;
388 } 409 }
389 410
390 if (clear_mask == 0) 411 if (!use_color_fb && !use_depth_fb) {
412 // No color surface nor depth/stencil surface are enabled
391 return; 413 return;
414 }
415
416 if (clear_mask == 0) {
417 // No clear mask is enabled
418 return;
419 }
392 420
393 ScopeAcquireGLContext acquire_context{emu_window}; 421 ScopeAcquireGLContext acquire_context{emu_window};
394 422
395 auto [dirty_color_surface, dirty_depth_surface] = 423 auto [dirty_color_surface, dirty_depth_surface] =
396 ConfigureFramebuffers(use_color_fb, use_depth_fb, false); 424 ConfigureFramebuffers(use_color_fb, use_depth_fb, false);
397 425
398 // TODO(Subv): Support clearing only partial colors. 426 clear_state.Apply();
427
399 glClearColor(regs.clear_color[0], regs.clear_color[1], regs.clear_color[2], 428 glClearColor(regs.clear_color[0], regs.clear_color[1], regs.clear_color[2],
400 regs.clear_color[3]); 429 regs.clear_color[3]);
401 glClearDepth(regs.clear_depth); 430 glClearDepth(regs.clear_depth);
431 glClearStencil(regs.clear_stencil);
402 432
403 glClear(clear_mask); 433 glClear(clear_mask);
404 434