@@ -445,10 +445,18 @@ class VulkanFence : public offloadtest::Fence {
445445
446446class VulkanQueue : public offloadtest ::Queue {
447447public:
448+ using Queue::submit;
449+
448450 VkQueue Queue = VK_NULL_HANDLE;
449451 uint32_t QueueFamilyIdx = 0 ;
450- VulkanQueue (VkQueue Q, uint32_t QueueFamilyIdx)
451- : Queue(Q), QueueFamilyIdx(QueueFamilyIdx) {}
452+ // TODO: Ensure device lifetime is managed (e.g. via shared_ptr).
453+ VkDevice Device = VK_NULL_HANDLE;
454+ VulkanQueue (VkQueue Q, uint32_t QueueFamilyIdx, VkDevice Device)
455+ : Queue(Q), QueueFamilyIdx(QueueFamilyIdx), Device(Device) {}
456+
457+ llvm::Error
458+ submit (llvm::SmallVector<std::unique_ptr<offloadtest::CommandBuffer>> CBs)
459+ override ;
452460};
453461
454462class VulkanCommandBuffer : public offloadtest ::CommandBuffer {
@@ -501,6 +509,37 @@ class VulkanCommandBuffer : public offloadtest::CommandBuffer {
501509 VulkanCommandBuffer () : CommandBuffer(GPUAPI::Vulkan) {}
502510};
503511
512+ llvm::Error VulkanQueue::submit (
513+ llvm::SmallVector<std::unique_ptr<offloadtest::CommandBuffer>> CBs) {
514+ for (auto &CB : CBs) {
515+ auto &VCB = CB->as <VulkanCommandBuffer>();
516+ if (vkEndCommandBuffer (VCB.CmdBuffer ))
517+ return llvm::createStringError (std::errc::device_or_resource_busy,
518+ " Could not end command buffer." );
519+
520+ VkSubmitInfo SubmitInfo = {};
521+ SubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
522+ SubmitInfo.commandBufferCount = 1 ;
523+ SubmitInfo.pCommandBuffers = &VCB.CmdBuffer ;
524+
525+ VkFenceCreateInfo FenceInfo = {};
526+ FenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
527+ VkFence Fence;
528+ if (vkCreateFence (Device, &FenceInfo, nullptr , &Fence))
529+ return llvm::createStringError (std::errc::device_or_resource_busy,
530+ " Could not create fence." );
531+
532+ if (vkQueueSubmit (Queue, 1 , &SubmitInfo, Fence))
533+ return llvm::createStringError (std::errc::device_or_resource_busy,
534+ " Failed to submit to queue." );
535+ if (vkWaitForFences (Device, 1 , &Fence, VK_TRUE, UINT64_MAX))
536+ return llvm::createStringError (std::errc::device_or_resource_busy,
537+ " Failed waiting for fence." );
538+
539+ vkDestroyFence (Device, Fence, nullptr );
540+ }
541+ return llvm::Error::success ();
542+ }
504543class VulkanDevice : public offloadtest ::Device {
505544private:
506545 std::shared_ptr<VulkanInstance> Instance;
@@ -699,7 +738,8 @@ class VulkanDevice : public offloadtest::Device {
699738 VkQueue DeviceQueue = VK_NULL_HANDLE;
700739 vkGetDeviceQueue (Device, QueueFamilyIdx, 0 , &DeviceQueue);
701740
702- const VulkanQueue GraphicsQueue = VulkanQueue (DeviceQueue, QueueFamilyIdx);
741+ const VulkanQueue GraphicsQueue =
742+ VulkanQueue (DeviceQueue, QueueFamilyIdx, Device);
703743
704744 return std::make_unique<VulkanDevice>(Instance, PhysicalDevice, Props,
705745 Device, std::move (GraphicsQueue),
@@ -1239,41 +1279,7 @@ class VulkanDevice : public offloadtest::Device {
12391279 }
12401280
12411281 llvm::Error executeCommandBuffer (InvocationState &IS) {
1242- // This is a hack but it works since this is all single threaded code.
1243- static uint64_t FenceCounter = 0 ;
1244- const uint64_t CurrentCounter = FenceCounter + 1 ;
1245-
1246- if (vkEndCommandBuffer (IS.CB ->CmdBuffer ))
1247- return llvm::createStringError (std::errc::device_or_resource_busy,
1248- " Could not end command buffer." );
1249-
1250- auto *F = static_cast <VulkanFence *>(IS.Fence .get ());
1251-
1252- VkTimelineSemaphoreSubmitInfo TimelineSubmitInfo = {};
1253- TimelineSubmitInfo.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
1254- TimelineSubmitInfo.signalSemaphoreValueCount = 1 ;
1255- TimelineSubmitInfo.pSignalSemaphoreValues = &CurrentCounter;
1256-
1257- VkSubmitInfo SubmitInfo = {};
1258- SubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1259- SubmitInfo.pNext = &TimelineSubmitInfo;
1260- SubmitInfo.commandBufferCount = 1 ;
1261- SubmitInfo.pCommandBuffers = &IS.CB ->CmdBuffer ;
1262- SubmitInfo.signalSemaphoreCount = 1 ;
1263- SubmitInfo.pSignalSemaphores = &F->Semaphore ;
1264-
1265- // Submit to the queue
1266- if (vkQueueSubmit (GraphicsQueue.Queue , 1 , &SubmitInfo, VK_NULL_HANDLE))
1267- return llvm::createStringError (std::errc::device_or_resource_busy,
1268- " Failed to submit to queue." );
1269-
1270- if (auto Err = IS.Fence ->waitForCompletion (CurrentCounter))
1271- return Err;
1272-
1273- vkFreeCommandBuffers (Device, IS.CB ->CmdPool , 1 , &IS.CB ->CmdBuffer );
1274-
1275- FenceCounter = CurrentCounter;
1276- return llvm::Error::success ();
1282+ return GraphicsQueue.submit (std::move (IS.CB ));
12771283 }
12781284
12791285 llvm::Error createDescriptorPool (Pipeline &P, InvocationState &IS) {
0 commit comments