aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/texture_cache
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/texture_cache')
-rw-r--r--src/video_core/texture_cache/image_base.cpp8
-rw-r--r--src/video_core/texture_cache/image_base.h5
-rw-r--r--src/video_core/texture_cache/texture_cache.h34
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h2
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