Explorar el Código

Texture Cache: More rescaling fixes.

Fernando Sahmkow hace 5 años
padre
commit
84f2aea896

+ 2 - 2
src/video_core/renderer_opengl/gl_texture_cache.cpp

@@ -918,7 +918,7 @@ bool Image::ScaleUp() {
         return false;
     }
     flags |= ImageFlagBits::Rescaled;
-    Scale();
+    //Scale();
     return true;
 }
 
@@ -927,7 +927,7 @@ bool Image::ScaleDown() {
         return false;
     }
     flags &= ~ImageFlagBits::Rescaled;
-    Scale();
+    //Scale();
     return true;
 }
 

+ 8 - 0
src/video_core/renderer_vulkan/vk_texture_cache.cpp

@@ -1078,6 +1078,10 @@ bool Image::ScaleUp(bool save_as_backup) {
     MemoryCommit new_commit(
         runtime->memory_allocator.Commit(rescaled_image, MemoryUsage::DeviceLocal));
 
+    if (aspect_mask == 0) {
+        aspect_mask = ImageAspectMask(info.format);
+    }
+
     const auto scale_up = [&](u32 value) {
         return (value * resolution.up_scale) >> resolution.down_shift;
     };
@@ -1170,6 +1174,10 @@ bool Image::ScaleDown(bool save_as_backup) {
         return (value * resolution.up_scale) >> resolution.down_shift;
     };
 
+    if (aspect_mask == 0) {
+        aspect_mask = ImageAspectMask(info.format);
+    }
+
     const bool is_2d = info.type == ImageType::e2D;
     boost::container::small_vector<VkImageBlit, 4> vkRegions(info.resources.levels);
     for (s32 level = 0; level < info.resources.levels; level++) {

+ 83 - 79
src/video_core/texture_cache/texture_cache.h

@@ -204,75 +204,68 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
         PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id));
         return;
     }
-    flags[Dirty::RenderTargets] = false;
-
-    // Render target control is used on all render targets, so force look ups when this one is up
-    const bool force = flags[Dirty::RenderTargetControl];
-    flags[Dirty::RenderTargetControl] = false;
-
-    bool can_rescale = true;
-    std::array<ImageId, NUM_RT> tmp_color_images{};
-    ImageId tmp_depth_image{};
-    const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) {
-        if (view_id) {
-            const auto& view = slot_image_views[view_id];
-            const auto image_id = view.image_id;
-            id_save = image_id;
-            auto& image = slot_images[image_id];
-            can_rescale &= ImageCanRescale(image);
-        } else {
-            id_save = CORRUPT_ID;
-        }
-    };
-    for (size_t index = 0; index < NUM_RT; ++index) {
-        ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index];
-        if (flags[Dirty::ColorBuffer0 + index] || force) {
-            flags[Dirty::ColorBuffer0 + index] = false;
-            BindRenderTarget(&color_buffer_id, FindColorBuffer(index, is_clear));
-        }
-        check_rescale(color_buffer_id, tmp_color_images[index]);
-    }
-    if (flags[Dirty::ZetaBuffer] || force) {
-        flags[Dirty::ZetaBuffer] = false;
-        BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
-    }
-    check_rescale(render_targets.depth_buffer_id, tmp_depth_image);
 
