yum-mirror/slang

Making it easier to work with shaders

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

Ellie Hermaszewskaformatf65d756bf

master
5.8 KiB191 linesraw
1// debug-command-buffer.cpp
2#include "debug-command-buffer.h"
3
4#include "debug-framebuffer.h"
5#include "debug-helper-functions.h"
6#include "debug-render-pass.h"
7
8namespace gfx
9{
10using namespace Slang;
11
12namespace debug
13{
14
15DebugCommandBuffer::DebugCommandBuffer()
16{
17    SLANG_GFX_API_FUNC;
18    m_renderCommandEncoder.commandBuffer = this;
19    m_computeCommandEncoder.commandBuffer = this;
20    m_resourceCommandEncoder.commandBuffer = this;
21    m_rayTracingCommandEncoder.commandBuffer = this;
22}
23
24ICommandBuffer* DebugCommandBuffer::getInterface(const Slang::Guid& guid)
25{
26    if (guid == GfxGUID::IID_ICommandBuffer || guid == GfxGUID::IID_ISlangUnknown)
27        return (DebugObject<ICommandBuffer>*)this;
28    if (guid == GfxGUID::IID_ICommandBufferD3D12)
29        return static_cast<ICommandBufferD3D12*>(this);
30    return nullptr;
31}
32
33void DebugCommandBuffer::encodeRenderCommands(
34    IRenderPassLayout* renderPass,
35    IFramebuffer* framebuffer,
36    IRenderCommandEncoder** outEncoder)
37{
38    SLANG_GFX_API_FUNC;
39    checkCommandBufferOpenWhenCreatingEncoder();
40    checkEncodersClosedBeforeNewEncoder();
41    auto innerRenderPass = getInnerObj(renderPass);
42    auto innerFramebuffer = getInnerObj(framebuffer);
43    m_renderCommandEncoder.isOpen = true;
44    baseObject->encodeRenderCommands(
45        innerRenderPass,
46        innerFramebuffer,
47        &m_renderCommandEncoder.baseObject);
48    if (m_renderCommandEncoder.baseObject)
49        *outEncoder = &m_renderCommandEncoder;
50    else
51        *outEncoder = nullptr;
52}
53
54void DebugCommandBuffer::encodeComputeCommands(IComputeCommandEncoder** outEncoder)
55{
56    SLANG_GFX_API_FUNC;
57    checkCommandBufferOpenWhenCreatingEncoder();
58    checkEncodersClosedBeforeNewEncoder();
59    m_computeCommandEncoder.isOpen = true;
60    baseObject->encodeComputeCommands(&m_computeCommandEncoder.baseObject);
61    if (m_computeCommandEncoder.baseObject)
62    {
63        *outEncoder = &m_computeCommandEncoder;
64    }
65    else
66    {
67        *outEncoder = nullptr;
68    }
69}
70
71void DebugCommandBuffer::encodeResourceCommands(IResourceCommandEncoder** outEncoder)
72{
73    SLANG_GFX_API_FUNC;
74    checkCommandBufferOpenWhenCreatingEncoder();
75    checkEncodersClosedBeforeNewEncoder();
76    m_resourceCommandEncoder.isOpen = true;
77    baseObject->encodeResourceCommands(&m_resourceCommandEncoder.baseObject);
78    if (m_resourceCommandEncoder.baseObject)
79    {
80        *outEncoder = &m_resourceCommandEncoder;
81    }
82    else
83    {
84        *outEncoder = nullptr;
85    }
86}
87
88void DebugCommandBuffer::encodeRayTracingCommands(IRayTracingCommandEncoder** outEncoder)
89{
90    SLANG_GFX_API_FUNC;
91    checkCommandBufferOpenWhenCreatingEncoder();
92    checkEncodersClosedBeforeNewEncoder();
93    m_rayTracingCommandEncoder.isOpen = true;
94    baseObject->encodeRayTracingCommands(&m_rayTracingCommandEncoder.baseObject);
95    if (m_rayTracingCommandEncoder.baseObject)
96    {
97        *outEncoder = &m_rayTracingCommandEncoder;
98    }
99    else
100    {
101        *outEncoder = nullptr;
102    }
103}
104
105void DebugCommandBuffer::close()
106{
107    SLANG_GFX_API_FUNC;
108    if (!isOpen)
109    {
110        GFX_DIAGNOSE_ERROR("command buffer is already closed.");
111    }
112    if (m_renderCommandEncoder.isOpen)
113    {
114        GFX_DIAGNOSE_ERROR(
115            "A render command encoder on this command buffer is still open. "
116            "IRenderCommandEncoder::endEncoding() must be called before closing a command buffer.");
117    }
118    if (m_computeCommandEncoder.isOpen)
119    {
120        GFX_DIAGNOSE_ERROR("A compute command encoder on this command buffer is still open. "
121                           "IComputeCommandEncoder::endEncoding() must be called before closing a "
122                           "command buffer.");
123    }
124    if (m_resourceCommandEncoder.isOpen)
125    {
126        GFX_DIAGNOSE_ERROR("A resource command encoder on this command buffer is still open. "
127                           "IResourceCommandEncoder::endEncoding() must be called before closing a "
128                           "command buffer.");
129    }
130    isOpen = false;
131    baseObject->close();
132}
133
134Result DebugCommandBuffer::getNativeHandle(InteropHandle* outHandle)
135{
136    SLANG_GFX_API_FUNC;
137    return baseObject->getNativeHandle(outHandle);
138}
139
140void DebugCommandBuffer::invalidateDescriptorHeapBinding()
141{
142    SLANG_GFX_API_FUNC;
143    ComPtr<ICommandBufferD3D12> cmdBuf;
144    if (SLANG_FAILED(baseObject->queryInterface(
145            SlangUUID SLANG_UUID_ICommandBufferD3D12,
146            (void**)cmdBuf.writeRef())))
147    {
148        GFX_DIAGNOSE_ERROR("The current command buffer implementation does not provide "
149                           "ICommandBufferD3D12 interface.");
150        return;
151    }
152    return cmdBuf->invalidateDescriptorHeapBinding();
153}
154
155void DebugCommandBuffer::ensureInternalDescriptorHeapsBound()
156{
157    SLANG_GFX_API_FUNC;
158    ComPtr<ICommandBufferD3D12> cmdBuf;
159    if (SLANG_FAILED(baseObject->queryInterface(
160            SlangUUID SLANG_UUID_ICommandBufferD3D12,
161            (void**)cmdBuf.writeRef())))
162    {
163        GFX_DIAGNOSE_ERROR("The current command buffer implementation does not provide "
164                           "ICommandBufferD3D12 interface.");
165        return;
166    }
167    return cmdBuf->ensureInternalDescriptorHeapsBound();
168}
169
170void DebugCommandBuffer::checkEncodersClosedBeforeNewEncoder()
171{
172    if (m_renderCommandEncoder.isOpen || m_resourceCommandEncoder.isOpen ||
173        m_computeCommandEncoder.isOpen)
174    {
175        GFX_DIAGNOSE_ERROR(
176            "A previouse command encoder created on this command buffer is still open. "
177            "endEncoding() must be called on the encoder before creating an encoder.");
178    }
179}
180
181void DebugCommandBuffer::checkCommandBufferOpenWhenCreatingEncoder()
182{
183    if (!isOpen)
184    {
185        GFX_DIAGNOSE_ERROR("The command buffer is already closed. Encoders can only be retrieved "
186                           "while the command buffer is open.");
187    }
188}
189
190} // namespace debug
191} // namespace gfx