Keep adjusting memory barriers to be more explicit

This commit is contained in:
CamilleLaVey
2026-09-26 04:13:18 -04:00
parent 9d4355064b
commit 49c3a79fa8
14 changed files with 246 additions and 326 deletions
+8 -32
View File
@@ -460,16 +460,8 @@ void RecordShaderReadBarrier(Scheduler& scheduler, const ImageView& image_view)
const VkImageMemoryBarrier2 barrier{ const VkImageMemoryBarrier2 barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT | .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT | .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT |
VK_PIPELINE_STAGE_2_TRANSFER_BIT |
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_SHADER_WRITE_BIT |
VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT | .dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT |
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT, .dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT,
@@ -950,8 +942,8 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline,
VkImageMemoryBarrier2{ VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = aspect_info.pre_src_stages, .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.srcAccessMask = aspect_info.pre_src_access, .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
.dstStageMask = aspect_info.pre_dst_stages, .dstStageMask = aspect_info.pre_dst_stages,
.dstAccessMask = aspect_info.pre_src_dst_access, .dstAccessMask = aspect_info.pre_src_dst_access,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -964,8 +956,8 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline,
VkImageMemoryBarrier2{ VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = aspect_info.pre_src_stages, .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.srcAccessMask = aspect_info.pre_src_access, .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
.dstStageMask = aspect_info.pre_dst_stages, .dstStageMask = aspect_info.pre_dst_stages,
.dstAccessMask = aspect_info.pre_dst_dst_access, .dstAccessMask = aspect_info.pre_dst_dst_access,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -1017,8 +1009,8 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = aspect_info.post_src_stages, .srcStageMask = aspect_info.post_src_stages,
.srcAccessMask = aspect_info.post_src_access, .srcAccessMask = aspect_info.post_src_access,
.dstStageMask = aspect_info.post_dst_stages, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = aspect_info.post_dst_access, .dstAccessMask = vk::ACCESS_IMAGE_USERS,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -1075,21 +1067,13 @@ void BlitImageHelper::CopyMSAA(RenderPassCache& render_pass_cache, VkImage dst_i
.src_view_aspect = VK_IMAGE_ASPECT_COLOR_BIT, .src_view_aspect = VK_IMAGE_ASPECT_COLOR_BIT,
.attachment_aspect = VK_IMAGE_ASPECT_COLOR_BIT, .attachment_aspect = VK_IMAGE_ASPECT_COLOR_BIT,
.barrier_aspect = VK_IMAGE_ASPECT_COLOR_BIT, .barrier_aspect = VK_IMAGE_ASPECT_COLOR_BIT,
.pre_src_access = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_2_SHADER_WRITE_BIT |
VK_ACCESS_2_TRANSFER_WRITE_BIT,
.pre_src_dst_access = VK_ACCESS_2_SHADER_READ_BIT, .pre_src_dst_access = VK_ACCESS_2_SHADER_READ_BIT,
.pre_dst_dst_access = .pre_dst_dst_access =
VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
.pre_src_stages = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT |
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.pre_dst_stages = .pre_dst_stages =
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
.post_src_access = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, .post_src_access = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
.post_dst_access = VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_TRANSFER_READ_BIT,
.post_src_stages = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, .post_src_stages = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
.post_dst_stages = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT |
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_2_TRANSFER_BIT,
}; };
const VkFormat src_vk_format = const VkFormat src_vk_format =
MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, true, src_format).format; MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, true, src_format).format;
@@ -1584,21 +1568,13 @@ void BlitImageHelper::CopyMSAADepth(RenderPassCache& render_pass_cache, VkImage
.src_view_aspect = VK_IMAGE_ASPECT_DEPTH_BIT, .src_view_aspect = VK_IMAGE_ASPECT_DEPTH_BIT,
.attachment_aspect = attachment_aspect, .attachment_aspect = attachment_aspect,
.barrier_aspect = attachment_aspect, .barrier_aspect = attachment_aspect,
.pre_src_access =
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_2_TRANSFER_WRITE_BIT,
.pre_src_dst_access = VK_ACCESS_2_SHADER_READ_BIT, .pre_src_dst_access = VK_ACCESS_2_SHADER_READ_BIT,
.pre_dst_dst_access = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT | .pre_dst_dst_access = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.pre_src_stages = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.pre_dst_stages = .pre_dst_stages =
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT,
.post_src_access = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .post_src_access = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.post_dst_access = VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_TRANSFER_READ_BIT |
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
.post_src_stages = VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT, .post_src_stages = VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
.post_dst_stages = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER,
}; };
const VkFormat src_vk_format = const VkFormat src_vk_format =
MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, true, src_format).format; MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, true, src_format).format;
@@ -140,15 +140,11 @@ private:
VkImageAspectFlags src_view_aspect; VkImageAspectFlags src_view_aspect;
VkImageAspectFlags attachment_aspect; VkImageAspectFlags attachment_aspect;
VkImageAspectFlags barrier_aspect; VkImageAspectFlags barrier_aspect;
VkAccessFlags2 pre_src_access;
VkAccessFlags2 pre_src_dst_access; VkAccessFlags2 pre_src_dst_access;
VkAccessFlags2 pre_dst_dst_access; VkAccessFlags2 pre_dst_dst_access;
VkPipelineStageFlags2 pre_src_stages;
VkPipelineStageFlags2 pre_dst_stages; VkPipelineStageFlags2 pre_dst_stages;
VkAccessFlags2 post_src_access; VkAccessFlags2 post_src_access;
VkAccessFlags2 post_dst_access;
VkPipelineStageFlags2 post_src_stages; VkPipelineStageFlags2 post_src_stages;
VkPipelineStageFlags2 post_dst_stages;
}; };
void BlitImpl(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, void BlitImpl(const Framebuffer* dst_framebuffer, const ImageView& src_image_view,
+11 -14
View File
@@ -49,16 +49,13 @@ vk::Image CreateWrappedImage(MemoryAllocator& allocator, VkExtent2D dimensions,
void TransitionImageLayout(vk::CommandBuffer& cmdbuf, VkImage image, VkImageLayout target_layout, void TransitionImageLayout(vk::CommandBuffer& cmdbuf, VkImage image, VkImageLayout target_layout,
VkImageLayout source_layout) { VkImageLayout source_layout) {
constexpr VkAccessFlags2 flags{VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_SHADER_READ_BIT};
const VkImageMemoryBarrier2 barrier{ const VkImageMemoryBarrier2 barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.srcAccessMask = flags, .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = flags, .dstAccessMask = vk::ACCESS_IMAGE_USERS,
.oldLayout = source_layout, .oldLayout = source_layout,
.newLayout = target_layout, .newLayout = target_layout,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -121,8 +118,8 @@ void DownloadColorImage(vk::CommandBuffer& cmdbuf, VkImage image, VkBuffer buffe
const VkImageMemoryBarrier2 read_barrier{ const VkImageMemoryBarrier2 read_barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT, .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -143,8 +140,8 @@ void DownloadColorImage(vk::CommandBuffer& cmdbuf, VkImage image, VkBuffer buffe
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_NONE, .srcAccessMask = VK_ACCESS_2_NONE,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT, .dstAccessMask = vk::ACCESS_IMAGE_USERS,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -162,9 +159,9 @@ void DownloadColorImage(vk::CommandBuffer& cmdbuf, VkImage image, VkBuffer buffe
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, .dstStageMask = vk::PIPELINE_STAGE_HOST,
.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT, .dstAccessMask = VK_ACCESS_2_HOST_READ_BIT,
}; };
const VkBufferImageCopy copy{ const VkBufferImageCopy copy{
.bufferOffset = 0, .bufferOffset = 0,
@@ -36,24 +36,6 @@ struct VertexBindings {
u32 count; u32 count;
}; };
constexpr VkMemoryBarrier2 READ_BARRIER{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_BUFFER_INPUTS | VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT | VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = vk::ACCESS_TRANSFER,
};
constexpr VkMemoryBarrier2 WRITE_BARRIER{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = vk::PIPELINE_STAGE_BUFFER_INPUTS,
.dstAccessMask = vk::ACCESS_BUFFER_INPUTS,
};
VkBufferCopy MakeBufferCopy(const VideoCommon::BufferCopy& copy) { VkBufferCopy MakeBufferCopy(const VideoCommon::BufferCopy& copy) {
return VkBufferCopy{ return VkBufferCopy{
.srcOffset = copy.src_offset, .srcOffset = copy.src_offset,
@@ -392,7 +374,23 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_, MemoryAllocator& m
staging_pool{staging_pool_}, guest_descriptor_queue{guest_descriptor_queue_}, staging_pool{staging_pool_}, guest_descriptor_queue{guest_descriptor_queue_},
quad_index_pass(device, scheduler, descriptor_pool, staging_pool, quad_index_pass(device, scheduler, descriptor_pool, staging_pool,
compute_pass_descriptor_queue), compute_pass_descriptor_queue),
multi_range_buffers(device_) { multi_range_buffers(device_),
read_barrier{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = device_.GetBufferUserStages(),
.srcAccessMask = vk::ACCESS_BUFFER_WRITES,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = vk::ACCESS_TRANSFER,
},
write_barrier{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = device_.GetBufferConsumerStages(),
.dstAccessMask = device_.GetBufferConsumerAccess(),
} {
const VkDriverIdKHR driver_id = device.GetDriverID(); const VkDriverIdKHR driver_id = device.GetDriverID();
limit_dynamic_storage_buffers = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY || limit_dynamic_storage_buffers = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
driver_id == VK_DRIVER_ID_ARM_PROPRIETARY; driver_id == VK_DRIVER_ID_ARM_PROPRIETARY;
@@ -513,28 +511,28 @@ void BufferCacheRuntime::CopyBuffer(VkBuffer dst_buffer, VkBuffer src_buffer,
} }
scheduler.RequestOutsideRenderPassOperationContext(); scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([src_buffer, dst_buffer, vk_copies, barrier](vk::CommandBuffer cmdbuf) { scheduler.Record([this, src_buffer, dst_buffer, vk_copies, barrier](vk::CommandBuffer cmdbuf) {
if (barrier) { if (barrier) {
cmdbuf.PipelineBarrier(READ_BARRIER); cmdbuf.PipelineBarrier(read_barrier);
} }
cmdbuf.CopyBuffer(src_buffer, dst_buffer, VideoCommon::FixSmallVectorADL(vk_copies)); cmdbuf.CopyBuffer(src_buffer, dst_buffer, VideoCommon::FixSmallVectorADL(vk_copies));
if (barrier) { if (barrier) {
cmdbuf.PipelineBarrier(WRITE_BARRIER); cmdbuf.PipelineBarrier(write_barrier);
} }
}); });
} }
void BufferCacheRuntime::PreCopyBarrier() { void BufferCacheRuntime::PreCopyBarrier() {
scheduler.RequestOutsideRenderPassOperationContext(); scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([](vk::CommandBuffer cmdbuf) { scheduler.Record([this](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(READ_BARRIER); cmdbuf.PipelineBarrier(read_barrier);
}); });
} }
void BufferCacheRuntime::PostCopyBarrier() { void BufferCacheRuntime::PostCopyBarrier() {
scheduler.RequestOutsideRenderPassOperationContext(); scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([](vk::CommandBuffer cmdbuf) { scheduler.Record([this](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(WRITE_BARRIER); cmdbuf.PipelineBarrier(write_barrier);
}); });
} }
@@ -544,10 +542,10 @@ void BufferCacheRuntime::ClearBuffer(VkBuffer dest_buffer, u32 offset, size_t si
} }
scheduler.RequestOutsideRenderPassOperationContext(); scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([dest_buffer, offset, size, value](vk::CommandBuffer cmdbuf) { scheduler.Record([this, dest_buffer, offset, size, value](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(READ_BARRIER); cmdbuf.PipelineBarrier(read_barrier);
cmdbuf.FillBuffer(dest_buffer, offset, size, value); cmdbuf.FillBuffer(dest_buffer, offset, size, value);
cmdbuf.PipelineBarrier(WRITE_BARRIER); cmdbuf.PipelineBarrier(write_barrier);
}); });
} }
@@ -270,6 +270,9 @@ private:
boost::container::small_vector<MultiRangeSource, 16> multi_range_sources; boost::container::small_vector<MultiRangeSource, 16> multi_range_sources;
VkDeviceSize multi_range_total{}; VkDeviceSize multi_range_total{};
VkMemoryBarrier2 read_barrier;
VkMemoryBarrier2 write_barrier;
bool limit_dynamic_storage_buffers = false; bool limit_dynamic_storage_buffers = false;
u32 max_dynamic_storage_buffers = (std::numeric_limits<u32>::max)(); u32 max_dynamic_storage_buffers = (std::numeric_limits<u32>::max)();
}; };
@@ -328,7 +328,7 @@ std::pair<VkBuffer, VkDeviceSize> Uint8Pass::Assemble(u32 num_vertices, VkBuffer
.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT,
.dstAccessMask = VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT, .dstAccessMask = VK_ACCESS_2_INDEX_READ_BIT,
}; };
const VkDescriptorSet set = descriptor_allocator.Commit(); const VkDescriptorSet set = descriptor_allocator.Commit();
device.GetLogical().UpdateDescriptorSet(set, *descriptor_template, descriptor_data); device.GetLogical().UpdateDescriptorSet(set, *descriptor_template, descriptor_data);
@@ -487,13 +487,13 @@ void ConditionalRenderingResolvePass::Resolve(VkBuffer dst_buffer, VkBuffer src_
scheduler.RequestOutsideRenderPassOperationContext(); scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([this, descriptor_data, compare_to_zero](vk::CommandBuffer cmdbuf) { scheduler.Record([this, descriptor_data, compare_to_zero](vk::CommandBuffer cmdbuf) {
static constexpr VkMemoryBarrier2 read_barrier{ const VkMemoryBarrier2 read_barrier{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .srcStageMask = device.GetBufferUserStages(),
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT | VK_ACCESS_2_SHADER_WRITE_BIT, .srcAccessMask = vk::ACCESS_BUFFER_WRITES,
.dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT, .dstAccessMask = vk::ACCESS_SHADER_RESOURCES,
}; };
static constexpr VkMemoryBarrier2 write_barrier{ static constexpr VkMemoryBarrier2 write_barrier{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
@@ -536,14 +536,22 @@ QueriesPrefixScanPass::QueriesPrefixScanPass(
void QueriesPrefixScanPass::Run(VkBuffer accumulation_buffer, VkBuffer dst_buffer, void QueriesPrefixScanPass::Run(VkBuffer accumulation_buffer, VkBuffer dst_buffer,
VkBuffer src_buffer, size_t number_of_sums, VkBuffer src_buffer, size_t number_of_sums,
size_t min_accumulation_limit, size_t max_accumulation_limit) { size_t min_accumulation_limit, size_t max_accumulation_limit) {
constexpr VkAccessFlags2 BASE_DST_ACCESS = VK_ACCESS_2_SHADER_READ_BIT | const VkMemoryBarrier2 read_barrier{
VK_ACCESS_2_TRANSFER_READ_BIT | .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT | .pNext = nullptr,
VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT | .srcStageMask = device.GetBufferUserStages(),
VK_ACCESS_2_INDEX_READ_BIT | .srcAccessMask = vk::ACCESS_BUFFER_WRITES,
VK_ACCESS_2_UNIFORM_READ_BIT; .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
const VkAccessFlags2 conditional_access = .dstAccessMask = vk::ACCESS_SHADER_RESOURCES,
device.IsExtConditionalRendering() ? VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT : 0; };
const VkMemoryBarrier2 write_barrier{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
.dstStageMask = device.GetBufferConsumerStages(),
.dstAccessMask = device.GetBufferConsumerAccess(),
};
size_t current_runs = number_of_sums; size_t current_runs = number_of_sums;
size_t offset = 0; size_t offset = 0;
while (current_runs != 0) { while (current_runs != 0) {
@@ -560,23 +568,8 @@ void QueriesPrefixScanPass::Run(VkBuffer accumulation_buffer, VkBuffer dst_buffe
scheduler.RequestOutsideRenderPassOperationContext(); scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([this, descriptor_data, min_accumulation_limit, max_accumulation_limit, scheduler.Record([this, descriptor_data, min_accumulation_limit, max_accumulation_limit,
runs_to_do, used_offset, conditional_access](vk::CommandBuffer cmdbuf) { runs_to_do, used_offset, read_barrier,
static constexpr VkMemoryBarrier2 read_barrier{ write_barrier](vk::CommandBuffer cmdbuf) {
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT,
};
const VkMemoryBarrier2 write_barrier{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
.dstAccessMask = BASE_DST_ACCESS | conditional_access,
};
const QueriesPrefixScanPushConstants uniforms{ const QueriesPrefixScanPushConstants uniforms{
.min_accumulation_base = static_cast<u32>(min_accumulation_limit), .min_accumulation_base = static_cast<u32>(min_accumulation_limit),
.max_accumulation_base = static_cast<u32>(max_accumulation_limit), .max_accumulation_base = static_cast<u32>(max_accumulation_limit),
@@ -604,9 +597,9 @@ void RecordUnswizzleBeginBarrier(Scheduler& scheduler, VkPipeline vk_pipeline, V
VkImageLayout old_layout = VK_IMAGE_LAYOUT_UNDEFINED; VkImageLayout old_layout = VK_IMAGE_LAYOUT_UNDEFINED;
VkPipelineStageFlags2 src_stage = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; VkPipelineStageFlags2 src_stage = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT;
if (is_initialized) { if (is_initialized) {
src_access = VK_ACCESS_2_SHADER_WRITE_BIT | VK_ACCESS_2_TRANSFER_WRITE_BIT; src_access = vk::ACCESS_IMAGE_WRITES;
old_layout = VK_IMAGE_LAYOUT_GENERAL; old_layout = VK_IMAGE_LAYOUT_GENERAL;
src_stage = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER; src_stage = vk::PIPELINE_STAGE_IMAGE_USERS;
} }
scheduler.Record([vk_pipeline, vk_image, aspect_mask, src_access, old_layout, scheduler.Record([vk_pipeline, vk_image, aspect_mask, src_access, old_layout,
src_stage](vk::CommandBuffer cmdbuf) { src_stage](vk::CommandBuffer cmdbuf) {
@@ -643,8 +636,8 @@ void RecordUnswizzleEndBarrier(Scheduler& scheduler, VkImage vk_image,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT, .dstAccessMask = vk::ACCESS_IMAGE_USERS,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -458,7 +458,7 @@ void PresentManager::CopyToSwapchainImpl(Frame* frame) {
VkImageMemoryBarrier2{ VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_NONE, .srcAccessMask = VK_ACCESS_2_NONE,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
@@ -478,8 +478,8 @@ void PresentManager::CopyToSwapchainImpl(Frame* frame) {
VkImageMemoryBarrier2{ VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -502,8 +502,8 @@ void PresentManager::CopyToSwapchainImpl(Frame* frame) {
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_NONE,
.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT, .dstAccessMask = VK_ACCESS_2_NONE,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -522,8 +522,8 @@ void PresentManager::CopyToSwapchainImpl(Frame* frame) {
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT, .srcAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT, .dstAccessMask = vk::ACCESS_IMAGE_USERS,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -869,7 +869,7 @@ public:
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = vk::PIPELINE_STAGE_HOST, .dstStageMask = vk::PIPELINE_STAGE_HOST,
.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT, .dstAccessMask = VK_ACCESS_2_HOST_READ_BIT,
}; };
scheduler.RequestOutsideRenderPassOperationContext(); scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([](vk::CommandBuffer cmdbuf) { scheduler.Record([](vk::CommandBuffer cmdbuf) {
@@ -1040,7 +1040,7 @@ private:
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT,
}; };
scheduler.RequestOutsideRenderPassOperationContext(); scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([dst_buffer = current_bank->GetBuffer(), scheduler.Record([dst_buffer = current_bank->GetBuffer(),
@@ -1577,32 +1577,24 @@ VideoCommon::StreamerInterface* QueryCacheRuntime::GetStreamerInterface(QueryTyp
} }
void QueryCacheRuntime::Barriers(bool is_prebarrier) { void QueryCacheRuntime::Barriers(bool is_prebarrier) {
static constexpr VkMemoryBarrier2 READ_BARRIER{ VkMemoryBarrier2 barrier{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER,
.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT | VK_ACCESS_2_TRANSFER_WRITE_BIT,
};
static constexpr VkMemoryBarrier2 WRITE_BARRIER{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER_HOST, .dstStageMask = impl->device.GetBufferConsumerStages(),
.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT, .dstAccessMask = impl->device.GetBufferConsumerAccess(),
}; };
impl->scheduler.RequestOutsideRenderPassOperationContext();
if (is_prebarrier) { if (is_prebarrier) {
impl->scheduler.Record([](vk::CommandBuffer cmdbuf) { barrier.srcStageMask = impl->device.GetBufferUserStages();
cmdbuf.PipelineBarrier(READ_BARRIER); barrier.srcAccessMask = vk::ACCESS_BUFFER_WRITES;
}); barrier.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
} else { barrier.dstAccessMask = vk::ACCESS_TRANSFER;
impl->scheduler.Record([](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(WRITE_BARRIER);
});
} }
impl->scheduler.RequestOutsideRenderPassOperationContext();
impl->scheduler.Record([barrier](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(barrier);
});
} }
template <typename SyncValuesType> template <typename SyncValuesType>
@@ -628,23 +628,14 @@ void RasterizerVulkan::DispatchCompute() {
return; return;
} }
static constexpr VkMemoryBarrier2 READ_BARRIER{ const VkMemoryBarrier2 read_barrier{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_BUFFER_INPUTS, .srcStageMask = device.GetBufferUserStages(),
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
.dstAccessMask = vk::ACCESS_SHADER_RESOURCES, .dstAccessMask = vk::ACCESS_SHADER_RESOURCES,
}; };
static constexpr VkMemoryBarrier2 INDIRECT_READ_BARRIER{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_BUFFER_INPUTS,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
.dstStageMask =
VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT | VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
.dstAccessMask = VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT | vk::ACCESS_SHADER_RESOURCES,
};
const auto& qmd{kepler_compute->launch_description}; const auto& qmd{kepler_compute->launch_description};
auto indirect_address = kepler_compute->GetIndirectComputeAddress(); auto indirect_address = kepler_compute->GetIndirectComputeAddress();
if (indirect_address) { if (indirect_address) {
@@ -654,12 +645,15 @@ void RasterizerVulkan::DispatchCompute() {
const auto [buffer, offset] = const auto [buffer, offset] =
buffer_cache.ObtainBuffer(*indirect_address, 12, sync_info, post_op); buffer_cache.ObtainBuffer(*indirect_address, 12, sync_info, post_op);
scheduler.RequestComputeDispatchContext(); scheduler.RequestComputeDispatchContext();
scheduler.Record([pipeline, indirect_buffer = buffer->Handle(), VkMemoryBarrier2 indirect_read_barrier = read_barrier;
indirect_offset = offset](vk::CommandBuffer cmdbuf) { indirect_read_barrier.dstStageMask |= VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT;
indirect_read_barrier.dstAccessMask |= VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT;
scheduler.Record([pipeline, indirect_buffer = buffer->Handle(), indirect_offset = offset,
indirect_read_barrier](vk::CommandBuffer cmdbuf) {
if (!pipeline->IsBound()) { if (!pipeline->IsBound()) {
return; return;
} }
cmdbuf.PipelineBarrier(INDIRECT_READ_BARRIER); cmdbuf.PipelineBarrier(indirect_read_barrier);
cmdbuf.DispatchIndirect(indirect_buffer, indirect_offset); cmdbuf.DispatchIndirect(indirect_buffer, indirect_offset);
}); });
return; return;
@@ -670,11 +664,11 @@ void RasterizerVulkan::DispatchCompute() {
return; return;
} }
scheduler.RequestComputeDispatchContext(); scheduler.RequestComputeDispatchContext();
scheduler.Record([pipeline, dim](vk::CommandBuffer cmdbuf) { scheduler.Record([pipeline, dim, read_barrier](vk::CommandBuffer cmdbuf) {
if (!pipeline->IsBound()) { if (!pipeline->IsBound()) {
return; return;
} }
cmdbuf.PipelineBarrier(READ_BARRIER); cmdbuf.PipelineBarrier(read_barrier);
cmdbuf.Dispatch(dim[0], dim[1], dim[2]); cmdbuf.Dispatch(dim[0], dim[1], dim[2]);
}); });
+18 -29
View File
@@ -47,11 +47,22 @@ Scheduler::Scheduler(const Device& device_, StateTracker& state_tracker_)
: device{device_}, state_tracker{state_tracker_}, : device{device_}, state_tracker{state_tracker_},
master_semaphore{std::make_unique<MasterSemaphore>(device)}, master_semaphore{std::make_unique<MasterSemaphore>(device)},
command_pool{std::make_unique<CommandPool>(*master_semaphore, device)} { command_pool{std::make_unique<CommandPool>(*master_semaphore, device)} {
compute_write_barrier = VkMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
.dstStageMask = device.GetBufferConsumerStages() | vk::PIPELINE_STAGE_ATTACHMENTS,
.dstAccessMask = device.GetBufferConsumerAccess() | vk::ACCESS_ATTACHMENTS,
};
renderpass_write_barrier = compute_write_barrier;
renderpass_write_barrier.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_SHADERS;
upload_write_barrier = compute_write_barrier;
upload_write_barrier.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
upload_write_barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
if (device.IsExtTransformFeedbackSupported()) { if (device.IsExtTransformFeedbackSupported()) {
renderpass_write_barrier.srcStageMask |= VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT; renderpass_write_barrier.srcStageMask |= VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT;
renderpass_write_barrier.srcAccessMask |= VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT; renderpass_write_barrier.srcAccessMask |= VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT;
renderpass_write_barrier.dstStageMask |= VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT;
renderpass_write_barrier.dstAccessMask |= VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT;
} }
AcquireNewChunk(); AcquireNewChunk();
@@ -241,18 +252,8 @@ void Scheduler::PublishComputeWrites() {
if (!std::exchange(compute_writes, false)) { if (!std::exchange(compute_writes, false)) {
return; return;
} }
Record([](vk::CommandBuffer cmdbuf) { Record([barrier = &compute_write_barrier](vk::CommandBuffer cmdbuf) {
static constexpr VkMemoryBarrier2 COMPUTE_WRITE_BARRIER{ cmdbuf.PipelineBarrier(*barrier);
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
.dstStageMask = vk::PIPELINE_STAGE_BUFFER_INPUTS | vk::PIPELINE_STAGE_ATTACHMENTS |
VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask =
vk::ACCESS_BUFFER_INPUTS | vk::ACCESS_ATTACHMENTS | vk::ACCESS_TRANSFER,
};
cmdbuf.PipelineBarrier(COMPUTE_WRITE_BARRIER);
}); });
} }
@@ -379,15 +380,7 @@ u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_se
const u64 signal_value = master_semaphore->NextTick(); const u64 signal_value = master_semaphore->NextTick();
RecordWithUploadBuffer([signal_semaphore, wait_semaphore, signal_value, RecordWithUploadBuffer([signal_semaphore, wait_semaphore, signal_value,
this](vk::CommandBuffer cmdbuf, vk::CommandBuffer upload_cmdbuf) { this](vk::CommandBuffer cmdbuf, vk::CommandBuffer upload_cmdbuf) {
static constexpr VkMemoryBarrier2 WRITE_BARRIER{ upload_cmdbuf.PipelineBarrier(upload_write_barrier);
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT,
};
upload_cmdbuf.PipelineBarrier(WRITE_BARRIER);
upload_cmdbuf.End(); upload_cmdbuf.End();
cmdbuf.End(); cmdbuf.End();
@@ -481,12 +474,8 @@ void Scheduler::EndRenderPass()
| VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT
| VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, | VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccessMask = src_access, .srcAccessMask = src_access,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT .dstAccessMask = vk::ACCESS_IMAGE_USERS,
| VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT
| VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT
| VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT
| VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -348,15 +348,9 @@ private:
bool renderpass_writes = false; bool renderpass_writes = false;
bool renderpass_depth_writes = false; bool renderpass_depth_writes = false;
bool compute_writes = false; bool compute_writes = false;
VkMemoryBarrier2 renderpass_write_barrier{ VkMemoryBarrier2 renderpass_write_barrier{};
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, VkMemoryBarrier2 compute_write_barrier{};
.pNext = nullptr, VkMemoryBarrier2 upload_write_barrier{};
.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_SHADERS,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
.dstStageMask = vk::PIPELINE_STAGE_BUFFER_INPUTS | vk::PIPELINE_STAGE_ATTACHMENTS |
VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = vk::ACCESS_BUFFER_INPUTS | vk::ACCESS_ATTACHMENTS | vk::ACCESS_TRANSFER,
};
u32 num_renderpass_images = 0; u32 num_renderpass_images = 0;
std::array<VkImage, 9> renderpass_images{}; std::array<VkImage, 9> renderpass_images{};
std::array<VkImageSubresourceRange, 9> renderpass_image_ranges{}; std::array<VkImageSubresourceRange, 9> renderpass_image_ranges{};
@@ -689,10 +689,6 @@ struct RangedBarrierRange {
void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage image, void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage image,
VkImageAspectFlags aspect_mask, bool is_initialized, VkImageAspectFlags aspect_mask, bool is_initialized,
std::span<const VkBufferImageCopy> copies) { std::span<const VkBufferImageCopy> copies) {
static constexpr VkAccessFlags2 WRITE_ACCESS_FLAGS =
VK_ACCESS_2_SHADER_WRITE_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
// Compute exact mip/layer range being written to // Compute exact mip/layer range being written to
RangedBarrierRange range; RangedBarrierRange range;
for (const auto& region : copies) { for (const auto& region : copies) {
@@ -703,10 +699,8 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im
const VkImageMemoryBarrier2 read_barrier{ const VkImageMemoryBarrier2 read_barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT | .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT | .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
.srcAccessMask = WRITE_ACCESS_FLAGS,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED, .oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED,
@@ -722,8 +716,8 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT, .dstAccessMask = vk::ACCESS_IMAGE_USERS,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -938,8 +932,8 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const
VkImageMemoryBarrier2{ VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT, .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -952,10 +946,8 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const
VkImageMemoryBarrier2{ VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT | .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, // Discard contents .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, // Discard contents
@@ -972,8 +964,8 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = 0, .srcAccessMask = 0,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT | VK_ACCESS_2_MEMORY_READ_BIT, .dstAccessMask = vk::ACCESS_IMAGE_USERS,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -986,8 +978,8 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT | VK_ACCESS_2_MEMORY_READ_BIT, .dstAccessMask = vk::ACCESS_IMAGE_USERS,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -1259,27 +1251,17 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src,
static constexpr VkMemoryBarrier2 READ_BARRIER{ static constexpr VkMemoryBarrier2 READ_BARRIER{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .srcStageMask = vk::PIPELINE_STAGE_BUFFER_USERS,
.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT, .srcAccessMask = vk::ACCESS_BUFFER_WRITES,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT | VK_ACCESS_2_TRANSFER_WRITE_BIT, .dstAccessMask = vk::ACCESS_TRANSFER,
};
static constexpr VkMemoryBarrier2 WRITE_BARRIER{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT,
}; };
const std::array pre_barriers{ const std::array pre_barriers{
VkImageMemoryBarrier2{ VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT | .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -1296,8 +1278,8 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = 0, .srcAccessMask = 0,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = 0, .dstAccessMask = vk::ACCESS_IMAGE_USERS,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -1310,10 +1292,8 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src,
VkImageMemoryBarrier2{ VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT | .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -1330,13 +1310,8 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT | .dstAccessMask = vk::ACCESS_IMAGE_USERS,
VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT |
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_TRANSFER_READ_BIT | VK_ACCESS_2_TRANSFER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -1349,7 +1324,7 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src,
cmdbuf.CopyImageToBuffer(src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, copy_buffer, cmdbuf.CopyImageToBuffer(src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, copy_buffer,
vk_in_copies); vk_in_copies);
cmdbuf.PipelineBarrier(0, WRITE_BARRIER, {}, middle_in_barrier); cmdbuf.PipelineBarrier(0, {}, {}, middle_in_barrier);
cmdbuf.PipelineBarrier(0, READ_BARRIER, {}, middle_out_barrier); cmdbuf.PipelineBarrier(0, READ_BARRIER, {}, middle_out_barrier);
cmdbuf.CopyBufferToImage(copy_buffer, dst_image, VK_IMAGE_LAYOUT_GENERAL, vk_out_copies); cmdbuf.CopyBufferToImage(copy_buffer, dst_image, VK_IMAGE_LAYOUT_GENERAL, vk_out_copies);
@@ -1435,10 +1410,8 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst
VkImageMemoryBarrier2{ VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT | .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -1457,10 +1430,8 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst
VkImageMemoryBarrier2{ VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT | .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -1482,11 +1453,8 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT | .dstAccessMask = vk::ACCESS_IMAGE_USERS,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_TRANSFER_READ_BIT | VK_ACCESS_2_TRANSFER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -1679,13 +1647,8 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
VkImageMemoryBarrier2{ VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT | .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT | .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -1698,13 +1661,8 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
VkImageMemoryBarrier2{ VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT | .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT | .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -1721,8 +1679,8 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = 0, .srcAccessMask = 0,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = 0, .dstAccessMask = vk::ACCESS_IMAGE_USERS,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -1735,8 +1693,8 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT, .dstAccessMask = vk::ACCESS_IMAGE_USERS,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -1768,17 +1726,6 @@ void TextureCacheRuntime::CopyImageMSAA(Image& dst, Image& src,
static_cast<u32>(copy.src_subresource.base_layer + copy.src_subresource.num_layers) <= static_cast<u32>(copy.src_subresource.base_layer + copy.src_subresource.num_layers) <=
shadow->layers) { shadow->layers) {
const VkImageAspectFlags aspect_mask = shadow->aspect_mask; const VkImageAspectFlags aspect_mask = shadow->aspect_mask;
VkPipelineStageFlags2 attachment_stage = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
VkAccessFlags2 attachment_write = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
VkAccessFlags2 attachment_read_write =
VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
if ((aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0) {
attachment_stage = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT;
attachment_write = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
attachment_read_write = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
}
const VkImage shadow_image = *shadow->image; const VkImage shadow_image = *shadow->image;
const VkImage dst_image = dst.Handle(); const VkImage dst_image = dst.Handle();
const VkImageCopy region{ const VkImageCopy region{
@@ -1799,15 +1746,14 @@ void TextureCacheRuntime::CopyImageMSAA(Image& dst, Image& src,
.extent = {copy.extent.width, copy.extent.height, 1}, .extent = {copy.extent.width, copy.extent.height, 1},
}; };
scheduler.RequestOutsideRenderPassOperationContext(); scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([shadow_image, dst_image, region, aspect_mask, attachment_stage, scheduler.Record([shadow_image, dst_image, region,
attachment_write, aspect_mask](vk::CommandBuffer cmdbuf) {
attachment_read_write](vk::CommandBuffer cmdbuf) {
const std::array pre_barriers{ const std::array pre_barriers{
VkImageMemoryBarrier2{ VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = attachment_stage | VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.srcAccessMask = attachment_write, .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -1821,9 +1767,8 @@ void TextureCacheRuntime::CopyImageMSAA(Image& dst, Image& src,
VkImageMemoryBarrier2{ VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = attachment_stage | VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT | attachment_write | .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -1841,8 +1786,8 @@ void TextureCacheRuntime::CopyImageMSAA(Image& dst, Image& src,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = 0, .srcAccessMask = 0,
.dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = 0, .dstAccessMask = vk::ACCESS_IMAGE_USERS,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -1856,9 +1801,8 @@ void TextureCacheRuntime::CopyImageMSAA(Image& dst, Image& src,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT | attachment_read_write | .dstAccessMask = vk::ACCESS_IMAGE_USERS,
VK_ACCESS_2_TRANSFER_READ_BIT | VK_ACCESS_2_TRANSFER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -2243,12 +2187,15 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o
scheduler->RequestOutsideRenderPassOperationContext(); scheduler->RequestOutsideRenderPassOperationContext();
scheduler->Record([buffers = std::move(buffers_vector), image = temp_vk_image, scheduler->Record([buffers = std::move(buffers_vector), image = temp_vk_image,
aspect_mask_ = aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) { aspect_mask_ = aspect_mask, vk_copies,
consumer_stages = runtime->device.GetBufferConsumerStages(),
consumer_access = runtime->device.GetBufferConsumerAccess()](
vk::CommandBuffer cmdbuf) {
const VkImageMemoryBarrier2 read_barrier{ const VkImageMemoryBarrier2 read_barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT, .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -2275,17 +2222,17 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, .dstStageMask = consumer_stages,
.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT, .dstAccessMask = consumer_access,
}; };
const VkImageMemoryBarrier2 image_write_barrier{ const VkImageMemoryBarrier2 image_write_barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = 0, .srcAccessMask = 0,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT, .dstAccessMask = vk::ACCESS_IMAGE_USERS,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -2318,12 +2265,15 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o
} }
scheduler->RequestOutsideRenderPassOperationContext(); scheduler->RequestOutsideRenderPassOperationContext();
scheduler->Record([buffers = std::move(buffers_vector), image = *original_image, scheduler->Record([buffers = std::move(buffers_vector), image = *original_image,
aspect_mask_ = aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) { aspect_mask_ = aspect_mask, vk_copies,
consumer_stages = runtime->device.GetBufferConsumerStages(),
consumer_access = runtime->device.GetBufferConsumerAccess()](
vk::CommandBuffer cmdbuf) {
const VkImageMemoryBarrier2 read_barrier{ const VkImageMemoryBarrier2 read_barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .srcStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT, .srcAccessMask = vk::ACCESS_IMAGE_WRITES,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT, .dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -2350,17 +2300,17 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, .dstStageMask = consumer_stages,
.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT, .dstAccessMask = consumer_access,
}; };
const VkImageMemoryBarrier2 image_write_barrier{ const VkImageMemoryBarrier2 image_write_barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = 0, .srcAccessMask = 0,
.dstStageMask = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT, .dstAccessMask = vk::ACCESS_IMAGE_USERS,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -3229,8 +3179,8 @@ void TextureCacheRuntime::TransitionImageLayout(Image& image) {
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_NONE, .srcStageMask = VK_PIPELINE_STAGE_2_NONE,
.srcAccessMask = VK_ACCESS_2_NONE, .srcAccessMask = VK_ACCESS_2_NONE,
.dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, .dstStageMask = vk::PIPELINE_STAGE_IMAGE_USERS,
.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT, .dstAccessMask = vk::ACCESS_IMAGE_USERS,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -869,6 +869,32 @@ FN_MAX_LIMIT_LIST
return extensions.conditional_rendering; return extensions.conditional_rendering;
} }
VkPipelineStageFlags2 GetBufferUserStages() const {
VkPipelineStageFlags2 stages = vk::PIPELINE_STAGE_BUFFER_USERS;
if (IsExtConditionalRendering()) {
stages |= VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT;
}
if (IsExtTransformFeedbackSupported()) {
stages |= VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT;
}
return stages;
}
VkPipelineStageFlags2 GetBufferConsumerStages() const {
return GetBufferUserStages() | VK_PIPELINE_STAGE_2_HOST_BIT;
}
VkAccessFlags2 GetBufferConsumerAccess() const {
VkAccessFlags2 access = vk::ACCESS_BUFFER_CONSUMERS;
if (IsExtConditionalRendering()) {
access |= VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT;
}
if (IsExtTransformFeedbackSupported()) {
access |= VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT;
}
return access;
}
bool IsExtAstcDecodeModeSupported() const { bool IsExtAstcDecodeModeSupported() const {
return extensions.astc_decode_mode; return extensions.astc_decode_mode;
} }
+21 -9
View File
@@ -147,15 +147,6 @@ inline VkResult Filter(VkResult result) {
return result; return result;
} }
inline constexpr VkPipelineStageFlags2 PIPELINE_STAGE_GRAPHICS_COMPUTE =
VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT;
inline constexpr VkPipelineStageFlags2 PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER =
PIPELINE_STAGE_GRAPHICS_COMPUTE | VK_PIPELINE_STAGE_2_TRANSFER_BIT;
inline constexpr VkPipelineStageFlags2 PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER_HOST =
PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER | VK_PIPELINE_STAGE_2_HOST_BIT;
inline constexpr VkPipelineStageFlags2 PIPELINE_STAGE_HOST = VK_PIPELINE_STAGE_2_HOST_BIT; inline constexpr VkPipelineStageFlags2 PIPELINE_STAGE_HOST = VK_PIPELINE_STAGE_2_HOST_BIT;
inline constexpr VkPipelineStageFlags2 PIPELINE_STAGE_GRAPHICS_SHADERS = inline constexpr VkPipelineStageFlags2 PIPELINE_STAGE_GRAPHICS_SHADERS =
@@ -183,6 +174,27 @@ inline constexpr VkAccessFlags2 ACCESS_ATTACHMENTS =
inline constexpr VkAccessFlags2 ACCESS_TRANSFER = inline constexpr VkAccessFlags2 ACCESS_TRANSFER =
VK_ACCESS_2_TRANSFER_READ_BIT | VK_ACCESS_2_TRANSFER_WRITE_BIT; VK_ACCESS_2_TRANSFER_READ_BIT | VK_ACCESS_2_TRANSFER_WRITE_BIT;
inline constexpr VkPipelineStageFlags2 PIPELINE_STAGE_BUFFER_USERS =
PIPELINE_STAGE_BUFFER_INPUTS | VK_PIPELINE_STAGE_2_TRANSFER_BIT;
inline constexpr VkAccessFlags2 ACCESS_BUFFER_WRITES =
VK_ACCESS_2_SHADER_WRITE_BIT | VK_ACCESS_2_TRANSFER_WRITE_BIT;
inline constexpr VkAccessFlags2 ACCESS_BUFFER_CONSUMERS =
ACCESS_BUFFER_INPUTS | ACCESS_TRANSFER | VK_ACCESS_2_HOST_READ_BIT;
inline constexpr VkPipelineStageFlags2 PIPELINE_STAGE_IMAGE_USERS =
PIPELINE_STAGE_GRAPHICS_SHADERS | VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT |
PIPELINE_STAGE_ATTACHMENTS | VK_PIPELINE_STAGE_2_TRANSFER_BIT;
inline constexpr VkAccessFlags2 ACCESS_IMAGE_WRITES =
VK_ACCESS_2_SHADER_WRITE_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_2_TRANSFER_WRITE_BIT;
inline constexpr VkAccessFlags2 ACCESS_IMAGE_USERS =
VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT | ACCESS_ATTACHMENTS |
ACCESS_TRANSFER;
/// Table holding Vulkan instance function pointers. /// Table holding Vulkan instance function pointers.
struct InstanceDispatch { struct InstanceDispatch {