diff options
Diffstat (limited to 'src/video_core/texture_cache')
| -rw-r--r-- | src/video_core/texture_cache/image_base.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/texture_cache/image_base.h | 5 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 34 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache_base.h | 2 |
4 files changed, 35 insertions, 14 deletions
diff --git a/src/video_core/texture_cache/image_base.cpp b/src/video_core/texture_cache/image_base.cpp index 077df28fb3..9b0f33220d 100644 --- a/src/video_core/texture_cache/image_base.cpp +++ b/src/video_core/texture_cache/image_base.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project @@ -121,7 +121,7 @@ void ImageBase::InsertView(const ImageViewInfo& view_info, ImageViewId image_vie image_view_ids.push_back(image_view_id); } -bool ImageBase::IsSafeDownload() const noexcept { +bool ImageBase::IsSafeGpuCopy() const noexcept { // Skip images that were not modified from the GPU if (False(flags & ImageFlagBits::GpuModified)) { return false; @@ -131,10 +131,6 @@ bool ImageBase::IsSafeDownload() const noexcept { if (True(flags & ImageFlagBits::CpuModified)) { return false; } - if (info.num_samples > 1) { - LOG_WARNING(HW_GPU, "MSAA image downloads are not implemented"); - return false; - } return true; } diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h index 0587d7b724..79fc8505d6 100644 --- a/src/video_core/texture_cache/image_base.h +++ b/src/video_core/texture_cache/image_base.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -64,7 +67,7 @@ struct ImageBase { void InsertView(const ImageViewInfo& view_info, ImageViewId image_view_id); - [[nodiscard]] bool IsSafeDownload() const noexcept; + [[nodiscard]] bool IsSafeGpuCopy() const noexcept; [[nodiscard]] bool Overlaps(VAddr overlap_cpu_addr, size_t overlap_size) const noexcept { const VAddr overlap_end = overlap_cpu_addr + overlap_size; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 98a5e053a7..bcc40afde0 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -134,7 +134,7 @@ void TextureCache<P>::RunGarbageCollector() { if (True(image.flags & ImageFlagBits::IsDecoding)) { return false; } - const bool must_download = image.IsSafeDownload() && False(image.flags & ImageFlagBits::BadOverlap); + const bool must_download = IsDownloadable(image) && False(image.flags & ImageFlagBits::BadOverlap); if ((!aggressive_mode && True(image.flags & ImageFlagBits::CostlyLoad)) || (!high_priority_mode && must_download)) { return false; } @@ -577,6 +577,7 @@ FramebufferId TextureCache<P>::GetFramebufferId(const RenderTargets& key) { return id ? &slot_image_views[id] : nullptr; }); ImageView* const depth_buffer = key.depth_buffer_id ? &slot_image_views[key.depth_buffer_id] : nullptr; + runtime.FlushDeferredClear(); framebuffer_id = slot_framebuffers.insert(runtime, color_buffers, depth_buffer, key); return framebuffer_id; } @@ -595,10 +596,25 @@ void TextureCache<P>::WriteMemory(DAddr cpu_addr, size_t size) { } template <class P> +bool TextureCache<P>::IsDownloadable(const ImageBase& image) const noexcept { + if (!image.IsSafeGpuCopy()) { + return false; + } + if (image.info.num_samples == 1) { + return true; + } + if constexpr (P::HAS_MSAA_DOWNLOADS) { + return runtime.CanDownloadMsaa(image.info); + } else { + return false; + } +} + +template <class P> void TextureCache<P>::DownloadMemory(DAddr cpu_addr, size_t size) { boost::container::small_vector<ImageId, 16> images; - ForEachImageInRegion(cpu_addr, size, [&images](ImageId image_id, ImageBase& image) { - if (!image.IsSafeDownload()) { + ForEachImageInRegion(cpu_addr, size, [this, &images](ImageId image_id, ImageBase& image) { + if (!IsDownloadable(image)) { return; } image.flags &= ~ImageFlagBits::GpuModified; @@ -1476,12 +1492,12 @@ template <class P> bool TextureCache<P>::ScaleUp(Image& image) { const bool has_copy = image.HasScaled(); const bool rescaled = image.ScaleUp(); + if (!has_copy && image.HasScaled()) { + total_used_memory += GetScaledImageSizeBytes(image); + } if (!rescaled) { return false; } - if (!has_copy) { - total_used_memory += GetScaledImageSizeBytes(image); - } InvalidateScale(image); return true; } @@ -1691,7 +1707,10 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, DA for (const auto& copy_object : join_copies_to_do) { Image& overlap = slot_images[copy_object.id]; if (copy_object.is_alias) { - if (!overlap.IsSafeDownload()) { + if (!overlap.IsSafeGpuCopy()) { + continue; + } + if (overlap.info.num_samples != new_image.info.num_samples) { continue; } const auto alias_pointer = join_alias_indices.find(copy_object.id); @@ -2461,6 +2480,7 @@ void TextureCache<P>::RemoveImageViewReferences(std::span<const ImageViewId> rem template <class P> void TextureCache<P>::RemoveFramebuffers(std::span<const ImageViewId> removed_views) { + runtime.FlushDeferredClear(); auto it = framebuffers.begin(); while (it != framebuffers.end()) { if (it->first.Contains(removed_views)) { diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index fafc331ef7..77947e83c7 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h @@ -303,6 +303,8 @@ private: FramebufferId GetFramebufferId(const RenderTargets& key); /// Refresh the contents (pixel data) of an image + [[nodiscard]] bool IsDownloadable(const ImageBase& image) const noexcept; + void RefreshContents(Image& image, ImageId image_id); /// Upload data from guest to an image |
