From 1bbc9debfbcbd960874e2f877604506d174f613c Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 10 May 2019 23:42:08 -0400 Subject: [PATCH] Remove Framebuffer reconfiguration and restrict rendertarget protection --- .../renderer_opengl/gl_rasterizer.cpp | 16 ++++------ .../renderer_opengl/gl_rasterizer.h | 5 ++-- src/video_core/texture_cache/surface_base.h | 15 ++++++---- src/video_core/texture_cache/texture_cache.h | 30 ++++++------------- 4 files changed, 27 insertions(+), 39 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 3baf1522d4..2d6fd154aa 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -461,15 +461,15 @@ void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading, } std::pair RasterizerOpenGL::ConfigureFramebuffers( - OpenGLState& current_state, bool must_reconfigure, bool using_color_fb, bool using_depth_fb, - bool preserve_contents, std::optional single_color_target) { + OpenGLState& current_state, bool using_color_fb, bool using_depth_fb, bool preserve_contents, + std::optional single_color_target) { MICROPROFILE_SCOPE(OpenGL_Framebuffer); auto& gpu = system.GPU().Maxwell3D(); const auto& regs = gpu.regs; const FramebufferConfigState fb_config_state{using_color_fb, using_depth_fb, preserve_contents, single_color_target}; - if (!must_reconfigure && fb_config_state == current_framebuffer_config_state && + if (fb_config_state == current_framebuffer_config_state && gpu.dirty_flags.color_buffer.none() && !gpu.dirty_flags.zeta_buffer) { // Only skip if the previous ConfigureFramebuffers call was from the same kind (multiple or // single color targets). This is done because the guest registers may not change but the @@ -622,9 +622,8 @@ void RasterizerOpenGL::Clear() { return; } - const auto [clear_depth, clear_stencil] = - ConfigureFramebuffers(clear_state, false, use_color, use_depth || use_stencil, false, - regs.clear_buffers.RT.Value()); + const auto [clear_depth, clear_stencil] = ConfigureFramebuffers( + clear_state, use_color, use_depth || use_stencil, false, regs.clear_buffers.RT.Value()); if (regs.clear_flags.scissor) { SyncScissorTest(clear_state); } @@ -659,7 +658,6 @@ void RasterizerOpenGL::DrawArrays() { auto& gpu = system.GPU().Maxwell3D(); const auto& regs = gpu.regs; - ConfigureFramebuffers(state); SyncColorMask(); SyncFragmentColorClampState(); SyncMultiSampleState(); @@ -706,9 +704,7 @@ void RasterizerOpenGL::DrawArrays() { DrawParameters params = SetupDraw(); SetupShaders(params.primitive_mode); - if (texture_cache.ConsumeReconfigurationFlag()) { - ConfigureFramebuffers(state, true); - } + ConfigureFramebuffers(state); buffer_cache.Unmap(); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 970637efaa..be5ac1b9f5 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -111,9 +111,8 @@ private: * (requires using_depth_fb to be true) */ std::pair ConfigureFramebuffers( - OpenGLState& current_state, bool must_reconfigure = false, bool use_color_fb = true, - bool using_depth_fb = true, bool preserve_contents = true, - std::optional single_color_target = {}); + OpenGLState& current_state, bool use_color_fb = true, bool using_depth_fb = true, + bool preserve_contents = true, std::optional single_color_target = {}); /// Configures the current constbuffers to use for the draw command. void SetupDrawConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, diff --git a/src/video_core/texture_cache/surface_base.h b/src/video_core/texture_cache/surface_base.h index 095deb6026..78db2d665a 100644 --- a/src/video_core/texture_cache/surface_base.h +++ b/src/video_core/texture_cache/surface_base.h @@ -218,12 +218,12 @@ public: virtual void DownloadTexture(std::vector& staging_buffer) = 0; void MarkAsModified(const bool is_modified_, const u64 tick) { - is_modified = is_modified_ || is_protected; + is_modified = is_modified_ || is_target; modification_tick = tick; } - void MarkAsProtected(const bool is_protected) { - this->is_protected = is_protected; + void MarkAsRenderTarget(const bool is_target) { + this->is_target = is_target; } void MarkAsPicked(const bool is_picked) { @@ -235,7 +235,12 @@ public: } bool IsProtected() const { - return is_protected; + // Only 3D Slices are to be protected + return is_target && params.block_depth > 0; + } + + bool IsRenderTarget() const { + return is_target; } bool IsRegistered() const { @@ -307,7 +312,7 @@ private: } bool is_modified{}; - bool is_protected{}; + bool is_target{}; bool is_registered{}; bool is_picked{}; u64 modification_tick{}; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 8aa0d6515a..4ac5668c85 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -105,11 +105,11 @@ public: regs.zeta.memory_layout.block_depth, regs.zeta.memory_layout.type)}; auto surface_view = GetSurface(gpu_addr, depth_params, preserve_contents); if (depth_buffer.target) - depth_buffer.target->MarkAsProtected(false); + depth_buffer.target->MarkAsRenderTarget(false); depth_buffer.target = surface_view.first; depth_buffer.view = surface_view.second; if (depth_buffer.target) - depth_buffer.target->MarkAsProtected(true); + depth_buffer.target->MarkAsRenderTarget(true); return surface_view.second; } @@ -138,11 +138,11 @@ public: auto surface_view = GetSurface(gpu_addr, SurfaceParams::CreateForFramebuffer(system, index), preserve_contents); if (render_targets[index].target) - render_targets[index].target->MarkAsProtected(false); + render_targets[index].target->MarkAsRenderTarget(false); render_targets[index].target = surface_view.first; render_targets[index].view = surface_view.second; if (render_targets[index].target) - render_targets[index].target->MarkAsProtected(true); + render_targets[index].target->MarkAsRenderTarget(true); return surface_view.second; } @@ -158,7 +158,7 @@ public: void SetEmptyDepthBuffer() { if (depth_buffer.target != nullptr) { - depth_buffer.target->MarkAsProtected(false); + depth_buffer.target->MarkAsRenderTarget(false); depth_buffer.target = nullptr; depth_buffer.view = nullptr; } @@ -166,7 +166,7 @@ public: void SetEmptyColorBuffer(std::size_t index) { if (render_targets[index].target != nullptr) { - render_targets[index].target->MarkAsProtected(false); + render_targets[index].target->MarkAsRenderTarget(false); render_targets[index].target = nullptr; render_targets[index].view = nullptr; } @@ -200,12 +200,6 @@ public: return ++ticks; } - bool ConsumeReconfigurationFlag() { - const bool result = force_reconfiguration; - force_reconfiguration = false; - return result; - } - protected: TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer) : system{system}, rasterizer{rasterizer} { @@ -242,8 +236,8 @@ protected: rasterizer.UpdatePagesCachedCount(*cpu_addr, size, 1); } - void Unregister(TSurface surface, const bool force_unregister = false) { - if (surface->IsProtected() && !force_unregister) { + void Unregister(TSurface surface) { + if (surface->IsProtected()) { return; } const GPUVAddr gpu_addr = surface->GetGpuAddr(); @@ -392,10 +386,8 @@ private: std::min(src_params.height, dst_height), 1); ImageCopy(surface, new_surface, copy_params); } - force_reconfiguration = false; for (auto surface : overlaps) { - force_reconfiguration |= surface->IsProtected(); - Unregister(surface, true); + Unregister(surface); } new_surface->MarkAsModified(modified, Tick()); Register(new_surface); @@ -567,10 +559,6 @@ private: u64 ticks{}; - // Sometimes Setup Textures can hit a surface that's on the render target, when this happens - // we force a reconfiguration of the frame buffer after setup. - bool force_reconfiguration; - // The internal Cache is different for the Texture Cache. It's based on buckets // of 1MB. This fits better for the purpose of this cache as textures are normaly // large in size.