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
6.5 KiB202 linesraw
1// d3d11-shader-object.h
2#pragma once
3#include "d3d11-base.h"
4#include "d3d11-buffer.h"
5#include "d3d11-helper-functions.h"
6#include "d3d11-resource-views.h"
7#include "d3d11-sampler.h"
8#include "d3d11-shader-object-layout.h"
9
10namespace gfx
11{
12
13using namespace Slang;
14
15namespace d3d11
16{
17
18class ShaderObjectImpl
19    : public ShaderObjectBaseImpl<ShaderObjectImpl, ShaderObjectLayoutImpl, SimpleShaderObjectData>
20{
21public:
22    static Result create(
23        IDevice* device,
24        ShaderObjectLayoutImpl* layout,
25        ShaderObjectImpl** outShaderObject);
26
27    RendererBase* getDevice() { return m_layout->getDevice(); }
28
29    SLANG_NO_THROW GfxCount SLANG_MCALL getEntryPointCount() SLANG_OVERRIDE { return 0; }
30
31    SLANG_NO_THROW Result SLANG_MCALL getEntryPoint(GfxIndex index, IShaderObject** outEntryPoint)
32        SLANG_OVERRIDE
33    {
34        *outEntryPoint = nullptr;
35        return SLANG_OK;
36    }
37
38    virtual SLANG_NO_THROW const void* SLANG_MCALL getRawData() override
39    {
40        return m_data.getBuffer();
41    }
42
43    virtual SLANG_NO_THROW size_t SLANG_MCALL getSize() override
44    {
45        return (size_t)m_data.getCount();
46    }
47
48    SLANG_NO_THROW Result SLANG_MCALL
49    setData(ShaderOffset const& inOffset, void const* data, size_t inSize) SLANG_OVERRIDE;
50
51    SLANG_NO_THROW Result SLANG_MCALL
52    setResource(ShaderOffset const& offset, IResourceView* resourceView) SLANG_OVERRIDE;
53
54    SLANG_NO_THROW Result SLANG_MCALL setSampler(ShaderOffset const& offset, ISamplerState* sampler)
55        SLANG_OVERRIDE;
56
57    SLANG_NO_THROW Result SLANG_MCALL setCombinedTextureSampler(
58        ShaderOffset const& offset,
59        IResourceView* textureView,
60        ISamplerState* sampler) SLANG_OVERRIDE
61    {
62        return SLANG_E_NOT_IMPLEMENTED;
63    }
64
65public:
66protected:
67    friend class ProgramVars;
68
69    Result init(IDevice* device, ShaderObjectLayoutImpl* layout);
70
71    /// Write the uniform/ordinary data of this object into the given `dest` buffer at the given
72    /// `offset`
73    Result _writeOrdinaryData(
74        void* dest,
75        size_t destSize,
76        ShaderObjectLayoutImpl* specializedLayout);
77
78    /// Ensure that the `m_ordinaryDataBuffer` has been created, if it is needed
79    ///
80    /// The `specializedLayout` type must represent a specialized layout for this
81    /// type that includes any "pending" data.
82    ///
83    Result _ensureOrdinaryDataBufferCreatedIfNeeded(
84        DeviceImpl* device,
85        ShaderObjectLayoutImpl* specializedLayout);
86
87    /// Bind the buffer for ordinary/uniform data, if needed
88    ///
89    /// The `ioOffset` parameter will be updated to reflect the constant buffer
90    /// register consumed by the ordinary data buffer, if one was bound.
91    ///
92    Result _bindOrdinaryDataBufferIfNeeded(
93        BindingContext* context,
94        BindingOffset& ioOffset,
95        ShaderObjectLayoutImpl* specializedLayout);
96
97public:
98    /// Bind this object as if it was declared as a `ConstantBuffer<T>` in Slang
99    Result bindAsConstantBuffer(
100        BindingContext* context,
101        BindingOffset const& inOffset,
102        ShaderObjectLayoutImpl* specializedLayout);
103
104    /// Bind this object as a value that appears in the body of another object.
105    ///
106    /// This case is directly used when binding an object for an interface-type
107    /// sub-object range when static specialization is used. It is also used
108    /// indirectly when binding sub-objects to constant buffer or parameter
109    /// block ranges.
110    ///
111    Result bindAsValue(
112        BindingContext* context,
113        BindingOffset const& offset,
114        ShaderObjectLayoutImpl* specializedLayout);
115
116    // Because the binding ranges have already been reflected
117    // and organized as part of each shader object layout,
118    // the object itself can store its data in a small number
119    // of simple arrays.
120    /// The shader resource views (SRVs) that are part of the state of this object
121    List<RefPtr<ShaderResourceViewImpl>> m_srvs;
122
123    /// The unordered access views (UAVs) that are part of the state of this object
124    List<RefPtr<UnorderedAccessViewImpl>> m_uavs;
125
126    /// The samplers that are part of the state of this object
127    List<RefPtr<SamplerStateImpl>> m_samplers;
128
129    /// A constant buffer used to stored ordinary data for this object
130    /// and existential-type sub-objects.
131    ///
132    /// Created on demand with `_createOrdinaryDataBufferIfNeeded()`
133    RefPtr<BufferResourceImpl> m_ordinaryDataBuffer;
134
135    bool m_isConstantBufferDirty = true;
136
137    /// Get the layout of this shader object with specialization arguments considered
138    ///
139    /// This operation should only be called after the shader object has been
140    /// fully filled in and finalized.
141    ///
142    Result _getSpecializedLayout(ShaderObjectLayoutImpl** outLayout);
143
144    /// Create the layout for this shader object with specialization arguments considered
145    ///
146    /// This operation is virtual so that it can be customized by `ProgramVars`.
147    ///
148    virtual Result _createSpecializedLayout(ShaderObjectLayoutImpl** outLayout);
149
150    RefPtr<ShaderObjectLayoutImpl> m_specializedLayout;
151};
152
153class MutableShaderObjectImpl
154    : public MutableShaderObject<MutableShaderObjectImpl, ShaderObjectLayoutImpl>
155{
156};
157
158class RootShaderObjectImpl : public ShaderObjectImpl
159{
160    typedef ShaderObjectImpl Super;
161
162public:
163    virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; }
164    virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; }
165
166    static Result create(
167        IDevice* device,
168        RootShaderObjectLayoutImpl* layout,
169        RootShaderObjectImpl** outShaderObject);
170
171    RootShaderObjectLayoutImpl* getLayout()
172    {
173        return static_cast<RootShaderObjectLayoutImpl*>(m_layout.Ptr());
174    }
175
176    SLANG_NO_THROW GfxCount SLANG_MCALL getEntryPointCount() SLANG_OVERRIDE
177    {
178        return (GfxCount)m_entryPoints.getCount();
179    }
180    SLANG_NO_THROW SlangResult SLANG_MCALL
181    getEntryPoint(GfxIndex index, IShaderObject** outEntryPoint) SLANG_OVERRIDE
182    {
183        returnComPtr(outEntryPoint, m_entryPoints[index]);
184        return SLANG_OK;
185    }
186
187    virtual Result collectSpecializationArgs(ExtendedShaderObjectTypeList& args) override;
188
189    /// Bind this object as a root shader object
190    Result bindAsRoot(BindingContext* context, RootShaderObjectLayoutImpl* specializedLayout);
191
192
193protected:
194    Result init(IDevice* device, RootShaderObjectLayoutImpl* layout);
195
196    Result _createSpecializedLayout(ShaderObjectLayoutImpl** outLayout) SLANG_OVERRIDE;
197
198    List<RefPtr<ShaderObjectImpl>> m_entryPoints;
199};
200
201} // namespace d3d11
202} // namespace gfx