From c2d33e5de4b9a548aef978e5b68e9f861dae4ab1 Mon Sep 17 00:00:00 2001 From: Ribbit Date: Mon, 20 Oct 2025 20:45:29 -0700 Subject: [PATCH] more changes --- .../renderer_vulkan/pipeline_helper.h | 6 ++- .../renderer_vulkan/vk_compute_pass.cpp | 9 ++-- .../renderer_vulkan/vk_scheduler.cpp | 11 +++++ src/video_core/renderer_vulkan/vk_scheduler.h | 2 + .../renderer_vulkan/vk_update_descriptor.cpp | 43 +++++++++++++++++++ .../renderer_vulkan/vk_update_descriptor.h | 21 +++------ 6 files changed, 73 insertions(+), 19 deletions(-) diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index 910e07a606..4f7aedc462 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h @@ -195,7 +195,8 @@ inline void PushImageDescriptors(TextureCache& texture_cache, !image_view.SupportsAnisotropy()}; const VkSampler vk_sampler{use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy() : sampler.Handle()}; - guest_descriptor_queue.AddSampledImage(vk_image_view, vk_sampler); + guest_descriptor_queue.AddSampledImage(image_view.ImageHandle(), vk_image_view, + vk_sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); rescaling.PushTexture(texture_cache.IsRescaling(image_view)); } } @@ -206,7 +207,8 @@ inline void PushImageDescriptors(TextureCache& texture_cache, texture_cache.MarkModification(image_view.image_id); } const VkImageView vk_image_view{image_view.StorageView(desc.type, desc.format)}; - guest_descriptor_queue.AddImage(vk_image_view); + guest_descriptor_queue.AddImage(image_view.ImageHandle(), vk_image_view, + VK_IMAGE_LAYOUT_GENERAL); rescaling.PushImage(texture_cache.IsRescaling(image_view)); } } diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp index 5938de6100..77ed88de1a 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp @@ -586,7 +586,8 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map, compute_pass_descriptor_queue.Acquire(); compute_pass_descriptor_queue.AddBuffer(map.buffer, input_offset, image.guest_size_bytes - swizzle.buffer_offset); - compute_pass_descriptor_queue.AddImage(image.StorageImageView(swizzle.level)); + compute_pass_descriptor_queue.AddImage(image.Handle(), image.StorageImageView(swizzle.level), + VK_IMAGE_LAYOUT_GENERAL); const void* const descriptor_data{compute_pass_descriptor_queue.UpdateData()}; // To unswizzle the ASTC data @@ -690,9 +691,11 @@ void MSAACopyPass::CopyImage(Image& dst_image, Image& src_image, compute_pass_descriptor_queue.Acquire(); compute_pass_descriptor_queue.AddImage( - src_image.StorageImageView(copy.src_subresource.base_level)); + src_image.Handle(), src_image.StorageImageView(copy.src_subresource.base_level), + VK_IMAGE_LAYOUT_GENERAL); compute_pass_descriptor_queue.AddImage( - dst_image.StorageImageView(copy.dst_subresource.base_level)); + dst_image.Handle(), dst_image.StorageImageView(copy.dst_subresource.base_level), + VK_IMAGE_LAYOUT_GENERAL); const void* const descriptor_data{compute_pass_descriptor_queue.UpdateData()}; const Common::Vec3 num_dispatches = { diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index 9eae6981ad..7d0ed0908a 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -23,6 +23,17 @@ namespace Vulkan { +VkImageLayout Scheduler::GetImageLayout(VkImage image) const noexcept { + if (image == VK_NULL_HANDLE) { + return VK_IMAGE_LAYOUT_GENERAL; + } + const auto it = image_layout_cache.find(ImageKey(image)); + if (it != image_layout_cache.end()) { + return it->second; + } + return VK_IMAGE_LAYOUT_GENERAL; +} + namespace { struct StageAccessInfo { VkPipelineStageFlags stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; diff --git a/src/video_core/renderer_vulkan/vk_scheduler.h b/src/video_core/renderer_vulkan/vk_scheduler.h index 1e02f35c69..4d0c8a6199 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.h +++ b/src/video_core/renderer_vulkan/vk_scheduler.h @@ -135,6 +135,8 @@ public: image_layout_cache.erase(ImageKey(image)); } + [[nodiscard]] VkImageLayout GetImageLayout(VkImage image) const noexcept; + std::mutex submit_mutex; private: diff --git a/src/video_core/renderer_vulkan/vk_update_descriptor.cpp b/src/video_core/renderer_vulkan/vk_update_descriptor.cpp index 0630ebda5e..053061b685 100644 --- a/src/video_core/renderer_vulkan/vk_update_descriptor.cpp +++ b/src/video_core/renderer_vulkan/vk_update_descriptor.cpp @@ -41,4 +41,47 @@ void UpdateDescriptorQueue::Acquire() { upload_start = payload_cursor; } +VkImageLayout UpdateDescriptorQueue::ResolveImageLayout(VkImage image, + VkImageLayout fallback) noexcept { + if (image == VK_NULL_HANDLE) { + return fallback; + } + VkImageLayout layout = scheduler.GetImageLayout(image); + + if (layout == fallback) { + return layout; + } + + const bool requires_attachment_to_general = + fallback == VK_IMAGE_LAYOUT_GENERAL && + (layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL || + layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + + if (requires_attachment_to_general) { + scheduler.RequestOutsideRenderPassOperationContext(); + scheduler.TrackImageLayout(image, VK_IMAGE_LAYOUT_GENERAL); + layout = VK_IMAGE_LAYOUT_GENERAL; + } + + return layout; +} + +void UpdateDescriptorQueue::AddSampledImage(VkImage image, VkImageView image_view, + VkSampler sampler, VkImageLayout fallback_layout) { + *(payload_cursor++) = VkDescriptorImageInfo{ + .sampler = sampler, + .imageView = image_view, + .imageLayout = ResolveImageLayout(image, fallback_layout), + }; +} + +void UpdateDescriptorQueue::AddImage(VkImage image, VkImageView image_view, + VkImageLayout fallback_layout) { + *(payload_cursor++) = VkDescriptorImageInfo{ + .sampler = VK_NULL_HANDLE, + .imageView = image_view, + .imageLayout = ResolveImageLayout(image, fallback_layout), + }; +} + } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_update_descriptor.h b/src/video_core/renderer_vulkan/vk_update_descriptor.h index 82fce298da..2156452b49 100644 --- a/src/video_core/renderer_vulkan/vk_update_descriptor.h +++ b/src/video_core/renderer_vulkan/vk_update_descriptor.h @@ -47,21 +47,11 @@ public: return upload_start; } - void AddSampledImage(VkImageView image_view, VkSampler sampler) { - *(payload_cursor++) = VkDescriptorImageInfo{ - .sampler = sampler, - .imageView = image_view, - .imageLayout = VK_IMAGE_LAYOUT_GENERAL, - }; - } + void AddSampledImage(VkImage image, VkImageView image_view, VkSampler sampler, + VkImageLayout fallback_layout = VK_IMAGE_LAYOUT_GENERAL); - void AddImage(VkImageView image_view) { - *(payload_cursor++) = VkDescriptorImageInfo{ - .sampler = VK_NULL_HANDLE, - .imageView = image_view, - .imageLayout = VK_IMAGE_LAYOUT_GENERAL, - }; - } + void AddImage(VkImage image, VkImageView image_view, + VkImageLayout fallback_layout = VK_IMAGE_LAYOUT_GENERAL); void AddBuffer(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size) { *(payload_cursor++) = VkDescriptorBufferInfo{ @@ -84,6 +74,9 @@ private: DescriptorUpdateEntry* payload_start = nullptr; const DescriptorUpdateEntry* upload_start = nullptr; std::array payload; + + [[nodiscard]] VkImageLayout ResolveImageLayout(VkImage image, + VkImageLayout fallback) noexcept; }; // TODO: should these be separate classes instead?