27 #include "StringTools.h" 34 template<
typename D3D_SHADER_DESC,
35 typename D3D_SHADER_INPUT_BIND_DESC,
36 typename TShaderReflection,
38 typename TOnResourcesCounted,
40 typename TOnNewTexUAV,
41 typename TOnNewBuffUAV,
42 typename TOnNewBuffSRV,
43 typename TOnNewSampler,
44 typename TOnNewTexSRV>
45 void LoadD3DShaderResources(ID3DBlob *pShaderByteCode,
47 TOnResourcesCounted OnResourcesCounted,
49 TOnNewTexUAV OnNewTexUAV,
50 TOnNewBuffUAV OnNewBuffUAV,
51 TOnNewBuffSRV OnNewBuffSRV,
52 TOnNewSampler OnNewSampler,
53 TOnNewTexSRV OnNewTexSRV,
55 const ShaderDesc &ShdrDesc,
56 const Char *SamplerSuffix)
58 CComPtr<TShaderReflection> pShaderReflection;
59 CHECK_D3D_RESULT_THROW( D3DReflect( pShaderByteCode->GetBufferPointer(), pShaderByteCode->GetBufferSize(), __uuidof(pShaderReflection),
reinterpret_cast<void**
>(
static_cast<TShaderReflection**
>(&pShaderReflection)) ),
60 "Failed to get the shader reflection" );
62 D3D_SHADER_DESC shaderDesc = {};
63 pShaderReflection->GetDesc( &shaderDesc );
65 std::vector<D3DShaderResourceAttribs, STDAllocatorRawMem<D3DShaderResourceAttribs> > Resources( STD_ALLOCATOR_RAW_MEM(D3DShaderResourceAttribs,
GetRawAllocator(),
"Allocator for vector<D3DShaderResourceAttribs>") );
66 Resources.reserve(shaderDesc.BoundResources);
68 Uint32 NumCBs = 0, NumTexSRVs = 0, NumTexUAVs = 0, NumBufSRVs = 0, NumBufUAVs = 0, NumSamplers = 0;
71 for( UINT Res = 0; Res < shaderDesc.BoundResources; Res += SkipCount )
73 D3D_SHADER_INPUT_BIND_DESC BindingDesc = {};
74 pShaderReflection->GetResourceBindingDesc( Res, &BindingDesc );
76 String Name(BindingDesc.Name);
80 UINT BindCount = BindingDesc.BindCount;
96 auto OpenBracketPos = Name.find(
'[');
97 if (String::npos != OpenBracketPos)
99 VERIFY(BindCount == 1,
"When array elements are enumerated individually, BindCount is expected to always be 1");
104 Name.erase(OpenBracketPos, Name.length() - OpenBracketPos);
106 VERIFY_EXPR(Name.length() == OpenBracketPos);
108 for (
const auto &ExistingRes : Resources)
110 VERIFY(ExistingRes.Name != Name,
"Resource with the same name has already been enumerated. All array elements are expected to be enumerated one after another");
113 for( UINT ArrElem = Res+1; ArrElem < shaderDesc.BoundResources; ++ArrElem)
115 D3D_SHADER_INPUT_BIND_DESC ArrElemBindingDesc = {};
116 pShaderReflection->GetResourceBindingDesc( ArrElem, &ArrElemBindingDesc );
120 if ( strncmp(Name.c_str(), ArrElemBindingDesc.Name, OpenBracketPos) == 0 && ArrElemBindingDesc.Name[OpenBracketPos] ==
'[')
124 UINT Ind = atoi(ArrElemBindingDesc.Name+OpenBracketPos+1);
125 BindCount = std::max(BindCount, Ind+1);
126 VERIFY(ArrElemBindingDesc.BindPoint == BindingDesc.BindPoint + Ind,
127 "Array elements are expected to use contigous bind points.\n",
128 BindingDesc.Name,
" uses slot ", BindingDesc.BindPoint,
", so ", ArrElemBindingDesc.Name,
" is expected to use slot ", BindingDesc.BindPoint + Ind,
" while ", ArrElemBindingDesc.BindPoint,
" is actually used" );
143 bool IsStaticSampler =
false;
144 if (BindingDesc.Type == D3D_SIT_SAMPLER)
146 for (
Uint32 s = 0; s < ShdrDesc.NumStaticSamplers; ++s)
148 if( StrCmpSuff(Name.c_str(), ShdrDesc.StaticSamplers[s].TextureName, SamplerSuffix) )
150 IsStaticSampler =
true;
155 VarType = GetShaderVariableType(ShdrDesc.DefaultVariableType, ShdrDesc.VariableDesc, ShdrDesc.NumVariables,
156 [&](
const char *TexName)
158 return StrCmpSuff(Name.c_str(), TexName, SamplerSuffix);
164 VarType = GetShaderVariableType(Name.c_str(), ShdrDesc.DefaultVariableType, ShdrDesc.VariableDesc, ShdrDesc.NumVariables);
168 switch( BindingDesc.Type )
170 case D3D_SIT_CBUFFER: ++NumCBs;
break;
171 case D3D_SIT_TBUFFER: UNSUPPORTED(
"TBuffers are not supported" );
break;
172 case D3D_SIT_TEXTURE: ++(BindingDesc.Dimension == D3D_SRV_DIMENSION_BUFFER ? NumBufSRVs : NumTexSRVs);
break;
173 case D3D_SIT_SAMPLER: ++NumSamplers;
break;
174 case D3D_SIT_UAV_RWTYPED: ++(BindingDesc.Dimension == D3D_SRV_DIMENSION_BUFFER ? NumBufUAVs : NumTexUAVs);
break;
175 case D3D_SIT_STRUCTURED: ++NumBufSRVs;
break;
176 case D3D_SIT_UAV_RWSTRUCTURED: ++NumBufUAVs;
break;
177 case D3D_SIT_BYTEADDRESS: UNSUPPORTED(
"Byte address buffers are not supported" );
break;
178 case D3D_SIT_UAV_RWBYTEADDRESS: ++NumBufUAVs;
break;
179 case D3D_SIT_UAV_APPEND_STRUCTURED: UNSUPPORTED(
"Append structured buffers are not supported" );
break;
180 case D3D_SIT_UAV_CONSUME_STRUCTURED: UNSUPPORTED(
"Consume structured buffers are not supported" );
break;
181 case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: UNSUPPORTED(
"RW structured buffers with counter are not supported" );
break;
182 default: UNEXPECTED(
"Unexpected resource type");
184 Resources.emplace_back(std::move(Name), BindingDesc.BindPoint, BindCount, BindingDesc.Type, VarType, BindingDesc.Dimension, D3DShaderResourceAttribs::InvalidSamplerId, IsStaticSampler);
189 if(ShdrDesc.NumVariables != 0 || ShdrDesc.NumStaticSamplers != 0 )
191 for (
Uint32 v = 0; v < ShdrDesc.NumVariables; ++v)
193 bool VariableFound =
false;
194 const auto *VarName = ShdrDesc.VariableDesc[v].Name;
196 for (
const auto& Res : Resources)
199 if (Res.GetInputType() != D3D_SIT_SAMPLER && Res.Name.compare(VarName) == 0)
201 VariableFound =
true;
207 LOG_WARNING_MESSAGE(
"Variable \"", VarName,
"\" not found in shader \"", ShdrDesc.Name,
'\"');
211 for (
Uint32 s = 0; s < ShdrDesc.NumStaticSamplers; ++s)
213 bool TextureFound =
false;
214 const auto *TexName = ShdrDesc.StaticSamplers[s].TextureName;
216 for (
const auto& Res : Resources)
218 if ( Res.GetInputType() == D3D_SIT_TEXTURE && Res.GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER && Res.Name.compare(TexName) == 0)
226 LOG_WARNING_MESSAGE(
"Static sampler specifies a texture \"", TexName,
"\" that is not found in shader \"", ShdrDesc.Name,
'\"');
232 OnResourcesCounted(NumCBs, NumTexSRVs, NumTexUAVs, NumBufSRVs, NumBufUAVs, NumSamplers);
234 std::vector<D3DShaderResourceAttribs, STDAllocatorRawMem<D3DShaderResourceAttribs> > TextureSRVs( STD_ALLOCATOR_RAW_MEM(D3DShaderResourceAttribs,
GetRawAllocator(),
"Allocator for vector<D3DShaderResourceAttribs>") );
235 TextureSRVs.reserve(NumTexSRVs);
237 for(
auto &Res : Resources)
239 switch( Res.GetInputType() )
241 case D3D_SIT_CBUFFER:
243 OnNewCB( std::move(Res) );
247 case D3D_SIT_TBUFFER:
249 UNSUPPORTED(
"TBuffers are not supported" );
253 case D3D_SIT_TEXTURE:
255 if( Res.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER )
257 OnNewBuffSRV( std::move(Res) );
261 TextureSRVs.emplace_back( std::move(Res) );
266 case D3D_SIT_SAMPLER:
268 OnNewSampler( std::move(Res) );
272 case D3D_SIT_UAV_RWTYPED:
274 if( Res.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER )
276 OnNewBuffUAV( std::move(Res) );
280 OnNewTexUAV( std::move(Res) );
285 case D3D_SIT_STRUCTURED:
287 OnNewBuffSRV( std::move(Res) );
291 case D3D_SIT_UAV_RWSTRUCTURED:
293 OnNewBuffUAV( std::move(Res) );
297 case D3D_SIT_BYTEADDRESS:
299 UNSUPPORTED(
"Byte address buffers are not supported" );
303 case D3D_SIT_UAV_RWBYTEADDRESS:
305 OnNewBuffUAV( std::move(Res) );
309 case D3D_SIT_UAV_APPEND_STRUCTURED:
311 UNSUPPORTED(
"Append structured buffers are not supported" );
315 case D3D_SIT_UAV_CONSUME_STRUCTURED:
317 UNSUPPORTED(
"Consume structured buffers are not supported" );
321 case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER:
323 UNSUPPORTED(
"RW structured buffers with counter are not supported" );
330 for(
auto &Tex : TextureSRVs )
332 OnNewTexSRV( std::move(Tex) );
Graphics engine namespace.
Definition: AdaptiveFixedBlockAllocator.h:30
IMemoryAllocator & GetRawAllocator()
Returns raw memory allocator.
Definition: EngineMemory.cpp:46
SHADER_VARIABLE_TYPE
Describes shader variable type that is used by ShaderVariableDesc.
Definition: Shader.h:100
std::basic_string< Char > String
String variable.
Definition: BasicTypes.h:51
uint32_t Uint32
32-bit unsigned integer
Definition: BasicTypes.h:39
Total number of shader variable types.
Definition: Shader.h:117