yum-mirror/slang

Making it easier to work with shaders

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

Jay KwakFix compiler warning with clang 18.1.8 on windows (#6843)04db5a956

master
9.6 KiB286 linesraw
1// vk-shader-object.h
2#pragma once
3
4#include "vk-base.h"
5#include "vk-helper-functions.h"
6#include "vk-resource-views.h"
7#include "vk-sampler.h"
8#include "vk-shader-object-layout.h"
9
10namespace gfx
11{
12
13using namespace Slang;
14
15namespace vk
16{
17
18struct CombinedTextureSamplerSlot
19{
20    RefPtr<TextureResourceViewImpl> textureView;
21    RefPtr<SamplerStateImpl> sampler;
22    operator bool() { return textureView && sampler; }
23};
24
25class ShaderObjectImpl
26    : public ShaderObjectBaseImpl<ShaderObjectImpl, ShaderObjectLayoutImpl, SimpleShaderObjectData>
27{
28public:
29    static Result create(
30        IDevice* device,
31        ShaderObjectLayoutImpl* layout,
32        ShaderObjectImpl** outShaderObject);
33
34    RendererBase* getDevice();
35
36    virtual SLANG_NO_THROW GfxCount SLANG_MCALL getEntryPointCount() override;
37
38    virtual SLANG_NO_THROW Result SLANG_MCALL
39    getEntryPoint(GfxIndex index, IShaderObject** outEntryPoint) override;
40
41    virtual SLANG_NO_THROW const void* SLANG_MCALL getRawData() override;
42
43    virtual SLANG_NO_THROW Size SLANG_MCALL getSize() override;
44
45    // TODO: Changed size_t to Size? inSize assigned to an Index variable inside implementation
46    virtual SLANG_NO_THROW Result SLANG_MCALL
47    setData(ShaderOffset const& inOffset, void const* data, size_t inSize) override;
48
49    virtual SLANG_NO_THROW Result SLANG_MCALL
50    setResource(ShaderOffset const& offset, IResourceView* resourceView) override;
51
52    virtual SLANG_NO_THROW Result SLANG_MCALL
53    setSampler(ShaderOffset const& offset, ISamplerState* sampler) override;
54
55    virtual SLANG_NO_THROW Result SLANG_MCALL setCombinedTextureSampler(
56        ShaderOffset const& offset,
57        IResourceView* textureView,
58        ISamplerState* sampler) override;
59
60protected:
61    friend class RootShaderObjectLayout;
62
63    Result init(IDevice* device, ShaderObjectLayoutImpl* layout);
64
65    /// Write the uniform/ordinary data of this object into the given `dest` buffer at the given
66    /// `offset`
67    Result _writeOrdinaryData(
68        PipelineCommandEncoder* encoder,
69        IBufferResource* buffer,
70        Offset offset,
71        Size destSize,
72        ShaderObjectLayoutImpl* specializedLayout);
73
74public:
75    /// Write a single descriptor using the Vulkan API
76    static void writeDescriptor(RootBindingContext& context, VkWriteDescriptorSet const& write);
77
78    static void writeBufferDescriptor(
79        RootBindingContext& context,
80        BindingOffset const& offset,
81        VkDescriptorType descriptorType,
82        BufferResourceImpl* buffer,
83        Offset bufferOffset,
84        Size bufferSize);
85
86    static void writeBufferDescriptor(
87        RootBindingContext& context,
88        BindingOffset const& offset,
89        VkDescriptorType descriptorType,
90        BufferResourceImpl* buffer);
91
92    static void writePlainBufferDescriptor(
93        RootBindingContext& context,
94        BindingOffset const& offset,
95        VkDescriptorType descriptorType,
96        ArrayView<RefPtr<ResourceViewInternalBase>> resourceViews);
97
98    static void writeTexelBufferDescriptor(
99        RootBindingContext& context,
100        BindingOffset const& offset,
101        VkDescriptorType descriptorType,
102        ArrayView<RefPtr<ResourceViewInternalBase>> resourceViews);
103
104    static void writeTextureSamplerDescriptor(
105        RootBindingContext& context,
106        BindingOffset const& offset,
107        VkDescriptorType descriptorType,
108        ArrayView<CombinedTextureSamplerSlot> slots);
109
110    static void writeAccelerationStructureDescriptor(
111        RootBindingContext& context,
112        BindingOffset const& offset,
113        VkDescriptorType descriptorType,
114        ArrayView<RefPtr<ResourceViewInternalBase>> resourceViews);
115
116    static void writeTextureDescriptor(
117        RootBindingContext& context,
118        BindingOffset const& offset,
119        VkDescriptorType descriptorType,
120        ArrayView<RefPtr<ResourceViewInternalBase>> resourceViews);
121
122    static void writeSamplerDescriptor(
123        RootBindingContext& context,
124        BindingOffset const& offset,
125        VkDescriptorType descriptorType,
126        ArrayView<RefPtr<SamplerStateImpl>> samplers);
127
128    bool shouldAllocateConstantBuffer(TransientResourceHeapImpl* transientHeap);
129
130    /// Ensure that the `m_ordinaryDataBuffer` has been created, if it is needed
131    Result _ensureOrdinaryDataBufferCreatedIfNeeded(
132        PipelineCommandEncoder* encoder,
133        ShaderObjectLayoutImpl* specializedLayout);
134
135public:
136    /// Bind this shader object as a "value"
137    ///
138    /// This is the mode used for binding sub-objects for existential-type
139    /// fields, and is also used as part of the implementation of the
140    /// parameter-block and constant-buffer cases.
141    ///
142    Result bindAsValue(
143        PipelineCommandEncoder* encoder,
144        RootBindingContext& context,
145        BindingOffset const& offset,
146        ShaderObjectLayoutImpl* specializedLayout);
147
148    /// Allocate the descriptor sets needed for binding this object (but not nested parameter
149    /// blocks)
150    Result allocateDescriptorSets(
151        PipelineCommandEncoder* encoder,
152        RootBindingContext& context,
153        BindingOffset const& offset,
154        ShaderObjectLayoutImpl* specializedLayout);
155
156    /// Bind this object as a `ParameterBlock<X>`.
157    Result bindAsParameterBlock(
158        PipelineCommandEncoder* encoder,
159        RootBindingContext& context,
160        BindingOffset const& inOffset,
161        ShaderObjectLayoutImpl* specializedLayout);
162
163    /// Bind the ordinary data buffer if needed.
164    Result bindOrdinaryDataBufferIfNeeded(
165        PipelineCommandEncoder* encoder,
166        RootBindingContext& context,
167        BindingOffset& ioOffset,
168        ShaderObjectLayoutImpl* specializedLayout);
169
170    /// Bind this object as a `ConstantBuffer<X>`.
171    Result bindAsConstantBuffer(
172        PipelineCommandEncoder* encoder,
173        RootBindingContext& context,
174        BindingOffset const& inOffset,
175        ShaderObjectLayoutImpl* specializedLayout);
176
177    List<RefPtr<ResourceViewInternalBase>> m_resourceViews;
178
179    List<RefPtr<SamplerStateImpl>> m_samplers;
180
181    List<CombinedTextureSamplerSlot> m_combinedTextureSamplers;
182
183    // The transient constant buffer that holds the GPU copy of the constant data,
184    // weak referenced.
185    IBufferResource* m_constantBuffer = nullptr;
186    // The offset into the transient constant buffer where the constant data starts.
187    Offset m_constantBufferOffset = 0;
188    Size m_constantBufferSize = 0;
189
190    /// Dirty bit tracking whether the constant buffer needs to be updated.
191    bool m_isConstantBufferDirty = true;
192    /// The transient heap from which the constant buffer is allocated.
193    TransientResourceHeapImpl* m_constantBufferTransientHeap;
194    /// The version of the transient heap when the constant buffer is allocated.
195    uint64_t m_constantBufferTransientHeapVersion;
196
197    /// Get the layout of this shader object with specialization arguments considered
198    ///
199    /// This operation should only be called after the shader object has been
200    /// fully filled in and finalized.
201    ///
202    Result _getSpecializedLayout(ShaderObjectLayoutImpl** outLayout);
203
204    /// Create the layout for this shader object with specialization arguments considered
205    ///
206    /// This operation is virtual so that it can be customized by `ProgramVars`.
207    ///
208    virtual Result _createSpecializedLayout(ShaderObjectLayoutImpl** outLayout);
209
210    RefPtr<ShaderObjectLayoutImpl> m_specializedLayout;
211};
212
213class EntryPointShaderObject : public ShaderObjectImpl
214{
215    typedef ShaderObjectImpl Super;
216
217public:
218    static Result create(
219        IDevice* device,
220        EntryPointLayout* layout,
221        EntryPointShaderObject** outShaderObject);
222
223    EntryPointLayout* getLayout();
224
225    /// Bind this shader object as an entry point
226    Result bindAsEntryPoint(
227        PipelineCommandEncoder* encoder,
228        RootBindingContext& context,
229        BindingOffset const& inOffset,
230        EntryPointLayout* layout);
231
232protected:
233    Result init(IDevice* device, EntryPointLayout* layout);
234};
235
236class RootShaderObjectImpl : public ShaderObjectImpl
237{
238    using Super = ShaderObjectImpl;
239
240public:
241    // Override default reference counting behavior to disable lifetime management.
242    // Root objects are managed by command buffer and does not need to be freed by the user.
243    virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; }
244    virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; }
245
246public:
247    RootShaderObjectLayout* getLayout();
248
249    RootShaderObjectLayout* getSpecializedLayout();
250
251    List<RefPtr<EntryPointShaderObject>> const& getEntryPoints() const;
252
253    virtual SLANG_NO_THROW GfxCount SLANG_MCALL getEntryPointCount() override;
254    virtual SLANG_NO_THROW Result SLANG_MCALL
255    getEntryPoint(GfxIndex index, IShaderObject** outEntryPoint) override;
256
257    virtual SLANG_NO_THROW Result SLANG_MCALL
258    copyFrom(IShaderObject* object, ITransientResourceHeap* transientHeap) override;
259
260    /// Bind this object as a root shader object
261    Result bindAsRoot(
262        PipelineCommandEncoder* encoder,
263        RootBindingContext& context,
264        RootShaderObjectLayout* layout);
265
266    virtual Result collectSpecializationArgs(ExtendedShaderObjectTypeList& args) override;
267
268public:
269    Result init(IDevice* device, RootShaderObjectLayout* layout);
270
271protected:
272    virtual Result _createSpecializedLayout(ShaderObjectLayoutImpl** outLayout) override;
273
274    List<RefPtr<EntryPointShaderObject>> m_entryPoints;
275};
276
277class MutableRootShaderObjectImpl : public RootShaderObjectImpl
278{
279public:
280    // Enable reference counting.
281    SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return ShaderObjectImpl::addRef(); }
282    SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return ShaderObjectImpl::release(); }
283};
284
285} // namespace vk
286} // namespace gfx