@@ -395,6 +395,8 @@ class VulkanFence : public offloadtest::Fence {
395395
396396 VulkanFence (VkDevice Device, VkSemaphore Semaphore, llvm::StringRef Name)
397397 : Device(Device), Semaphore(Semaphore), Name(Name) {}
398+
399+ ~VulkanFence () { vkDestroySemaphore (Device, Semaphore, nullptr ); }
398400};
399401
400402class VulkanQueue : public offloadtest ::Queue {
@@ -492,6 +494,8 @@ class VulkanDevice : public offloadtest::Device {
492494 VkPipelineCache PipelineCache;
493495 VkPipeline Pipeline;
494496
497+ std::shared_ptr<Fence> Fence;
498+
495499 // FrameBuffer associated data for offscreen rendering.
496500 VkFramebuffer FrameBuffer;
497501 ResourceBundle FrameBufferResource = {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 0 ,
@@ -1172,32 +1176,41 @@ class VulkanDevice : public offloadtest::Device {
11721176
11731177 llvm::Error executeCommandBuffer (InvocationState &IS,
11741178 VkPipelineStageFlags WaitMask = 0 ) {
1179+ // This is a hack but it works since this is all single threaded code.
1180+ static uint64_t FenceCounter = 0 ;
1181+ const uint64_t CurrentCounter = FenceCounter + 1 ;
1182+
11751183 if (vkEndCommandBuffer (IS.CmdBuffer ))
11761184 return llvm::createStringError (std::errc::device_or_resource_busy,
11771185 " Could not end command buffer." );
11781186
1187+ auto *F = static_cast <VulkanFence *>(IS.Fence .get ());
1188+
1189+ VkTimelineSemaphoreSubmitInfo TimelineSubmitInfo = {};
1190+ TimelineSubmitInfo.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
1191+ TimelineSubmitInfo.signalSemaphoreValueCount = 1 ;
1192+ TimelineSubmitInfo.pSignalSemaphoreValues = &CurrentCounter;
1193+
11791194 VkSubmitInfo SubmitInfo = {};
11801195 SubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1196+ SubmitInfo.pNext = &TimelineSubmitInfo;
11811197 SubmitInfo.commandBufferCount = 1 ;
11821198 SubmitInfo.pCommandBuffers = &IS.CmdBuffer ;
11831199 SubmitInfo.pWaitDstStageMask = &WaitMask;
1184- VkFenceCreateInfo FenceInfo = {};
1185- FenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
1186- VkFence Fence;
1187- if (vkCreateFence (Device, &FenceInfo, nullptr , &Fence))
1188- return llvm::createStringError (std::errc::device_or_resource_busy,
1189- " Could not create fence." );
1200+ SubmitInfo.signalSemaphoreCount = 1 ;
1201+ SubmitInfo.pSignalSemaphores = &F->Semaphore ;
11901202
11911203 // Submit to the queue
1192- if (vkQueueSubmit (GraphicsQueue.Queue , 1 , &SubmitInfo, Fence ))
1204+ if (vkQueueSubmit (GraphicsQueue.Queue , 1 , &SubmitInfo, VK_NULL_HANDLE ))
11931205 return llvm::createStringError (std::errc::device_or_resource_busy,
11941206 " Failed to submit to queue." );
1195- if (vkWaitForFences (Device, 1 , &Fence, VK_TRUE, UINT64_MAX))
1196- return llvm::createStringError (std::errc::device_or_resource_busy,
1197- " Failed waiting for fence." );
11981207
1199- vkDestroyFence (Device, Fence, nullptr );
1208+ if (auto Err = IS.Fence ->waitForCompletion (CurrentCounter))
1209+ return Err;
1210+
12001211 vkFreeCommandBuffers (Device, IS.CmdPool , 1 , &IS.CmdBuffer );
1212+
1213+ FenceCounter = CurrentCounter;
12011214 return llvm::Error::success ();
12021215 }
12031216
@@ -2333,6 +2346,12 @@ class VulkanDevice : public offloadtest::Device {
23332346 InvocationState State;
23342347 if (auto Err = createDevice (State))
23352348 return Err;
2349+
2350+ auto FenceOrErr = this ->createFence (" Fence" );
2351+ if (!FenceOrErr)
2352+ return FenceOrErr.takeError ();
2353+ State.Fence = *FenceOrErr;
2354+
23362355 llvm::outs () << " Physical device created.\n " ;
23372356 if (auto Err = createShaderModules (P, State))
23382357 return Err;
0 commit comments