11/*
2- * Copyright 2019-2023 Diligent Graphics LLC
2+ * Copyright 2019-2024 Diligent Graphics LLC
33 * Copyright 2015-2019 Egor Yusov
44 *
55 * Licensed under the Apache License, Version 2.0 (the "License");
3636#include " ShaderToolsCommon.hpp"
3737#include " D3DCommonTypeConversions.hpp"
3838#include " EngineMemory.h"
39+ #include " ParsingTools.hpp"
3940
4041// / \file
4142// / D3D shader resource loading
@@ -185,12 +186,20 @@ void LoadD3DShaderResources(TShaderReflection* pShaderReflection,
185186 D3D_SHADER_INPUT_BIND_DESC BindingDesc = {};
186187 pShaderReflection->GetResourceBindingDesc (Res, &BindingDesc);
187188
189+ std::string Name;
190+ const auto ArrayIndex = Parsing::GetArrayIndex (BindingDesc.Name , Name);
191+
188192 if (BindingDesc.BindPoint == UINT32_MAX)
193+ {
189194 BindingDesc.BindPoint = D3DShaderResourceAttribs::InvalidBindPoint;
190-
191- std::string Name{BindingDesc.Name };
192-
193- SkipCount = 1 ;
195+ }
196+ else if (ArrayIndex > 0 )
197+ {
198+ // Adjust bind point for array index
199+ VERIFY (BindingDesc.BindPoint >= static_cast <UINT>(ArrayIndex), " Resource '" , BindingDesc.Name , " ' uses bind point point " , BindingDesc.BindPoint ,
200+ " , which is invalid for its array index " , ArrayIndex);
201+ BindingDesc.BindPoint -= static_cast <UINT>(ArrayIndex);
202+ }
194203
195204 UINT BindCount = BindingDesc.BindCount ;
196205 if (BindCount == UINT_MAX)
@@ -217,17 +226,11 @@ void LoadD3DShaderResources(TShaderReflection* pShaderReflection,
217226 //
218227 // Notice that if some array element is not used by the shader, it will not be enumerated
219228
220- auto OpenBracketPos = Name. find ( ' [ ' ) ;
221- if (String::npos != OpenBracketPos )
229+ SkipCount = 1 ;
230+ if (ArrayIndex >= 0 )
222231 {
223232 VERIFY (BindCount == 1 , " When array elements are enumerated individually, BindCount is expected to always be 1" );
224233
225- // Name == "g_tex2DDiffuse[0]"
226- // ^
227- // OpenBracketPos
228- Name.erase (OpenBracketPos, Name.length () - OpenBracketPos);
229- // Name == "g_tex2DDiffuse"
230- VERIFY_EXPR (Name.length () == OpenBracketPos);
231234#ifdef DILIGENT_DEBUG
232235 for (const auto & ExistingRes : Resources)
233236 {
@@ -236,21 +239,23 @@ void LoadD3DShaderResources(TShaderReflection* pShaderReflection,
236239#endif
237240 for (UINT ArrElem = Res + 1 ; ArrElem < shaderDesc.BoundResources ; ++ArrElem)
238241 {
239- D3D_SHADER_INPUT_BIND_DESC ArrElemBindingDesc = {};
240- pShaderReflection->GetResourceBindingDesc (ArrElem, &ArrElemBindingDesc);
242+ D3D_SHADER_INPUT_BIND_DESC NextElemBindingDesc = {};
243+ pShaderReflection->GetResourceBindingDesc (ArrElem, &NextElemBindingDesc);
244+
245+ std::string NextElemName;
246+ const auto NextElemIndex = Parsing::GetArrayIndex (NextElemBindingDesc.Name , NextElemName);
241247
242248 // Make sure this case is handled correctly:
243249 // "g_tex2DDiffuse[.]" != "g_tex2DDiffuse2[.]"
244- if (strncmp ( Name. c_str (), ArrElemBindingDesc. Name , OpenBracketPos) == 0 && ArrElemBindingDesc. Name [OpenBracketPos] == ' [ ' )
250+ if (Name == NextElemName )
245251 {
246- // g_tex2DDiffuse[2]
247- // ^
248- UINT Ind = atoi (ArrElemBindingDesc.Name + OpenBracketPos + 1 );
249- BindCount = std::max (BindCount, Ind + 1 );
250- VERIFY (ArrElemBindingDesc.BindPoint == BindingDesc.BindPoint + Ind,
252+ VERIFY_EXPR (NextElemIndex > 0 );
253+
254+ BindCount = std::max (BindCount, static_cast <UINT>(NextElemIndex) + 1 );
255+ VERIFY (NextElemBindingDesc.BindPoint == BindingDesc.BindPoint + NextElemIndex,
251256 " Array elements are expected to use contiguous bind points.\n " ,
252- BindingDesc.Name , " uses slot " , BindingDesc.BindPoint , " , so " , ArrElemBindingDesc .Name ,
253- " is expected to use slot " , BindingDesc.BindPoint + Ind , " while " , ArrElemBindingDesc .BindPoint ,
257+ BindingDesc.Name , " uses slot " , BindingDesc.BindPoint , " , so " , NextElemBindingDesc .Name ,
258+ " is expected to use slot " , BindingDesc.BindPoint + NextElemIndex , " while " , NextElemBindingDesc .BindPoint ,
254259 " is actually used" );
255260
256261 // Note that skip count may not necessarily be the same as BindCount.
0 commit comments