From 5a9df3c6753e66519acaa13685abb89231e45ade Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 3 Jul 2018 22:32:59 -0500 Subject: GPU: Only configure the used framebuffers during clear. Don't try to configure the color buffer if it is not being cleared, it may not be completely valid at this point. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 20 ++++++++----- src/video_core/renderer_opengl/gl_rasterizer.h | 2 +- .../renderer_opengl/gl_rasterizer_cache.cpp | 34 +++++++++++++++++----- .../renderer_opengl/gl_rasterizer_cache.h | 9 ++++-- 4 files changed, 48 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 43dbf4da9..e516eb1ad 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -297,7 +297,8 @@ bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) { return true; } -std::pair RasterizerOpenGL::ConfigureFramebuffers() { +std::pair RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, + bool using_depth_fb) { const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; // Sync the depth test state before configuring the framebuffer surfaces. @@ -306,9 +307,6 @@ std::pair RasterizerOpenGL::ConfigureFramebuffers() { // TODO(bunnei): Implement this const bool has_stencil = false; - const bool using_color_fb = true; - const bool using_depth_fb = regs.zeta.Address() != 0; - const MathUtil::Rectangle viewport_rect{regs.viewport_transform[0].GetRect()}; const bool write_color_fb = @@ -358,18 +356,25 @@ std::pair RasterizerOpenGL::ConfigureFramebuffers() { void RasterizerOpenGL::Clear() { const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; + 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 && regs.clear_buffers.A) { clear_mask |= GL_COLOR_BUFFER_BIT; + use_color_fb = true; } - if (regs.clear_buffers.Z) + if (regs.clear_buffers.Z) { clear_mask |= GL_DEPTH_BUFFER_BIT; + use_depth_fb = true; + } if (clear_mask == 0) return; - auto [dirty_color_surface, dirty_depth_surface] = ConfigureFramebuffers(); + auto [dirty_color_surface, dirty_depth_surface] = + ConfigureFramebuffers(use_color_fb, use_depth_fb); // TODO(Subv): Support clearing only partial colors. glClearColor(regs.clear_color[0], regs.clear_color[1], regs.clear_color[2], @@ -394,7 +399,8 @@ void RasterizerOpenGL::DrawArrays() { MICROPROFILE_SCOPE(OpenGL_Drawing); const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; - auto [dirty_color_surface, dirty_depth_surface] = ConfigureFramebuffers(); + auto [dirty_color_surface, dirty_depth_surface] = + ConfigureFramebuffers(true, regs.zeta.Address() != 0); SyncBlendState(); SyncCullMode(); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 7738f40b1..c406142e4 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -85,7 +85,7 @@ private: /// Configures the color and depth framebuffer states and returns the dirty /// surfaces if writing was enabled. - std::pair ConfigureFramebuffers(); + std::pair ConfigureFramebuffers(bool using_color_fb, bool using_depth_fb); /// Binds the framebuffer color and depth surface void BindFramebufferSurfaces(const Surface& color_surface, const Surface& depth_surface, diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 3a00d9383..50469c05c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -65,6 +65,25 @@ struct FormatTuple { return params; } +/*static*/ SurfaceParams SurfaceParams::CreateForDepthBuffer( + const Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig& config, Tegra::GPUVAddr zeta_address, + Tegra::DepthFormat format) { + + SurfaceParams params{}; + params.addr = zeta_address; + params.is_tiled = true; + params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight; + params.pixel_format = PixelFormatFromDepthFormat(format); + params.component_type = ComponentTypeFromDepthFormat(format); + params.type = GetFormatType(params.pixel_format); + params.size_in_bytes = params.SizeInBytes(); + params.width = config.width; + params.height = config.height; + params.unaligned_height = config.height; + params.size_in_bytes = params.SizeInBytes(); + return params; +} + static constexpr std::array tex_format_tuples = {{ {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8 {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, ComponentType::UNorm, false}, // B5G6R5 @@ -461,15 +480,16 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( LOG_WARNING(Render_OpenGL, "hard-coded for render target 0!"); // get color and depth surfaces - const SurfaceParams color_params{SurfaceParams::CreateForFramebuffer(regs.rt[0])}; - SurfaceParams depth_params{color_params}; + SurfaceParams color_params{}; + SurfaceParams depth_params{}; + + if (using_color_fb) { + color_params = SurfaceParams::CreateForFramebuffer(regs.rt[0]); + } if (using_depth_fb) { - depth_params.addr = regs.zeta.Address(); - depth_params.pixel_format = SurfaceParams::PixelFormatFromDepthFormat(regs.zeta.format); - depth_params.component_type = SurfaceParams::ComponentTypeFromDepthFormat(regs.zeta.format); - depth_params.type = SurfaceParams::GetFormatType(depth_params.pixel_format); - depth_params.size_in_bytes = depth_params.SizeInBytes(); + depth_params = + SurfaceParams::CreateForDepthBuffer(regs.rt[0], regs.zeta.Address(), regs.zeta.format); } MathUtil::Rectangle color_rect{}; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 7aaf371bd..8005a81b8 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -326,13 +326,18 @@ struct SurfaceParams { return addr <= (region_addr + region_size) && region_addr <= (addr + size_in_bytes); } - /// Creates SurfaceParams from a texture configation + /// Creates SurfaceParams from a texture configuration static SurfaceParams CreateForTexture(const Tegra::Texture::FullTextureInfo& config); - /// Creates SurfaceParams from a framebuffer configation + /// Creates SurfaceParams from a framebuffer configuration static SurfaceParams CreateForFramebuffer( const Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig& config); + /// Creates SurfaceParams for a depth buffer configuration + static SurfaceParams CreateForDepthBuffer( + const Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig& config, + Tegra::GPUVAddr zeta_address, Tegra::DepthFormat format); + Tegra::GPUVAddr addr; bool is_tiled; u32 block_height; -- cgit v1.2.3