From 72112271c0ce1f2a0ebb74f28996b5cdc4de799c Mon Sep 17 00:00:00 2001 From: psucien Date: Sat, 31 Aug 2024 00:04:24 +0200 Subject: [PATCH] missing barriers --- .../renderer_vulkan/vk_graphics_pipeline.cpp | 21 +++++++++++- .../texture_cache/texture_cache.cpp | 34 ++++++++++++++++--- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 709bf7601..7830de53b 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -359,6 +359,7 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs, boost::container::static_vector buffer_infos; boost::container::static_vector image_infos; boost::container::small_vector set_writes; + boost::container::small_vector buffer_barriers; Shader::PushData push_data{}; u32 binding{}; @@ -424,6 +425,16 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs, } buffer_view = vk_buffer->View(offset_aligned, size + adjust, tex_buffer.is_written, vsharp.GetDataFmt(), vsharp.GetNumberFmt()); + + if (buffer_cache.IsRegionGpuModified(address, size)) { + buffer_barriers.push_back(vk::BufferMemoryBarrier{ + .srcAccessMask = vk::AccessFlagBits::eShaderWrite, + .dstAccessMask = vk::AccessFlagBits::eShaderRead, + .buffer = vk_buffer->Handle(), + .offset = offset, + .size = size, + }); + } } set_writes.push_back({ .dstSet = VK_NULL_HANDLE, @@ -467,7 +478,7 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs, auto ssharp = sampler.GetSharp(*stage); if (ssharp.force_degamma) { LOG_WARNING(Render_Vulkan, "Texture requires gamma correction"); - } + } if (sampler.disable_aniso) { const auto& tsharp = tsharps[sampler.associated_image]; if (tsharp.base_level == 0 && tsharp.last_level == 0) { @@ -488,6 +499,14 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs, } const auto cmdbuf = scheduler.CommandBuffer(); + + if (!buffer_barriers.empty()) { + cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eFragmentShader | + vk::PipelineStageFlagBits::eComputeShader, + vk::PipelineStageFlagBits::eFragmentShader, + vk::DependencyFlagBits::eByRegion, {}, buffer_barriers, {}); + } + if (!set_writes.empty()) { cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eGraphics, *pipeline_layout, 0, set_writes); diff --git a/src/video_core/texture_cache/texture_cache.cpp b/src/video_core/texture_cache/texture_cache.cpp index 8e5f70039..bf4470e05 100644 --- a/src/video_core/texture_cache/texture_cache.cpp +++ b/src/video_core/texture_cache/texture_cache.cpp @@ -286,10 +286,18 @@ ImageView& TextureCache::FindDepthTarget(const ImageInfo& image_info, Image& image = slot_images[image_id]; image.flags |= ImageFlagBits::GpuModified; image.flags &= ~ImageFlagBits::CpuModified; - image.aspect_mask = vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil; + image.aspect_mask = vk::ImageAspectFlagBits::eDepth; - const auto new_layout = view_info.is_storage ? vk::ImageLayout::eDepthStencilAttachmentOptimal - : vk::ImageLayout::eDepthStencilReadOnlyOptimal; + const bool has_stencil = image_info.usage.stencil; + if (has_stencil) { + image.aspect_mask |= vk::ImageAspectFlagBits::eStencil; + } + + const auto new_layout = view_info.is_storage + ? has_stencil ? vk::ImageLayout::eDepthStencilAttachmentOptimal + : vk::ImageLayout::eDepthAttachmentOptimal + : has_stencil ? vk::ImageLayout::eDepthStencilReadOnlyOptimal + : vk::ImageLayout::eDepthReadOnlyOptimal; image.Transit(new_layout, vk::AccessFlagBits::eDepthStencilAttachmentWrite | vk::AccessFlagBits::eDepthStencilAttachmentRead); @@ -372,6 +380,22 @@ void TextureCache::RefreshImage(Image& image, Vulkan::Scheduler* custom_schedule const auto [vk_buffer, buf_offset] = buffer_cache.ObtainTempBuffer(image_addr, image_size); buffer = vk_buffer->Handle(); offset = buf_offset; + + // The obtained buffer may be written by a shader so we need to emit a barrier to prevent + // RAW hazard + if (buffer_cache.IsRegionGpuModified(image_addr, image_size)) { + const vk::BufferMemoryBarrier post_barrier{ + .srcAccessMask = vk::AccessFlagBits::eShaderWrite, + .dstAccessMask = vk::AccessFlagBits::eTransferRead, + .buffer = buffer, + .offset = offset, + .size = image_size, + }; + cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eFragmentShader | + vk::PipelineStageFlagBits::eComputeShader, + vk::PipelineStageFlagBits::eTransfer, + vk::DependencyFlagBits::eByRegion, {}, post_barrier, {}); + } } for (auto& copy : image_copy) { @@ -418,7 +442,7 @@ void TextureCache::UnregisterImage(ImageId image_id) { } void TextureCache::TrackImage(ImageId image_id) { - auto& image = slot_images[image_id]; + auto& image = slot_images[image_id]; if (True(image.flags & ImageFlagBits::Tracked)) { return; } @@ -427,7 +451,7 @@ void TextureCache::TrackImage(ImageId image_id) { } void TextureCache::UntrackImage(ImageId image_id) { - auto& image = slot_images[image_id]; + auto& image = slot_images[image_id]; if (False(image.flags & ImageFlagBits::Tracked)) { return; }