mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Merge pull request #609 from Subv/clear_buffers
GPU: Implemented the CLEAR_BUFFERS register.
This commit is contained in:
		
						commit
						c996787d84
					
				@ -126,6 +126,10 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
 | 
				
			|||||||
        DrawArrays();
 | 
					        DrawArrays();
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    case MAXWELL3D_REG_INDEX(clear_buffers): {
 | 
				
			||||||
 | 
					        ProcessClearBuffers();
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    case MAXWELL3D_REG_INDEX(query.query_get): {
 | 
					    case MAXWELL3D_REG_INDEX(query.query_get): {
 | 
				
			||||||
        ProcessQueryGet();
 | 
					        ProcessQueryGet();
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@ -415,5 +419,13 @@ bool Maxwell3D::IsShaderStageEnabled(Regs::ShaderStage stage) const {
 | 
				
			|||||||
    UNREACHABLE();
 | 
					    UNREACHABLE();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Maxwell3D::ProcessClearBuffers() {
 | 
				
			||||||
 | 
					    ASSERT(regs.clear_buffers.R == regs.clear_buffers.G &&
 | 
				
			||||||
 | 
					           regs.clear_buffers.R == regs.clear_buffers.B &&
 | 
				
			||||||
 | 
					           regs.clear_buffers.R == regs.clear_buffers.A);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VideoCore::g_renderer->Rasterizer()->Clear();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Engines
 | 
					} // namespace Engines
 | 
				
			||||||
} // namespace Tegra
 | 
					} // namespace Tegra
 | 
				
			||||||
 | 
				
			|||||||
@ -436,7 +436,12 @@ public:
 | 
				
			|||||||
                    u32 count;
 | 
					                    u32 count;
 | 
				
			||||||
                } vertex_buffer;
 | 
					                } vertex_buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                INSERT_PADDING_WORDS(0x99);
 | 
					                INSERT_PADDING_WORDS(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                float clear_color[4];
 | 
				
			||||||
 | 
					                float clear_depth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                INSERT_PADDING_WORDS(0x93);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                struct {
 | 
					                struct {
 | 
				
			||||||
                    u32 address_high;
 | 
					                    u32 address_high;
 | 
				
			||||||
@ -584,7 +589,21 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                Cull cull;
 | 
					                Cull cull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                INSERT_PADDING_WORDS(0x77);
 | 
					                INSERT_PADDING_WORDS(0x2B);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                union {
 | 
				
			||||||
 | 
					                    u32 raw;
 | 
				
			||||||
 | 
					                    BitField<0, 1, u32> Z;
 | 
				
			||||||
 | 
					                    BitField<1, 1, u32> S;
 | 
				
			||||||
 | 
					                    BitField<2, 1, u32> R;
 | 
				
			||||||
 | 
					                    BitField<3, 1, u32> G;
 | 
				
			||||||
 | 
					                    BitField<4, 1, u32> B;
 | 
				
			||||||
 | 
					                    BitField<5, 1, u32> A;
 | 
				
			||||||
 | 
					                    BitField<6, 4, u32> RT;
 | 
				
			||||||
 | 
					                    BitField<10, 11, u32> layer;
 | 
				
			||||||
 | 
					                } clear_buffers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                INSERT_PADDING_WORDS(0x4B);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                struct {
 | 
					                struct {
 | 
				
			||||||
                    u32 query_address_high;
 | 
					                    u32 query_address_high;
 | 
				
			||||||
@ -766,6 +785,9 @@ private:
 | 
				
			|||||||
    /// Handles writes to the macro uploading registers.
 | 
					    /// Handles writes to the macro uploading registers.
 | 
				
			||||||
    void ProcessMacroUpload(u32 data);
 | 
					    void ProcessMacroUpload(u32 data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Handles a write to the CLEAR_BUFFERS register.
 | 
				
			||||||
 | 
					    void ProcessClearBuffers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Handles a write to the QUERY_GET register.
 | 
					    /// Handles a write to the QUERY_GET register.
 | 
				
			||||||
    void ProcessQueryGet();
 | 
					    void ProcessQueryGet();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -788,6 +810,8 @@ ASSERT_REG_POSITION(rt, 0x200);
 | 
				
			|||||||
ASSERT_REG_POSITION(viewport_transform[0], 0x280);
 | 
					ASSERT_REG_POSITION(viewport_transform[0], 0x280);
 | 
				
			||||||
ASSERT_REG_POSITION(viewport, 0x300);
 | 
					ASSERT_REG_POSITION(viewport, 0x300);
 | 
				
			||||||
ASSERT_REG_POSITION(vertex_buffer, 0x35D);
 | 
					ASSERT_REG_POSITION(vertex_buffer, 0x35D);
 | 
				
			||||||
 | 
					ASSERT_REG_POSITION(clear_color[0], 0x360);
 | 
				
			||||||
 | 
					ASSERT_REG_POSITION(clear_depth, 0x364);
 | 
				
			||||||
ASSERT_REG_POSITION(zeta, 0x3F8);
 | 
					ASSERT_REG_POSITION(zeta, 0x3F8);
 | 
				
			||||||
ASSERT_REG_POSITION(vertex_attrib_format[0], 0x458);
 | 
					ASSERT_REG_POSITION(vertex_attrib_format[0], 0x458);
 | 
				
			||||||
ASSERT_REG_POSITION(rt_control, 0x487);
 | 
					ASSERT_REG_POSITION(rt_control, 0x487);
 | 
				
			||||||
@ -803,6 +827,7 @@ ASSERT_REG_POSITION(code_address, 0x582);
 | 
				
			|||||||
ASSERT_REG_POSITION(draw, 0x585);
 | 
					ASSERT_REG_POSITION(draw, 0x585);
 | 
				
			||||||
ASSERT_REG_POSITION(index_array, 0x5F2);
 | 
					ASSERT_REG_POSITION(index_array, 0x5F2);
 | 
				
			||||||
ASSERT_REG_POSITION(cull, 0x646);
 | 
					ASSERT_REG_POSITION(cull, 0x646);
 | 
				
			||||||
 | 
					ASSERT_REG_POSITION(clear_buffers, 0x674);
 | 
				
			||||||
ASSERT_REG_POSITION(query, 0x6C0);
 | 
					ASSERT_REG_POSITION(query, 0x6C0);
 | 
				
			||||||
ASSERT_REG_POSITION(vertex_array[0], 0x700);
 | 
					ASSERT_REG_POSITION(vertex_array[0], 0x700);
 | 
				
			||||||
ASSERT_REG_POSITION(independent_blend, 0x780);
 | 
					ASSERT_REG_POSITION(independent_blend, 0x780);
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,9 @@ public:
 | 
				
			|||||||
    /// Draw the current batch of vertex arrays
 | 
					    /// Draw the current batch of vertex arrays
 | 
				
			||||||
    virtual void DrawArrays() = 0;
 | 
					    virtual void DrawArrays() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Clear the current framebuffer
 | 
				
			||||||
 | 
					    virtual void Clear() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Notify rasterizer that the specified Maxwell register has been changed
 | 
					    /// Notify rasterizer that the specified Maxwell register has been changed
 | 
				
			||||||
    virtual void NotifyMaxwellRegisterChanged(u32 method) = 0;
 | 
					    virtual void NotifyMaxwellRegisterChanged(u32 method) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -297,11 +297,7 @@ bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) {
 | 
				
			|||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void RasterizerOpenGL::DrawArrays() {
 | 
					std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers() {
 | 
				
			||||||
    if (accelerate_draw == AccelDraw::Disabled)
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    MICROPROFILE_SCOPE(OpenGL_Drawing);
 | 
					 | 
				
			||||||
    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
 | 
					    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Sync the depth test state before configuring the framebuffer surfaces.
 | 
					    // Sync the depth test state before configuring the framebuffer surfaces.
 | 
				
			||||||
@ -344,11 +340,6 @@ void RasterizerOpenGL::DrawArrays() {
 | 
				
			|||||||
    BindFramebufferSurfaces(color_surface, depth_surface, has_stencil);
 | 
					    BindFramebufferSurfaces(color_surface, depth_surface, has_stencil);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SyncViewport(surfaces_rect);
 | 
					    SyncViewport(surfaces_rect);
 | 
				
			||||||
    SyncBlendState();
 | 
					 | 
				
			||||||
    SyncCullMode();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // TODO(bunnei): Sync framebuffer_scale uniform here
 | 
					 | 
				
			||||||
    // TODO(bunnei): Sync scissorbox uniform(s) here
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect. Enable
 | 
					    // Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect. Enable
 | 
				
			||||||
    // scissor test to prevent drawing outside of the framebuffer region
 | 
					    // scissor test to prevent drawing outside of the framebuffer region
 | 
				
			||||||
@ -359,6 +350,58 @@ void RasterizerOpenGL::DrawArrays() {
 | 
				
			|||||||
    state.scissor.height = draw_rect.GetHeight();
 | 
					    state.scissor.height = draw_rect.GetHeight();
 | 
				
			||||||
    state.Apply();
 | 
					    state.Apply();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Only return the surface to be marked as dirty if writing to it is enabled.
 | 
				
			||||||
 | 
					    return std::make_pair(write_color_fb ? color_surface : nullptr,
 | 
				
			||||||
 | 
					                          write_depth_fb ? depth_surface : nullptr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RasterizerOpenGL::Clear() {
 | 
				
			||||||
 | 
					    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GLbitfield clear_mask = 0;
 | 
				
			||||||
 | 
					    if (regs.clear_buffers.R && regs.clear_buffers.G && regs.clear_buffers.B &&
 | 
				
			||||||
 | 
					        regs.clear_buffers.A) {
 | 
				
			||||||
 | 
					        clear_mask |= GL_COLOR_BUFFER_BIT;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (regs.clear_buffers.Z)
 | 
				
			||||||
 | 
					        clear_mask |= GL_DEPTH_BUFFER_BIT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (clear_mask == 0)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto [dirty_color_surface, dirty_depth_surface] = ConfigureFramebuffers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    glClear(clear_mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Mark framebuffer surfaces as dirty
 | 
				
			||||||
 | 
					    if (dirty_color_surface != nullptr) {
 | 
				
			||||||
 | 
					        res_cache.MarkSurfaceAsDirty(dirty_color_surface);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (dirty_depth_surface != nullptr) {
 | 
				
			||||||
 | 
					        res_cache.MarkSurfaceAsDirty(dirty_depth_surface);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RasterizerOpenGL::DrawArrays() {
 | 
				
			||||||
 | 
					    if (accelerate_draw == AccelDraw::Disabled)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MICROPROFILE_SCOPE(OpenGL_Drawing);
 | 
				
			||||||
 | 
					    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto [dirty_color_surface, dirty_depth_surface] = ConfigureFramebuffers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SyncBlendState();
 | 
				
			||||||
 | 
					    SyncCullMode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO(bunnei): Sync framebuffer_scale uniform here
 | 
				
			||||||
 | 
					    // TODO(bunnei): Sync scissorbox uniform(s) here
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Draw the vertex batch
 | 
					    // Draw the vertex batch
 | 
				
			||||||
    const bool is_indexed = accelerate_draw == AccelDraw::Indexed;
 | 
					    const bool is_indexed = accelerate_draw == AccelDraw::Indexed;
 | 
				
			||||||
    const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()};
 | 
					    const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()};
 | 
				
			||||||
@ -439,11 +482,11 @@ void RasterizerOpenGL::DrawArrays() {
 | 
				
			|||||||
    state.Apply();
 | 
					    state.Apply();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Mark framebuffer surfaces as dirty
 | 
					    // Mark framebuffer surfaces as dirty
 | 
				
			||||||
    if (color_surface != nullptr && write_color_fb) {
 | 
					    if (dirty_color_surface != nullptr) {
 | 
				
			||||||
        res_cache.MarkSurfaceAsDirty(color_surface);
 | 
					        res_cache.MarkSurfaceAsDirty(dirty_color_surface);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (depth_surface != nullptr && write_depth_fb) {
 | 
					    if (dirty_depth_surface != nullptr) {
 | 
				
			||||||
        res_cache.MarkSurfaceAsDirty(depth_surface);
 | 
					        res_cache.MarkSurfaceAsDirty(dirty_depth_surface);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,7 @@
 | 
				
			|||||||
#include <array>
 | 
					#include <array>
 | 
				
			||||||
#include <cstddef>
 | 
					#include <cstddef>
 | 
				
			||||||
#include <memory>
 | 
					#include <memory>
 | 
				
			||||||
 | 
					#include <utility>
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
#include <glad/glad.h>
 | 
					#include <glad/glad.h>
 | 
				
			||||||
#include "common/common_types.h"
 | 
					#include "common/common_types.h"
 | 
				
			||||||
@ -28,6 +29,7 @@ public:
 | 
				
			|||||||
    ~RasterizerOpenGL() override;
 | 
					    ~RasterizerOpenGL() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void DrawArrays() override;
 | 
					    void DrawArrays() override;
 | 
				
			||||||
 | 
					    void Clear() override;
 | 
				
			||||||
    void NotifyMaxwellRegisterChanged(u32 method) override;
 | 
					    void NotifyMaxwellRegisterChanged(u32 method) override;
 | 
				
			||||||
    void FlushAll() override;
 | 
					    void FlushAll() override;
 | 
				
			||||||
    void FlushRegion(Tegra::GPUVAddr addr, u64 size) override;
 | 
					    void FlushRegion(Tegra::GPUVAddr addr, u64 size) override;
 | 
				
			||||||
@ -81,6 +83,10 @@ private:
 | 
				
			|||||||
        u32 border_color_a;
 | 
					        u32 border_color_a;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Configures the color and depth framebuffer states and returns the dirty <Color, Depth>
 | 
				
			||||||
 | 
					    /// surfaces if writing was enabled.
 | 
				
			||||||
 | 
					    std::pair<Surface, Surface> ConfigureFramebuffers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Binds the framebuffer color and depth surface
 | 
					    /// Binds the framebuffer color and depth surface
 | 
				
			||||||
    void BindFramebufferSurfaces(const Surface& color_surface, const Surface& depth_surface,
 | 
					    void BindFramebufferSurfaces(const Surface& color_surface, const Surface& depth_surface,
 | 
				
			||||||
                                 bool has_stencil);
 | 
					                                 bool has_stencil);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user