yum-mirror/slang

Making it easier to work with shaders

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

Ellie Hermaszewskaformatf65d756bf

master
3.3 KiB121 linesraw
1// d3d12-command-queue.cpp
2#include "d3d12-command-queue.h"
3
4#include "d3d12-command-buffer.h"
5#include "d3d12-device.h"
6#include "d3d12-fence.h"
7
8namespace gfx
9{
10namespace d3d12
11{
12
13using namespace Slang;
14
15Result CommandQueueImpl::init(DeviceImpl* device, uint32_t queueIndex)
16{
17    m_queueIndex = queueIndex;
18    m_renderer = device;
19    m_device = device->m_device;
20    D3D12_COMMAND_QUEUE_DESC queueDesc = {};
21    queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
22    SLANG_RETURN_ON_FAIL(
23        m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(m_d3dQueue.writeRef())));
24    SLANG_RETURN_ON_FAIL(
25        m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(m_fence.writeRef())));
26    globalWaitHandle = CreateEventEx(
27        nullptr,
28        nullptr,
29        CREATE_EVENT_INITIAL_SET | CREATE_EVENT_MANUAL_RESET,
30        EVENT_ALL_ACCESS);
31    return SLANG_OK;
32}
33
34CommandQueueImpl::~CommandQueueImpl()
35{
36    waitOnHost();
37    CloseHandle(globalWaitHandle);
38    m_renderer->m_queueIndexAllocator.free((int)m_queueIndex, 1);
39}
40
41void CommandQueueImpl::executeCommandBuffers(
42    GfxCount count,
43    ICommandBuffer* const* commandBuffers,
44    IFence* fence,
45    uint64_t valueToSignal)
46{
47    ShortList<ID3D12CommandList*> commandLists;
48    for (GfxCount i = 0; i < count; i++)
49    {
50        auto cmdImpl = static_cast<CommandBufferImpl*>(commandBuffers[i]);
51        commandLists.add(cmdImpl->m_cmdList);
52    }
53    if (count > 0)
54    {
55        m_d3dQueue->ExecuteCommandLists((UINT)count, commandLists.getArrayView().getBuffer());
56
57        m_fenceValue++;
58
59        for (GfxCount i = 0; i < count; i++)
60        {
61            if (i > 0 && commandBuffers[i] == commandBuffers[i - 1])
62                continue;
63            auto cmdImpl = static_cast<CommandBufferImpl*>(commandBuffers[i]);
64            auto transientHeap = cmdImpl->m_transientHeap;
65            auto& waitInfo = transientHeap->getQueueWaitInfo(m_queueIndex);
66            waitInfo.waitValue = m_fenceValue;
67            waitInfo.fence = m_fence;
68            waitInfo.queue = m_d3dQueue;
69        }
70    }
71
72    if (fence)
73    {
74        auto fenceImpl = static_cast<FenceImpl*>(fence);
75        m_d3dQueue->Signal(fenceImpl->m_fence.get(), valueToSignal);
76    }
77}
78
79void CommandQueueImpl::waitOnHost()
80{
81    m_fenceValue++;
82    m_d3dQueue->Signal(m_fence, m_fenceValue);
83    ResetEvent(globalWaitHandle);
84    m_fence->SetEventOnCompletion(m_fenceValue, globalWaitHandle);
85    WaitForSingleObject(globalWaitHandle, INFINITE);
86}
87
88Result CommandQueueImpl::waitForFenceValuesOnDevice(
89    GfxCount fenceCount,
90    IFence** fences,
91    uint64_t* waitValues)
92{
93    for (GfxCount i = 0; i < fenceCount; ++i)
94    {
95        auto fenceImpl = static_cast<FenceImpl*>(fences[i]);
96        m_d3dQueue->Wait(fenceImpl->m_fence.get(), waitValues[i]);
97    }
98    return SLANG_OK;
99}
100
101const CommandQueueImpl::Desc& CommandQueueImpl::getDesc()
102{
103    return m_desc;
104}
105
106ICommandQueue* CommandQueueImpl::getInterface(const Guid& guid)
107{
108    if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_ICommandQueue)
109        return static_cast<ICommandQueue*>(this);
110    return nullptr;
111}
112
113Result CommandQueueImpl::getNativeHandle(InteropHandle* handle)
114{
115    handle->api = InteropHandleAPI::D3D12;
116    handle->handleValue = (uint64_t)m_d3dQueue.get();
117    return SLANG_OK;
118}
119
120} // namespace d3d12
121} // namespace gfx