yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Ellie Hermaszewskaformatf65d756bf

master
3.2 KiB122 linesraw
1// metal-command-queue.cpp
2#include "metal-command-queue.h"
3
4#include "metal-command-buffer.h"
5#include "metal-fence.h"
6#include "metal-util.h"
7
8namespace gfx
9{
10
11using namespace Slang;
12
13namespace metal
14{
15
16ICommandQueue* CommandQueueImpl::getInterface(const Guid& guid)
17{
18    if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_ICommandQueue)
19        return static_cast<ICommandQueue*>(this);
20    return nullptr;
21}
22
23CommandQueueImpl::~CommandQueueImpl() {}
24
25void CommandQueueImpl::init(DeviceImpl* device, NS::SharedPtr<MTL::CommandQueue> commandQueue)
26{
27    m_device = device;
28    m_commandQueue = commandQueue;
29}
30
31void CommandQueueImpl::waitOnHost()
32{
33    // TODO implement
34}
35
36Result CommandQueueImpl::getNativeHandle(InteropHandle* outHandle)
37{
38    outHandle->api = InteropHandleAPI::Metal;
39    outHandle->handleValue = reinterpret_cast<intptr_t>(m_commandQueue.get());
40    return SLANG_OK;
41}
42
43const CommandQueueImpl::Desc& CommandQueueImpl::getDesc()
44{
45    return m_desc;
46}
47
48Result CommandQueueImpl::waitForFenceValuesOnDevice(
49    GfxCount fenceCount,
50    IFence** fences,
51    uint64_t* waitValues)
52{
53    for (GfxCount i = 0; i < fenceCount; ++i)
54    {
55        FenceWaitInfo waitInfo;
56        waitInfo.fence = static_cast<FenceImpl*>(fences[i]);
57        waitInfo.waitValue = waitValues[i];
58        m_pendingWaitFences.add(waitInfo);
59    }
60    return SLANG_OK;
61}
62
63void CommandQueueImpl::queueSubmitImpl(
64    uint32_t count,
65    ICommandBuffer* const* commandBuffers,
66    IFence* fence,
67    uint64_t valueToSignal)
68{
69    // If there are any pending wait fences, encode them to a new command buffer.
70    // Metal ensures that command buffers are executed in the order they are committed.
71    if (m_pendingWaitFences.getCount() > 0)
72    {
73        MTL::CommandBuffer* commandBuffer = m_commandQueue->commandBuffer();
74        for (const auto& fenceInfo : m_pendingWaitFences)
75        {
76            commandBuffer->encodeWait(fenceInfo.fence->m_event.get(), fenceInfo.waitValue);
77        }
78        commandBuffer->commit();
79        m_pendingWaitFences.clear();
80    }
81
82    for (uint32_t i = 0; i < count; ++i)
83    {
84        CommandBufferImpl* cmdBufImpl = static_cast<CommandBufferImpl*>(commandBuffers[i]);
85        // If this is the last command buffer and a fence is provided, signal the fence.
86        if (i == count - 1 && fence != nullptr)
87        {
88            cmdBufImpl->m_commandBuffer->encodeSignalEvent(
89                static_cast<FenceImpl*>(fence)->m_event.get(),
90                valueToSignal);
91        }
92        cmdBufImpl->m_commandBuffer->commit();
93    }
94
95    // If there are no command buffers to submit, but a fence is provided, signal the fence.
96    if (count == 0 && fence != nullptr)
97    {
98        MTL::CommandBuffer* commandBuffer = m_commandQueue->commandBuffer();
99        commandBuffer->encodeSignalEvent(
100            static_cast<FenceImpl*>(fence)->m_event.get(),
101            valueToSignal);
102        commandBuffer->commit();
103    }
104}
105
106void CommandQueueImpl::executeCommandBuffers(
107    GfxCount count,
108    ICommandBuffer* const* commandBuffers,
109    IFence* fence,
110    uint64_t valueToSignal)
111{
112    AUTORELEASEPOOL
113
114    if (count == 0 && fence == nullptr)
115    {
116        return;
117    }
118    queueSubmitImpl(count, commandBuffers, fence, valueToSignal);
119}
120
121} // namespace metal
122} // namespace gfx