summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2018-06-06 23:54:25 -0500
committerGravatar Subv2018-07-03 16:56:44 -0500
commitbe51120d237cb551fae90fbfaebda41669c40403 (patch)
tree37e4ec442f159f6c63ee6db560e4ff23df44bad1 /src
parentGPU: Added registers for the CLEAR_BUFFERS and CLEAR_COLOR methods. (diff)
downloadyuzu-be51120d237cb551fae90fbfaebda41669c40403.tar.gz
yuzu-be51120d237cb551fae90fbfaebda41669c40403.tar.xz
yuzu-be51120d237cb551fae90fbfaebda41669c40403.zip
GPU: Bind and clear the render target when the CLEAR_BUFFERS register is written to.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp11
-rw-r--r--src/video_core/rasterizer_interface.h3
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp71
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h1
4 files changed, 86 insertions, 0 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 93c43c8cb..78f1c0ea7 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -126,6 +126,10 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
126 DrawArrays(); 126 DrawArrays();
127 break; 127 break;
128 } 128 }
129 case MAXWELL3D_REG_INDEX(clear_buffers): {
130 ProcessClearBuffers();
131 break;
132 }
129 case MAXWELL3D_REG_INDEX(query.query_get): { 133 case MAXWELL3D_REG_INDEX(query.query_get): {
130 ProcessQueryGet(); 134 ProcessQueryGet();
131 break; 135 break;
@@ -415,5 +419,12 @@ bool Maxwell3D::IsShaderStageEnabled(Regs::ShaderStage stage) const {
415 UNREACHABLE(); 419 UNREACHABLE();
416} 420}
417 421
422void Maxwell3D::ProcessClearBuffers() {
423 ASSERT(regs.clear_buffers.R && regs.clear_buffers.G && regs.clear_buffers.B &&
424 regs.clear_buffers.A);
425
426 VideoCore::g_renderer->Rasterizer()->Clear();
427}
428
418} // namespace Engines 429} // namespace Engines
419} // namespace Tegra 430} // namespace Tegra
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index 145e58334..499e84b89 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -19,6 +19,9 @@ public:
19 /// Draw the current batch of vertex arrays 19 /// Draw the current batch of vertex arrays
20 virtual void DrawArrays() = 0; 20 virtual void DrawArrays() = 0;
21 21
22 /// Clear the current framebuffer
23 virtual void Clear() = 0;
24
22 /// Notify rasterizer that the specified Maxwell register has been changed 25 /// Notify rasterizer that the specified Maxwell register has been changed
23 virtual void NotifyMaxwellRegisterChanged(u32 method) = 0; 26 virtual void NotifyMaxwellRegisterChanged(u32 method) = 0;
24 27
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index ca3814cfc..8e1171161 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -297,6 +297,77 @@ bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) {
297 return true; 297 return true;
298} 298}
299 299
300void RasterizerOpenGL::Clear() {
301 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
302
303 // TODO(bunnei): Implement these
304 const bool has_stencil = false;
305 const bool using_color_fb = true;
306 const bool using_depth_fb = regs.zeta.Address() != 0;
307 const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()};
308
309 const bool write_color_fb =
310 state.color_mask.red_enabled == GL_TRUE || state.color_mask.green_enabled == GL_TRUE ||
311 state.color_mask.blue_enabled == GL_TRUE || state.color_mask.alpha_enabled == GL_TRUE;
312
313 const bool write_depth_fb =
314 (state.depth.test_enabled && state.depth.write_mask == GL_TRUE) ||
315 (has_stencil && state.stencil.test_enabled && state.stencil.write_mask != 0);
316
317 Surface color_surface;
318 Surface depth_surface;
319 MathUtil::Rectangle<u32> surfaces_rect;
320 std::tie(color_surface, depth_surface, surfaces_rect) =
321 res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb, viewport_rect);
322
323 MathUtil::Rectangle<u32> draw_rect{
324 static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + viewport_rect.left,
325 surfaces_rect.left, surfaces_rect.right)), // Left
326 static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.bottom) + viewport_rect.top,
327 surfaces_rect.bottom, surfaces_rect.top)), // Top
328 static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + viewport_rect.right,
329 surfaces_rect.left, surfaces_rect.right)), // Right
330 static_cast<u32>(
331 std::clamp<s32>(static_cast<s32>(surfaces_rect.bottom) + viewport_rect.bottom,
332 surfaces_rect.bottom, surfaces_rect.top))}; // Bottom
333
334 // Bind the framebuffer surfaces
335 BindFramebufferSurfaces(color_surface, depth_surface, has_stencil);
336
337 // Sync the viewport
338 SyncViewport(surfaces_rect);
339
340 // TODO(bunnei): Sync scissorbox uniform(s) here
341
342 // Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect. Enable
343 // scissor test to prevent drawing outside of the framebuffer region
344 state.scissor.enabled = true;
345 state.scissor.x = draw_rect.left;
346 state.scissor.y = draw_rect.bottom;
347 state.scissor.width = draw_rect.GetWidth();
348 state.scissor.height = draw_rect.GetHeight();
349 state.Apply();
350
351 // TODO(Subv): Support clearing only partial colors.
352 glClearColor(regs.clear_color[0], regs.clear_color[1], regs.clear_color[2],
353 regs.clear_color[3]);
354 glClearDepth(regs.clear_depth);
355
356 GLbitfield clear_mask = GL_COLOR_BUFFER_BIT;
357 if (regs.clear_buffers.Z)
358 clear_mask |= GL_DEPTH_BUFFER_BIT;
359
360 glClear(clear_mask);
361
362 // Mark framebuffer surfaces as dirty
363 if (color_surface != nullptr && write_color_fb) {
364 res_cache.MarkSurfaceAsDirty(color_surface);
365 }
366 if (depth_surface != nullptr && write_depth_fb) {
367 res_cache.MarkSurfaceAsDirty(depth_surface);
368 }
369}
370
300void RasterizerOpenGL::DrawArrays() { 371void RasterizerOpenGL::DrawArrays() {
301 if (accelerate_draw == AccelDraw::Disabled) 372 if (accelerate_draw == AccelDraw::Disabled)
302 return; 373 return;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 493aa39e5..0b1e139b0 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -28,6 +28,7 @@ public:
28 ~RasterizerOpenGL() override; 28 ~RasterizerOpenGL() override;
29 29
30 void DrawArrays() override; 30 void DrawArrays() override;
31 void Clear() override;
31 void NotifyMaxwellRegisterChanged(u32 method) override; 32 void NotifyMaxwellRegisterChanged(u32 method) override;
32 void FlushAll() override; 33 void FlushAll() override;
33 void FlushRegion(Tegra::GPUVAddr addr, u64 size) override; 34 void FlushRegion(Tegra::GPUVAddr addr, u64 size) override;