Skip to content

Commit c4fda62

Browse files
MarijnS95claude
andcommitted
Move Fence creation logic into static create() factories
Make constructors private and expose static create() methods on DXFence, VulkanFence, and MTLFence that return Expected<unique_ptr<...>>. This keeps all platform-specific resource creation encapsulated in each type, matching the pattern used for CommandBuffer. Each Device::createFence override now simply delegates to the respective Fence::create(). Also adds native accessors (getNativeFence, getNativeSemaphore, getNativeEvent) to replace direct member access. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b924236 commit c4fda62

3 files changed

Lines changed: 80 additions & 64 deletions

File tree

lib/API/DX/Device.cpp

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,13 @@ class DXBuffer : public offloadtest::Buffer {
294294
};
295295

296296
class DXFence : public offloadtest::Fence {
297+
#ifdef _WIN32
298+
DXFence(ComPtr<ID3D12Fence> Fence, HANDLE Event, llvm::StringRef Name)
299+
#else // WSL
300+
DXFence(ComPtr<ID3D12Fence> Fence, int Event, llvm::StringRef Name)
301+
#endif
302+
: Name(Name), Fence(Fence), Event(Event) {}
303+
297304
public:
298305
std::string Name;
299306
ComPtr<ID3D12Fence> Fence;
@@ -303,6 +310,35 @@ class DXFence : public offloadtest::Fence {
303310
int Event;
304311
#endif
305312

313+
static llvm::Expected<std::unique_ptr<DXFence>>
314+
create(ID3D12Device *Device, llvm::StringRef Name) {
315+
ComPtr<ID3D12Fence> Fence;
316+
if (auto Err = HR::toError(
317+
Device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&Fence)),
318+
"Failed to create Fence."))
319+
return Err;
320+
321+
#ifdef _WIN32
322+
HANDLE Event = CreateEventA(nullptr, false, false, nullptr);
323+
if (!Event)
324+
#else // WSL
325+
int Event = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
326+
if (Event == -1)
327+
#endif
328+
return llvm::createStringError(std::errc::device_or_resource_busy,
329+
"Failed to create event.");
330+
331+
return std::make_unique<DXFence>(DXFence(std::move(Fence), Event, Name));
332+
}
333+
334+
~DXFence() {
335+
#ifdef _WIN32
336+
CloseHandle(Event);
337+
#else // WSL
338+
close(Event);
339+
#endif
340+
}
341+
306342
uint64_t getFenceValue() override { return Fence->GetCompletedValue(); }
307343

308344
llvm::Error waitForCompletion(uint64_t SignalValue) override {
@@ -330,21 +366,6 @@ class DXFence : public offloadtest::Fence {
330366
#endif
331367
return llvm::Error::success();
332368
}
333-
334-
#ifdef _WIN32
335-
DXFence(ComPtr<ID3D12Fence> Fence, HANDLE Event, llvm::StringRef Name)
336-
#else // WSL
337-
DXFence(ComPtr<ID3D12Fence> Fence, int Event, llvm::StringRef Name)
338-
#endif
339-
: Name(Name), Fence(Fence), Event(Event) {}
340-
341-
~DXFence() {
342-
#ifdef _WIN32
343-
CloseHandle(Event);
344-
#else // WSL
345-
close(Event);
346-
#endif
347-
}
348369
};
349370

350371
class DXQueue : public offloadtest::Queue {
@@ -429,23 +450,7 @@ class DXDevice : public offloadtest::Device {
429450

430451
llvm::Expected<std::unique_ptr<offloadtest::Fence>>
431452
createFence(llvm::StringRef Name) override {
432-
ComPtr<ID3D12Fence> Fence;
433-
if (auto Err = HR::toError(
434-
Device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&Fence)),
435-
"Failed to create Fence."))
436-
return Err;
437-
438-
#ifdef _WIN32
439-
HANDLE Event = CreateEventA(nullptr, false, false, nullptr);
440-
if (!Event)
441-
#else // WSL
442-
int Event = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
443-
if (Event == -1)
444-
#endif
445-
return llvm::createStringError(std::errc::device_or_resource_busy,
446-
"Failed to create event.");
447-
448-
return std::make_unique<DXFence>(Fence, Event, Name);
453+
return DXFence::create(Device.Get(), Name);
449454
}
450455

451456
llvm::Expected<std::shared_ptr<offloadtest::Buffer>>

lib/API/MTL/MTLDevice.cpp

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,27 @@ class MTLQueue : public offloadtest::Queue {
8484
};
8585

