summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp12
-rw-r--r--src/video_core/engines/maxwell_3d.h29
-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.h6
5 files changed, 105 insertions, 16 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 9b209a49e..3bca16364 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,13 @@ 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 &&
424 regs.clear_buffers.R == regs.clear_buffers.B &&
425 regs.clear_buffers.R == regs.clear_buffers.A);
426
427 VideoCore::g_renderer->Rasterizer()->Clear();
428}
429
418} // namespace Engines 430} // namespace Engines
419} // namespace Tegra 431} // namespace Tegra
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 12aec3549..988a6433e 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -436,7 +436,12 @@ public:
436 u32 count; 436 u32 count;
437 } vertex_buffer; 437 } vertex_buffer;
438 438
439 INSERT_PADDING_WORDS(0x99); 439 INSERT_PADDING_WORDS(1);
440
441 float clear_color[4];
442 float clear_depth;
443
444 INSERT_PADDING_WORDS(0x93);
440 445
441 struct { 446 struct {
442 u32 address_high; 447 u32 address_high;
@@ -584,7 +589,21 @@ public:
584 589
585 Cull cull; 590 Cull cull;
586 591
587 INSERT_PADDING_WORDS(0x77); 592 INSERT_PADDING_WORDS(0x2B);
593
594 union {
595 u32 raw;
596 BitField<0, 1, u32> Z;
597 BitField<1, 1, u32> S;
598 BitField<2, 1, u32> R;
599 BitField<3, 1, u32> G;
600 BitField<4, 1, u32> B;
601 BitField<5, 1, u32> A;
602 BitField<6, 4, u32> RT;
603 BitField<10, 11, u32> layer;
604 } clear_buffers;
605
606 INSERT_PADDING_WORDS(0x4B);
588 607
589 struct { 608 struct {
590 u32 query_address_high; 609 u32 query_address_high;
@@ -766,6 +785,9 @@ private:
766 /// Handles writes to the macro uploading registers. 785 /// Handles writes to the macro uploading registers.
767 void ProcessMacroUpload(u32 data); 786 void ProcessMacroUpload(u32 data);
768 787
788 /// Handles a write to the CLEAR_BUFFERS register.
789 void ProcessClearBuffers();
790
769 /// Handles a write to the QUERY_GET register. 791 /// Handles a write to the QUERY_GET register.
770 void ProcessQueryGet(); 792 void ProcessQueryGet();
771 793
@@ -788,6 +810,8 @@ ASSERT_REG_POSITION(rt, 0x200);
788ASSERT_REG_POSITION(viewport_transform[0], 0x280); 810ASSERT_REG_POSITION(viewport_transform[0], 0x280);
789ASSERT_REG_POSITION(viewport, 0x300); 811ASSERT_REG_POSITION(viewport, 0x300);
790ASSERT_REG_POSITION(vertex_buffer, 0x35D); 812ASSERT_REG_POSITION(vertex_buffer, 0x35D);
813ASSERT_REG_POSITION(clear_color[0], 0x360);
814ASSERT_REG_POSITION(clear_depth, 0x364);
791ASSERT_REG_POSITION(zeta, 0x3F8); 815ASSERT_REG_POSITION(zeta, 0x3F8);
792ASSERT_REG_POSITION(vertex_attrib_format[0], 0x458); 816ASSERT_REG_POSITION(vertex_attrib_format[0], 0x458);
793ASSERT_REG_POSITION(rt_control, 0x487); 817ASSERT_REG_POSITION(rt_control, 0x487);
@@ -803,6 +827,7 @@ ASSERT_REG_POSITION(code_address, 0x582);
803ASSERT_REG_POSITION(draw, 0x585); 827ASSERT_REG_POSITION(draw, 0x585);
804ASSERT_REG_POSITION(index_array, 0x5F2); 828ASSERT_REG_POSITION(index_array, 0x5F2);
805ASSERT_REG_POSITION(cull, 0x646); 829ASSERT_REG_POSITION(cull, 0x646);
830ASSERT_REG_POSITION(clear_buffers, 0x674);
806ASSERT_REG_POSITION(query, 0x6C0); 831ASSERT_REG_POSITION(query, 0x6C0);
807ASSERT_REG_POSITION(vertex_array[0], 0x700); 832ASSERT_REG_POSITION(vertex_array[0], 0x700);
808ASSERT_REG_POSITION(independent_blend, 0x780); 833ASSERT_REG_POSITION(independent_blend, 0x780);
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 c7b7a5817..43dbf4da9 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -297,11 +297,7 @@ bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) {
297 return true; 297 return true;
298} 298}
299 299
300void RasterizerOpenGL::DrawArrays() { 300std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers() {
301 if (accelerate_draw == AccelDraw::Disabled)
302 return;
303
304 MICROPROFILE_SCOPE(OpenGL_Drawing);
305 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; 301 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
306 302
307 // Sync the depth test state before configuring the framebuffer surfaces. 303 // Sync the depth test state before configuring the framebuffer surfaces.
@@ -344,11 +340,6 @@ void RasterizerOpenGL::DrawArrays() {
344 BindFramebufferSurfaces(color_surface, depth_surface, has_stencil); 340 BindFramebufferSurfaces(color_surface, depth_surface, has_stencil);
345 341
346 SyncViewport(surfaces_rect); 342 SyncViewport(surfaces_rect);
347 SyncBlendState();
348 SyncCullMode();
349
350 // TODO(bunnei): Sync framebuffer_scale uniform here
351 // TODO(bunnei): Sync scissorbox uniform(s) here
352 343
353 // Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect. Enable 344 // Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect. Enable
354 // scissor test to prevent drawing outside of the framebuffer region 345 // scissor test to prevent drawing outside of the framebuffer region
@@ -359,6 +350,58 @@ void RasterizerOpenGL::DrawArrays() {
359 state.scissor.height = draw_rect.GetHeight(); 350 state.scissor.height = draw_rect.GetHeight();
360 state.Apply(); 351 state.Apply();
361 352
353 // Only return the surface to be marked as dirty if writing to it is enabled.
354 return std::make_pair(write_color_fb ? color_surface : nullptr,
355 write_depth_fb ? depth_surface : nullptr);
356}
357
358void RasterizerOpenGL::Clear() {
359 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
360
361 GLbitfield clear_mask = 0;
362 if (regs.clear_buffers.R && regs.clear_buffers.G && regs.clear_buffers.B &&
363 regs.clear_buffers.A) {
364 clear_mask |= GL_COLOR_BUFFER_BIT;
365 }
366 if (regs.clear_buffers.Z)
367 clear_mask |= GL_DEPTH_BUFFER_BIT;
368
369 if (clear_mask == 0)
370 return;
371
372 auto [dirty_color_surface, dirty_depth_surface] = ConfigureFramebuffers();
373
374 // TODO(Subv): Support clearing only partial colors.
375 glClearColor(regs.clear_color[0], regs.clear_color[1], regs.clear_color[2],
376 regs.clear_color[3]);
377 glClearDepth(regs.clear_depth);
378
379 glClear(clear_mask);
380
381 // Mark framebuffer surfaces as dirty
382 if (dirty_color_surface != nullptr) {
383 res_cache.MarkSurfaceAsDirty(dirty_color_surface);
384 }
385 if (dirty_depth_surface != nullptr) {
386 res_cache.MarkSurfaceAsDirty(dirty_depth_surface);
387 }
388}
389
390void RasterizerOpenGL::DrawArrays() {
391 if (accelerate_draw == AccelDraw::Disabled)
392 return;
393
394 MICROPROFILE_SCOPE(OpenGL_Drawing);
395 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
396
397 auto [dirty_color_surface, dirty_depth_surface] = ConfigureFramebuffers();
398
399 SyncBlendState();
400 SyncCullMode();
401
402 // TODO(bunnei): Sync framebuffer_scale uniform here
403 // TODO(bunnei): Sync scissorbox uniform(s) here
404
362 // Draw the vertex batch 405 // Draw the vertex batch
363 const bool is_indexed = accelerate_draw == AccelDraw::Indexed; 406 const bool is_indexed = accelerate_draw == AccelDraw::Indexed;
364 const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()}; 407 const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()};
@@ -439,11 +482,11 @@ void RasterizerOpenGL::DrawArrays() {
439 state.Apply(); 482 state.Apply();
440 483
441 // Mark framebuffer surfaces as dirty 484 // Mark framebuffer surfaces as dirty
442 if (color_surface != nullptr && write_color_fb) { 485 if (dirty_color_surface != nullptr) {
443 res_cache.MarkSurfaceAsDirty(color_surface); 486 res_cache.MarkSurfaceAsDirty(dirty_color_surface);
444 } 487 }
445 if (depth_surface != nullptr && write_depth_fb) { 488 if (dirty_depth_surface != nullptr) {
446 res_cache.MarkSurfaceAsDirty(depth_surface); 489 res_cache.MarkSurfaceAsDirty(dirty_depth_surface);
447 } 490 }
448} 491}
449 492
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 493aa39e5..7738f40b1 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -7,6 +7,7 @@
7#include <array> 7#include <array>
8#include <cstddef> 8#include <cstddef>
9#include <memory> 9#include <memory>
10#include <utility>
10#include <vector> 11#include <vector>
11#include <glad/glad.h> 12#include <glad/glad.h>
12#include "common/common_types.h" 13#include "common/common_types.h"
@@ -28,6 +29,7 @@ public:
28 ~RasterizerOpenGL() override; 29 ~RasterizerOpenGL() override;
29 30
30 void DrawArrays() override; 31 void DrawArrays() override;
32 void Clear() override;
31 void NotifyMaxwellRegisterChanged(u32 method) override; 33 void NotifyMaxwellRegisterChanged(u32 method) override;
32 void FlushAll() override; 34 void FlushAll() override;
33 void FlushRegion(Tegra::GPUVAddr addr, u64 size) override; 35 void FlushRegion(Tegra::GPUVAddr addr, u64 size) override;
@@ -81,6 +83,10 @@ private:
81 u32 border_color_a; 83 u32 border_color_a;
82 }; 84 };
83 85
86 /// Configures the color and depth framebuffer states and returns the dirty <Color, Depth>
87 /// surfaces if writing was enabled.
88 std::pair<Surface, Surface> ConfigureFramebuffers();
89
84 /// Binds the framebuffer color and depth surface 90 /// Binds the framebuffer color and depth surface
85 void BindFramebufferSurfaces(const Surface& color_surface, const Surface& depth_surface, 91 void BindFramebufferSurfaces(const Surface& color_surface, const Surface& depth_surface,
86 bool has_stencil); 92 bool has_stencil);