diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/gfx/metal/metal-device.cpp | 11 | ||||
| -rw-r--r-- | tools/gfx/metal/metal-fence.cpp | 36 | ||||
| -rw-r--r-- | tools/gfx/metal/metal-fence.h | 3 | ||||
| -rw-r--r-- | tools/gfx/metal/metal-shader-object.cpp | 2 |
4 files changed, 50 insertions, 2 deletions
diff --git a/tools/gfx/metal/metal-device.cpp b/tools/gfx/metal/metal-device.cpp index 623cd8a81..e20d3ea3b 100644 --- a/tools/gfx/metal/metal-device.cpp +++ b/tools/gfx/metal/metal-device.cpp @@ -875,7 +875,16 @@ Result DeviceImpl::waitForFences( bool waitForAll, uint64_t timeout) { - return SLANG_E_NOT_IMPLEMENTED; + // return SLANG_E_NOT_IMPLEMENTED; + for (GfxCount i = 0; i < fenceCount; ++i) + { + FenceImpl* fenceImpl = static_cast<FenceImpl*>(fences[i]); + if (!fenceImpl->waitForFence(fenceValues[i], timeout)) + { + return SLANG_FAIL; + } + } + return SLANG_OK; } } // namespace metal diff --git a/tools/gfx/metal/metal-fence.cpp b/tools/gfx/metal/metal-fence.cpp index 0de7d8ffb..c0be4d8b7 100644 --- a/tools/gfx/metal/metal-fence.cpp +++ b/tools/gfx/metal/metal-fence.cpp @@ -22,6 +22,13 @@ Result FenceImpl::init(DeviceImpl* device, const IFence::Desc& desc) return SLANG_FAIL; } m_event->setSignaledValue(desc.initialValue); + + m_eventListener = NS::TransferPtr(MTL::SharedEventListener::alloc()->init()); + if (!m_eventListener) + { + return SLANG_FAIL; + } + return SLANG_OK; } @@ -49,5 +56,34 @@ Result FenceImpl::getNativeHandle(InteropHandle* outNativeHandle) return SLANG_OK; } +bool FenceImpl::waitForFence(uint64_t value, uint64_t timeout) +{ + // Create a semaphore to synchronize the notification + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + + // Create and store the notification block + MTL::SharedEventNotificationBlock block = ^(MTL::SharedEvent* event, uint64_t eventValue) { + dispatch_semaphore_signal(semaphore); + }; + + // Set up notification handler + m_event->notifyListener(m_eventListener.get(), value, block); + + // Wait for the notification or timeout + if (timeout & (1LLU << 63)) + { + timeout = DISPATCH_TIME_FOREVER; + } + else + { + timeout = dispatch_time(DISPATCH_TIME_NOW, timeout); + } + + long result = dispatch_semaphore_wait(semaphore, timeout); + dispatch_release(semaphore); + + return result == 0; +} + } // namespace metal } // namespace gfx diff --git a/tools/gfx/metal/metal-fence.h b/tools/gfx/metal/metal-fence.h index 434f2f65d..da98bfe41 100644 --- a/tools/gfx/metal/metal-fence.h +++ b/tools/gfx/metal/metal-fence.h @@ -16,6 +16,7 @@ class FenceImpl : public FenceBase public: RefPtr<DeviceImpl> m_device; NS::SharedPtr<MTL::SharedEvent> m_event; + NS::SharedPtr<MTL::SharedEventListener> m_eventListener; ~FenceImpl(); @@ -29,6 +30,8 @@ public: virtual SLANG_NO_THROW Result SLANG_MCALL getNativeHandle(InteropHandle* outNativeHandle) override; + + bool waitForFence(uint64_t value, uint64_t timeout); }; } // namespace metal diff --git a/tools/gfx/metal/metal-shader-object.cpp b/tools/gfx/metal/metal-shader-object.cpp index adbecdfe1..1aa79f495 100644 --- a/tools/gfx/metal/metal-shader-object.cpp +++ b/tools/gfx/metal/metal-shader-object.cpp @@ -768,7 +768,7 @@ Result RootShaderObjectImpl::bindAsRoot(BindingContext* context, RootShaderObjec Result RootShaderObjectImpl::init(IDevice* device, RootShaderObjectLayoutImpl* layout) { SLANG_RETURN_ON_FAIL(Super::init(device, layout)); - + m_entryPoints.clear(); for (auto entryPointInfo : layout->getEntryPoints()) { RefPtr<ShaderObjectImpl> entryPoint; |
