yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
04db5a956
master
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{ 20RefPtr < TextureResourceViewImpl > textureView ; 21RefPtr < SamplerStateImpl > sampler ; 22operator bool () {return textureView && sampler ; } 23}; 24 25class ShaderObjectImpl 26 :public ShaderObjectBaseImpl < ShaderObjectImpl ,ShaderObjectLayoutImpl ,SimpleShaderObjectData > 27{ 28public : 29static Result create ( 30IDevice * device , 31ShaderObjectLayoutImpl * layout , 32ShaderObjectImpl ** outShaderObject ); 33 34RendererBase * getDevice (); 35 36virtual SLANG_NO_THROW GfxCount SLANG_MCALL getEntryPointCount ()override ; 37 38virtual SLANG_NO_THROW Result SLANG_MCALL 39getEntryPoint ( GfxIndex index, IShaderObject ** outEntryPoint) override; 40 41virtual SLANG_NO_THROW const void * SLANG_MCALL getRawData () override; 42 43virtual SLANG_NO_THROW Size SLANG_MCALL getSize () override; 44 45// TODO: Changed size_t to Size? inSize assigned to an Index variable inside implementation 46virtual SLANG_NO_THROW Result SLANG_MCALL 47setData ( ShaderOffset const & inOffset, void const * data, size_t inSize) override; 48 49virtual SLANG_NO_THROW Result SLANG_MCALL 50setResource ( ShaderOffset const & offset, IResourceView * resourceView) override; 51 52virtual SLANG_NO_THROW Result SLANG_MCALL 53setSampler ( ShaderOffset const & offset, ISamplerState * sampler) override; 54 55virtual SLANG_NO_THROW Result SLANG_MCALL setCombinedTextureSampler ( 56ShaderOffset const & offset, 57IResourceView * textureView, 58ISamplerState * sampler) override; 59 60protected: 61friend class RootShaderObjectLayout; 62 63Result 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` 67Result _writeOrdinaryData ( 68PipelineCommandEncoder * encoder, 69IBufferResource * buffer, 70Offset offset, 71Size destSize, 72ShaderObjectLayoutImpl * specializedLayout); 73 74public : 75/// Write a single descriptor using the Vulkan API 76static void writeDescriptor ( RootBindingContext & context, VkWriteDescriptorSet const & write); 77 78static void writeBufferDescriptor ( 79RootBindingContext & context, 80BindingOffset const & offset, 81VkDescriptorType descriptorType, 82BufferResourceImpl * buffer, 83Offset bufferOffset, 84Size bufferSize); 85 86static void writeBufferDescriptor ( 87RootBindingContext & context, 88BindingOffset const & offset, 89VkDescriptorType descriptorType, 90BufferResourceImpl * buffer); 91 92static void writePlainBufferDescriptor ( 93RootBindingContext & context, 94BindingOffset const & offset, 95VkDescriptorType descriptorType, 96ArrayView < RefPtr < ResourceViewInternalBase>> resourceViews); 97 98static void writeTexelBufferDescriptor ( 99RootBindingContext & context, 100BindingOffset const & offset, 101VkDescriptorType descriptorType, 102ArrayView < RefPtr < ResourceViewInternalBase>> resourceViews); 103 104static void writeTextureSamplerDescriptor ( 105RootBindingContext & context, 106BindingOffset const & offset, 107VkDescriptorType descriptorType, 108ArrayView < CombinedTextureSamplerSlot > slots); 109 110static void writeAccelerationStructureDescriptor ( 111RootBindingContext & context, 112BindingOffset const & offset, 113VkDescriptorType descriptorType, 114ArrayView < RefPtr < ResourceViewInternalBase>> resourceViews); 115 116static void writeTextureDescriptor ( 117RootBindingContext & context, 118BindingOffset const & offset, 119VkDescriptorType descriptorType, 120ArrayView < RefPtr < ResourceViewInternalBase>> resourceViews); 121 122static void writeSamplerDescriptor ( 123RootBindingContext & context, 124BindingOffset const & offset, 125VkDescriptorType descriptorType, 126ArrayView < RefPtr < SamplerStateImpl>> samplers); 127 128bool shouldAllocateConstantBuffer ( TransientResourceHeapImpl * transientHeap); 129 130/// Ensure that the `m_ordinaryDataBuffer` has been created, if it is needed 131Result _ensureOrdinaryDataBufferCreatedIfNeeded ( 132PipelineCommandEncoder * encoder, 133ShaderObjectLayoutImpl * 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/// 142Result bindAsValue ( 143PipelineCommandEncoder * encoder, 144RootBindingContext & context, 145BindingOffset const & offset, 146ShaderObjectLayoutImpl * specializedLayout); 147 148/// Allocate the descriptor sets needed for binding this object (but not nested parameter 149/// blocks) 150Result allocateDescriptorSets ( 151PipelineCommandEncoder * encoder, 152RootBindingContext & context, 153BindingOffset const & offset, 154ShaderObjectLayoutImpl * specializedLayout); 155 156/// Bind this object as a `ParameterBlock<X>`. 157Result bindAsParameterBlock ( 158PipelineCommandEncoder * encoder, 159RootBindingContext & context, 160BindingOffset const & inOffset, 161ShaderObjectLayoutImpl * specializedLayout); 162 163/// Bind the ordinary data buffer if needed. 164Result bindOrdinaryDataBufferIfNeeded ( 165PipelineCommandEncoder * encoder, 166RootBindingContext & context, 167BindingOffset & ioOffset, 168ShaderObjectLayoutImpl * specializedLayout); 169 170/// Bind this object as a `ConstantBuffer<X>`. 171Result bindAsConstantBuffer ( 172PipelineCommandEncoder * encoder, 173RootBindingContext & context, 174BindingOffset const & inOffset, 175ShaderObjectLayoutImpl * specializedLayout); 176 177List < RefPtr < ResourceViewInternalBase>> m_resourceViews; 178 179List < RefPtr < SamplerStateImpl>> m_samplers; 180 181List < CombinedTextureSamplerSlot > m_combinedTextureSamplers; 182 183// The transient constant buffer that holds the GPU copy of the constant data, 184// weak referenced. 185IBufferResource * m_constantBuffer = nullptr ; 186// The offset into the transient constant buffer where the constant data starts. 187Offset m_constantBufferOffset = 0 ; 188Size m_constantBufferSize = 0 ; 189 190/// Dirty bit tracking whether the constant buffer needs to be updated. 191bool m_isConstantBufferDirty = true; 192/// The transient heap from which the constant buffer is allocated. 193TransientResourceHeapImpl * m_constantBufferTransientHeap; 194/// The version of the transient heap when the constant buffer is allocated. 195uint64_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/// 202Result _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/// 208virtual Result _createSpecializedLayout ( ShaderObjectLayoutImpl ** outLayout); 209 210RefPtr < ShaderObjectLayoutImpl > m_specializedLayout; 211}; 212 213class EntryPointShaderObject : public ShaderObjectImpl 214{ 215typedef ShaderObjectImpl Super ; 216 217public : 218static Result create ( 219IDevice * device, 220EntryPointLayout * layout, 221EntryPointShaderObject ** outShaderObject); 222 223EntryPointLayout * getLayout (); 224 225/// Bind this shader object as an entry point 226Result bindAsEntryPoint ( 227PipelineCommandEncoder * encoder, 228RootBindingContext & context, 229BindingOffset const & inOffset, 230EntryPointLayout * layout); 231 232protected : 233Result init ( IDevice * device, EntryPointLayout * layout); 234}; 235 236class RootShaderObjectImpl : public ShaderObjectImpl 237{ 238using 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. 243virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef () override { return 1 ; } 244virtual SLANG_NO_THROW uint32_t SLANG_MCALL release () override { return 1 ; } 245 246public : 247RootShaderObjectLayout * getLayout (); 248 249RootShaderObjectLayout * getSpecializedLayout (); 250 251List < RefPtr < EntryPointShaderObject>> const & getEntryPoints () const; 252 253virtual SLANG_NO_THROW GfxCount SLANG_MCALL getEntryPointCount () override ; 254virtual SLANG_NO_THROW Result SLANG_MCALL 255getEntryPoint ( GfxIndex index, IShaderObject ** outEntryPoint) override; 256 257virtual SLANG_NO_THROW Result SLANG_MCALL 258copyFrom ( IShaderObject * object, ITransientResourceHeap * transientHeap) override; 259 260/// Bind this object as a root shader object 261Result bindAsRoot ( 262PipelineCommandEncoder * encoder, 263RootBindingContext & context, 264RootShaderObjectLayout * layout); 265 266virtual Result collectSpecializationArgs ( ExtendedShaderObjectTypeList & args) override; 267 268public: 269Result init ( IDevice * device, RootShaderObjectLayout * layout); 270 271protected : 272virtual Result _createSpecializedLayout ( ShaderObjectLayoutImpl ** outLayout) override; 273 274List < RefPtr < EntryPointShaderObject>> m_entryPoints; 275}; 276 277class MutableRootShaderObjectImpl : public RootShaderObjectImpl 278{ 279public : 280// Enable reference counting. 281SLANG_NO_THROW uint32_t SLANG_MCALL addRef () override { return ShaderObjectImpl:: addRef (); } 282SLANG_NO_THROW uint32_t SLANG_MCALL release () override { return ShaderObjectImpl:: release (); } 283}; 284 285} // namespace vk 286} // namespace gfx