Merge remote-tracking branch 'LocalGitHub/master'
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index b606389..aa29267 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -6535,6 +6535,7 @@
optimizer.RegisterPass(CreateInsertExtractElimPass());
optimizer.RegisterPass(CreateAggressiveDCEPass());
optimizer.RegisterPass(CreateDeadBranchElimPass());
+ optimizer.RegisterPass(CreateCFGCleanupPass());
optimizer.RegisterPass(CreateBlockMergePass());
optimizer.RegisterPass(CreateLocalMultiStoreElimPass());
optimizer.RegisterPass(CreateInsertExtractElimPass());
diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index 771ddeb..977ee62 100644
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -55,6 +55,7 @@
#include <cctype>
#include <cmath>
#include <array>
+#include <map>
#include <memory>
#include <thread>
@@ -157,12 +158,11 @@
unsigned int TargetVersion = 0x00010000; // maps to, say, SPIR-V 1.0
std::vector<std::string> Processes; // what should be recorded by OpModuleProcessed, or equivalent
-std::array<unsigned int, EShLangCount> baseSamplerBinding;
-std::array<unsigned int, EShLangCount> baseTextureBinding;
-std::array<unsigned int, EShLangCount> baseImageBinding;
-std::array<unsigned int, EShLangCount> baseUboBinding;
-std::array<unsigned int, EShLangCount> baseSsboBinding;
-std::array<unsigned int, EShLangCount> baseUavBinding;
+// Per descriptor-set binding base data
+typedef std::map<unsigned int, unsigned int> TPerSetBaseBinding;
+
+std::array<std::array<unsigned int, EShLangCount>, glslang::EResCount> baseBinding;
+std::array<std::array<TPerSetBaseBinding, EShLangCount>, glslang::EResCount> baseBindingForSet;
std::array<std::vector<std::string>, EShLangCount> baseResourceSetBinding;
// Add things like "#define ..." to a preamble to use in the beginning of the shader.
@@ -266,31 +266,54 @@
}
//
-// Process an optional binding base of the form:
-// --argname [stage] base
+// Process an optional binding base of one the forms:
+// --argname [stage] base // base for stage (if given) or all stages (if not)
+// --argname [stage] [set base]... // set/base pairs: set the base for given binding set.
+
// Where stage is one of the forms accepted by FindLanguage, and base is an integer
//
-void ProcessBindingBase(int& argc, char**& argv, std::array<unsigned int, EShLangCount>& base)
+void ProcessBindingBase(int& argc, char**& argv, glslang::TResourceType res)
{
if (argc < 2)
usage();
- if (!isdigit(argv[1][0])) {
+ EShLanguage lang = EShLangCount;
+ int singleBase = 0;
+ TPerSetBaseBinding perSetBase;
+ int arg = 1;
+
+ // Parse stage, if given
+ if (!isdigit(argv[arg][0])) {
if (argc < 3) // this form needs one more argument
usage();
- // Parse form: --argname stage base
- const EShLanguage lang = FindLanguage(argv[1], false);
- base[lang] = atoi(argv[2]);
- argc-= 2;
- argv+= 2;
- } else {
- // Parse form: --argname base
- for (int lang=0; lang<EShLangCount; ++lang)
- base[lang] = atoi(argv[1]);
+ lang = FindLanguage(argv[arg++], false);
+ }
- argc--;
- argv++;
+ if ((argc - arg) > 2 && isdigit(argv[arg+0][0]) && isdigit(argv[arg+1][0])) {
+ // Parse a per-set binding base
+ while ((argc - arg) > 2 && isdigit(argv[arg+0][0]) && isdigit(argv[arg+1][0])) {
+ const int setNum = atoi(argv[arg++]);
+ const int baseNum = atoi(argv[arg++]);
+ perSetBase[setNum] = baseNum;
+ }
+ } else {
+ // Parse single binding base
+ singleBase = atoi(argv[arg++]);
+ }
+
+ argc -= (arg-1);
+ argv += (arg-1);
+
+ // Set one or all languages
+ const int langMin = (lang < EShLangCount) ? lang+0 : 0;
+ const int langMax = (lang < EShLangCount) ? lang+1 : EShLangCount;
+
+ for (int lang = langMin; lang < langMax; ++lang) {
+ if (!perSetBase.empty())
+ baseBindingForSet[res][lang] = perSetBase;
+ else
+ baseBinding[res][lang] = singleBase;
}
}
@@ -339,12 +362,8 @@
//
void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItems, int argc, char* argv[])
{
- baseSamplerBinding.fill(0);
- baseTextureBinding.fill(0);
- baseImageBinding.fill(0);
- baseUboBinding.fill(0);
- baseSsboBinding.fill(0);
- baseUavBinding.fill(0);
+ for (int res = 0; res < glslang::EResCount; ++res)
+ baseBinding[res].fill(0);
ExecutableName = argv[0];
workItems.reserve(argc);
@@ -441,30 +460,30 @@
} else if (lowerword == "shift-image-bindings" || // synonyms
lowerword == "shift-image-binding" ||
lowerword == "sib") {
- ProcessBindingBase(argc, argv, baseImageBinding);
+ ProcessBindingBase(argc, argv, glslang::EResImage);
} else if (lowerword == "shift-sampler-bindings" || // synonyms
lowerword == "shift-sampler-binding" ||
lowerword == "ssb") {
- ProcessBindingBase(argc, argv, baseSamplerBinding);
+ ProcessBindingBase(argc, argv, glslang::EResSampler);
} else if (lowerword == "shift-uav-bindings" || // synonyms
lowerword == "shift-uav-binding" ||
lowerword == "suavb") {
- ProcessBindingBase(argc, argv, baseUavBinding);
+ ProcessBindingBase(argc, argv, glslang::EResUav);
} else if (lowerword == "shift-texture-bindings" || // synonyms
lowerword == "shift-texture-binding" ||
lowerword == "stb") {
- ProcessBindingBase(argc, argv, baseTextureBinding);
+ ProcessBindingBase(argc, argv, glslang::EResTexture);
} else if (lowerword == "shift-ubo-bindings" || // synonyms
lowerword == "shift-ubo-binding" ||
lowerword == "shift-cbuffer-bindings" ||
lowerword == "shift-cbuffer-binding" ||
lowerword == "sub" ||
lowerword == "scb") {
- ProcessBindingBase(argc, argv, baseUboBinding);
+ ProcessBindingBase(argc, argv, glslang::EResUbo);
} else if (lowerword == "shift-ssbo-bindings" || // synonyms
lowerword == "shift-ssbo-binding" ||
lowerword == "sbb") {
- ProcessBindingBase(argc, argv, baseSsboBinding);
+ ProcessBindingBase(argc, argv, glslang::EResSsbo);
} else if (lowerword == "source-entrypoint" || // synonyms
lowerword == "sep") {
if (argc <= 1)
@@ -795,12 +814,20 @@
shader->setPreamble(UserPreamble.get());
shader->addProcesses(Processes);
- shader->setShiftSamplerBinding(baseSamplerBinding[compUnit.stage]);
- shader->setShiftTextureBinding(baseTextureBinding[compUnit.stage]);
- shader->setShiftImageBinding(baseImageBinding[compUnit.stage]);
- shader->setShiftUboBinding(baseUboBinding[compUnit.stage]);
- shader->setShiftSsboBinding(baseSsboBinding[compUnit.stage]);
- shader->setShiftUavBinding(baseUavBinding[compUnit.stage]);
+ // Set IO mapper binding shift values
+ for (int r = 0; r < glslang::EResCount; ++r) {
+ const glslang::TResourceType res = glslang::TResourceType(r);
+
+ // Set base bindings
+ shader->setShiftBinding(res, baseBinding[res][compUnit.stage]);
+
+ // Set bindings for particular resource sets
+ // TODO: use a range based for loop here, when available in all environments.
+ for (auto i = baseBindingForSet[res][compUnit.stage].begin();
+ i != baseBindingForSet[res][compUnit.stage].end(); ++i)
+ shader->setShiftBindingForSet(res, i->first, i->second);
+ }
+
shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0);
shader->setNoStorageFormat((Options & EOptionNoStorageFormat) != 0);
shader->setResourceSetBinding(baseResourceSetBinding[compUnit.stage]);
@@ -1278,17 +1305,24 @@
" Set descriptor set for all resources\n"
" --rsb [stage] type set binding synonym for --resource-set-binding\n"
" --shift-image-binding [stage] num base binding number for images (uav)\n"
+ " --shift-image-binding [stage] [set num]... per-descriptor-set shift values\n"
" --sib [stage] num synonym for --shift-image-binding\n"
" --shift-sampler-binding [stage] num base binding number for samplers\n"
+ " --shift-sampler-binding [stage] [set num]... per-descriptor-set shift values\n"
" --ssb [stage] num synonym for --shift-sampler-binding\n"
" --shift-ssbo-binding [stage] num base binding number for SSBOs\n"
+ " --shift-ssbo-binding [stage] [set num]... per-descriptor-set shift values\n"
" --sbb [stage] num synonym for --shift-ssbo-binding\n"
" --shift-texture-binding [stage] num base binding number for textures\n"
+ " --shift-texture-binding [stage] [set num]... per-descriptor-set shift values\n"
" --stb [stage] num synonym for --shift-texture-binding\n"
" --shift-uav-binding [stage] num base binding number for UAVs\n"
+ " --shift-uav-binding [stage] [set num]... per-descriptor-set shift values\n"
" --suavb [stage] num synonym for --shift-uav-binding\n"
" --shift-UBO-binding [stage] num base binding number for UBOs\n"
+ " --shift-UBO-binding [stage] [set num]... per-descriptor-set shift values\n"
" --shift-cbuffer-binding [stage] num synonym for --shift-UBO-binding\n"
+ " --shift-cbuffer-binding [stage] [set num]... per-descriptor-set shift values\n"
" --sub [stage] num synonym for --shift-UBO-binding\n"
" --source-entrypoint <name> the given shader source function is\n"
" renamed to be the <name> given in -e\n"
diff --git a/Test/baseResults/hlsl.shift.per-set.frag.out b/Test/baseResults/hlsl.shift.per-set.frag.out
new file mode 100644
index 0000000..57b32e5
--- /dev/null
+++ b/Test/baseResults/hlsl.shift.per-set.frag.out
@@ -0,0 +1,225 @@
+hlsl.shift.per-set.frag
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:34 Function Definition: @main( ( temp 4-component vector of float)
+0:34 Function Parameters:
+0:? Sequence
+0:35 't1' (layout( set=1 binding=1) uniform texture1D)
+0:36 't2' (layout( set=1 binding=2) uniform texture2D)
+0:37 't3' (layout( set=2 binding=1) uniform texture3D)
+0:38 direct index (layout( row_major std430) buffer 4-component vector of float)
+0:38 @data: direct index for structure (layout( row_major std430) buffer implicitly-sized array of 4-component vector of float)
+0:38 't4' (layout( set=3 binding=1 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data})
+0:38 Constant:
+0:38 0 (const uint)
+0:38 Constant:
+0:38 0 (const int)
+0:39 indirect index (layout( row_major std430) buffer uint)
+0:39 @data: direct index for structure (layout( row_major std430) buffer implicitly-sized array of uint)
+0:39 't5' (layout( set=3 binding=2 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of uint @data})
+0:39 Constant:
+0:39 0 (const uint)
+0:39 right-shift ( temp int)
+0:39 Constant:
+0:39 0 (const int)
+0:39 Constant:
+0:39 2 (const int)
+0:40 't6' (layout( set=3 binding=3 rgba32f) uniform textureBuffer)
+0:42 's1' (layout( set=1 binding=1) uniform sampler)
+0:43 's2' (layout( set=2 binding=2) uniform sampler)
+0:45 'u1' (layout( set=1 binding=1 rgba32f) uniform image1D)
+0:46 'u2' (layout( set=2 binding=2 rgba32f) uniform image2D)
+0:47 'u3' (layout( set=2 binding=3 rgba32f) uniform image3D)
+0:49 imageLoad ( temp float)
+0:49 'u4' (layout( set=1 binding=4 r32f) uniform imageBuffer)
+0:49 Constant:
+0:49 0 (const int)
+0:50 indirect index (layout( row_major std430) buffer uint)
+0:50 @data: direct index for structure (layout( row_major std430) buffer implicitly-sized array of uint)
+0:50 'u5' (layout( set=2 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of uint @data})
+0:50 Constant:
+0:50 0 (const uint)
+0:50 right-shift ( temp int)
+0:50 Constant:
+0:50 0 (const int)
+0:50 Constant:
+0:50 2 (const int)
+0:51 direct index (layout( row_major std430) buffer float)
+0:51 @data: direct index for structure (layout( row_major std430) buffer implicitly-sized array of float)
+0:51 'u6' (layout( set=3 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
+0:51 Constant:
+0:51 0 (const uint)
+0:51 Constant:
+0:51 0 (const int)
+0:52 'u7' (layout( set=4 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
+0:53 'u8' (layout( set=5 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
+0:55 cb1: direct index for structure (layout( row_major std140) uniform int)
+0:55 'anon@0' (layout( set=6 binding=1 row_major std140) uniform block{layout( row_major std140) uniform int cb1})
+0:55 Constant:
+0:55 0 (const uint)
+0:56 tb1: direct index for structure (layout( row_major std430) buffer int)
+0:56 'anon@1' (layout( binding=7 row_major std430) readonly buffer block{layout( row_major std430) buffer int tb1})
+0:56 Constant:
+0:56 0 (const uint)
+0:58 Branch: Return with expression
+0:58 Constant:
+0:58 0.000000
+0:58 0.000000
+0:58 0.000000
+0:58 0.000000
+0:34 Function Definition: main( ( temp void)
+0:34 Function Parameters:
+0:? Sequence
+0:34 move second child to first child ( temp 4-component vector of float)
+0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+0:34 Function Call: @main( ( temp 4-component vector of float)
+0:? Linker Objects
+0:? 's1' (layout( set=1 binding=1) uniform sampler)
+0:? 's2' (layout( set=2 binding=2) uniform sampler)
+0:? 't1' (layout( set=1 binding=1) uniform texture1D)
+0:? 't2' (layout( set=1 binding=2) uniform texture2D)
+0:? 't3' (layout( set=2 binding=1) uniform texture3D)
+0:? 't4' (layout( set=3 binding=1 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data})
+0:? 't5' (layout( set=3 binding=2 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of uint @data})
+0:? 't6' (layout( set=3 binding=3 rgba32f) uniform textureBuffer)
+0:? 'u1' (layout( set=1 binding=1 rgba32f) uniform image1D)
+0:? 'u2' (layout( set=2 binding=2 rgba32f) uniform image2D)
+0:? 'u3' (layout( set=2 binding=3 rgba32f) uniform image3D)
+0:? 'u4' (layout( set=1 binding=4 r32f) uniform imageBuffer)
+0:? 'u5' (layout( set=2 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of uint @data})
+0:? 'u6' (layout( set=3 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
+0:? 'u7' (layout( set=4 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
+0:? 'u8' (layout( set=5 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
+0:? 'anon@0' (layout( set=6 binding=1 row_major std140) uniform block{layout( row_major std140) uniform int cb1})
+0:? 'anon@1' (layout( binding=7 row_major std430) readonly buffer block{layout( row_major std430) buffer int tb1})
+0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+
+
+Linked fragment stage:
+
+
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:34 Function Definition: @main( ( temp 4-component vector of float)
+0:34 Function Parameters:
+0:? Sequence
+0:35 't1' (layout( set=1 binding=1) uniform texture1D)
+0:36 't2' (layout( set=1 binding=2) uniform texture2D)
+0:37 't3' (layout( set=2 binding=1) uniform texture3D)
+0:38 direct index (layout( row_major std430) buffer 4-component vector of float)
+0:38 @data: direct index for structure (layout( row_major std430) buffer implicitly-sized array of 4-component vector of float)
+0:38 't4' (layout( set=3 binding=1 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data})
+0:38 Constant:
+0:38 0 (const uint)
+0:38 Constant:
+0:38 0 (const int)
+0:39 indirect index (layout( row_major std430) buffer uint)
+0:39 @data: direct index for structure (layout( row_major std430) buffer implicitly-sized array of uint)
+0:39 't5' (layout( set=3 binding=2 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of uint @data})
+0:39 Constant:
+0:39 0 (const uint)
+0:39 right-shift ( temp int)
+0:39 Constant:
+0:39 0 (const int)
+0:39 Constant:
+0:39 2 (const int)
+0:40 't6' (layout( set=3 binding=3 rgba32f) uniform textureBuffer)
+0:42 's1' (layout( set=1 binding=1) uniform sampler)
+0:43 's2' (layout( set=2 binding=2) uniform sampler)
+0:45 'u1' (layout( set=1 binding=1 rgba32f) uniform image1D)
+0:46 'u2' (layout( set=2 binding=2 rgba32f) uniform image2D)
+0:47 'u3' (layout( set=2 binding=3 rgba32f) uniform image3D)
+0:49 imageLoad ( temp float)
+0:49 'u4' (layout( set=1 binding=4 r32f) uniform imageBuffer)
+0:49 Constant:
+0:49 0 (const int)
+0:50 indirect index (layout( row_major std430) buffer uint)
+0:50 @data: direct index for structure (layout( row_major std430) buffer implicitly-sized array of uint)
+0:50 'u5' (layout( set=2 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of uint @data})
+0:50 Constant:
+0:50 0 (const uint)
+0:50 right-shift ( temp int)
+0:50 Constant:
+0:50 0 (const int)
+0:50 Constant:
+0:50 2 (const int)
+0:51 direct index (layout( row_major std430) buffer float)
+0:51 @data: direct index for structure (layout( row_major std430) buffer implicitly-sized array of float)
+0:51 'u6' (layout( set=3 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
+0:51 Constant:
+0:51 0 (const uint)
+0:51 Constant:
+0:51 0 (const int)
+0:52 'u7' (layout( set=4 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
+0:53 'u8' (layout( set=5 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
+0:55 cb1: direct index for structure (layout( row_major std140) uniform int)
+0:55 'anon@0' (layout( set=6 binding=1 row_major std140) uniform block{layout( row_major std140) uniform int cb1})
+0:55 Constant:
+0:55 0 (const uint)
+0:56 tb1: direct index for structure (layout( row_major std430) buffer int)
+0:56 'anon@1' (layout( binding=7 row_major std430) readonly buffer block{layout( row_major std430) buffer int tb1})
+0:56 Constant:
+0:56 0 (const uint)
+0:58 Branch: Return with expression
+0:58 Constant:
+0:58 0.000000
+0:58 0.000000
+0:58 0.000000
+0:58 0.000000
+0:34 Function Definition: main( ( temp void)
+0:34 Function Parameters:
+0:? Sequence
+0:34 move second child to first child ( temp 4-component vector of float)
+0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+0:34 Function Call: @main( ( temp 4-component vector of float)
+0:? Linker Objects
+0:? 's1' (layout( set=1 binding=1) uniform sampler)
+0:? 's2' (layout( set=2 binding=2) uniform sampler)
+0:? 't1' (layout( set=1 binding=1) uniform texture1D)
+0:? 't2' (layout( set=1 binding=2) uniform texture2D)
+0:? 't3' (layout( set=2 binding=1) uniform texture3D)
+0:? 't4' (layout( set=3 binding=1 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data})
+0:? 't5' (layout( set=3 binding=2 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of uint @data})
+0:? 't6' (layout( set=3 binding=3 rgba32f) uniform textureBuffer)
+0:? 'u1' (layout( set=1 binding=1 rgba32f) uniform image1D)
+0:? 'u2' (layout( set=2 binding=2 rgba32f) uniform image2D)
+0:? 'u3' (layout( set=2 binding=3 rgba32f) uniform image3D)
+0:? 'u4' (layout( set=1 binding=4 r32f) uniform imageBuffer)
+0:? 'u5' (layout( set=2 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of uint @data})
+0:? 'u6' (layout( set=3 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
+0:? 'u7' (layout( set=4 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
+0:? 'u8' (layout( set=5 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
+0:? 'anon@0' (layout( set=6 binding=1 row_major std140) uniform block{layout( row_major std140) uniform int cb1})
+0:? 'anon@1' (layout( binding=7 row_major std430) readonly buffer block{layout( row_major std430) buffer int tb1})
+0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+
+Uniform reflection:
+t1: offset -1, type 8b5d, size 1, index -1, binding 21
+t2: offset -1, type 8b5e, size 1, index -1, binding 22
+t3: offset -1, type 8b5f, size 1, index -1, binding 26
+t4.@data: offset 0, type 8b52, size 1, index 0, binding -1
+t5.@data: offset 0, type 1405, size 0, index 1, binding -1
+t6: offset -1, type 8dc2, size 1, index -1, binding 23
+s1: offset -1, type 0, size 1, index -1, binding 11
+s2: offset -1, type 0, size 1, index -1, binding 17
+u1: offset -1, type 904c, size 1, index -1, binding 31
+u2: offset -1, type 904d, size 1, index -1, binding 42
+u3: offset -1, type 904e, size 1, index -1, binding 43
+u4: offset -1, type 9051, size 1, index -1, binding 34
+u5.@data: offset 0, type 1405, size 0, index 2, binding -1
+u6.@data: offset 0, type 1406, size 1, index 3, binding -1
+cb1: offset 0, type 1404, size 1, index 4, binding -1
+tb1: offset 0, type 1404, size 1, index 5, binding -1
+
+Uniform block reflection:
+t4: offset -1, type ffffffff, size 0, index -1, binding 21
+t5: offset -1, type ffffffff, size 0, index -1, binding 22
+u5: offset -1, type ffffffff, size 0, index -1, binding 44
+u6: offset -1, type ffffffff, size 0, index -1, binding 34
+cb: offset -1, type ffffffff, size 4, index -1, binding 51
+tb: offset -1, type ffffffff, size 4, index -1, binding 27
+
+Vertex attribute reflection:
+
diff --git a/Test/baseResults/implicitInnerAtomicUint.frag.out b/Test/baseResults/implicitInnerAtomicUint.frag.out
new file mode 100644
index 0000000..6f68980
--- /dev/null
+++ b/Test/baseResults/implicitInnerAtomicUint.frag.out
@@ -0,0 +1,21 @@
+implicitInnerAtomicUint.frag
+ERROR: 0:2: '[]' : only outermost dimension of an array of arrays can be implicitly sized
+ERROR: 0:2: 'atomic_uint' : array must be explicitly sized
+ERROR: 2 compilation errors. No code generated.
+
+
+Shader version: 460
+ERROR: node is still EOpNull!
+0:? Linker Objects
+0:? 'c' (layout( binding=0 offset=0) uniform 1-element array of implicitly-sized array of atomic_uint)
+
+
+Linked fragment stage:
+
+ERROR: Linking fragment stage: Missing entry point: Each stage requires one entry point
+
+Shader version: 460
+ERROR: node is still EOpNull!
+0:? Linker Objects
+0:? 'c' (layout( binding=0 offset=0) uniform 1-element array of implicitly-sized array of atomic_uint)
+
diff --git a/Test/baseResults/invalidSwizzle.vert.out b/Test/baseResults/invalidSwizzle.vert.out
index f53974b..5104fdc 100644
--- a/Test/baseResults/invalidSwizzle.vert.out
+++ b/Test/baseResults/invalidSwizzle.vert.out
@@ -1,17 +1,20 @@
invalidSwizzle.vert
-ERROR: 0:6: 'xx' : does not apply to this type: global void
-ERROR: 0:7: 'xy' : does not apply to this type: global void
-ERROR: 2 compilation errors. No code generated.
+ERROR: 0:7: 'rr' : does not apply to this type: uniform sampler2D
+ERROR: 0:7: '=' : cannot convert from ' uniform sampler2D' to ' temp 2-component vector of float'
+ERROR: 0:8: 'xx' : does not apply to this type: global void
+ERROR: 0:9: 'xy' : does not apply to this type: global void
+ERROR: 4 compilation errors. No code generated.
Shader version: 420
ERROR: node is still EOpNull!
-0:5 Function Definition: main( ( global void)
-0:5 Function Parameters:
-0:6 Sequence
-0:6 Function Call: f( ( global void)
-0:7 Function Call: f( ( global void)
+0:6 Function Definition: main( ( global void)
+0:6 Function Parameters:
+0:? Sequence
+0:8 Function Call: f( ( global void)
+0:9 Function Call: f( ( global void)
0:? Linker Objects
+0:? 's' ( uniform sampler2D)
0:? 'gl_VertexID' ( gl_VertexId int VertexId)
0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId)
@@ -23,12 +26,13 @@
Shader version: 420
ERROR: node is still EOpNull!
-0:5 Function Definition: main( ( global void)
-0:5 Function Parameters:
-0:6 Sequence
-0:6 Function Call: f( ( global void)
-0:7 Function Call: f( ( global void)
+0:6 Function Definition: main( ( global void)
+0:6 Function Parameters:
+0:? Sequence
+0:8 Function Call: f( ( global void)
+0:9 Function Call: f( ( global void)
0:? Linker Objects
+0:? 's' ( uniform sampler2D)
0:? 'gl_VertexID' ( gl_VertexId int VertexId)
0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId)
diff --git a/Test/baseResults/numeral.frag.out b/Test/baseResults/numeral.frag.out
index 11def12..c1e3134 100644
--- a/Test/baseResults/numeral.frag.out
+++ b/Test/baseResults/numeral.frag.out
@@ -11,7 +11,9 @@
ERROR: 0:88: '' : float literal needs a decimal point or exponent
ERROR: 0:98: '' : numeric literal too big
ERROR: 0:101: '' : numeric literal too big
-ERROR: 12 compilation errors. No code generated.
+ERROR: 0:104: '#' : preprocessor directive cannot be preceded by another token
+ERROR: 0:104: '' : syntax error, unexpected $end, expecting COMMA or SEMICOLON
+ERROR: 14 compilation errors. No code generated.
Shader version: 400
@@ -417,6 +419,7 @@
0:? 'g4' ( global int)
0:? 'g5' ( global int)
0:? 'g6' ( global int)
+0:? 'inf1' ( global float)
Linked fragment stage:
@@ -825,4 +828,5 @@
0:? 'g4' ( global int)
0:? 'g5' ( global int)
0:? 'g6' ( global int)
+0:? 'inf1' ( global float)
diff --git a/Test/baseResults/overlongLiteral.frag.out b/Test/baseResults/overlongLiteral.frag.out
new file mode 100644
index 0000000..372d777
--- /dev/null
+++ b/Test/baseResults/overlongLiteral.frag.out
@@ -0,0 +1,19 @@
+overlongLiteral.frag
+ERROR: 0:1: '' : hexadecimal literal too long
+ERROR: 0:1: '' : syntax error, unexpected INTCONSTANT
+ERROR: 2 compilation errors. No code generated.
+
+
+Shader version: 100
+ERROR: node is still EOpNull!
+0:? Linker Objects
+
+
+Linked fragment stage:
+
+ERROR: Linking fragment stage: Missing entry point: Each stage requires one entry point
+
+Shader version: 100
+ERROR: node is still EOpNull!
+0:? Linker Objects
+
diff --git a/Test/cppIntMinOverNegativeOne.frag b/Test/cppIntMinOverNegativeOne.frag
index 1cdaaeb..b7e0a95 100644
--- a/Test/cppIntMinOverNegativeOne.frag
+++ b/Test/cppIntMinOverNegativeOne.frag
@@ -1,3 +1,6 @@
#if (-2147483648 / -1) != 0
#error INT_MIN / -1 should yield 0, something went wrong.
+#endif
+#if (-2147483648 % -1) != 0
+#error INT_MIN % -1 should yield 0, something went wrong.
#endif
\ No newline at end of file
diff --git a/Test/hlsl.shift.per-set.frag b/Test/hlsl.shift.per-set.frag
new file mode 100644
index 0000000..9c29f9d
--- /dev/null
+++ b/Test/hlsl.shift.per-set.frag
@@ -0,0 +1,59 @@
+// Test register class offsets for different resource types
+
+SamplerState s1 : register(s1, space1);
+SamplerComparisonState s2 : register(s2, space2);
+
+Texture1D <float4> t1 : register(t1, space1);
+Texture2D <float4> t2 : register(t2, space1);
+Texture3D <float4> t3 : register(t1, space2);
+
+StructuredBuffer<float4> t4 : register(t1, space3);
+
+ByteAddressBuffer t5 : register(t2, space3);
+Buffer<float4> t6 : register(t3, space3);
+
+RWTexture1D <float4> u1 : register(u1, space1);
+RWTexture2D <float4> u2 : register(u2, space2);
+RWTexture3D <float4> u3 : register(u3, space2);
+
+RWBuffer <float> u4 : register(u4, space1);
+RWByteAddressBuffer u5 : register(u4, space2);
+RWStructuredBuffer<float> u6 : register(u4, space3);
+AppendStructuredBuffer<float> u7 : register(u4, space4);
+ConsumeStructuredBuffer<float> u8 : register(u4, space5);
+
+cbuffer cb : register(b1, space6) {
+ int cb1;
+};
+
+tbuffer tb : register(t7) {
+ int tb1;
+};
+
+float4 main() : SV_Target0
+{
+ t1;
+ t2;
+ t3;
+ t4[0];
+ t5.Load(0);
+ t6;
+
+ s1;
+ s2;
+
+ u1;
+ u2;
+ u3;
+
+ u4[0];
+ u5.Load(0);
+ u6[0];
+ u7;
+ u8;
+
+ cb1;
+ tb1;
+
+ return 0;
+}
diff --git a/Test/implicitInnerAtomicUint.frag b/Test/implicitInnerAtomicUint.frag
new file mode 100644
index 0000000..bb76516
--- /dev/null
+++ b/Test/implicitInnerAtomicUint.frag
@@ -0,0 +1,2 @@
+#version 460
+layout(binding = 0) uniform atomic_uint c[1][];
\ No newline at end of file
diff --git a/Test/invalidSwizzle.vert b/Test/invalidSwizzle.vert
index 00b5625..799ff87 100644
--- a/Test/invalidSwizzle.vert
+++ b/Test/invalidSwizzle.vert
@@ -1,8 +1,10 @@
#version 420
void f();
+uniform sampler2D s;
void main() {
+ vec2 v = s.rr; // Swizzles do not apply to samplers
f().xx; // Scalar swizzle does not apply to void
f().xy; // Vector swizzle does not apply either
}
\ No newline at end of file
diff --git a/Test/numeral.frag b/Test/numeral.frag
index cc0862c..39814f4 100644
--- a/Test/numeral.frag
+++ b/Test/numeral.frag
@@ -101,3 +101,6 @@
int g4 = 4294967296; // ERROR, too big
int g5 = 4294967295;
int g6 = 4294967294;
+float inf1 = -1.#INF;
+float inf2 = 1.#INF;
+float inf3 = +1.#INF;
diff --git a/Test/overlongLiteral.frag b/Test/overlongLiteral.frag
new file mode 100644
index 0000000..c351ed6
--- /dev/null
+++ b/Test/overlongLiteral.frag
@@ -0,0 +1 @@
+0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
diff --git a/Test/runtests b/Test/runtests
index 24d4004..c31a022 100755
--- a/Test/runtests
+++ b/Test/runtests
@@ -105,6 +105,13 @@
diff -b $BASEDIR/hlsl.explicitDescriptorSet-2.frag.out $TARGETDIR/hlsl.explicitDescriptorSet-2.frag.out || HASERROR=1
#
+# Testing per-descriptor-set IO map shift
+#
+echo 'Testing per-descriptor-set IO map shift'
+$EXE -e main --hlsl-iomap --ssb 1 10 2 15 --stb 20 --stb 2 25 --suavb 30 --suavb 2 40 --sub 6 50 -i -q -D -V hlsl.shift.per-set.frag > $TARGETDIR/hlsl.shift.per-set.frag.out || HASERROR=1
+diff -b $BASEDIR/hlsl.shift.per-set.frag.out $TARGETDIR/hlsl.shift.per-set.frag.out || HASERROR=1
+
+#
# Testing location error
#
echo Testing SPV no location
diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h
index d8c7a3e..c77c356 100644
--- a/glslang/Include/intermediate.h
+++ b/glslang/Include/intermediate.h
@@ -1029,6 +1029,8 @@
virtual bool isVector() const { return type.isVector(); }
virtual bool isScalar() const { return type.isScalar(); }
virtual bool isStruct() const { return type.isStruct(); }
+ virtual bool isFloatingDomain() const { return type.isFloatingDomain(); }
+ virtual bool isIntegerDomain() const { return type.isIntegerDomain(); }
TString getCompleteString() const { return type.getCompleteString(); }
protected:
diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp
index 6b89456..b5e2aac 100644
--- a/glslang/MachineIndependent/Intermediate.cpp
+++ b/glslang/MachineIndependent/Intermediate.cpp
@@ -3800,4 +3800,20 @@
root->traverse(&transform);
}
+const char* TIntermediate::getResourceName(TResourceType res)
+{
+ switch (res) {
+ case EResSampler: return "shift-sampler-binding";
+ case EResTexture: return "shift-texture-binding";
+ case EResImage: return "shift-image-binding";
+ case EResUbo: return "shift-UBO-binding";
+ case EResSsbo: return "shift-ssbo-binding";
+ case EResUav: return "shift-uav-binding";
+ default:
+ assert(0); // internal error: should only be called with valid resource types.
+ return nullptr;
+ }
+}
+
+
} // end namespace glslang
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index b02f77b..7bf036d 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -666,7 +666,8 @@
// leaving swizzles and struct/block dereferences.
TIntermTyped* result = base;
- if (base->getBasicType() != EbtVoid && (base->isVector() || base->isScalar())) {
+ if ((base->isVector() || base->isScalar()) &&
+ (base->isFloatingDomain() || base->isIntegerDomain() || base->getBasicType() == EbtBool)) {
if (base->isScalar()) {
const char* dotFeature = "scalar swizzle";
requireProfile(loc, ~EEsProfile, dotFeature);
@@ -4458,8 +4459,8 @@
switch (qualifier.storage) {
case EvqVaryingIn:
case EvqVaryingOut:
- if (type.getBasicType() != EbtBlock ||
- (!(*type.getStruct())[0].type->getQualifier().hasLocation() &&
+ if (type.getBasicType() != EbtBlock ||
+ (!(*type.getStruct())[0].type->getQualifier().hasLocation() &&
(*type.getStruct())[0].type->getQualifier().builtIn == EbvNone))
error(loc, "SPIR-V requires location for user input/output", "location", "");
break;
@@ -4856,7 +4857,7 @@
// Check for overlap
int numOffsets = 4;
if (symbol.getType().isArray()) {
- if (symbol.getType().isExplicitlySizedArray())
+ if (symbol.getType().isExplicitlySizedArray() && ! symbol.getType().getArraySizes()->isInnerImplicit())
numOffsets *= symbol.getType().getCumulativeArraySize();
else {
// "It is a compile-time error to declare an unsized array of atomic_uint."
diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp
index dbc8e14..05d2212 100644
--- a/glslang/MachineIndependent/ShaderLang.cpp
+++ b/glslang/MachineIndependent/ShaderLang.cpp
@@ -1661,20 +1661,30 @@
intermediate->addProcesses(p);
}
+// Set binding base for given resource type
+void TShader::setShiftBinding(TResourceType res, unsigned int base) {
+ intermediate->setShiftBinding(res, base);
+}
+
+// Set binding base for given resource type for a given binding set.
+void TShader::setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base) {
+ intermediate->setShiftBindingForSet(res, set, base);
+}
+
// Set binding base for sampler types
-void TShader::setShiftSamplerBinding(unsigned int base) { intermediate->setShiftSamplerBinding(base); }
+void TShader::setShiftSamplerBinding(unsigned int base) { setShiftBinding(EResSampler, base); }
// Set binding base for texture types (SRV)
-void TShader::setShiftTextureBinding(unsigned int base) { intermediate->setShiftTextureBinding(base); }
+void TShader::setShiftTextureBinding(unsigned int base) { setShiftBinding(EResTexture, base); }
// Set binding base for image types
-void TShader::setShiftImageBinding(unsigned int base) { intermediate->setShiftImageBinding(base); }
+void TShader::setShiftImageBinding(unsigned int base) { setShiftBinding(EResImage, base); }
// Set binding base for uniform buffer objects (CBV)
-void TShader::setShiftUboBinding(unsigned int base) { intermediate->setShiftUboBinding(base); }
+void TShader::setShiftUboBinding(unsigned int base) { setShiftBinding(EResUbo, base); }
// Synonym for setShiftUboBinding, to match HLSL language.
-void TShader::setShiftCbufferBinding(unsigned int base) { intermediate->setShiftUboBinding(base); }
+void TShader::setShiftCbufferBinding(unsigned int base) { setShiftBinding(EResUbo, base); }
// Set binding base for UAV (unordered access view)
-void TShader::setShiftUavBinding(unsigned int base) { intermediate->setShiftUavBinding(base); }
+void TShader::setShiftUavBinding(unsigned int base) { setShiftBinding(EResUav, base); }
// Set binding base for SSBOs
-void TShader::setShiftSsboBinding(unsigned int base) { intermediate->setShiftSsboBinding(base); }
+void TShader::setShiftSsboBinding(unsigned int base) { setShiftBinding(EResSsbo, base); }
// Enables binding automapping using TIoMapper
void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); }
// Fragile: currently within one stage: simple auto-assignment of location
diff --git a/glslang/MachineIndependent/iomapper.cpp b/glslang/MachineIndependent/iomapper.cpp
index 4926cf8..a7d9d91 100644
--- a/glslang/MachineIndependent/iomapper.cpp
+++ b/glslang/MachineIndependent/iomapper.cpp
@@ -351,16 +351,21 @@
// Base class for shared TIoMapResolver services, used by several derivations.
struct TDefaultIoResolverBase : public glslang::TIoMapResolver
{
- int baseSamplerBinding;
- int baseTextureBinding;
- int baseImageBinding;
- int baseUboBinding;
- int baseSsboBinding;
- int baseUavBinding;
- std::vector<std::string> baseResourceSetBinding;
- bool doAutoBindingMapping;
- bool doAutoLocationMapping;
- int nextUniformLocation;
+ TDefaultIoResolverBase(const TIntermediate &intermediate) :
+ intermediate(intermediate),
+ nextUniformLocation(0)
+ { }
+
+ int getBaseBinding(TResourceType res, unsigned int set) const {
+ return selectBaseBinding(intermediate.getShiftBinding(res),
+ intermediate.getShiftBindingForSet(res, set));
+ }
+
+ const std::vector<std::string>& getResourceSetBinding() const { return intermediate.getResourceSetBinding(); }
+
+ bool doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); }
+ bool doAutoLocationMapping() const { return intermediate.getAutoMapLocations(); }
+
typedef std::vector<int> TSlotSet;
typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
TSlotSetMap slots;
@@ -411,15 +416,15 @@
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());
+ if (getResourceSetBinding().size() == 1)
+ return atoi(getResourceSetBinding()[0].c_str());
return 0;
}
int resolveUniformLocation(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
{
// kick out of not doing this
- if (!doAutoLocationMapping)
+ if (!doAutoLocationMapping())
return -1;
// no locations added if already present, a built-in variable, a block, or an opaque
@@ -444,7 +449,7 @@
int resolveInOutLocation(EShLanguage /*stage*/, const char* /*name*/, const TType& type, bool /*is_live*/) override
{
// kick out of not doing this
- if (!doAutoLocationMapping)
+ if (!doAutoLocationMapping())
return -1;
// no locations added if already present, or a built-in variable
@@ -485,6 +490,14 @@
void endResolve(EShLanguage) override {}
protected:
+ const TIntermediate &intermediate;
+ int nextUniformLocation;
+
+ // Return descriptor set specific base if there is one, and the generic base otherwise.
+ int selectBaseBinding(int base, int descriptorSetBase) const {
+ return descriptorSetBase != -1 ? descriptorSetBase : base;
+ }
+
static int getLayoutSet(const glslang::TType& type) {
if (type.getQualifier().hasSet())
return type.getQualifier().layoutSet;
@@ -518,6 +531,8 @@
*/
struct TDefaultIoResolver : public TDefaultIoResolverBase
{
+ TDefaultIoResolver(const TIntermediate &intermediate) : TDefaultIoResolverBase(intermediate) { }
+
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override
{
return true;
@@ -529,37 +544,37 @@
if (type.getQualifier().hasBinding()) {
if (isImageType(type))
- return reserveSlot(set, baseImageBinding + type.getQualifier().layoutBinding);
+ return reserveSlot(set, getBaseBinding(EResImage, set) + type.getQualifier().layoutBinding);
if (isTextureType(type))
- return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
+ return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding);
if (isSsboType(type))
- return reserveSlot(set, baseSsboBinding + type.getQualifier().layoutBinding);
+ return reserveSlot(set, getBaseBinding(EResSsbo, set) + type.getQualifier().layoutBinding);
if (isSamplerType(type))
- return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding);
+ return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding);
if (isUboType(type))
- return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
- } else if (is_live && doAutoBindingMapping) {
+ return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding);
+ } else if (is_live && doAutoBindingMapping()) {
// find free slot, the caller did make sure it passes all vars with binding
// first and now all are passed that do not have a binding and needs one
if (isImageType(type))
- return getFreeSlot(set, baseImageBinding);
+ return getFreeSlot(set, getBaseBinding(EResImage, set));
if (isTextureType(type))
- return getFreeSlot(set, baseTextureBinding);
+ return getFreeSlot(set, getBaseBinding(EResTexture, set));
if (isSsboType(type))
- return getFreeSlot(set, baseSsboBinding);
+ return getFreeSlot(set, getBaseBinding(EResSsbo, set));
if (isSamplerType(type))
- return getFreeSlot(set, baseSamplerBinding);
+ return getFreeSlot(set, getBaseBinding(EResSampler, set));
if (isUboType(type))
- return getFreeSlot(set, baseUboBinding);
+ return getFreeSlot(set, getBaseBinding(EResUbo, set));
}
return -1;
@@ -620,6 +635,8 @@
********************************************************************************/
struct TDefaultHlslIoResolver : public TDefaultIoResolverBase
{
+ TDefaultHlslIoResolver(const TIntermediate &intermediate) : TDefaultIoResolverBase(intermediate) { }
+
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override
{
return true;
@@ -631,31 +648,31 @@
if (type.getQualifier().hasBinding()) {
if (isUavType(type))
- return reserveSlot(set, baseUavBinding + type.getQualifier().layoutBinding);
+ return reserveSlot(set, getBaseBinding(EResUav, set) + type.getQualifier().layoutBinding);
if (isSrvType(type))
- return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
+ return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding);
if (isSamplerType(type))
- return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding);
+ return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding);
if (isUboType(type))
- return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
- } else if (is_live && doAutoBindingMapping) {
+ return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding);
+ } else if (is_live && doAutoBindingMapping()) {
// find free slot, the caller did make sure it passes all vars with binding
// first and now all are passed that do not have a binding and needs one
if (isUavType(type))
- return getFreeSlot(set, baseUavBinding);
+ return getFreeSlot(set, getBaseBinding(EResUav, set));
if (isSrvType(type))
- return getFreeSlot(set, baseTextureBinding);
+ return getFreeSlot(set, getBaseBinding(EResTexture, set));
if (isSamplerType(type))
- return getFreeSlot(set, baseSamplerBinding);
+ return getFreeSlot(set, getBaseBinding(EResSampler, set));
if (isUboType(type))
- return getFreeSlot(set, baseUboBinding);
+ return getFreeSlot(set, getBaseBinding(EResUbo, set));
}
return -1;
@@ -684,17 +701,17 @@
// Returns false if the input is too malformed to do this.
bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSink &infoSink, TIoMapResolver *resolver)
{
- // Trivial return if there is nothing to do.
- if (intermediate.getShiftSamplerBinding() == 0 &&
- intermediate.getShiftTextureBinding() == 0 &&
- intermediate.getShiftImageBinding() == 0 &&
- intermediate.getShiftUboBinding() == 0 &&
- intermediate.getShiftSsboBinding() == 0 &&
- intermediate.getShiftUavBinding() == 0 &&
- intermediate.getResourceSetBinding().empty() &&
- intermediate.getAutoMapBindings() == false &&
- intermediate.getAutoMapLocations() == false &&
- resolver == nullptr)
+ bool somethingToDo = !intermediate.getResourceSetBinding().empty() ||
+ intermediate.getAutoMapBindings() ||
+ intermediate.getAutoMapLocations();
+
+ for (int res = 0; res < EResCount; ++res) {
+ somethingToDo = somethingToDo ||
+ (intermediate.getShiftBinding(TResourceType(res)) != 0) ||
+ intermediate.hasShiftBindingForSet(TResourceType(res));
+ }
+
+ if (!somethingToDo && resolver == nullptr)
return true;
if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive())
@@ -705,30 +722,15 @@
return false;
// if no resolver is provided, use the default resolver with the given shifts and auto map settings
- TDefaultIoResolver defaultResolver;
- TDefaultHlslIoResolver defaultHlslResolver;
+ TDefaultIoResolver defaultResolver(intermediate);
+ TDefaultHlslIoResolver defaultHlslResolver(intermediate);
if (resolver == nullptr) {
- TDefaultIoResolverBase* resolverBase;
-
// TODO: use a passed in IO mapper for this
if (intermediate.usingHlslIoMapping())
- resolverBase = &defaultHlslResolver;
+ resolver = &defaultHlslResolver;
else
- resolverBase = &defaultResolver;
-
- resolverBase->baseSamplerBinding = intermediate.getShiftSamplerBinding();
- resolverBase->baseTextureBinding = intermediate.getShiftTextureBinding();
- resolverBase->baseImageBinding = intermediate.getShiftImageBinding();
- resolverBase->baseUboBinding = intermediate.getShiftUboBinding();
- resolverBase->baseSsboBinding = intermediate.getShiftSsboBinding();
- resolverBase->baseUavBinding = intermediate.getShiftUavBinding();
- resolverBase->baseResourceSetBinding = intermediate.getResourceSetBinding();
- resolverBase->doAutoBindingMapping = intermediate.getAutoMapBindings();
- resolverBase->doAutoLocationMapping = intermediate.getAutoMapLocations();
- resolverBase->nextUniformLocation = 0;
-
- resolver = resolverBase;
+ resolver = &defaultResolver;
}
TVarLiveMap inVarMap, outVarMap, uniformVarMap;
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index 8be3a13..60deb1c 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -43,6 +43,7 @@
#include <algorithm>
#include <set>
+#include <array>
class TInfoSink;
@@ -222,12 +223,6 @@
layoutOverrideCoverage(false),
geoPassthroughEXT(false),
#endif
- shiftSamplerBinding(0),
- shiftTextureBinding(0),
- shiftImageBinding(0),
- shiftUboBinding(0),
- shiftSsboBinding(0),
- shiftUavBinding(0),
autoMapBindings(false),
autoMapLocations(false),
flattenUniformArrays(false),
@@ -245,6 +240,8 @@
localSizeSpecId[1] = TQualifier::layoutNotSet;
localSizeSpecId[2] = TQualifier::layoutNotSet;
xfbBuffers.resize(TQualifier::layoutXfbBufferEnd);
+
+ shiftBinding.fill(0);
}
void setLimits(const TBuiltInResource& r) { resources = r; }
@@ -264,42 +261,39 @@
const std::string& getEntryPointName() const { return entryPointName; }
const std::string& getEntryPointMangledName() const { return entryPointMangledName; }
- void setShiftSamplerBinding(unsigned int shift)
+ void setShiftBinding(TResourceType res, unsigned int shift)
{
- shiftSamplerBinding = shift;
- processes.addIfNonZero("shift-sampler-binding", shift);
+ shiftBinding[res] = shift;
+
+ const char* name = getResourceName(res);
+ if (name != nullptr)
+ processes.addIfNonZero(name, shift);
}
- unsigned int getShiftSamplerBinding() const { return shiftSamplerBinding; }
- void setShiftTextureBinding(unsigned int shift)
+
+ unsigned int getShiftBinding(TResourceType res) const { return shiftBinding[res]; }
+
+ void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int shift)
{
- shiftTextureBinding = shift;
- processes.addIfNonZero("shift-texture-binding", shift);
+ if (shift == 0) // ignore if there's no shift: it's a no-op.
+ return;
+
+ shiftBindingForSet[res][set] = shift;
+
+ const char* name = getResourceName(res);
+ if (name != nullptr) {
+ processes.addProcess(name);
+ processes.addArgument(set);
+ processes.addArgument(shift);
+ }
}
- unsigned int getShiftTextureBinding() const { return shiftTextureBinding; }
- void setShiftImageBinding(unsigned int shift)
+
+ int getShiftBindingForSet(TResourceType res, unsigned int set) const
{
- shiftImageBinding = shift;
- processes.addIfNonZero("shift-image-binding", shift);
+ const auto shift = shiftBindingForSet[res].find(set);
+ return shift == shiftBindingForSet[res].end() ? -1 : shift->second;
}
- unsigned int getShiftImageBinding() const { return shiftImageBinding; }
- void setShiftUboBinding(unsigned int shift)
- {
- shiftUboBinding = shift;
- processes.addIfNonZero("shift-UBO-binding", shift);
- }
- unsigned int getShiftUboBinding() const { return shiftUboBinding; }
- void setShiftSsboBinding(unsigned int shift)
- {
- shiftSsboBinding = shift;
- processes.addIfNonZero("shift-ssbo-binding", shift);
- }
- unsigned int getShiftSsboBinding() const { return shiftSsboBinding; }
- void setShiftUavBinding(unsigned int shift)
- {
- shiftUavBinding = shift;
- processes.addIfNonZero("shift-uav-binding", shift);
- }
- unsigned int getShiftUavBinding() const { return shiftUavBinding; }
+ bool hasShiftBindingForSet(TResourceType res) const { return !shiftBindingForSet[res].empty(); }
+
void setResourceSetBinding(const std::vector<std::string>& shift)
{
resourceSetBinding = shift;
@@ -648,6 +642,7 @@
TIntermUnary* createConversion(TBasicType convertTo, TIntermTyped* node) const;
std::tuple<TBasicType, TBasicType> getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const;
bool extensionRequested(const char *extension) const {return requestedExtensions.find(extension) != requestedExtensions.end();}
+ static const char* getResourceName(TResourceType);
const EShLanguage language; // stage, known at construction time
EShSource source; // source language, known a bit later
@@ -688,12 +683,12 @@
bool geoPassthroughEXT;
#endif
- unsigned int shiftSamplerBinding;
- unsigned int shiftTextureBinding;
- unsigned int shiftImageBinding;
- unsigned int shiftUboBinding;
- unsigned int shiftSsboBinding;
- unsigned int shiftUavBinding;
+ // Base shift values
+ std::array<unsigned int, EResCount> shiftBinding;
+
+ // Per-descriptor-set shift values
+ std::array<std::map<int, int>, EResCount> shiftBindingForSet;
+
std::vector<std::string> resourceSetBinding;
bool autoMapBindings;
bool autoMapLocations;
diff --git a/glslang/MachineIndependent/preprocessor/Pp.cpp b/glslang/MachineIndependent/preprocessor/Pp.cpp
index 5a552d8..df7ec88 100644
--- a/glslang/MachineIndependent/preprocessor/Pp.cpp
+++ b/glslang/MachineIndependent/preprocessor/Pp.cpp
@@ -352,7 +352,7 @@
int op_sub(int a, int b) { return a - b; }
int op_mul(int a, int b) { return a * b; }
int op_div(int a, int b) { return a == INT_MIN && b == -1 ? 0 : a / b; }
- int op_mod(int a, int b) { return a % b; }
+ int op_mod(int a, int b) { return a == INT_MIN && b == -1 ? 0 : a % b; }
int op_pos(int a) { return a; }
int op_neg(int a) { return -a; }
int op_cmpl(int a) { return ~a; }
diff --git a/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/glslang/MachineIndependent/preprocessor/PpScanner.cpp
index cd8613f..340b8cb 100644
--- a/glslang/MachineIndependent/preprocessor/PpScanner.cpp
+++ b/glslang/MachineIndependent/preprocessor/PpScanner.cpp
@@ -132,7 +132,7 @@
ch = getChar();
// 1.#INF or -1.#INF
- if (ch == '#') {
+ if (parseContext.intermediate.getSource() == EShSourceHlsl && ch == '#') {
if ((len < 2) ||
(len == 2 && ppToken->name[0] != '1') ||
(len == 3 && ppToken->name[1] != '1' && !(ppToken->name[0] == '-' || ppToken->name[0] == '+')) ||
@@ -432,7 +432,7 @@
ival = 0;
do {
- if (ival <= 0x0fffffffu || (enableInt64 && ival <= 0x0fffffffffffffffull)) {
+ if (len < MaxTokenLength && (ival <= 0x0fffffffu || (enableInt64 && ival <= 0x0fffffffffffffffull))) {
ppToken->name[len++] = (char)ch;
if (ch >= '0' && ch <= '9') {
ii = ch - '0';
@@ -445,7 +445,10 @@
ival = (ival << 4) | ii;
} else {
if (! AlreadyComplained) {
- pp->parseContext.ppError(ppToken->loc, "hexadecimal literal too big", "", "");
+ if(len < MaxTokenLength)
+ pp->parseContext.ppError(ppToken->loc, "hexadecimal literal too big", "", "");
+ else
+ pp->parseContext.ppError(ppToken->loc, "hexadecimal literal too long", "", "");
AlreadyComplained = 1;
}
ival = 0xffffffffffffffffull;
diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h
index a531072..f0990ad 100644
--- a/glslang/Public/ShaderLang.h
+++ b/glslang/Public/ShaderLang.h
@@ -324,6 +324,17 @@
// Call once per process to tear down everything
void FinalizeProcess();
+// Resource type for IO resolver
+enum TResourceType {
+ EResSampler,
+ EResTexture,
+ EResImage,
+ EResUbo,
+ EResSsbo,
+ EResUav,
+ EResCount
+};
+
// Make one TShader per shader that you will link into a program. Then provide
// the shader through setStrings() or setStringsWithLengths(), then call parse(),
// then query the info logs.
@@ -347,13 +358,17 @@
void setEntryPoint(const char* entryPoint);
void setSourceEntryPoint(const char* sourceEntryPointName);
void addProcesses(const std::vector<std::string>&);
- void setShiftSamplerBinding(unsigned int base);
- void setShiftTextureBinding(unsigned int base);
- void setShiftImageBinding(unsigned int base);
- void setShiftUboBinding(unsigned int base);
- void setShiftUavBinding(unsigned int base);
- void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding
- void setShiftSsboBinding(unsigned int base);
+
+ // IO resolver binding data: see comments in ShaderLang.cpp
+ void setShiftBinding(TResourceType res, unsigned int base);
+ void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding
+ void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
void setResourceSetBinding(const std::vector<std::string>& base);
void setAutoMapBindings(bool map);
void setAutoMapLocations(bool map);
diff --git a/gtests/AST.FromFile.cpp b/gtests/AST.FromFile.cpp
index f96b788..b978fda 100644
--- a/gtests/AST.FromFile.cpp
+++ b/gtests/AST.FromFile.cpp
@@ -159,6 +159,7 @@
"460.vert",
"dce.frag",
"atomic_uint.frag",
+ "implicitInnerAtomicUint.frag",
"aggOps.frag",
"always-discard.frag",
"always-discard2.frag",
@@ -183,6 +184,7 @@
"matrix2.frag",
"newTexture.frag",
"Operations.frag",
+ "overlongLiteral.frag",
"prepost.frag",
"simpleFunctionCall.frag",
"structAssignment.frag",
diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp
index 2daaa65..c9d858c 100755
--- a/hlsl/hlslParseHelper.cpp
+++ b/hlsl/hlslParseHelper.cpp
@@ -1157,8 +1157,8 @@
case EvqVaryingOut:
return type.isStruct() || type.isArray();
case EvqUniform:
- return type.isArray() && intermediate.getFlattenUniformArrays() && topLevel ||
- type.isStruct() && type.containsOpaque();
+ return (type.isArray() && intermediate.getFlattenUniformArrays() && topLevel) ||
+ (type.isStruct() && type.containsOpaque());
default:
return type.isStruct() && type.containsOpaque();
};
diff --git a/known_good.json b/known_good.json
index ea3a808..87cc63d 100644
--- a/known_good.json
+++ b/known_good.json
@@ -5,7 +5,7 @@
"site" : "github",
"subrepo" : "KhronosGroup/SPIRV-Tools",
"subdir" : "External/spirv-tools",
- "commit" : "1a9061a2be884eed0e518ac19866246a5c9babc0"
+ "commit" : "5834719fc17d4735fce0102738b87b70255cfd5f"
},
{
"name" : "spirv-tools/external/spirv-headers",