8686
class MTLFence : public offloadtest::Fence {
87+
MTLFence(MTL::SharedEvent *Event, llvm::StringRef Name)
88+
: Name(Name), Event(Event) {}
89+
8790
public:
8891
std::string Name;
8992
MTL::SharedEvent *Event;
9093

94+
static llvm::Expected<std::unique_ptr<MTLFence>>
95+
create(MTL::Device *Device, llvm::StringRef Name) {
96+
MTL::SharedEvent *Event = Device->newSharedEvent();
97+
if (!Event)
98+
return llvm::createStringError(std::errc::device_or_resource_busy,
99+
"Failed to create shared event.");
100+
return std::make_unique<MTLFence>(MTLFence(Event, Name));
101+
}
102+
103+
~MTLFence() {
104+
if (Event)
105+
Event->release();
106+
}
107+
91108
uint64_t getFenceValue() override { return Event->signaledValue(); }
92109

93110
llvm::Error waitForCompletion(uint64_t SignalValue) override {
@@ -96,14 +113,6 @@ class MTLFence : public offloadtest::Fence {
96113
"Timed out waiting on shared event.");
97114
return llvm::Error::success();
98115
}
99-
100-
MTLFence(MTL::SharedEvent *Event, llvm::StringRef Name)
101-
: Name(Name), Event(Event) {}
102-
103-
~MTLFence() {
104-
if (Event)
105-
Event->release();
106-
}
107116
};
108117

109118
class MTLBuffer : public offloadtest::Buffer {
@@ -600,11 +609,7 @@ class MTLDevice : public offloadtest::Device {
600609

601610
llvm::Expected<std::unique_ptr<offloadtest::Fence>>
602611
createFence(llvm::StringRef Name) override {
603-
MTL::SharedEvent *Event = Device->newSharedEvent();
604-
if (!Event)
605-
return llvm::createStringError(std::errc::device_or_resource_busy,
606-
"Failed to create shared event.");
607-
return std::make_unique<MTLFence>(Event, Name);
612+
return MTLFence::create(Device, Name);
608613
}
609614

610615
llvm::Expected<std::shared_ptr<offloadtest::Buffer>>

lib/API/VK/Device.cpp

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -392,11 +392,35 @@ class VulkanBuffer : public offloadtest::Buffer {
392392
};
393393

394394
class VulkanFence : public offloadtest::Fence {
395+
VulkanFence(VkDevice Device, VkSemaphore Semaphore, llvm::StringRef Name)
396+
: Name(Name), Device(Device), Semaphore(Semaphore) {}
397+
395398
public:
396399
std::string Name;
397400
VkDevice Device;
398401
VkSemaphore Semaphore;
399402

403+
static llvm::Expected<std::unique_ptr<VulkanFence>>
404+
create(VkDevice Device, llvm::StringRef Name) {
405+
VkSemaphoreTypeCreateInfo TypeCreateInfo = {};
406+
TypeCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
407+
TypeCreateInfo.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
408+
409+
VkSemaphoreCreateInfo CreateInfo = {};
410+
CreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
411+
CreateInfo.pNext = &TypeCreateInfo;
412+
413+
VkSemaphore Semaphore = VK_NULL_HANDLE;
414+
if (vkCreateSemaphore(Device, &CreateInfo, nullptr, &Semaphore))
415+
return llvm::createStringError(std::errc::device_or_resource_busy,
416+
"Failed to create Semaphore.");
417+
418+
return std::make_unique<VulkanFence>(
419+
VulkanFence(Device, Semaphore, Name));
420+
}
421+
422+
~VulkanFence() { vkDestroySemaphore(Device, Semaphore, nullptr); }
423+
400424
uint64_t getFenceValue() override {
401425
uint64_t Value = 0;
402426
[[maybe_unused]] VkResult Ret =
@@ -418,11 +442,6 @@ class VulkanFence : public offloadtest::Fence {
418442

419443
return llvm::Error::success();
420444
}
421-
422-
VulkanFence(VkDevice Device, VkSemaphore Semaphore, llvm::StringRef Name)
423-
: Name(Name), Device(Device), Semaphore(Semaphore) {}
424-
425-
~VulkanFence() { vkDestroySemaphore(Device, Semaphore, nullptr); }
426445
};
427446

428447
class VulkanQueue : public offloadtest::Queue {
@@ -687,20 +706,7 @@ class VulkanDevice : public offloadtest::Device {
687706

688707
llvm::Expected<std::unique_ptr<offloadtest::Fence>>
689708
createFence(llvm::StringRef Name) override {
690-
VkSemaphoreTypeCreateInfo TypeCreateInfo = {};
691-
TypeCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
692-
TypeCreateInfo.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
693-
694-
VkSemaphoreCreateInfo CreateInfo = {};
695-
CreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
696-
CreateInfo.pNext = &TypeCreateInfo;
697-
698-
VkSemaphore Semaphore = VK_NULL_HANDLE;
699-
if (vkCreateSemaphore(Device, &CreateInfo, nullptr, &Semaphore))
700-
return llvm::createStringError(std::errc::device_or_resource_busy,
701-
"Failed to create Semaphore.");
702-
703-
return std::make_unique<VulkanFence>(Device, Semaphore, Name);
709+
return VulkanFence::create(Device, Name);
704710
}
705711

706712
llvm::Expected<std::shared_ptr<offloadtest::Buffer>>

0 commit comments

Comments
 (0)