summaryrefslogtreecommitdiff
path: root/tools/gfx/metal/metal-command-queue.cpp
diff options
context:
space:
mode:
authorskallweitNV <64953474+skallweitNV@users.noreply.github.com>2024-06-06 18:08:38 +0200
committerGitHub <noreply@github.com>2024-06-06 09:08:38 -0700
commit8ea3854d94eb1ff213be716a38493d601784810b (patch)
tree071be96574be4afa54afe0a1fe0d66f10eb2cd80 /tools/gfx/metal/metal-command-queue.cpp
parent40d48bf1742cf21cc1ad3dd00d11fb04f37e512f (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.cpp50
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;