yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1// cpu-shader-object-layout.cpp 2#include "cpu-shader-object-layout.h" 3 4namespace gfx 5{ 6using namespace Slang ; 7 8namespace cpu 9{ 10 11ShaderObjectLayoutImpl ::ShaderObjectLayoutImpl ( 12RendererBase * renderer , 13 slang::ISession * session , 14 slang::TypeLayoutReflection * layout ) 15{ 16initBase (renderer ,session ,layout ); 17 18m_subObjectCount = 0 ; 19m_resourceCount = 0 ; 20 21m_elementTypeLayout = _unwrapParameterGroups (layout ,m_containerType ); 22m_size = m_elementTypeLayout -> getSize (); 23 24// Compute the binding ranges that are used to store 25// the logical contents of the object in memory. These will relate 26// to the descriptor ranges in the various sets, but not always 27// in a one-to-one fashion. 28 29SlangInt bindingRangeCount = m_elementTypeLayout -> getBindingRangeCount (); 30for (SlangInt r = 0 ;r < bindingRangeCount ;++ r ) 31 { 32 slang::BindingType slangBindingType = m_elementTypeLayout -> getBindingRangeType (r ); 33SlangInt count = m_elementTypeLayout -> getBindingRangeBindingCount (r ); 34 slang::TypeLayoutReflection * slangLeafTypeLayout = 35m_elementTypeLayout -> getBindingRangeLeafTypeLayout (r ); 36 37SlangInt descriptorSetIndex = m_elementTypeLayout -> getBindingRangeDescriptorSetIndex (r ); 38SlangInt rangeIndexInDescriptorSet = 39m_elementTypeLayout -> getBindingRangeFirstDescriptorRangeIndex (r ); 40 41// TODO: This logic assumes that for any binding range that might consume 42// multiple kinds of resources, the descriptor range for its uniform 43// usage will be the first one in the range. 44// 45// We need to decide whether that assumption is one we intend to support 46// applications making, or whether they should be forced to perform a 47// linear search over the descriptor ranges for a specific binding range. 48// 49auto uniformOffset = m_elementTypeLayout -> getDescriptorSetDescriptorRangeIndexOffset ( 50descriptorSetIndex , 51rangeIndexInDescriptorSet ); 52 53Index baseIndex = 0 ; 54Index subObjectIndex = 0 ; 55switch (slangBindingType ) 56 { 57case slang::BindingType ::ConstantBuffer : 58case slang::BindingType ::ParameterBlock : 59case slang::BindingType ::ExistentialValue : 60baseIndex = m_subObjectCount ; 61subObjectIndex = baseIndex ; 62m_subObjectCount += count ; 63break ; 64case slang::BindingType ::RawBuffer : 65case slang::BindingType ::MutableRawBuffer : 66if (slangLeafTypeLayout -> getType ()-> getElementType ()!= nullptr ) 67 { 68// A structured buffer occupies both a resource slot and 69// a sub-object slot. 70subObjectIndex = m_subObjectCount ; 71m_subObjectCount += count ; 72 } 73baseIndex = m_resourceCount ; 74m_resourceCount += count ; 75break ; 76default : 77baseIndex = m_resourceCount ; 78m_resourceCount += count ; 79break ; 80 } 81 82BindingRangeInfo bindingRangeInfo ; 83bindingRangeInfo .bindingType = slangBindingType ; 84bindingRangeInfo .count = count ; 85bindingRangeInfo .baseIndex = baseIndex ; 86bindingRangeInfo .uniformOffset = uniformOffset ; 87bindingRangeInfo .subObjectIndex = subObjectIndex ; 88bindingRangeInfo .isSpecializable = m_elementTypeLayout -> isBindingRangeSpecializable (r ); 89m_bindingRanges .add (bindingRangeInfo ); 90 } 91 92SlangInt subObjectRangeCount = m_elementTypeLayout -> getSubObjectRangeCount (); 93for (SlangInt r = 0 ;r < subObjectRangeCount ;++ r ) 94 { 95SlangInt bindingRangeIndex = m_elementTypeLayout -> getSubObjectRangeBindingRangeIndex (r ); 96auto slangBindingType = m_elementTypeLayout -> getBindingRangeType (bindingRangeIndex ); 97 slang::TypeLayoutReflection * slangLeafTypeLayout = 98m_elementTypeLayout -> getBindingRangeLeafTypeLayout (bindingRangeIndex ); 99 100// A sub-object range can either represent a sub-object of a known 101// type, like a `ConstantBuffer<Foo>` or `ParameterBlock<Foo>` 102// (in which case we can pre-compute a layout to use, based on 103// the type `Foo`) *or* it can represent a sub-object of some 104// existential type (e.g., `IBar`) in which case we cannot 105// know the appropriate type/layout of sub-object to allocate. 106// 107RefPtr < ShaderObjectLayoutImpl > subObjectLayout ; 108if (slangBindingType != slang::BindingType ::ExistentialValue ) 109 { 110subObjectLayout = new ShaderObjectLayoutImpl ( 111renderer , 112m_slangSession , 113slangLeafTypeLayout -> getElementTypeLayout ()); 114 } 115 116SubObjectRangeInfo subObjectRange ; 117subObjectRange .bindingRangeIndex = bindingRangeIndex ; 118subObjectRange .layout = subObjectLayout ; 119subObjectRanges .add (subObjectRange ); 120 } 121} 122 123size_t ShaderObjectLayoutImpl ::getSize () 124{ 125return m_size ; 126} 127 128Index ShaderObjectLayoutImpl ::getResourceCount ()const 129{ 130return m_resourceCount ; 131} 132Index ShaderObjectLayoutImpl ::getSubObjectCount ()const 133{ 134return m_subObjectCount ; 135} 136List < SubObjectRangeInfo >& ShaderObjectLayoutImpl ::getSubObjectRanges () 137{ 138return subObjectRanges ; 139} 140BindingRangeInfo ShaderObjectLayoutImpl ::getBindingRange (Index index ) 141{ 142return m_bindingRanges [index ]; 143} 144Index ShaderObjectLayoutImpl ::getBindingRangeCount ()const 145{ 146return m_bindingRanges .getCount (); 147} 148 149const char * EntryPointLayoutImpl ::getEntryPointName () 150{ 151return m_entryPointLayout -> getName (); 152} 153 154RootShaderObjectLayoutImpl ::RootShaderObjectLayoutImpl ( 155RendererBase * renderer , 156 slang::ISession * session , 157 slang::ProgramLayout * programLayout ) 158 :ShaderObjectLayoutImpl (renderer ,session ,programLayout -> getGlobalParamsTypeLayout ()) 159 ,m_programLayout (programLayout ) 160{ 161for (UInt i = 0 ;i < programLayout -> getEntryPointCount ();i ++ ) 162 { 163m_entryPointLayouts .add ( 164new EntryPointLayoutImpl (renderer ,session ,programLayout -> getEntryPointByIndex (i ))); 165 } 166} 167 168int RootShaderObjectLayoutImpl ::getKernelIndex (UnownedStringSlice kernelName ) 169{ 170auto entryPointCount = (int )m_programLayout -> getEntryPointCount (); 171for (int i = 0 ;i < entryPointCount ;i ++ ) 172 { 173auto entryPoint = m_programLayout -> getEntryPointByIndex (i ); 174if (kernelName == entryPoint -> getName ()) 175 { 176return i ; 177 } 178 } 179return -1 ; 180} 181 182void RootShaderObjectLayoutImpl ::getKernelThreadGroupSize (int kernelIndex ,UInt * threadGroupSizes ) 183{ 184auto entryPoint = m_programLayout -> getEntryPointByIndex (kernelIndex ); 185entryPoint -> getComputeThreadGroupSize (3 ,threadGroupSizes ); 186} 187 188EntryPointLayoutImpl * RootShaderObjectLayoutImpl ::getEntryPoint (Index index ) 189{ 190return m_entryPointLayouts [index ]; 191} 192 193}// namespace cpu 194}// namespace gfx