|
|
@ -6,6 +6,7 @@ |
|
|
|
|
|
|
|
|
#pragma once |
|
|
#pragma once |
|
|
|
|
|
|
|
|
|
|
|
#include <array> |
|
|
#include <exception> |
|
|
#include <exception> |
|
|
#include <limits> |
|
|
#include <limits> |
|
|
#include <memory> |
|
|
#include <memory> |
|
|
@ -237,6 +238,7 @@ struct DeviceDispatch : InstanceDispatch { |
|
|
PFN_vkCmdEndTransformFeedbackEXT vkCmdEndTransformFeedbackEXT{}; |
|
|
PFN_vkCmdEndTransformFeedbackEXT vkCmdEndTransformFeedbackEXT{}; |
|
|
PFN_vkCmdFillBuffer vkCmdFillBuffer{}; |
|
|
PFN_vkCmdFillBuffer vkCmdFillBuffer{}; |
|
|
PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier{}; |
|
|
PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier{}; |
|
|
|
|
|
PFN_vkCmdPipelineBarrier2 vkCmdPipelineBarrier2{}; |
|
|
PFN_vkCmdPushConstants vkCmdPushConstants{}; |
|
|
PFN_vkCmdPushConstants vkCmdPushConstants{}; |
|
|
PFN_vkCmdPushDescriptorSetWithTemplateKHR vkCmdPushDescriptorSetWithTemplateKHR{}; |
|
|
PFN_vkCmdPushDescriptorSetWithTemplateKHR vkCmdPushDescriptorSetWithTemplateKHR{}; |
|
|
PFN_vkCmdResolveImage vkCmdResolveImage{}; |
|
|
PFN_vkCmdResolveImage vkCmdResolveImage{}; |
|
|
@ -340,6 +342,7 @@ struct DeviceDispatch : InstanceDispatch { |
|
|
PFN_vkGetSemaphoreCounterValue vkGetSemaphoreCounterValue{}; |
|
|
PFN_vkGetSemaphoreCounterValue vkGetSemaphoreCounterValue{}; |
|
|
PFN_vkMapMemory vkMapMemory{}; |
|
|
PFN_vkMapMemory vkMapMemory{}; |
|
|
PFN_vkQueueSubmit vkQueueSubmit{}; |
|
|
PFN_vkQueueSubmit vkQueueSubmit{}; |
|
|
|
|
|
PFN_vkQueueSubmit2 vkQueueSubmit2{}; |
|
|
PFN_vkResetFences vkResetFences{}; |
|
|
PFN_vkResetFences vkResetFences{}; |
|
|
PFN_vkResetQueryPool vkResetQueryPool{}; |
|
|
PFN_vkResetQueryPool vkResetQueryPool{}; |
|
|
PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT{}; |
|
|
PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT{}; |
|
|
@ -819,6 +822,13 @@ public: |
|
|
return dld->vkQueueSubmit(queue, submit_infos.size(), submit_infos.data(), fence); |
|
|
return dld->vkQueueSubmit(queue, submit_infos.size(), submit_infos.data(), fence); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Submits using VK_KHR_synchronization2 / Vulkan 1.3 vkQueueSubmit2. |
|
|
|
|
|
/// Only valid to call when the device dispatch table has vkQueueSubmit2 loaded. |
|
|
|
|
|
VkResult Submit2(Span<VkSubmitInfo2> submit_infos, |
|
|
|
|
|
VkFence fence = VK_NULL_HANDLE) const noexcept { |
|
|
|
|
|
return dld->vkQueueSubmit2(queue, submit_infos.size(), submit_infos.data(), fence); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
VkResult Present(const VkPresentInfoKHR& present_info) const noexcept { |
|
|
VkResult Present(const VkPresentInfoKHR& present_info) const noexcept { |
|
|
return dld->vkQueuePresentKHR(queue, &present_info); |
|
|
return dld->vkQueuePresentKHR(queue, &present_info); |
|
|
} |
|
|
} |
|
|
@ -1287,6 +1297,74 @@ public: |
|
|
VkDependencyFlags dependency_flags, Span<VkMemoryBarrier> memory_barriers, |
|
|
VkDependencyFlags dependency_flags, Span<VkMemoryBarrier> memory_barriers, |
|
|
Span<VkBufferMemoryBarrier> buffer_barriers, |
|
|
Span<VkBufferMemoryBarrier> buffer_barriers, |
|
|
Span<VkImageMemoryBarrier> image_barriers) const noexcept { |
|
|
Span<VkImageMemoryBarrier> image_barriers) const noexcept { |
|
|
|
|
|
// Legacy VkPipelineStageFlagBits/VkAccessFlagBits are bit-compatible with their |
|
|
|
|
|
// Synchronization2 *2 counterparts, so barriers can be widened without a lookup table. |
|
|
|
|
|
static constexpr u32 MaxBarriers = 16; |
|
|
|
|
|
if (dld->vkCmdPipelineBarrier2 && memory_barriers.size() <= MaxBarriers && |
|
|
|
|
|
buffer_barriers.size() <= MaxBarriers && image_barriers.size() <= MaxBarriers) { |
|
|
|
|
|
const auto src_stage_mask2 = static_cast<VkPipelineStageFlags2>(src_stage_mask); |
|
|
|
|
|
const auto dst_stage_mask2 = static_cast<VkPipelineStageFlags2>(dst_stage_mask); |
|
|
|
|
|
|
|
|
|
|
|
std::array<VkMemoryBarrier2, MaxBarriers> memory_barriers2; |
|
|
|
|
|
for (u32 i = 0; i < memory_barriers.size(); ++i) { |
|
|
|
|
|
memory_barriers2[i] = VkMemoryBarrier2{ |
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, |
|
|
|
|
|
.pNext = nullptr, |
|
|
|
|
|
.srcStageMask = src_stage_mask2, |
|
|
|
|
|
.srcAccessMask = static_cast<VkAccessFlags2>(memory_barriers[i].srcAccessMask), |
|
|
|
|
|
.dstStageMask = dst_stage_mask2, |
|
|
|
|
|
.dstAccessMask = static_cast<VkAccessFlags2>(memory_barriers[i].dstAccessMask), |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
std::array<VkBufferMemoryBarrier2, MaxBarriers> buffer_barriers2; |
|
|
|
|
|
for (u32 i = 0; i < buffer_barriers.size(); ++i) { |
|
|
|
|
|
const auto& barrier = buffer_barriers[i]; |
|
|
|
|
|
buffer_barriers2[i] = VkBufferMemoryBarrier2{ |
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2, |
|
|
|
|
|
.pNext = nullptr, |
|
|
|
|
|
.srcStageMask = src_stage_mask2, |
|
|
|
|
|
.srcAccessMask = static_cast<VkAccessFlags2>(barrier.srcAccessMask), |
|
|
|
|
|
.dstStageMask = dst_stage_mask2, |
|
|
|
|
|
.dstAccessMask = static_cast<VkAccessFlags2>(barrier.dstAccessMask), |
|
|
|
|
|
.srcQueueFamilyIndex = barrier.srcQueueFamilyIndex, |
|
|
|
|
|
.dstQueueFamilyIndex = barrier.dstQueueFamilyIndex, |
|
|
|
|
|
.buffer = barrier.buffer, |
|
|
|
|
|
.offset = barrier.offset, |
|
|
|
|
|
.size = barrier.size, |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
std::array<VkImageMemoryBarrier2, MaxBarriers> image_barriers2; |
|
|
|
|
|
for (u32 i = 0; i < image_barriers.size(); ++i) { |
|
|
|
|
|
const auto& barrier = image_barriers[i]; |
|
|
|
|
|
image_barriers2[i] = VkImageMemoryBarrier2{ |
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, |
|
|
|
|
|
.pNext = nullptr, |
|
|
|
|
|
.srcStageMask = src_stage_mask2, |
|
|
|
|
|
.srcAccessMask = static_cast<VkAccessFlags2>(barrier.srcAccessMask), |
|
|
|
|
|
.dstStageMask = dst_stage_mask2, |
|
|
|
|
|
.dstAccessMask = static_cast<VkAccessFlags2>(barrier.dstAccessMask), |
|
|
|
|
|
.oldLayout = barrier.oldLayout, |
|
|
|
|
|
.newLayout = barrier.newLayout, |
|
|
|
|
|
.srcQueueFamilyIndex = barrier.srcQueueFamilyIndex, |
|
|
|
|
|
.dstQueueFamilyIndex = barrier.dstQueueFamilyIndex, |
|
|
|
|
|
.image = barrier.image, |
|
|
|
|
|
.subresourceRange = barrier.subresourceRange, |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
const VkDependencyInfo dependency_info{ |
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, |
|
|
|
|
|
.pNext = nullptr, |
|
|
|
|
|
.dependencyFlags = dependency_flags, |
|
|
|
|
|
.memoryBarrierCount = memory_barriers.size(), |
|
|
|
|
|
.pMemoryBarriers = memory_barriers2.data(), |
|
|
|
|
|
.bufferMemoryBarrierCount = buffer_barriers.size(), |
|
|
|
|
|
.pBufferMemoryBarriers = buffer_barriers2.data(), |
|
|
|
|
|
.imageMemoryBarrierCount = image_barriers.size(), |
|
|
|
|
|
.pImageMemoryBarriers = image_barriers2.data(), |
|
|
|
|
|
}; |
|
|
|
|
|
dld->vkCmdPipelineBarrier2(handle, &dependency_info); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
dld->vkCmdPipelineBarrier(handle, src_stage_mask, dst_stage_mask, dependency_flags, |
|
|
dld->vkCmdPipelineBarrier(handle, src_stage_mask, dst_stage_mask, dependency_flags, |
|
|
memory_barriers.size(), memory_barriers.data(), |
|
|
memory_barriers.size(), memory_barriers.data(), |
|
|
buffer_barriers.size(), buffer_barriers.data(), |
|
|
buffer_barriers.size(), buffer_barriers.data(), |
|
|
|