From d3595fd2b1287633bc778c4b52dc894889001450 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Mon, 10 Nov 2025 00:22:08 -0400 Subject: [PATCH] [gl, vk, texture cache] Attempt to get correct MSAA image upload and download --- .../renderer_opengl/gl_texture_cache.h | 4 ++ .../renderer_vulkan/vk_texture_cache.h | 4 ++ src/video_core/texture_cache/image_base.cpp | 4 -- src/video_core/texture_cache/texture_cache.h | 50 ++++++++++++++++--- .../texture_cache/texture_cache_base.h | 2 + 5 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index d4165d8e4d..a673c4feef 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h @@ -97,6 +97,10 @@ public: return true; } + bool CanDownloadMSAA() const noexcept { + return true; + } + void CopyImage(Image& dst, Image& src, std::span copies); void CopyImageMSAA(Image& dst, Image& src, std::span copies); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index cd11cc8fc7..17db56bb43 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -85,6 +85,10 @@ public: return msaa_copy_pass.operator bool(); } + bool CanDownloadMSAA() const noexcept { + return msaa_copy_pass.operator bool(); + } + void AccelerateImageUpload(Image&, const StagingBufferRef&, std::span); diff --git a/src/video_core/texture_cache/image_base.cpp b/src/video_core/texture_cache/image_base.cpp index 077df28fb3..93abad3c5c 100644 --- a/src/video_core/texture_cache/image_base.cpp +++ b/src/video_core/texture_cache/image_base.cpp @@ -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/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 8ac025f1df..f1ac55555c 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -101,8 +101,12 @@ void TextureCache

::RunGarbageCollector() { if (!aggressive_mode && True(image.flags & ImageFlagBits::CostlyLoad)) { return false; } - const bool must_download = - image.IsSafeDownload() && False(image.flags & ImageFlagBits::BadOverlap); + const bool supports_msaa_download = HasMsaaDownloadSupport(image.info); + if (!supports_msaa_download && image.info.num_samples > 1) { + LOG_WARNING(HW_GPU, "MSAA image downloads are not implemented"); + } + const bool must_download = supports_msaa_download && image.IsSafeDownload() && + False(image.flags & ImageFlagBits::BadOverlap); if (!high_priority_mode && must_download) { return false; } @@ -548,10 +552,14 @@ void TextureCache

::WriteMemory(DAddr cpu_addr, size_t size) { template void TextureCache

::DownloadMemory(DAddr cpu_addr, size_t size) { boost::container::small_vector images; - ForEachImageInRegion(cpu_addr, size, [&images](ImageId image_id, ImageBase& image) { + ForEachImageInRegion(cpu_addr, size, [this, &images](ImageId image_id, ImageBase& image) { if (!image.IsSafeDownload()) { return; } + if (!HasMsaaDownloadSupport(image.info)) { + LOG_WARNING(HW_GPU, "MSAA image downloads are not implemented"); + return; + } image.flags &= ~ImageFlagBits::GpuModified; images.push_back(image_id); }); @@ -930,6 +938,17 @@ ImageId TextureCache

::DmaImageId(const Tegra::DMA::ImageOperand& operand, boo return NULL_IMAGE_ID; } auto& image = slot_images[dst_id]; + if (image.info.num_samples > 1) { + if (is_upload) { + if (!HasMsaaUploadSupport(image.info)) { + return NULL_IMAGE_ID; + } + } else { + if (!HasMsaaDownloadSupport(image.info)) { + return NULL_IMAGE_ID; + } + } + } if (False(image.flags & ImageFlagBits::GpuModified)) { // No need to waste time on an image that's synced with guest return NULL_IMAGE_ID; @@ -1056,7 +1075,7 @@ void TextureCache

::RefreshContents(Image& image, ImageId image_id) { image.flags &= ~ImageFlagBits::CpuModified; TrackImage(image, image_id); - if (image.info.num_samples > 1 && !runtime.CanUploadMSAA()) { + if (!HasMsaaUploadSupport(image.info)) { LOG_WARNING(HW_GPU, "MSAA image uploads are not implemented"); runtime.TransitionImageLayout(image); return; @@ -1274,6 +1293,16 @@ u64 TextureCache

::GetScaledImageSizeBytes(const ImageBase& image) { return fitted_size; } +template +bool TextureCache

::HasMsaaUploadSupport(const ImageInfo& info) const noexcept { + return info.num_samples <= 1 || runtime.CanUploadMSAA(); +} + +template +bool TextureCache

::HasMsaaDownloadSupport(const ImageInfo& info) const noexcept { + return info.num_samples <= 1 || runtime.CanDownloadMSAA(); +} + template void TextureCache

::QueueAsyncDecode(Image& image, ImageId image_id) { UNIMPLEMENTED_IF(False(image.flags & ImageFlagBits::Converted)); @@ -1575,6 +1604,10 @@ ImageId TextureCache

::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 (!HasMsaaDownloadSupport(overlap.info)) { + LOG_WARNING(HW_GPU, "MSAA image downloads are not implemented"); + continue; + } if (!overlap.IsSafeDownload()) { continue; } @@ -2491,8 +2524,13 @@ void TextureCache

::BindRenderTarget(ImageViewId* old_id, ImageViewId new_id) if (new_id) { const ImageViewBase& old_view = slot_image_views[new_id]; if (True(old_view.flags & ImageViewFlagBits::PreemtiveDownload)) { - const PendingDownload new_download{true, 0, old_view.image_id}; - uncommitted_downloads.emplace_back(new_download); + const ImageBase& image = slot_images[old_view.image_id]; + if (!HasMsaaDownloadSupport(image.info)) { + LOG_WARNING(HW_GPU, "MSAA image downloads are not implemented"); + } else { + const PendingDownload new_download{true, 0, old_view.image_id}; + uncommitted_downloads.emplace_back(new_download); + } } } *old_id = new_id; diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index 01a9a6a3f1..2435f6fa75 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h @@ -426,6 +426,8 @@ private: bool ScaleUp(Image& image); bool ScaleDown(Image& image); u64 GetScaledImageSizeBytes(const ImageBase& image); + [[nodiscard]] bool HasMsaaUploadSupport(const ImageInfo& info) const noexcept; + [[nodiscard]] bool HasMsaaDownloadSupport(const ImageInfo& info) const noexcept; void QueueAsyncDecode(Image& image, ImageId image_id); void TickAsyncDecode();