From 8961bc37f38aad701c830639e3993b0c38133ddb Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Fri, 3 Jul 2026 15:37:19 -0400 Subject: [PATCH] [vulkan] Added transfer bits to compute memory barriers --- .../renderer_vulkan/renderer_vulkan.cpp | 1 + .../renderer_vulkan/vk_compute_pass.cpp | 15 +++++---- .../renderer_vulkan/vk_texture_cache.cpp | 32 +++++++++++-------- src/video_core/vulkan_common/vulkan_device.h | 10 ++++++ 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index b0a7d0c579..88e2895598 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -169,6 +169,7 @@ try } RendererVulkan::~RendererVulkan() { + scheduler.WaitWorker(); scheduler.RegisterOnSubmit([] {}); void(device.GetLogical().WaitIdle()); } diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp index 0cd8e5c9e7..611a389f61 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp @@ -751,7 +751,8 @@ void BlockLinearUnswizzleImage2DPass::Unswizzle( .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .pNext = nullptr, .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | + VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, .oldLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, @@ -766,7 +767,7 @@ void BlockLinearUnswizzleImage2DPass::Unswizzle( }, }; cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, 0, image_barrier); + vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, 0, image_barrier); }); scheduler.Finish(); } @@ -858,7 +859,8 @@ void BlockLinearUnswizzleImage3DPass::Unswizzle( .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .pNext = nullptr, .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | + VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, .oldLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, @@ -873,7 +875,7 @@ void BlockLinearUnswizzleImage3DPass::Unswizzle( }, }; cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, 0, image_barrier); + vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, 0, image_barrier); }); scheduler.Finish(); } @@ -956,7 +958,8 @@ void PitchUnswizzlePass::Unswizzle(Image& image, const StagingBufferRef& map, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .pNext = nullptr, .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | + VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, .oldLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, @@ -971,7 +974,7 @@ void PitchUnswizzlePass::Unswizzle(Image& image, const StagingBufferRef& map, }, }; cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, 0, image_barrier); + vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, 0, image_barrier); }); scheduler.Finish(); } diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 9d7ca4d251..afa040486d 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -213,9 +213,19 @@ constexpr VkBorderColor ConvertBorderColor(const std::array& color) { } } -[[nodiscard]] bool IsUnswizzleStorageFormatSupported(u32 bytes_per_block) { - return bytes_per_block == 1 || bytes_per_block == 2 || bytes_per_block == 4 || - bytes_per_block == 8 || bytes_per_block == 16; +[[nodiscard]] bool IsUnswizzleStorageFormatSupported(const Device& device, u32 bytes_per_block) { + switch (bytes_per_block) { + case 1: + return device.IsStorageBuffer8BitAccessSupported(); + case 2: + return device.IsStorageBuffer16BitAccessSupported(); + case 4: + case 8: + case 16: + return true; + default: + return false; + } } [[nodiscard]] vk::ImageView MakeStorageView(const vk::Device& device, u32 level, VkImage image, @@ -924,11 +934,8 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, Scheduler& sched if (IsPixelFormatASTC(image_format) && !device.IsOptimalAstcSupported()) { view_formats[index_a].push_back(VK_FORMAT_A8B8G8R8_UNORM_PACK32); } else if (!IsPixelFormatASTC(image_format) && !IsPixelFormatBCn(image_format)) { - // Generic block-linear/pitch accelerated unswizzle needs an alternate UINT - // storage view registered up-front so MakeImage() enables mutable format + - // storage usage for these images (see Image::Image / storage_image_views below). const u32 bpp = VideoCore::Surface::BytesPerBlock(image_format); - if (IsUnswizzleStorageFormatSupported(bpp)) { + if (IsUnswizzleStorageFormatSupported(device, bpp)) { view_formats[index_a].push_back(UnswizzleStorageFormat(bpp)); } } @@ -1617,13 +1624,12 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu flags |= VideoCommon::ImageFlagBits::Converted; flags |= VideoCommon::ImageFlagBits::CostlyLoad; } - if (!IsPixelFormatASTC(info.format) && !IsPixelFormatBCn(info.format)) { - if (info.type == ImageType::e2D || info.type == ImageType::e3D) { + if (!IsPixelFormatASTC(info.format) && !IsPixelFormatBCn(info.format) && + (info.type == ImageType::e2D || info.type == ImageType::e3D || + info.type == ImageType::Linear)) { + if (IsUnswizzleStorageFormatSupported(runtime->device, + VideoCore::Surface::BytesPerBlock(info.format))) { flags |= VideoCommon::ImageFlagBits::AcceleratedUpload; - } else if (info.type == ImageType::Linear) { - if (IsUnswizzleStorageFormatSupported(VideoCore::Surface::BytesPerBlock(info.format))) { - flags |= VideoCommon::ImageFlagBits::AcceleratedUpload; - } } } if (runtime->device.HasDebuggingToolAttached()) { diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 110d0c1199..6adc9b9fcf 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -888,6 +888,16 @@ FN_MAX_LIMIT_LIST features.bit16_storage.storageBuffer16BitAccess; } + /// Returns true if the device supports reading 8-bit values from a storage buffer. + bool IsStorageBuffer8BitAccessSupported() const { + return features.bit8_storage.storageBuffer8BitAccess; + } + + /// Returns true if the device supports reading 16-bit values from a storage buffer. + bool IsStorageBuffer16BitAccessSupported() const { + return features.bit16_storage.storageBuffer16BitAccess; + } + [[nodiscard]] static constexpr bool CheckBrokenCompute(VkDriverId driver_id, u32 driver_version) { if (driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) {