-    if (can_rescale) {
-        const auto scale_up = [this](ImageId image_id) {
-            if (image_id != CORRUPT_ID) {
-                Image& image = slot_images[image_id];
-                return ScaleUp(image);
+    do {
+        flags[Dirty::RenderTargets] = false;
+
+        has_deleted_images = false;
+        // Render target control is used on all render targets, so force look ups when this one is
+        // up
+        const bool force = flags[Dirty::RenderTargetControl];
+        flags[Dirty::RenderTargetControl] = false;
+
+        bool can_rescale = true;
+        std::array<ImageId, NUM_RT> tmp_color_images{};
+        ImageId tmp_depth_image{};
+        const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) {
+            if (view_id) {
+                const auto& view = slot_image_views[view_id];
+                const auto image_id = view.image_id;
+                id_save = image_id;
+                auto& image = slot_images[image_id];
+                can_rescale &= ImageCanRescale(image);
+            } else {
+                id_save = CORRUPT_ID;
             }
-            return false;
         };
         for (size_t index = 0; index < NUM_RT; ++index) {
-            if (scale_up(tmp_color_images[index])) {
-                BindRenderTarget(&render_targets.color_buffer_ids[index],
-                                 FindColorBuffer(index, is_clear));
+            ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index];
+            if (flags[Dirty::ColorBuffer0 + index] || force) {
+                flags[Dirty::ColorBuffer0 + index] = false;
+                BindRenderTarget(&color_buffer_id, FindColorBuffer(index, is_clear));
             }
+            check_rescale(color_buffer_id, tmp_color_images[index]);
         }
-        if (scale_up(tmp_depth_image)) {
+        if (flags[Dirty::ZetaBuffer] || force) {
+            flags[Dirty::ZetaBuffer] = false;
             BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
         }
-    } else {
-        const auto scale_down = [this](ImageId image_id) {
-            if (image_id != CORRUPT_ID) {
-                Image& image = slot_images[image_id];
-                return ScaleDown(image);
+        check_rescale(render_targets.depth_buffer_id, tmp_depth_image);
+
+        if (can_rescale) {
+            const auto scale_up = [this](ImageId image_id) {
+                if (image_id != CORRUPT_ID) {
+                    Image& image = slot_images[image_id];
+                    ScaleUp(image);
+                }
+            };
+            for (size_t index = 0; index < NUM_RT; ++index) {
+                scale_up(tmp_color_images[index]);
             }
-            return false;
-        };
-        for (size_t index = 0; index < NUM_RT; ++index) {
-            if (scale_down(tmp_color_images[index])) {
-                BindRenderTarget(&render_targets.color_buffer_ids[index],
-                                 FindColorBuffer(index, is_clear));
+            scale_up(tmp_depth_image);
+        } else {
+            const auto scale_down = [this](ImageId image_id) {
+                if (image_id != CORRUPT_ID) {
+                    Image& image = slot_images[image_id];
+                    ScaleDown(image);
+                }
+            };
+            for (size_t index = 0; index < NUM_RT; ++index) {
+                scale_down(tmp_color_images[index]);
             }
+            scale_down(tmp_depth_image);
         }
-        if (scale_down(tmp_depth_image)) {
-            BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
-        }
-    }
+    } while (has_deleted_images);
     // Rescale End
 
     for (size_t index = 0; index < NUM_RT; ++index) {
@@ -708,43 +701,54 @@ bool TextureCache<P>::ImageCanRescale(Image& image) {
 }
 
 template <class P>
-void TextureCache<P>::InvalidateScale(Image& image, bool invalidate_rt) {
+void TextureCache<P>::InvalidateScale(Image& image) {
     const std::span<const ImageViewId> image_view_ids = image.image_view_ids;
-    if (invalidate_rt) {
-        auto& dirty = maxwell3d.dirty.flags;
-        dirty[Dirty::RenderTargets] = true;
-        dirty[Dirty::ZetaBuffer] = true;
-        for (size_t rt = 0; rt < NUM_RT; ++rt) {
-            dirty[Dirty::ColorBuffer0 + rt] = true;
-        }
-        for (const ImageViewId image_view_id : image_view_ids) {
-            std::ranges::replace(render_targets.color_buffer_ids, image_view_id, ImageViewId{});
-            if (render_targets.depth_buffer_id == image_view_id) {
-                render_targets.depth_buffer_id = ImageViewId{};
-            }
+    auto& dirty = maxwell3d.dirty.flags;
+    dirty[Dirty::RenderTargets] = true;
+    dirty[Dirty::ZetaBuffer] = true;
+    for (size_t rt = 0; rt < NUM_RT; ++rt) {
+        dirty[Dirty::ColorBuffer0 + rt] = true;
+    }
+    for (const ImageViewId image_view_id : image_view_ids) {
+        std::ranges::replace(render_targets.color_buffer_ids, image_view_id, ImageViewId{});
+        if (render_targets.depth_buffer_id == image_view_id) {
+            render_targets.depth_buffer_id = ImageViewId{};
         }
     }
     RemoveImageViewReferences(image_view_ids);
     RemoveFramebuffers(image_view_ids);
+    for (const ImageViewId image_view_id : image_view_ids) {
+        sentenced_image_view.Push(std::move(slot_image_views[image_view_id]));
+        slot_image_views.erase(image_view_id);
+    }
+    image.image_view_ids.clear();
+    image.image_view_infos.clear();
+    if constexpr (ENABLE_VALIDATION) {
+        std::ranges::fill(graphics_image_view_ids, CORRUPT_ID);
+        std::ranges::fill(compute_image_view_ids, CORRUPT_ID);
+    }
+    graphics_image_table.Invalidate();
+    compute_image_table.Invalidate();
+    has_deleted_images = true;
 }
 
 template <class P>
-bool TextureCache<P>::ScaleUp(Image& image, bool invalidate_rt) {
+bool TextureCache<P>::ScaleUp(Image& image) {
     const bool rescaled = image.ScaleUp();
     if (!rescaled) {
         return false;
     }
-    InvalidateScale(image, invalidate_rt);
+    InvalidateScale(image);
     return true;
 }
 
 template <class P>
-bool TextureCache<P>::ScaleDown(Image& image, bool invalidate_rt) {
+bool TextureCache<P>::ScaleDown(Image& image) {
     const bool rescaled = image.ScaleDown();
     if (!rescaled) {
         return false;
     }
-    InvalidateScale(image, invalidate_rt);
+    InvalidateScale(image);
     return true;
 }
 
@@ -861,12 +865,12 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
     if (can_rescale) {
         for (const ImageId sibling_id : all_siblings) {
             Image& sibling = slot_images[sibling_id];
-            ScaleUp(sibling, true);
+            ScaleUp(sibling);
         }
     } else {
         for (const ImageId sibling_id : all_siblings) {
             Image& sibling = slot_images[sibling_id];
-            ScaleDown(sibling, true);
+            ScaleDown(sibling);
         }
     }
 
@@ -893,9 +897,9 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
     RefreshContents(new_image, new_image_id);
 
     if (can_rescale) {
-        new_image.ScaleUp();
+        ScaleUp(new_image);
     } else {
-        new_image.ScaleDown();
+        ScaleDown(new_image);
     }
 
     for (const ImageId overlap_id : overlap_ids) {

+ 3 - 3
src/video_core/texture_cache/texture_cache_base.h

@@ -327,9 +327,9 @@ private:
     [[nodiscard]] bool IsFullClear(ImageViewId id);
 
     bool ImageCanRescale(Image& image);
-    void InvalidateScale(Image& image, bool invalidate_rt = false);
-    bool ScaleUp(Image& image, bool invalidate_rt = false);
-    bool ScaleDown(Image& image, bool invalidate_rt = false);
+    void InvalidateScale(Image& image);
+    bool ScaleUp(Image& image);
+    bool ScaleDown(Image& image);
 
     Runtime& runtime;
     VideoCore::RasterizerInterface& rasterizer;