|
|
|
@ -810,8 +810,7 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const |
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
|
|
|
.pNext = nullptr, |
|
|
|
.srcAccessMask = 0, |
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | |
|
|
|
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
|
|
|
.dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT, |
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
@ -823,8 +822,7 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const |
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
|
|
|
.pNext = nullptr, |
|
|
|
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, |
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | |
|
|
|
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
|
|
|
.dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT, |
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
@ -833,26 +831,11 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const |
|
|
|
.subresourceRange = subresource_range, |
|
|
|
}, |
|
|
|
}; |
|
|
|
// Use specific pipeline stages for better parallelism
|
|
|
|
const VkPipelineStageFlags src_stages = |
|
|
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | |
|
|
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT; |
|
|
|
cmdbuf.PipelineBarrier(src_stages, VK_PIPELINE_STAGE_TRANSFER_BIT, |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, |
|
|
|
0, nullptr, nullptr, read_barriers); |
|
|
|
cmdbuf.BlitImage(src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_image, |
|
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, regions, vk_filter); |
|
|
|
// After transfer, images may be used in graphics, compute, or as attachments
|
|
|
|
const VkPipelineStageFlags dst_stages = |
|
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | |
|
|
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stages, |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, |
|
|
|
0, nullptr, nullptr, write_barriers); |
|
|
|
}); |
|
|
|
} |
|
|
|
@ -1040,12 +1023,11 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src, |
|
|
|
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, |
|
|
|
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, |
|
|
|
}; |
|
|
|
// After reinterpret, buffers used as transfer source, uniforms, or storage
|
|
|
|
static constexpr VkMemoryBarrier WRITE_BARRIER{ |
|
|
|
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, |
|
|
|
.pNext = nullptr, |
|
|
|
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, |
|
|
|
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_READ_BIT, |
|
|
|
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, |
|
|
|
}; |
|
|
|
const std::array pre_barriers{ |
|
|
|
VkImageMemoryBarrier{ |
|
|
|
@ -1112,39 +1094,18 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src, |
|
|
|
.subresourceRange = dst_range.SubresourceRange(dst_aspect_mask), |
|
|
|
}, |
|
|
|
}; |
|
|
|
const VkPipelineStageFlags src_stages_transfer = |
|
|
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | |
|
|
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT; |
|
|
|
cmdbuf.PipelineBarrier(src_stages_transfer, VK_PIPELINE_STAGE_TRANSFER_BIT, |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, |
|
|
|
0, {}, {}, pre_barriers); |
|
|
|
|
|
|
|
cmdbuf.CopyImageToBuffer(src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, copy_buffer, |
|
|
|
vk_in_copies); |
|
|
|
const VkPipelineStageFlags dst_stages_transfer = |
|
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | |
|
|
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT; |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stages_transfer, |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, |
|
|
|
0, WRITE_BARRIER, nullptr, middle_in_barrier); |
|
|
|
|
|
|
|
cmdbuf.PipelineBarrier(src_stages_transfer, VK_PIPELINE_STAGE_TRANSFER_BIT, |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, |
|
|
|
0, READ_BARRIER, {}, middle_out_barrier); |
|
|
|
cmdbuf.CopyBufferToImage(copy_buffer, dst_image, VK_IMAGE_LAYOUT_GENERAL, vk_out_copies); |
|
|
|
// After reinterpret copy, image may be used in shaders or as attachment
|
|
|
|
const VkPipelineStageFlags dst_stages_post = |
|
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | |
|
|
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stages_post, |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, |
|
|
|
0, {}, {}, post_barriers); |
|
|
|
}); |
|
|
|
} |
|
|
|
@ -1271,12 +1232,7 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst |
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS, |
|
|
|
}, |
|
|
|
}; |
|
|
|
const VkPipelineStageFlags src_stages_resolve = |
|
|
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | |
|
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT; |
|
|
|
cmdbuf.PipelineBarrier(src_stages_resolve, VK_PIPELINE_STAGE_TRANSFER_BIT, |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, |
|
|
|
0, nullptr, nullptr, read_barriers); |
|
|
|
if (is_resolve) { |
|
|
|
cmdbuf.ResolveImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, |
|
|
|
@ -1289,14 +1245,7 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst |
|
|
|
src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
|
|
|
MakeImageBlit(dst_region, src_region, dst_layers, src_layers), vk_filter); |
|
|
|
} |
|
|
|
// After blit/resolve, image may be used in shaders or as attachment
|
|
|
|
const VkPipelineStageFlags dst_stages_blit = |
|
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | |
|
|
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stages_blit, |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, |
|
|
|
0, write_barrier); |
|
|
|
}); |
|
|
|
} |
|
|
|
@ -1874,14 +1823,7 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o |
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS, |
|
|
|
}, |
|
|
|
}; |
|
|
|
const VkPipelineStageFlags src_stages_download = |
|
|
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | |
|
|
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT; |
|
|
|
cmdbuf.PipelineBarrier(src_stages_download, VK_PIPELINE_STAGE_TRANSFER_BIT, |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, |
|
|
|
0, read_barrier); |
|
|
|
|
|
|
|
for (size_t index = 0; index < buffers.size(); index++) { |
|
|
|
@ -1889,20 +1831,17 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o |
|
|
|
vk_copies[index]); |
|
|
|
} |
|
|
|
|
|
|
|
// Host will read the downloaded data
|
|
|
|
const VkMemoryBarrier memory_write_barrier{ |
|
|
|
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, |
|
|
|
.pNext = nullptr, |
|
|
|
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, |
|
|
|
.dstAccessMask = VK_ACCESS_HOST_READ_BIT, |
|
|
|
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, |
|
|
|
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, |
|
|
|
}; |
|
|
|
// Image will be used for shaders or as attachment
|
|
|
|
const VkImageMemoryBarrier image_write_barrier{ |
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
|
|
|
.pNext = nullptr, |
|
|
|
.srcAccessMask = 0, |
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | |
|
|
|
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
|
|
|
.dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, |
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
@ -1916,13 +1855,7 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o |
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS, |
|
|
|
}, |
|
|
|
}; |
|
|
|
const VkPipelineStageFlags dst_stages_download = |
|
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | |
|
|
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stages_download, |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, |
|
|
|
0, memory_write_barrier, nullptr, image_write_barrier); |
|
|
|
}); |
|
|
|
return; |
|
|
|
@ -1957,15 +1890,7 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o |
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS, |
|
|
|
}, |
|
|
|
}; |
|
|
|
// Image writes can come from graphics or compute stages
|
|
|
|
const VkPipelineStageFlags src_stages_img = |
|
|
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | |
|
|
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT; |
|
|
|
cmdbuf.PipelineBarrier(src_stages_img, VK_PIPELINE_STAGE_TRANSFER_BIT, |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, |
|
|
|
0, read_barrier); |
|
|
|
|
|
|
|
for (size_t index = 0; index < buffers.size(); index++) { |
|
|
|
@ -1997,14 +1922,7 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o |
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS, |
|
|
|
}, |
|
|
|
}; |
|
|
|
// After download, image may be used in shaders or as attachment
|
|
|
|
const VkPipelineStageFlags dst_stages_img = |
|
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | |
|
|
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stages_img, |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, |
|
|
|
0, memory_write_barrier, nullptr, image_write_barrier); |
|
|
|
}); |
|
|
|
} |
|
|
|
@ -2566,9 +2484,7 @@ void TextureCacheRuntime::TransitionImageLayout(Image& image) { |
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
|
|
|
.pNext = nullptr, |
|
|
|
.srcAccessMask = VK_ACCESS_NONE, |
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | |
|
|
|
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | |
|
|
|
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, |
|
|
|
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, |
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, |
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
@ -2584,16 +2500,8 @@ void TextureCacheRuntime::TransitionImageLayout(Image& image) { |
|
|
|
}; |
|
|
|
scheduler.RequestOutsideRenderPassOperationContext(); |
|
|
|
scheduler.Record([barrier](vk::CommandBuffer cmdbuf) { |
|
|
|
// After layout transition, image may be used in shaders or as attachment
|
|
|
|
const VkPipelineStageFlags dst_stages_layout = |
|
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | |
|
|
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | |
|
|
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | |
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT; |
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, |
|
|
|
dst_stages_layout, 0, barrier); |
|
|
|
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, barrier); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|