vulkan: fix locking for non-dedicated queues (#720)

Some devices don't offer dedicated queues, just one "does everything"
queue. In those cases, our logically separate queues are the same
Vulkan queue, so we need to make sure that those queue share the same
mutex.

Co-authored-by: Turánszki János <turanszkij@users.noreply.github.com>
This commit is contained in:
Dennis Brakhane
2023-07-31 07:28:51 +02:00
committed by GitHub
parent 8701e38411
commit 3d351274a5
2 changed files with 17 additions and 7 deletions
+16 -6
View File
@@ -1299,7 +1299,7 @@ using namespace vulkan_internal;
{
if (queue == VK_NULL_HANDLE)
return;
std::scoped_lock lock(locker);
std::scoped_lock lock(*locker);
VkSubmitInfo2 submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2;
@@ -1489,7 +1489,7 @@ using namespace vulkan_internal;
submitInfo.signalSemaphoreInfoCount = 1;
submitInfo.pSignalSemaphoreInfos = signalSemaphoreInfos;
std::scoped_lock lock(device->queues[QUEUE_COPY].locker);
std::scoped_lock lock(*device->queues[QUEUE_COPY].locker);
res = vkQueueSubmit2(device->queues[QUEUE_COPY].queue, 1, &submitInfo, VK_NULL_HANDLE);
assert(res == VK_SUCCESS);
}
@@ -1518,7 +1518,7 @@ using namespace vulkan_internal;
}
submitInfo.pSignalSemaphoreInfos = signalSemaphoreInfos;
std::scoped_lock lock(device->queues[QUEUE_GRAPHICS].locker);
std::scoped_lock lock(*device->queues[QUEUE_GRAPHICS].locker);
res = vkQueueSubmit2(device->queues[QUEUE_GRAPHICS].queue, 1, &submitInfo, VK_NULL_HANDLE);
assert(res == VK_SUCCESS);
}
@@ -1535,7 +1535,7 @@ using namespace vulkan_internal;
submitInfo.signalSemaphoreInfoCount = 0;
submitInfo.pSignalSemaphoreInfos = nullptr;
std::scoped_lock lock(device->queues[QUEUE_VIDEO_DECODE].locker);
std::scoped_lock lock(*device->queues[QUEUE_VIDEO_DECODE].locker);
res = vkQueueSubmit2(device->queues[QUEUE_VIDEO_DECODE].queue, 1, &submitInfo, VK_NULL_HANDLE);
assert(res == VK_SUCCESS);
}
@@ -1552,7 +1552,7 @@ using namespace vulkan_internal;
submitInfo.signalSemaphoreInfoCount = 0;
submitInfo.pSignalSemaphoreInfos = nullptr;
std::scoped_lock lock(device->queues[QUEUE_COMPUTE].locker);
std::scoped_lock lock(*device->queues[QUEUE_COMPUTE].locker);
res = vkQueueSubmit2(device->queues[QUEUE_COMPUTE].queue, 1, &submitInfo, cmd.fence); // final submit also signals fence!
assert(res == VK_SUCCESS);
}
@@ -2326,6 +2326,8 @@ using namespace vulkan_internal;
{
wi::Timer timer;
wi::unordered_map<uint32_t, std::shared_ptr<std::mutex>> queue_lockers;
TOPLEVEL_ACCELERATION_STRUCTURE_INSTANCE_SIZE = sizeof(VkAccelerationStructureInstanceKHR);
validationMode = validationMode_;
@@ -2969,6 +2971,7 @@ using namespace vulkan_internal;
float queuePriority = 1.0f;
for (uint32_t queueFamily : uniqueQueueFamilies)
{
queue_lockers.emplace(queueFamily, std::make_shared<std::mutex>());
VkDeviceQueueCreateInfo queueCreateInfo = {};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = queueFamily;
@@ -3009,9 +3012,15 @@ using namespace vulkan_internal;
}
queues[QUEUE_GRAPHICS].queue = graphicsQueue;
queues[QUEUE_GRAPHICS].locker = queue_lockers[graphicsFamily];
queues[QUEUE_COMPUTE].queue = computeQueue;
queues[QUEUE_COMPUTE].locker = queue_lockers[computeFamily];
queues[QUEUE_COPY].queue = copyQueue;
queues[QUEUE_COPY].locker = queue_lockers[copyFamily];
queues[QUEUE_VIDEO_DECODE].queue = videoQueue;
if (videoFamily != VK_QUEUE_FAMILY_IGNORED) {
queues[QUEUE_VIDEO_DECODE].locker = queue_lockers[videoFamily];
}
VkSemaphoreTypeCreateInfo timelineCreateInfo = {};
timelineCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
@@ -3564,6 +3573,7 @@ using namespace vulkan_internal;
for (auto& queue : queues)
{
vkDestroySemaphore(device, queue.semaphore, nullptr);
queue.locker.reset();
}
for (uint32_t fr = 0; fr < BUFFERCOUNT; ++fr)
@@ -7369,7 +7379,7 @@ using namespace vulkan_internal;
// Queue command:
{
CommandQueue& q = queues[queue];
std::scoped_lock lock(q.locker);
std::scoped_lock lock(*q.locker);
assert(q.sparse_binding_supported);
VkResult res = vkQueueBindSparse(q.queue, (uint32_t)sparse_infos.size(), sparse_infos.data(), VK_NULL_HANDLE);
+1 -1
View File
@@ -118,7 +118,7 @@ namespace wi::graphics
wi::vector<VkCommandBufferSubmitInfo> submit_cmds;
bool sparse_binding_supported = false;
std::mutex locker;
std::shared_ptr<std::mutex> locker;
void submit(GraphicsDevice_Vulkan* device, VkFence fence);