Skip to content

Commit d312da4

Browse files
Use the new Fence type in both DX and Vulkan backends.
1 parent 1286c7e commit d312da4

2 files changed

Lines changed: 39 additions & 60 deletions

File tree

lib/API/DX/Device.cpp

Lines changed: 9 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -386,12 +386,7 @@ class DXDevice : public offloadtest::Device {
386386
ComPtr<ID3D12PipelineState> PSO;
387387
ComPtr<ID3D12CommandAllocator> Allocator;
388388
ComPtr<ID3D12GraphicsCommandList> CmdList;
389-
ComPtr<ID3D12Fence> Fence;
390-
#ifdef _WIN32
391-
HANDLE Event;
392-
#else // WSL
393-
int Event;
394-
#endif
389+
std::shared_ptr<offloadtest::Fence> Fence;
395390

396391
// Resources for graphics pipelines.
397392
ComPtr<ID3D12Resource> RT;
@@ -1197,56 +1192,20 @@ class DXDevice : public offloadtest::Device {
11971192
IS.CmdList->ResourceBarrier(1, &Barrier);
11981193
}
11991194

1200-
llvm::Error createEvent(InvocationState &IS) {
1201-
if (auto Err = HR::toError(Device->CreateFence(0, D3D12_FENCE_FLAG_NONE,
1202-
IID_PPV_ARGS(&IS.Fence)),
1203-
"Failed to create fence."))
1204-
return Err;
1205-
#ifdef _WIN32
1206-
IS.Event = CreateEventA(nullptr, false, false, nullptr);
1207-
if (!IS.Event)
1208-
#else // WSL
1209-
IS.Event = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
1210-
if (IS.Event == -1)
1211-
#endif
1212-
return llvm::createStringError(std::errc::device_or_resource_busy,
1213-
"Failed to create event.");
1214-
return llvm::Error::success();
1215-
}
1216-
12171195
llvm::Error waitForSignal(InvocationState &IS) {
12181196
// This is a hack but it works since this is all single threaded code.
12191197
static uint64_t FenceCounter = 0;
12201198
const uint64_t CurrentCounter = FenceCounter + 1;
1199+
auto *F = static_cast<DXFence *>(IS.Fence.get());
12211200

12221201
if (auto Err = HR::toError(
1223-
GraphicsQueue.Queue->Signal(IS.Fence.Get(), CurrentCounter),
1202+
GraphicsQueue.Queue->Signal(F->Fence.Get(), CurrentCounter),
12241203
"Failed to add signal."))
12251204
return Err;
12261205

1227-
if (IS.Fence->GetCompletedValue() < CurrentCounter) {
1228-
#ifdef _WIN32
1229-
HANDLE Event = IS.Event;
1230-
#else // WSL
1231-
HANDLE Event = reinterpret_cast<HANDLE>(IS.Event);
1232-
#endif
1233-
if (auto Err =
1234-
HR::toError(IS.Fence->SetEventOnCompletion(CurrentCounter, Event),
1235-
"Failed to register end event."))
1236-
return Err;
1206+
if (auto Err = IS.Fence->waitForCompletion(CurrentCounter))
1207+
return Err;
12371208

1238-
#ifdef _WIN32
1239-
WaitForSingleObject(IS.Event, INFINITE);
1240-
#else // WSL
1241-
pollfd PollEvent;
1242-
PollEvent.fd = IS.Event;
1243-
PollEvent.events = POLLIN;
1244-
PollEvent.revents = 0;
1245-
if (poll(&PollEvent, 1, -1) == -1)
1246-
return llvm::createStringError(
1247-
std::error_code(errno, std::system_category()), strerror(errno));
1248-
#endif
1249-
}
12501209
FenceCounter = CurrentCounter;
12511210
return llvm::Error::success();
12521211
}
@@ -1751,9 +1710,10 @@ class DXDevice : public offloadtest::Device {
17511710
return Err;
17521711
llvm::outs() << "Command structures created.\n";
17531712

1754-
if (auto Err = createEvent(State))
1755-
return Err;
1756-
llvm::outs() << "Event prepared.\n";
1713+
auto FenceOrErr = this->createFence("Fence");
1714+
if (!FenceOrErr)
1715+
return FenceOrErr.takeError();
1716+
State.Fence = *FenceOrErr;
17571717

17581718
if (auto Err = createBuffers(P, State))
17591719
return Err;

lib/API/VK/Device.cpp

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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

400402
class 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

Comments
 (0)