Răsfoiți Sursa

Remove Framebuffer reconfiguration and restrict rendertarget protection

Fernando Sahmkow 7 ani în urmă
părinte
comite
1bbc9debfb

+ 6 - 10
src/video_core/renderer_opengl/gl_rasterizer.cpp

@@ -461,15 +461,15 @@ void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading,
 }
 
 std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
-    OpenGLState& current_state, bool must_reconfigure, bool using_color_fb, bool using_depth_fb,
-    bool preserve_contents, std::optional<std::size_t> single_color_target) {
+    OpenGLState& current_state, bool using_color_fb, bool using_depth_fb, bool preserve_contents,
+    std::optional<std::size_t> 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();
 

+ 2 - 3
src/video_core/renderer_opengl/gl_rasterizer.h

@@ -111,9 +111,8 @@ private:
      * (requires using_depth_fb to be true)
      */
     std::pair<bool, bool> ConfigureFramebuffers(
-        OpenGLState& current_state, bool must_reconfigure = false, bool use_color_fb = true,
-        bool using_depth_fb = true, bool preserve_contents = true,
-        std::optional<std::size_t> single_color_target = {});
+        OpenGLState& current_state, bool use_color_fb = true, bool using_depth_fb = true,
+        bool preserve_contents = true, std::optional<std::size_t> single_color_target = {});
 
     /// Configures the current constbuffers to use for the draw command.
     void SetupDrawConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,

+ 10 - 5
src/video_core/texture_cache/surface_base.h

@@ -218,12 +218,12 @@ public:
     virtual void DownloadTexture(std::vector<u8>& 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{};

+ 9 - 21
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.