From 52017192e551e19bce586b9069587e11021f9240 Mon Sep 17 00:00:00 2001 From: LoopDawg Date: Fri, 14 Jul 2017 15:15:47 -0600 Subject: [PATCH] Fix crash with --resource-set-binding [n] (common set form, not per-register form) --resource-set-binding has a mode which allows per-register assignments of bindings and descriptor sets on the command line, and another accepting a single descriptor set value to assign to all variables. The former worked, but the latter would crash when assigning the values. This fixes it, and makes the former case a bit more robust against premature termination of the pre-register values, which must come in (regname,set,binding) triples. This also allows the form "--resource-set-binding stage setnum", which was mentioned in the usage message, but did not parse. The operation of the per-register form of this option is unchanged. --- StandAlone/StandAlone.cpp | 41 ++++++------ .../hlsl.explicitDescriptorSet-2.frag.out | 66 +++++++++++++++++++ .../hlsl.explicitDescriptorSet.frag.out | 66 +++++++++++++++++++ Test/hlsl.explicitDescriptorSet.frag | 15 +++++ Test/runtests | 6 ++ glslang/MachineIndependent/iomapper.cpp | 5 ++ hlsl/hlslParseHelper.cpp | 18 +++-- 7 files changed, 191 insertions(+), 26 deletions(-) create mode 100644 Test/baseResults/hlsl.explicitDescriptorSet-2.frag.out create mode 100644 Test/baseResults/hlsl.explicitDescriptorSet.frag.out create mode 100644 Test/hlsl.explicitDescriptorSet.frag diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index 1089432a3..3301df453 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -289,31 +289,29 @@ void ProcessResourceSetBindingBase(int& argc, char**& argv, std::array 1 && argv[1] != nullptr && argv[1][0] != '-') { + base[lang].push_back(argv[1]); + + argc--; + argv++; } + + // Must have one arg, or a multiple of three (for [regname set binding] triples) + if (base[lang].size() != 1 && (base[lang].size() % 3) != 0) + usage(); + } else { - // Parse form: --argname base + // Parse form: --argname set for (int lang=0; lang g_tTex1df4 : register(t0); + +SamplerState g_sSamp2_amb; +uniform float floatval_amb; + +Buffer floatbuff; + +float4 main() : SV_Target0 +{ + g_sSamp2_amb; + + return 0; +} diff --git a/Test/runtests b/Test/runtests index 2a8542f49..c5a93378f 100755 --- a/Test/runtests +++ b/Test/runtests @@ -97,6 +97,12 @@ echo Configuring HLSL descriptor set and binding number manually $EXE -V -D -e main -H hlsl.multiDescriptorSet.frag --rsb frag t0 0 0 t1 1 0 s0 0 1 s1 1 1 b0 2 0 b1 2 1 b2 2 2 > $TARGETDIR/hlsl.multiDescriptorSet.frag.out diff -b $BASEDIR/hlsl.multiDescriptorSet.frag.out $TARGETDIR/hlsl.multiDescriptorSet.frag.out || HASERROR=1 +$EXE -V -D -e main -H hlsl.explicitDescriptorSet.frag --hlsl-iomap --amb --ssb 10 --stb 20 --rsb 4 > $TARGETDIR/hlsl.explicitDescriptorSet.frag.out +diff -b $BASEDIR/hlsl.explicitDescriptorSet.frag.out $TARGETDIR/hlsl.explicitDescriptorSet.frag.out || HASERROR=1 + +$EXE -V -D -e main -H hlsl.explicitDescriptorSet.frag --hlsl-iomap --amb --ssb 10 --stb 20 --rsb frag 3 > $TARGETDIR/hlsl.explicitDescriptorSet-2.frag.out +diff -b $BASEDIR/hlsl.explicitDescriptorSet-2.frag.out $TARGETDIR/hlsl.explicitDescriptorSet-2.frag.out || HASERROR=1 + # # Testing location error # diff --git a/glslang/MachineIndependent/iomapper.cpp b/glslang/MachineIndependent/iomapper.cpp index ea5f16113..958562708 100644 --- a/glslang/MachineIndependent/iomapper.cpp +++ b/glslang/MachineIndependent/iomapper.cpp @@ -404,6 +404,11 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver { if (type.getQualifier().hasSet()) return type.getQualifier().layoutSet; + + // If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN) + if (baseResourceSetBinding.size() == 1) + return atoi(baseResourceSetBinding[0].c_str()); + return 0; } diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 50d88d2f2..0c64c71e4 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -5370,7 +5370,7 @@ void HlslParseContext::handleRegister(const TSourceLoc& loc, TQualifier& qualifi } // TODO: learn what all these really mean and how they interact with regNumber and subComponent - std::vector resourceInfo = intermediate.getResourceSetBinding(); + const std::vector& resourceInfo = intermediate.getResourceSetBinding(); switch (std::tolower(desc[0])) { case 'b': case 't': @@ -5378,11 +5378,17 @@ void HlslParseContext::handleRegister(const TSourceLoc& loc, TQualifier& qualifi case 's': case 'u': qualifier.layoutBinding = regNumber + subComponent; - for (auto it = resourceInfo.cbegin(); it != resourceInfo.cend(); it = it + 3) { - if (strcmp(desc.c_str(), it[0].c_str()) == 0) { - qualifier.layoutSet = atoi(it[1].c_str()); - qualifier.layoutBinding = atoi(it[2].c_str()) + subComponent; - break; + + // This handles per-register layout sets numbers. For the global mode which sets + // every symbol to the same value, see setLinkageLayoutSets(). + if ((resourceInfo.size() % 3) == 0) { + // Apply per-symbol resource set and binding. + for (auto it = resourceInfo.cbegin(); it != resourceInfo.cend(); it = it + 3) { + if (strcmp(desc.c_str(), it[0].c_str()) == 0) { + qualifier.layoutSet = atoi(it[1].c_str()); + qualifier.layoutBinding = atoi(it[2].c_str()) + subComponent; + break; + } } } break;