diff options
| author | 2018-06-06 23:54:25 -0500 | |
|---|---|---|
| committer | 2018-07-03 16:56:44 -0500 | |
| commit | be51120d237cb551fae90fbfaebda41669c40403 (patch) | |
| tree | 37e4ec442f159f6c63ee6db560e4ff23df44bad1 /src | |
| parent | GPU: Added registers for the CLEAR_BUFFERS and CLEAR_COLOR methods. (diff) | |
| download | yuzu-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.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/rasterizer_interface.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 71 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 1 |
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 | ||
| 422 | void 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 | ||
| 300 | void 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 | |||
| 300 | void RasterizerOpenGL::DrawArrays() { | 371 | void 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; |