From 236696b0ff9463dcc51500d9141cbdcb8cf49d6d Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Wed, 29 Jul 2026 20:56:56 -0400 Subject: [PATCH] [TEST] New optimal image layouts access --- .../renderer_opengl/gl_texture_cache.h | 2 ++ .../renderer_vulkan/pipeline_helper.h | 3 ++- .../renderer_vulkan/vk_texture_cache.cpp | 16 ++++++++++++++++ .../renderer_vulkan/vk_texture_cache.h | 18 ++++++++++++++++++ .../renderer_vulkan/vk_update_descriptor.h | 5 +++-- src/video_core/texture_cache/texture_cache.h | 2 ++ 6 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 5dd2a80ec1..e445f601c2 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h @@ -252,6 +252,8 @@ public: return false; } + void MarkAttachmentUse() noexcept {} + bool IsRescaled() const; bool ScaleUp(bool ignore = false); diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index 882372aee2..d084c3b99b 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h @@ -246,7 +246,8 @@ inline void PushImageDescriptors(TextureCache& texture_cache, !image_view.SupportsDepthComparison()) { vk_sampler = sampler.HandleWithoutDepthComparison(); } - guest_descriptor_queue.AddSampledImage(vk_image_view, vk_sampler); + guest_descriptor_queue.AddSampledImage(vk_image_view, vk_sampler, + image_view.SampledLayout()); const bool element_rescaled{texture_cache.IsRescaling(image_view)}; is_rescaled |= element_rescaled; } diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 246bd0f112..93209f80c5 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -57,6 +57,7 @@ constexpr bool ENABLE_MSAA_RESOLVE_CONSUME = true; constexpr bool ENABLE_MSAA_COLOR_DISCARD = true; constexpr bool ENABLE_MSAA_DEPTH_DISCARD = true; constexpr bool ENABLE_MSAA_DEPTH_RESOLVE = false; +constexpr bool ENABLE_OPTIMAL_IMAGE_LAYOUTS = true; constexpr VkBorderColor ConvertBorderColor(const std::array& color) { if (color == std::array{0, 0, 0, 0}) { @@ -2487,6 +2488,7 @@ bool Image::EnableStorageUsage() { commit(scaled_image, new_scaled, scaled_info); } wants_storage = true; + current_layout = initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED; storage_image_views.clear(); storage_image_views.resize(info.resources.levels); scale_framebuffer.reset(); @@ -2496,6 +2498,13 @@ bool Image::EnableStorageUsage() { return true; } +VkImageLayout Image::PreferredLayout() const noexcept { + if (!ENABLE_OPTIMAL_IMAGE_LAYOUTS || wants_storage || attachment_used) { + return VK_IMAGE_LAYOUT_GENERAL; + } + return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; +} + bool Image::IsRescaled() const noexcept { return True(flags & ImageFlagBits::Rescaled); } @@ -2832,6 +2841,13 @@ bool ImageView::IsRescaled() const noexcept { return (*slot_images)[image_id].IsRescaled(); } +VkImageLayout ImageView::SampledLayout() const noexcept { + if (slot_images == nullptr) { + return VK_IMAGE_LAYOUT_GENERAL; + } + return (*slot_images)[image_id].PreferredLayout(); +} + vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask, std::optional texture_type) { VkImageViewType view_type = ImageViewType(type); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index eaa83f2d6a..c2997d2326 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -399,6 +399,20 @@ public: bool EnableStorageUsage(); + [[nodiscard]] VkImageLayout PreferredLayout() const noexcept; + + [[nodiscard]] VkImageLayout CurrentLayout() const noexcept { + return current_layout; + } + + void SetCurrentLayout(VkImageLayout layout) noexcept { + current_layout = layout; + } + + void MarkAttachmentUse() noexcept { + attachment_used = true; + } + bool IsRescaled() const noexcept; bool ScaleUp(bool ignore = false); @@ -419,6 +433,8 @@ private: bool storage_capable = false; bool wants_storage = false; + bool attachment_used = false; + VkImageLayout current_layout = VK_IMAGE_LAYOUT_GENERAL; vk::Image original_image; vk::Image scaled_image; @@ -471,6 +487,8 @@ public: [[nodiscard]] bool IsRescaled() const noexcept; + [[nodiscard]] VkImageLayout SampledLayout() const noexcept; + [[nodiscard]] VkImageView Handle(Shader::TextureType texture_type) const noexcept { return *image_views[static_cast(texture_type)]; } diff --git a/src/video_core/renderer_vulkan/vk_update_descriptor.h b/src/video_core/renderer_vulkan/vk_update_descriptor.h index 991efc4232..49ce474bc3 100644 --- a/src/video_core/renderer_vulkan/vk_update_descriptor.h +++ b/src/video_core/renderer_vulkan/vk_update_descriptor.h @@ -45,11 +45,12 @@ public: return upload_start; } - void AddSampledImage(VkImageView image_view, VkSampler sampler) { + void AddSampledImage(VkImageView image_view, VkSampler sampler, + VkImageLayout image_layout = VK_IMAGE_LAYOUT_GENERAL) { *(payload_cursor++) = VkDescriptorImageInfo{ .sampler = sampler, .imageView = image_view, - .imageLayout = VK_IMAGE_LAYOUT_GENERAL, + .imageLayout = image_layout, }; } diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 6c9d185b6c..1ca7895499 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -2774,6 +2774,7 @@ void TextureCache

::BindRenderTarget(ImageViewId* old_id, ImageViewId new_id) const PendingDownload new_download{true, 0, old_view.image_id}; uncommitted_downloads.emplace_back(new_download); } + slot_images[old_view.image_id].MarkAttachmentUse(); } *old_id = new_id; } @@ -2782,6 +2783,7 @@ template std::pair TextureCache

::RenderTargetFromImage( ImageId image_id, const ImageViewInfo& view_info) { const ImageViewId view_id = FindOrEmplaceImageView(image_id, view_info); + slot_images[image_id].MarkAttachmentUse(); const ImageBase& image = slot_images[image_id]; const bool is_rescaled = True(image.flags & ImageFlagBits::Rescaled); const bool is_color = GetFormatType(image.info.format) == SurfaceType::ColorTexture;