From 8ea3854d94eb1ff213be716a38493d601784810b Mon Sep 17 00:00:00 2001 From: skallweitNV <64953474+skallweitNV@users.noreply.github.com> Date: Thu, 6 Jun 2024 18:08:38 +0200 Subject: 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 --- tools/gfx/metal/metal-command-queue.cpp | 50 +++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 8 deletions(-) (limited to 'tools/gfx/metal/metal-command-queue.cpp') 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 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(m_commandQueue); + outHandle->handleValue = reinterpret_cast(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(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(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(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(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; -- cgit v1.2.3