@@ -472,10 +472,23 @@ class VulkanFence : public offloadtest::Fence {
472472
473473class VulkanQueue : public offloadtest ::Queue {
474474public:
475+ using Queue::submit;
476+
475477 VkQueue Queue = VK_NULL_HANDLE;
476478 uint32_t QueueFamilyIdx = 0 ;
477- VulkanQueue (VkQueue Q, uint32_t QueueFamilyIdx)
478- : Queue(Q), QueueFamilyIdx(QueueFamilyIdx) {}
479+ // TODO: Ensure device lifetime is managed (e.g. via shared_ptr).
480+ VkDevice Device = VK_NULL_HANDLE;
481+ std::unique_ptr<VulkanFence> SubmitFence;
482+ uint64_t FenceCounter = 0 ;
483+
484+ VulkanQueue (VkQueue Q, uint32_t QueueFamilyIdx, VkDevice Device,
485+ std::unique_ptr<VulkanFence> SubmitFence)
486+ : Queue(Q), QueueFamilyIdx(QueueFamilyIdx), Device(Device),
487+ SubmitFence (std::move(SubmitFence)) {}
488+
489+ llvm::Error
490+ submit (llvm::SmallVector<std::unique_ptr<offloadtest::CommandBuffer>> CBs)
491+ override ;
479492};
480493
481494class VulkanCommandBuffer : public offloadtest ::CommandBuffer {
@@ -528,6 +541,38 @@ class VulkanCommandBuffer : public offloadtest::CommandBuffer {
528541 VulkanCommandBuffer () : CommandBuffer(GPUAPI::Vulkan) {}
529542};
530543
544+ llvm::Error VulkanQueue::submit (
545+ llvm::SmallVector<std::unique_ptr<offloadtest::CommandBuffer>> CBs) {
546+ for (auto &CB : CBs) {
547+ auto &VCB = CB->as <VulkanCommandBuffer>();
548+ if (vkEndCommandBuffer (VCB.CmdBuffer ))
549+ return llvm::createStringError (std::errc::device_or_resource_busy,
550+ " Could not end command buffer." );
551+
552+ const uint64_t SignalValue = ++FenceCounter;
553+
554+ VkTimelineSemaphoreSubmitInfo TimelineInfo = {};
555+ TimelineInfo.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
556+ TimelineInfo.signalSemaphoreValueCount = 1 ;
557+ TimelineInfo.pSignalSemaphoreValues = &SignalValue;
558+
559+ VkSubmitInfo SubmitInfo = {};
560+ SubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
561+ SubmitInfo.pNext = &TimelineInfo;
562+ SubmitInfo.commandBufferCount = 1 ;
563+ SubmitInfo.pCommandBuffers = &VCB.CmdBuffer ;
564+ SubmitInfo.signalSemaphoreCount = 1 ;
565+ SubmitInfo.pSignalSemaphores = &SubmitFence->Semaphore ;
566+
567+ if (vkQueueSubmit (Queue, 1 , &SubmitInfo, VK_NULL_HANDLE))
568+ return llvm::createStringError (std::errc::device_or_resource_busy,
569+ " Failed to submit to queue." );
570+
571+ if (auto Err = SubmitFence->waitForCompletion (SignalValue))
572+ return Err;
573+ }
574+ return llvm::Error::success ();
575+ }
531576class VulkanDevice : public offloadtest ::Device {
532577private:
533578 std::shared_ptr<VulkanInstance> Instance;
@@ -726,7 +771,11 @@ class VulkanDevice : public offloadtest::Device {
726771 VkQueue DeviceQueue = VK_NULL_HANDLE;
727772 vkGetDeviceQueue (Device, QueueFamilyIdx, 0 , &DeviceQueue);
728773
729- const VulkanQueue GraphicsQueue = VulkanQueue (DeviceQueue, QueueFamilyIdx);
774+ auto SubmitFenceOrErr = VulkanFence::create (Device, " QueueSubmitFence" );
775+ if (!SubmitFenceOrErr)
776+ return SubmitFenceOrErr.takeError ();
777+ VulkanQueue GraphicsQueue (DeviceQueue, QueueFamilyIdx, Device,
778+ std::move (*SubmitFenceOrErr));
730779
731780 return std::make_unique<VulkanDevice>(Instance, PhysicalDevice, Props,
732781 Device, std::move (GraphicsQueue),
@@ -1298,41 +1347,7 @@ class VulkanDevice : public offloadtest::Device {
12981347 }
12991348
13001349 llvm::Error executeCommandBuffer (InvocationState &IS) {
1301- // This is a hack but it works since this is all single threaded code.
1302- static uint64_t FenceCounter = 0 ;
1303- const uint64_t CurrentCounter = FenceCounter + 1 ;
1304-
1305- if (vkEndCommandBuffer (IS.CB ->CmdBuffer ))
1306- return llvm::createStringError (std::errc::device_or_resource_busy,
1307- " Could not end command buffer." );
1308-
1309- auto *F = static_cast <VulkanFence *>(IS.Fence .get ());
1310-
1311- VkTimelineSemaphoreSubmitInfo TimelineSubmitInfo = {};
1312- TimelineSubmitInfo.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
1313- TimelineSubmitInfo.signalSemaphoreValueCount = 1 ;
1314- TimelineSubmitInfo.pSignalSemaphoreValues = &CurrentCounter;
1315-
1316- VkSubmitInfo SubmitInfo = {};
1317- SubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1318- SubmitInfo.pNext = &TimelineSubmitInfo;
1319- SubmitInfo.commandBufferCount = 1 ;
1320- SubmitInfo.pCommandBuffers = &IS.CB ->CmdBuffer ;
1321- SubmitInfo.signalSemaphoreCount = 1 ;
1322- SubmitInfo.pSignalSemaphores = &F->Semaphore ;
1323-
1324- // Submit to the queue
1325- if (vkQueueSubmit (GraphicsQueue.Queue , 1 , &SubmitInfo, VK_NULL_HANDLE))
1326- return llvm::createStringError (std::errc::device_or_resource_busy,
1327- " Failed to submit to queue." );
1328-
1329- if (auto Err = IS.Fence ->waitForCompletion (CurrentCounter))
1330- return Err;
1331-
1332- vkFreeCommandBuffers (Device, IS.CB ->CmdPool , 1 , &IS.CB ->CmdBuffer );
1333-
1334- FenceCounter = CurrentCounter;
1335- return llvm::Error::success ();
1350+ return GraphicsQueue.submit (std::move (IS.CB ));
13361351 }
13371352
13381353 llvm::Error createDescriptorPool (Pipeline &P, InvocationState &IS) {
0 commit comments