diff options
| author | skallweitNV <64953474+skallweitNV@users.noreply.github.com> | 2024-06-06 18:08:38 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-06 09:08:38 -0700 |
| commit | 8ea3854d94eb1ff213be716a38493d601784810b (patch) | |
| tree | 071be96574be4afa54afe0a1fe0d66f10eb2cd80 /tools/gfx/metal/metal-command-queue.cpp | |
| parent | 40d48bf1742cf21cc1ad3dd00d11fb04f37e512f (diff) | |
work on gfx metal backend (#4287)
* implement sampler state
* implement input layout
* implement fence object
* buffer implementation
* texture implementation
* cleanup
* add adapter enumeration
* supported formats and allocation info
* work on device and implement readBufferResource
* skeleton for transient resource heap
* initial work on command queue / buffers / encoders
* fix uploading initial buffer data
* implement buffer resource view
* string utility functions
* wip query pool implementation
* cleanup
* swapchain
* wip
* remove plain buffer view
* extend gfxGetDeviceTypeName with metal
* basic support for resource binding with compute shaders
* needed for metal bindings
* replace assert(0) with SLANG_UNIMPLEMENTED_X
Diffstat (limited to 'tools/gfx/metal/metal-command-queue.cpp')
| -rw-r--r-- | tools/gfx/metal/metal-command-queue.cpp | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/tools/gfx/metal/metal-command-queue.cpp b/tools/gfx/metal/metal-command-queue.cpp index c8b36ff1e..920b6ef7e 100644 --- a/tools/gfx/metal/metal-command-queue.cpp +++ b/tools/gfx/metal/metal-command-queue.cpp @@ -3,6 +3,7 @@ #include "metal-command-buffer.h" #include "metal-fence.h" +#include "metal-util.h" namespace gfx { @@ -23,22 +24,21 @@ CommandQueueImpl::~CommandQueueImpl() { } -void CommandQueueImpl::init(DeviceImpl* renderer) +void CommandQueueImpl::init(DeviceImpl* device, NS::SharedPtr<MTL::CommandQueue> commandQueue) { - m_renderer = renderer; - - MTL::Device* device = m_renderer->m_device; - m_commandQueue = device->newCommandQueue(8); + m_device = device; + m_commandQueue = commandQueue; } void CommandQueueImpl::waitOnHost() { + // TODO implement } Result CommandQueueImpl::getNativeHandle(InteropHandle* outHandle) { outHandle->api = InteropHandleAPI::Metal; - outHandle->handleValue = reinterpret_cast<intptr_t>(m_commandQueue); + outHandle->handleValue = reinterpret_cast<intptr_t>(m_commandQueue.get()); return SLANG_OK; } @@ -47,23 +47,57 @@ const CommandQueueImpl::Desc& CommandQueueImpl::getDesc() { return m_desc; } Result CommandQueueImpl::waitForFenceValuesOnDevice( GfxCount fenceCount, IFence** fences, uint64_t* waitValues) { - return SLANG_E_NOT_IMPLEMENTED; + for (GfxCount i = 0; i < fenceCount; ++i) + { + FenceWaitInfo waitInfo; + waitInfo.fence = static_cast<FenceImpl*>(fences[i]); + waitInfo.waitValue = waitValues[i]; + m_pendingWaitFences.add(waitInfo); + } + return SLANG_OK; } void CommandQueueImpl::queueSubmitImpl( uint32_t count, ICommandBuffer* const* commandBuffers, IFence* fence, uint64_t valueToSignal) { + // If there are any pending wait fences, encode them to a new command buffer. + // Metal ensures that command buffers are executed in the order they are committed. + if (m_pendingWaitFences.getCount() > 0) + { + MTL::CommandBuffer* commandBuffer = m_commandQueue->commandBuffer(); + for (const auto& fenceInfo : m_pendingWaitFences) + { + commandBuffer->encodeWait(fenceInfo.fence->m_event.get(), fenceInfo.waitValue); + } + commandBuffer->commit(); + m_pendingWaitFences.clear(); + } + for (uint32_t i = 0; i < count; ++i) { CommandBufferImpl* cmdBufImpl = static_cast<CommandBufferImpl*>(commandBuffers[i]); - cmdBufImpl->m_commandBuffer->presentDrawable(m_renderer->m_drawable); + // If this is the last command buffer and a fence is provided, signal the fence. + if (i == count - 1 && fence != nullptr) + { + cmdBufImpl->m_commandBuffer->encodeSignalEvent(static_cast<FenceImpl*>(fence)->m_event.get(), valueToSignal); + } cmdBufImpl->m_commandBuffer->commit(); } + + // If there are no command buffers to submit, but a fence is provided, signal the fence. + if (count == 0 && fence != nullptr) + { + MTL::CommandBuffer* commandBuffer = m_commandQueue->commandBuffer(); + commandBuffer->encodeSignalEvent(static_cast<FenceImpl*>(fence)->m_event.get(), valueToSignal); + commandBuffer->commit(); + } } void CommandQueueImpl::executeCommandBuffers( GfxCount count, ICommandBuffer* const* commandBuffers, IFence* fence, uint64_t valueToSignal) { + AUTORELEASEPOOL + if (count == 0 && fence == nullptr) { return; |
