Compare commits

...

5 Commits

2 changed files with 40 additions and 7 deletions

View File

@@ -489,8 +489,10 @@ public:
float clear_color[4];
float clear_depth;
INSERT_PADDING_WORDS(0x3);
s32 clear_stencil;
INSERT_PADDING_WORDS(0x93);
INSERT_PADDING_WORDS(0x8F);
struct {
u32 address_high;
@@ -918,6 +920,7 @@ ASSERT_REG_POSITION(viewport, 0x300);
ASSERT_REG_POSITION(vertex_buffer, 0x35D);
ASSERT_REG_POSITION(clear_color[0], 0x360);
ASSERT_REG_POSITION(clear_depth, 0x364);
ASSERT_REG_POSITION(clear_stencil, 0x368);
ASSERT_REG_POSITION(zeta, 0x3F8);
ASSERT_REG_POSITION(vertex_attrib_format[0], 0x458);
ASSERT_REG_POSITION(rt_control, 0x487);

View File

@@ -14,6 +14,7 @@
#include "common/logging/log.h"
#include "common/math_util.h"
#include "common/microprofile.h"
#include "common/scope_exit.h"
#include "core/core.h"
#include "core/frontend/emu_window.h"
#include "core/hle/kernel/process.h"
@@ -363,15 +364,30 @@ std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_c
void RasterizerOpenGL::Clear() {
const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
const auto prev_state{state};
SCOPE_EXIT({
state = prev_state;
state.Apply();
});
bool use_color_fb = false;
bool use_depth_fb = false;
GLbitfield clear_mask = 0;
if (regs.clear_buffers.R && regs.clear_buffers.G && regs.clear_buffers.B &&
state.color_mask.red_enabled = regs.clear_buffers.R ? GL_TRUE : GL_FALSE;
state.color_mask.green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE;
state.color_mask.blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE;
state.color_mask.alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE;
GLbitfield clear_mask{};
if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
regs.clear_buffers.A) {
clear_mask |= GL_COLOR_BUFFER_BIT;
use_color_fb = true;
if (regs.clear_buffers.RT != 0) {
LOG_CRITICAL(HW_GPU, "Clear unimplemented for RT {}", regs.clear_buffers.RT);
UNREACHABLE();
return;
}
}
if (regs.clear_buffers.Z) {
clear_mask |= GL_DEPTH_BUFFER_BIT;
@@ -382,21 +398,35 @@ void RasterizerOpenGL::Clear() {
state.depth.test_enabled = true;
state.depth.write_mask = GL_TRUE;
state.depth.test_func = GL_ALWAYS;
state.Apply();
}
if (regs.clear_buffers.S) {
clear_mask |= GL_STENCIL_BUFFER_BIT;
state.stencil.test_enabled = true;
state.stencil.write_mask = GL_TRUE;
state.stencil.test_func = GL_ALWAYS;
}
if (clear_mask == 0)
if (!use_color_fb && !use_depth_fb) {
// No color surface or depth/stencil enabled
return;
}
if (clear_mask == 0) {
// No clear mask is enabled
return;
}
state.Apply();
ScopeAcquireGLContext acquire_context{emu_window};
auto [dirty_color_surface, dirty_depth_surface] =
ConfigureFramebuffers(use_color_fb, use_depth_fb, false);
// TODO(Subv): Support clearing only partial colors.
glClearColor(regs.clear_color[0], regs.clear_color[1], regs.clear_color[2],
regs.clear_color[3]);
glClearDepth(regs.clear_depth);
glClearStencil(regs.clear_stencil);
glClear(clear_mask);