Przeglądaj źródła

Updated glslang.

Бранимир Караџић 7 lat temu
rodzic
commit
a9bc78b91f
37 zmienionych plików z 1462 dodań i 430 usunięć
  1. 1 1
      3rdparty/glslang/StandAlone/ResourceLimits.h
  2. 21 1
      3rdparty/glslang/StandAlone/StandAlone.cpp
  3. 2 2
      3rdparty/glslang/Test/baseResults/440.vert.out
  4. 18 11
      3rdparty/glslang/Test/baseResults/hlsl.automap.frag.out
  5. 12 5
      3rdparty/glslang/Test/baseResults/hlsl.reflection.binding.frag.out
  6. 60 54
      3rdparty/glslang/Test/baseResults/hlsl.reflection.vert.out
  7. 18 11
      3rdparty/glslang/Test/baseResults/hlsl.shift.per-set.frag.out
  8. 1 0
      3rdparty/glslang/Test/baseResults/hlsl.structbuffer.fn2.comp.out
  9. 13 0
      3rdparty/glslang/Test/baseResults/reflection.frag.out
  10. 21 0
      3rdparty/glslang/Test/baseResults/reflection.linked.options.out
  11. 20 0
      3rdparty/glslang/Test/baseResults/reflection.linked.out
  12. 14 0
      3rdparty/glslang/Test/baseResults/reflection.options.frag.out
  13. 40 0
      3rdparty/glslang/Test/baseResults/reflection.options.vert.out
  14. 111 67
      3rdparty/glslang/Test/baseResults/reflection.vert.out
  15. 120 0
      3rdparty/glslang/Test/baseResults/spv.16bitxfb.vert.out
  16. 153 131
      3rdparty/glslang/Test/baseResults/spv.meshTaskShader.task.out
  17. 2 4
      3rdparty/glslang/Test/baseResults/spv.xfbOffsetOnStructMembersAssignment.vert.out
  18. 8 0
      3rdparty/glslang/Test/reflection.frag
  19. 19 0
      3rdparty/glslang/Test/reflection.linked.frag
  20. 19 0
      3rdparty/glslang/Test/reflection.linked.vert
  21. 44 0
      3rdparty/glslang/Test/reflection.options.vert
  22. 23 0
      3rdparty/glslang/Test/reflection.vert
  23. 10 0
      3rdparty/glslang/Test/runtests
  24. 33 0
      3rdparty/glslang/Test/spv.16bitxfb.vert
  25. 5 0
      3rdparty/glslang/Test/spv.meshTaskShader.task
  26. 1 1
      3rdparty/glslang/glslang/Include/revision.h
  27. 8 0
      3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp
  28. 27 11
      3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp
  29. 35 24
      3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp
  30. 79 1
      3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp
  31. 13 0
      3rdparty/glslang/glslang/MachineIndependent/localintermediate.h
  32. 294 31
      3rdparty/glslang/glslang/MachineIndependent/reflection.cpp
  33. 72 49
      3rdparty/glslang/glslang/MachineIndependent/reflection.h
  34. 130 25
      3rdparty/glslang/glslang/Public/ShaderLang.h
  35. 1 0
      3rdparty/glslang/gtests/Spv.FromFile.cpp
  36. 13 0
      3rdparty/glslang/hlsl/hlslParseHelper.cpp
  37. 1 1
      3rdparty/glslang/known_good.json

+ 1 - 1
3rdparty/glslang/StandAlone/ResourceLimits.h

@@ -37,7 +37,7 @@
 
 
 #include <string>
 #include <string>
 
 
-#include "glslang/Include/ResourceLimits.h"
+#include "../glslang/Include/ResourceLimits.h"
 
 
 namespace glslang {
 namespace glslang {
 
 

+ 21 - 1
3rdparty/glslang/StandAlone/StandAlone.cpp

@@ -152,6 +152,7 @@ void ProcessConfigFile()
     }
     }
 }
 }
 
 
+int ReflectOptions = EShReflectionDefault;
 int Options = 0;
 int Options = 0;
 const char* ExecutableName = nullptr;
 const char* ExecutableName = nullptr;
 const char* binaryFileName = nullptr;
 const char* binaryFileName = nullptr;
@@ -523,6 +524,16 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
                         Options |= EOptionNoStorageFormat;
                         Options |= EOptionNoStorageFormat;
                     } else if (lowerword == "relaxed-errors") {
                     } else if (lowerword == "relaxed-errors") {
                         Options |= EOptionRelaxedErrors;
                         Options |= EOptionRelaxedErrors;
+                    } else if (lowerword == "reflect-strict-array-suffix") {
+                        ReflectOptions |= EShReflectionStrictArraySuffix;
+                    } else if (lowerword == "reflect-basic-array-suffix") {
+                        ReflectOptions |= EShReflectionBasicArraySuffix;
+                    } else if (lowerword == "reflect-intermediate-io") {
+                        ReflectOptions |= EShReflectionIntermediateIO;
+                    } else if (lowerword == "reflect-separate-buffers") {
+                        ReflectOptions |= EShReflectionSeparateBuffers;
+                    } else if (lowerword == "reflect-all-block-variables") {
+                        ReflectOptions |= EShReflectionAllBlockVariables;
                     } else if (lowerword == "resource-set-bindings" ||  // synonyms
                     } else if (lowerword == "resource-set-bindings" ||  // synonyms
                                lowerword == "resource-set-binding"  ||
                                lowerword == "resource-set-binding"  ||
                                lowerword == "rsb") {
                                lowerword == "rsb") {
@@ -1051,7 +1062,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
 
 
     // Reflect
     // Reflect
     if (Options & EOptionDumpReflection) {
     if (Options & EOptionDumpReflection) {
-        program.buildReflection();
+        program.buildReflection(ReflectOptions);
         program.dumpReflection();
         program.dumpReflection();
     }
     }
 
 
@@ -1518,6 +1529,15 @@ void usage()
            "  --invert-y | --iy                 invert position.Y output in vertex shader\n"
            "  --invert-y | --iy                 invert position.Y output in vertex shader\n"
            "  --keep-uncalled | --ku            don't eliminate uncalled functions\n"
            "  --keep-uncalled | --ku            don't eliminate uncalled functions\n"
            "  --no-storage-format | --nsf       use Unknown image format\n"
            "  --no-storage-format | --nsf       use Unknown image format\n"
+           "  --reflect-strict-array-suffix     use strict array suffix rules when\n"
+           "                                    reflecting\n"
+           "  --reflect-basic-array-suffix      arrays of basic types will have trailing [0]\n"
+           "  --reflect-intermediate-io         reflection includes inputs/outputs of linked\n"
+           "                                    shaders rather than just vertex/fragment\n"
+           "  --reflect-separate-buffers        reflect buffer variables and blocks\n"
+           "                                    separately to uniforms\n"
+           "  --reflect-all-block-variables     reflect all variables in blocks, whether\n"
+           "                                    inactive or active\n"
            "  --resource-set-binding [stage] name set binding\n"
            "  --resource-set-binding [stage] name set binding\n"
            "                                    set descriptor set and binding for\n"
            "                                    set descriptor set and binding for\n"
            "                                    individual resources\n"
            "                                    individual resources\n"

+ 2 - 2
3rdparty/glslang/Test/baseResults/440.vert.out

@@ -39,9 +39,9 @@ ERROR: 0:131: 'xfb_stride' : all stride settings must match for xfb buffer 3
 ERROR: 0:152: 'xfb_offset' : overlapping offsets at offset 64 in buffer 0
 ERROR: 0:152: 'xfb_offset' : overlapping offsets at offset 64 in buffer 0
 ERROR: 0:157: 'xfb_buffer' : buffer is too large: gl_MaxTransformFeedbackBuffers is 4
 ERROR: 0:157: 'xfb_buffer' : buffer is too large: gl_MaxTransformFeedbackBuffers is 4
 ERROR: 0:158: 'xfb_offset' : must be a multiple of size of first component 
 ERROR: 0:158: 'xfb_offset' : must be a multiple of size of first component 
-ERROR: 0:159: 'xfb_offset' : type contains double; xfb_offset must be a multiple of 8 
+ERROR: 0:159: 'xfb_offset' : type contains double or 64-bit integer; xfb_offset must be a multiple of 8 
 ERROR: 0:161: 'xfb_offset' : must be a multiple of size of first component 
 ERROR: 0:161: 'xfb_offset' : must be a multiple of size of first component 
-ERROR: 0:162: 'xfb_offset' : type contains double; xfb_offset must be a multiple of 8 
+ERROR: 0:162: 'xfb_offset' : type contains double or 64-bit integer; xfb_offset must be a multiple of 8 
 ERROR: 0:166: 'xfb_buffer' : buffer is too large: gl_MaxTransformFeedbackBuffers is 4
 ERROR: 0:166: 'xfb_buffer' : buffer is too large: gl_MaxTransformFeedbackBuffers is 4
 ERROR: 0:169: 'xfb_buffer' : buffer is too large: gl_MaxTransformFeedbackBuffers is 4
 ERROR: 0:169: 'xfb_buffer' : buffer is too large: gl_MaxTransformFeedbackBuffers is 4
 ERROR: 0:169: 'xfb_stride' : 1/4 stride is too large: gl_MaxTransformFeedbackInterleavedComponents is 64
 ERROR: 0:169: 'xfb_stride' : 1/4 stride is too large: gl_MaxTransformFeedbackInterleavedComponents is 64

+ 18 - 11
3rdparty/glslang/Test/baseResults/hlsl.automap.frag.out

@@ -3,8 +3,8 @@ Uniform reflection:
 t1: offset -1, type 8b5d, size 1, index -1, binding 11, stages 16
 t1: offset -1, type 8b5d, size 1, index -1, binding 11, stages 16
 t2: offset -1, type 8b5e, size 1, index -1, binding 12, stages 16
 t2: offset -1, type 8b5e, size 1, index -1, binding 12, stages 16
 t3: offset -1, type 8b5f, size 1, index -1, binding 13, stages 16
 t3: offset -1, type 8b5f, size 1, index -1, binding 13, stages 16
-t4.@data: offset 0, type 8b52, size 1, index 0, binding -1, stages 16
-t5.@data: offset 0, type 1405, size 0, index 1, binding -1, stages 16
+t4.@data: offset 0, type 8b52, size 1, index 0, binding -1, stages 16, arrayStride 16, topLevelArrayStride 16
+t5.@data: offset 0, type 1405, size 0, index 1, binding -1, stages 16, arrayStride 4, topLevelArrayStride 4
 t6: offset -1, type 8dc2, size 1, index -1, binding 16, stages 16
 t6: offset -1, type 8dc2, size 1, index -1, binding 16, stages 16
 s1: offset -1, type 0, size 1, index -1, binding 31, stages 16
 s1: offset -1, type 0, size 1, index -1, binding 31, stages 16
 s2: offset -1, type 0, size 1, index -1, binding 32, stages 16
 s2: offset -1, type 0, size 1, index -1, binding 32, stages 16
@@ -12,18 +12,25 @@ u1: offset -1, type 904c, size 1, index -1, binding 41, stages 16
 u2: offset -1, type 904d, size 1, index -1, binding 42, stages 16
 u2: offset -1, type 904d, size 1, index -1, binding 42, stages 16
 u3: offset -1, type 904e, size 1, index -1, binding 43, stages 16
 u3: offset -1, type 904e, size 1, index -1, binding 43, stages 16
 u4: offset -1, type 9051, size 1, index -1, binding 44, stages 16
 u4: offset -1, type 9051, size 1, index -1, binding 44, stages 16
-u5.@data: offset 0, type 1405, size 0, index 2, binding -1, stages 16
-u6.@data: offset 0, type 1406, size 1, index 3, binding -1, stages 16
+u5.@data: offset 0, type 1405, size 0, index 2, binding -1, stages 16, arrayStride 4, topLevelArrayStride 4
+u6.@data: offset 0, type 1406, size 1, index 3, binding -1, stages 16, arrayStride 4, topLevelArrayStride 4
 cb1: offset 0, type 1404, size 1, index 4, binding -1, stages 16
 cb1: offset 0, type 1404, size 1, index 4, binding -1, stages 16
 tb1: offset 0, type 1404, size 1, index 5, binding -1, stages 16
 tb1: offset 0, type 1404, size 1, index 5, binding -1, stages 16
 
 
 Uniform block reflection:
 Uniform block reflection:
-t4: offset -1, type ffffffff, size 0, index -1, binding 14, stages 0
-t5: offset -1, type ffffffff, size 0, index -1, binding 15, stages 0
-u5: offset -1, type ffffffff, size 0, index -1, binding 45, stages 0
-u6: offset -1, type ffffffff, size 0, index -1, binding 46, stages 0
-cb: offset -1, type ffffffff, size 4, index -1, binding 51, stages 0
-tb: offset -1, type ffffffff, size 4, index -1, binding 17, stages 0
+t4: offset -1, type ffffffff, size 0, index -1, binding 14, stages 16, numMembers 1
+t5: offset -1, type ffffffff, size 0, index -1, binding 15, stages 16, numMembers 1
+u5: offset -1, type ffffffff, size 0, index -1, binding 45, stages 16, numMembers 1
+u6: offset -1, type ffffffff, size 0, index -1, binding 46, stages 16, numMembers 1
+cb: offset -1, type ffffffff, size 4, index -1, binding 51, stages 16, numMembers 1
+tb: offset -1, type ffffffff, size 4, index -1, binding 17, stages 16, numMembers 1
 
 
-Vertex attribute reflection:
+Buffer variable reflection:
+
+Buffer block reflection:
+
+Pipeline input reflection:
+
+Pipeline output reflection:
+@entryPointOutput: offset 0, type 8b52, size 0, index 0, binding -1, stages 16
 
 

+ 12 - 5
3rdparty/glslang/Test/baseResults/hlsl.reflection.binding.frag.out

@@ -2,8 +2,8 @@ hlsl.reflection.binding.frag
 Uniform reflection:
 Uniform reflection:
 t1: offset -1, type 8b5d, size 1, index -1, binding 15, stages 16
 t1: offset -1, type 8b5d, size 1, index -1, binding 15, stages 16
 s1: offset -1, type 0, size 1, index -1, binding 5, stages 16
 s1: offset -1, type 0, size 1, index -1, binding 5, stages 16
-t1a: offset -1, type 8b5d, size 1, index -1, binding 16, stages 16
-s1a: offset -1, type 0, size 1, index -1, binding 6, stages 16
+t1a: offset -1, type 8b5d, size 1, index -1, binding 16, stages 16, arrayStride 4, topLevelArrayStride 4
+s1a: offset -1, type 0, size 1, index -1, binding 6, stages 16, arrayStride 4, topLevelArrayStride 4
 c1_a: offset 0, type 8b52, size 1, index 0, binding -1, stages 16
 c1_a: offset 0, type 8b52, size 1, index 0, binding -1, stages 16
 c1_b: offset 16, type 1404, size 1, index 0, binding -1, stages 16
 c1_b: offset 16, type 1404, size 1, index 0, binding -1, stages 16
 c1_c: offset 20, type 1406, size 1, index 0, binding -1, stages 16
 c1_c: offset 20, type 1406, size 1, index 0, binding -1, stages 16
@@ -12,8 +12,15 @@ c2_b: offset 16, type 1404, size 1, index 1, binding -1, stages 16
 c2_c: offset 20, type 1406, size 1, index 1, binding -1, stages 16
 c2_c: offset 20, type 1406, size 1, index 1, binding -1, stages 16
 
 
 Uniform block reflection:
 Uniform block reflection:
-cbuff1: offset -1, type ffffffff, size 24, index -1, binding 2, stages 0
-cbuff2: offset -1, type ffffffff, size 24, index -1, binding 3, stages 0
+cbuff1: offset -1, type ffffffff, size 24, index -1, binding 2, stages 16, numMembers 3
+cbuff2: offset -1, type ffffffff, size 24, index -1, binding 3, stages 16, numMembers 3
 
 
-Vertex attribute reflection:
+Buffer variable reflection:
+
+Buffer block reflection:
+
+Pipeline input reflection:
+
+Pipeline output reflection:
+psout.Color: offset 0, type 8b52, size 0, index 0, binding -1, stages 16
 
 

+ 60 - 54
3rdparty/glslang/Test/baseResults/hlsl.reflection.vert.out

@@ -7,70 +7,76 @@ scalarAfterm23: offset 48, type 1404, size 1, index 0, binding -1, stages 1
 c_m23: offset 16, type 8b67, size 1, index 2, binding -1, stages 1
 c_m23: offset 16, type 8b67, size 1, index 2, binding -1, stages 1
 c_scalarAfterm23: offset 48, type 1404, size 1, index 2, binding -1, stages 1
 c_scalarAfterm23: offset 48, type 1404, size 1, index 2, binding -1, stages 1
 scalarBeforeArray: offset 96, type 1404, size 1, index 0, binding -1, stages 1
 scalarBeforeArray: offset 96, type 1404, size 1, index 0, binding -1, stages 1
-floatArray: offset 112, type 1406, size 5, index 0, binding -1, stages 1
+floatArray: offset 112, type 1406, size 5, index 0, binding -1, stages 1, arrayStride 16, topLevelArrayStride 16
 scalarAfterArray: offset 192, type 1404, size 1, index 0, binding -1, stages 1
 scalarAfterArray: offset 192, type 1404, size 1, index 0, binding -1, stages 1
-m22: offset 208, type 8b5a, size 9, index 0, binding -1, stages 1
-dm22: offset 32, type 8b5a, size 4, index 1, binding -1, stages 1
+m22: offset 208, type 8b5a, size 9, index 0, binding -1, stages 1, arrayStride 32, topLevelArrayStride 32
+dm22: offset 32, type 8b5a, size 4, index 1, binding -1, stages 1, arrayStride 32, topLevelArrayStride 32
 foo.n1.a: offset 0, type 1406, size 1, index 3, binding -1, stages 1
 foo.n1.a: offset 0, type 1406, size 1, index 3, binding -1, stages 1
 foo.n2.b: offset 16, type 1406, size 1, index 3, binding -1, stages 1
 foo.n2.b: offset 16, type 1406, size 1, index 3, binding -1, stages 1
 foo.n2.c: offset 20, type 1406, size 1, index 3, binding -1, stages 1
 foo.n2.c: offset 20, type 1406, size 1, index 3, binding -1, stages 1
 foo.n2.d: offset 24, type 1406, size 1, index 3, binding -1, stages 1
 foo.n2.d: offset 24, type 1406, size 1, index 3, binding -1, stages 1
-deepA.d2.d1[2].va: offset 440, type 8b50, size 2, index 1, binding -1, stages 1
-deepB.d2.d1.va: offset 984, type 8b50, size 2, index 1, binding -1, stages 1
-deepB.d2.d1[0].va: offset 984, type 8b50, size 2, index 1, binding -1, stages 1
-deepB.d2.d1[1].va: offset 1016, type 8b50, size 2, index 1, binding -1, stages 1
-deepB.d2.d1[2].va: offset 1048, type 8b50, size 2, index 1, binding -1, stages 1
-deepB.d2.d1[3].va: offset 1080, type 8b50, size 2, index 1, binding -1, stages 1
-deepC.iv4: offset 1568, type 8b52, size 1, index 1, binding -1, stages 1
-deepC.d2.i: offset 1584, type 1404, size 1, index 1, binding -1, stages 1
-deepC.d2.d1[0].va: offset 1592, type 8b50, size 3, index 1, binding -1, stages 1
-deepC.d2.d1[0].b: offset 1616, type 8b56, size 1, index 1, binding -1, stages 1
-deepC.d2.d1[1].va: offset 1624, type 8b50, size 3, index 1, binding -1, stages 1
-deepC.d2.d1[1].b: offset 1648, type 8b56, size 1, index 1, binding -1, stages 1
-deepC.d2.d1[2].va: offset 1656, type 8b50, size 3, index 1, binding -1, stages 1
-deepC.d2.d1[2].b: offset 1680, type 8b56, size 1, index 1, binding -1, stages 1
-deepC.d2.d1[3].va: offset 1688, type 8b50, size 3, index 1, binding -1, stages 1
-deepC.d2.d1[3].b: offset 1712, type 8b56, size 1, index 1, binding -1, stages 1
-deepC.v3: offset 1728, type 8b54, size 1, index 1, binding -1, stages 1
-deepD[0].iv4: offset 2480, type 8b52, size 1, index 1, binding -1, stages 1
-deepD[0].d2.i: offset 2496, type 1404, size 1, index 1, binding -1, stages 1
-deepD[0].d2.d1[0].va: offset 2504, type 8b50, size 3, index 1, binding -1, stages 1
-deepD[0].d2.d1[0].b: offset 2528, type 8b56, size 1, index 1, binding -1, stages 1
-deepD[0].d2.d1[1].va: offset 2536, type 8b50, size 3, index 1, binding -1, stages 1
-deepD[0].d2.d1[1].b: offset 2560, type 8b56, size 1, index 1, binding -1, stages 1
-deepD[0].d2.d1[2].va: offset 2568, type 8b50, size 3, index 1, binding -1, stages 1
-deepD[0].d2.d1[2].b: offset 2592, type 8b56, size 1, index 1, binding -1, stages 1
-deepD[0].d2.d1[3].va: offset 2600, type 8b50, size 3, index 1, binding -1, stages 1
-deepD[0].d2.d1[3].b: offset 2624, type 8b56, size 1, index 1, binding -1, stages 1
-deepD[0].v3: offset 2640, type 8b54, size 1, index 1, binding -1, stages 1
-deepD[1].iv4: offset 2784, type 8b52, size 1, index 1, binding -1, stages 1
-deepD[1].d2.i: offset 2800, type 1404, size 1, index 1, binding -1, stages 1
-deepD[1].d2.d1[0].va: offset 2808, type 8b50, size 3, index 1, binding -1, stages 1
-deepD[1].d2.d1[0].b: offset 2832, type 8b56, size 1, index 1, binding -1, stages 1
-deepD[1].d2.d1[1].va: offset 2840, type 8b50, size 3, index 1, binding -1, stages 1
-deepD[1].d2.d1[1].b: offset 2864, type 8b56, size 1, index 1, binding -1, stages 1
-deepD[1].d2.d1[2].va: offset 2872, type 8b50, size 3, index 1, binding -1, stages 1
-deepD[1].d2.d1[2].b: offset 2896, type 8b56, size 1, index 1, binding -1, stages 1
-deepD[1].d2.d1[3].va: offset 2904, type 8b50, size 3, index 1, binding -1, stages 1
-deepD[1].d2.d1[3].b: offset 2928, type 8b56, size 1, index 1, binding -1, stages 1
-deepD[1].v3: offset 2944, type 8b54, size 1, index 1, binding -1, stages 1
+deepA.d2.d1[2].va: offset 440, type 8b50, size 2, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepB.d2.d1.va: offset 984, type 8b50, size 2, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepB.d2.d1[0].va: offset 984, type 8b50, size 2, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepB.d2.d1[1].va: offset 1016, type 8b50, size 2, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepB.d2.d1[2].va: offset 1048, type 8b50, size 2, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepB.d2.d1[3].va: offset 1080, type 8b50, size 2, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepC.iv4: offset 1568, type 8b52, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepC.d2.i: offset 1584, type 1404, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepC.d2.d1[0].va: offset 1592, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepC.d2.d1[0].b: offset 1616, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepC.d2.d1[1].va: offset 1624, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepC.d2.d1[1].b: offset 1648, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepC.d2.d1[2].va: offset 1656, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepC.d2.d1[2].b: offset 1680, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepC.d2.d1[3].va: offset 1688, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepC.d2.d1[3].b: offset 1712, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepC.v3: offset 1728, type 8b54, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepD[0].iv4: offset 2480, type 8b52, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepD[0].d2.i: offset 2496, type 1404, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepD[0].d2.d1[0].va: offset 2504, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepD[0].d2.d1[0].b: offset 2528, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepD[0].d2.d1[1].va: offset 2536, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepD[0].d2.d1[1].b: offset 2560, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepD[0].d2.d1[2].va: offset 2568, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepD[0].d2.d1[2].b: offset 2592, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepD[0].d2.d1[3].va: offset 2600, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepD[0].d2.d1[3].b: offset 2624, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepD[0].v3: offset 2640, type 8b54, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepD[1].iv4: offset 2784, type 8b52, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepD[1].d2.i: offset 2800, type 1404, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepD[1].d2.d1[0].va: offset 2808, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepD[1].d2.d1[0].b: offset 2832, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepD[1].d2.d1[1].va: offset 2840, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepD[1].d2.d1[1].b: offset 2864, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepD[1].d2.d1[2].va: offset 2872, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepD[1].d2.d1[2].b: offset 2896, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepD[1].d2.d1[3].va: offset 2904, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304
+deepD[1].d2.d1[3].b: offset 2928, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
+deepD[1].v3: offset 2944, type 8b54, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304
 foo1: offset 0, type 1406, size 1, index 4, binding -1, stages 1
 foo1: offset 0, type 1406, size 1, index 4, binding -1, stages 1
 foo2: offset 0, type 1406, size 1, index 5, binding -1, stages 1
 foo2: offset 0, type 1406, size 1, index 5, binding -1, stages 1
 anonMember1: offset 0, type 8b51, size 1, index 0, binding -1, stages 1
 anonMember1: offset 0, type 8b51, size 1, index 0, binding -1, stages 1
 uf1: offset 16, type 1406, size 1, index 1, binding -1, stages 1
 uf1: offset 16, type 1406, size 1, index 1, binding -1, stages 1
 
 
 Uniform block reflection:
 Uniform block reflection:
-nameless: offset -1, type ffffffff, size 496, index -1, binding -1, stages 0
-$Global: offset -1, type ffffffff, size 3088, index -1, binding -1, stages 0
-c_nameless: offset -1, type ffffffff, size 96, index -1, binding -1, stages 0
-nested: offset -1, type ffffffff, size 32, index -1, binding -1, stages 0
-abl: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
-abl2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
+nameless: offset -1, type ffffffff, size 496, index -1, binding -1, stages 1, numMembers 9
+$Global: offset -1, type ffffffff, size 3088, index -1, binding -1, stages 1, numMembers 106
+c_nameless: offset -1, type ffffffff, size 96, index -1, binding -1, stages 1, numMembers 5
+nested: offset -1, type ffffffff, size 32, index -1, binding -1, stages 1, numMembers 4
+abl: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
+abl2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
 
 
-Vertex attribute reflection:
-attributeFloat: offset 0, type 1406, size 0, index 0, binding -1, stages 0
-attributeFloat2: offset 0, type 8b50, size 0, index 0, binding -1, stages 0
-attributeFloat3: offset 0, type 8b51, size 0, index 0, binding -1, stages 0
-attributeFloat4: offset 0, type 8b52, size 0, index 0, binding -1, stages 0
-attributeMat4: offset 0, type 8b5c, size 0, index 0, binding -1, stages 0
+Buffer variable reflection:
+
+Buffer block reflection:
+
+Pipeline input reflection:
+attributeFloat: offset 0, type 1406, size 0, index 0, binding -1, stages 1
+attributeFloat2: offset 0, type 8b50, size 0, index 0, binding -1, stages 1
+attributeFloat3: offset 0, type 8b51, size 0, index 0, binding -1, stages 1
+attributeFloat4: offset 0, type 8b52, size 0, index 0, binding -1, stages 1
+attributeMat4: offset 0, type 8b5c, size 0, index 0, binding -1, stages 1
+
+Pipeline output reflection:
 
 

+ 18 - 11
3rdparty/glslang/Test/baseResults/hlsl.shift.per-set.frag.out

@@ -203,8 +203,8 @@ Uniform reflection:
 t1: offset -1, type 8b5d, size 1, index -1, binding 21, stages 16
 t1: offset -1, type 8b5d, size 1, index -1, binding 21, stages 16
 t2: offset -1, type 8b5e, size 1, index -1, binding 22, stages 16
 t2: offset -1, type 8b5e, size 1, index -1, binding 22, stages 16
 t3: offset -1, type 8b5f, size 1, index -1, binding 26, stages 16
 t3: offset -1, type 8b5f, size 1, index -1, binding 26, stages 16
-t4.@data: offset 0, type 8b52, size 1, index 0, binding -1, stages 16
-t5.@data: offset 0, type 1405, size 0, index 1, binding -1, stages 16
+t4.@data: offset 0, type 8b52, size 1, index 0, binding -1, stages 16, arrayStride 16, topLevelArrayStride 16
+t5.@data: offset 0, type 1405, size 0, index 1, binding -1, stages 16, arrayStride 4, topLevelArrayStride 4
 t6: offset -1, type 8dc2, size 1, index -1, binding 23, stages 16
 t6: offset -1, type 8dc2, size 1, index -1, binding 23, stages 16
 s1: offset -1, type 0, size 1, index -1, binding 11, stages 16
 s1: offset -1, type 0, size 1, index -1, binding 11, stages 16
 s2: offset -1, type 0, size 1, index -1, binding 17, stages 16
 s2: offset -1, type 0, size 1, index -1, binding 17, stages 16
@@ -212,19 +212,26 @@ u1: offset -1, type 904c, size 1, index -1, binding 31, stages 16
 u2: offset -1, type 904d, size 1, index -1, binding 42, stages 16
 u2: offset -1, type 904d, size 1, index -1, binding 42, stages 16
 u3: offset -1, type 904e, size 1, index -1, binding 43, stages 16
 u3: offset -1, type 904e, size 1, index -1, binding 43, stages 16
 u4: offset -1, type 9051, size 1, index -1, binding 34, stages 16
 u4: offset -1, type 9051, size 1, index -1, binding 34, stages 16
-u5.@data: offset 0, type 1405, size 0, index 2, binding -1, stages 16
-u6.@data: offset 0, type 1406, size 1, index 3, binding -1, stages 16
+u5.@data: offset 0, type 1405, size 0, index 2, binding -1, stages 16, arrayStride 4, topLevelArrayStride 4
+u6.@data: offset 0, type 1406, size 1, index 3, binding -1, stages 16, arrayStride 4, topLevelArrayStride 4
 cb1: offset 0, type 1404, size 1, index 4, binding -1, stages 16
 cb1: offset 0, type 1404, size 1, index 4, binding -1, stages 16
 tb1: offset 0, type 1404, size 1, index 5, binding -1, stages 16
 tb1: offset 0, type 1404, size 1, index 5, binding -1, stages 16
 ts6: offset -1, type 8b5f, size 1, index -1, binding 71, stages 16
 ts6: offset -1, type 8b5f, size 1, index -1, binding 71, stages 16
 
 
 Uniform block reflection:
 Uniform block reflection:
-t4: offset -1, type ffffffff, size 0, index -1, binding 21, stages 0
-t5: offset -1, type ffffffff, size 0, index -1, binding 22, stages 0
-u5: offset -1, type ffffffff, size 0, index -1, binding 44, stages 0
-u6: offset -1, type ffffffff, size 0, index -1, binding 34, stages 0
-cb: offset -1, type ffffffff, size 4, index -1, binding 51, stages 0
-tb: offset -1, type ffffffff, size 4, index -1, binding 27, stages 0
+t4: offset -1, type ffffffff, size 0, index -1, binding 21, stages 16, numMembers 1
+t5: offset -1, type ffffffff, size 0, index -1, binding 22, stages 16, numMembers 1
+u5: offset -1, type ffffffff, size 0, index -1, binding 44, stages 16, numMembers 1
+u6: offset -1, type ffffffff, size 0, index -1, binding 34, stages 16, numMembers 1
+cb: offset -1, type ffffffff, size 4, index -1, binding 51, stages 16, numMembers 1
+tb: offset -1, type ffffffff, size 4, index -1, binding 27, stages 16, numMembers 1
 
 
-Vertex attribute reflection:
+Buffer variable reflection:
+
+Buffer block reflection:
+
+Pipeline input reflection:
+
+Pipeline output reflection:
+@entryPointOutput: offset 0, type 8b52, size 0, index 0, binding -1, stages 16
 
 

+ 1 - 0
3rdparty/glslang/Test/baseResults/hlsl.structbuffer.fn2.comp.out

@@ -135,6 +135,7 @@ local_size = (256, 1, 1)
 0:?     'g_output' (layout( binding=1 rg32ui) uniform uimageBuffer)
 0:?     'g_output' (layout( binding=1 rg32ui) uniform uimageBuffer)
 0:?     'dispatchId' ( in 3-component vector of uint GlobalInvocationID)
 0:?     'dispatchId' ( in 3-component vector of uint GlobalInvocationID)
 
 
+Validation failed
 // Module Version 10000
 // Module Version 10000
 // Generated by (magic number): 80007
 // Generated by (magic number): 80007
 // Id's are bound by 63
 // Id's are bound by 63

+ 13 - 0
3rdparty/glslang/Test/baseResults/reflection.frag.out

@@ -0,0 +1,13 @@
+reflection.frag
+Uniform reflection:
+
+Uniform block reflection:
+
+Buffer variable reflection:
+
+Buffer block reflection:
+
+Pipeline input reflection:
+
+Pipeline output reflection:
+

+ 21 - 0
3rdparty/glslang/Test/baseResults/reflection.linked.options.out

@@ -0,0 +1,21 @@
+reflection.linked.vert
+reflection.linked.frag
+Uniform reflection:
+ubo_block.unused_uniform: offset 0, type 1406, size 1, index 0, binding -1, stages 0
+ubo_block.shared_uniform: offset 4, type 1406, size 1, index 0, binding -1, stages 17
+ubo_block.vsonly_uniform: offset 8, type 1406, size 1, index 0, binding -1, stages 1
+ubo_block.fsonly_uniform: offset 12, type 1406, size 1, index 0, binding -1, stages 16
+
+Uniform block reflection:
+ubo_block: offset -1, type ffffffff, size 16, index -1, binding 0, stages 17, numMembers 4
+
+Buffer variable reflection:
+
+Buffer block reflection:
+
+Pipeline input reflection:
+vertin: offset 0, type 1406, size 0, index 0, binding -1, stages 1
+
+Pipeline output reflection:
+fragout: offset 0, type 1406, size 0, index 0, binding -1, stages 16
+

+ 20 - 0
3rdparty/glslang/Test/baseResults/reflection.linked.out

@@ -0,0 +1,20 @@
+reflection.linked.vert
+reflection.linked.frag
+Uniform reflection:
+ubo_block.shared_uniform: offset 4, type 1406, size 1, index 0, binding -1, stages 17
+ubo_block.vsonly_uniform: offset 8, type 1406, size 1, index 0, binding -1, stages 17
+ubo_block.fsonly_uniform: offset 12, type 1406, size 1, index 0, binding -1, stages 16
+
+Uniform block reflection:
+ubo_block: offset -1, type ffffffff, size 16, index -1, binding 0, stages 17, numMembers 4
+
+Buffer variable reflection:
+
+Buffer block reflection:
+
+Pipeline input reflection:
+vertin: offset 0, type 1406, size 0, index 0, binding -1, stages 1
+
+Pipeline output reflection:
+fragout: offset 0, type 1406, size 0, index 0, binding -1, stages 16
+

+ 14 - 0
3rdparty/glslang/Test/baseResults/reflection.options.frag.out

@@ -0,0 +1,14 @@
+reflection.frag
+Uniform reflection:
+
+Uniform block reflection:
+
+Buffer variable reflection:
+
+Buffer block reflection:
+
+Pipeline input reflection:
+inval: offset 0, type 1406, size 0, index 0, binding -1, stages 16
+
+Pipeline output reflection:
+

+ 40 - 0
3rdparty/glslang/Test/baseResults/reflection.options.vert.out

@@ -0,0 +1,40 @@
+reflection.options.vert
+Uniform reflection:
+UBO.verts[0].position[0]: offset 0, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+UBO.verts[0].normal[0]: offset 12, type 1406, size 3, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
+UBO.verts[1].position[0]: offset 24, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+UBO.verts[1].normal[0]: offset 36, type 1406, size 3, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
+UBO.flt[0]: offset 48, type 1406, size 8, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4
+UBO.unused: offset 80, type 8dc8, size 1, index 0, binding -1, stages 0
+
+Uniform block reflection:
+UBO: offset -1, type ffffffff, size 96, index -1, binding -1, stages 1, numMembers 6
+
+Buffer variable reflection:
+t[0].v[0].position[0]: offset 0, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[0].v[0].normal[0]: offset 12, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[0].v[1].position[0]: offset 24, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[0].v[1].normal[0]: offset 36, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[0].v[2].position[0]: offset 48, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[0].v[2].normal[0]: offset 60, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+padding[0]: offset 360, type 1405, size 10, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 4
+MultipleArrays.tri[0].v[0].position[0]: offset 0, type 1406, size 3, index 1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+MultipleArrays.tri[0].v[0].normal[0]: offset 12, type 1406, size 3, index 1, binding -1, stages 0, arrayStride 4, topLevelArrayStride 72
+MultipleArrays.tri[0].v[1].position[0]: offset 24, type 1406, size 3, index 1, binding -1, stages 0, arrayStride 4, topLevelArrayStride 72
+MultipleArrays.tri[0].v[1].normal[0]: offset 36, type 1406, size 3, index 1, binding -1, stages 0, arrayStride 4, topLevelArrayStride 72
+MultipleArrays.tri[0].v[2].position[0]: offset 48, type 1406, size 3, index 1, binding -1, stages 0, arrayStride 4, topLevelArrayStride 72
+MultipleArrays.tri[0].v[2].normal[0]: offset 60, type 1406, size 3, index 1, binding -1, stages 0, arrayStride 4, topLevelArrayStride 72
+MultipleArrays.vert[0].position[0]: offset 360, type 1406, size 3, index 1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+MultipleArrays.vert[0].normal[0]: offset 372, type 1406, size 3, index 1, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
+MultipleArrays.f[0]: offset 480, type 1406, size 5, index 1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4
+
+Buffer block reflection:
+VertexCollection: offset -1, type ffffffff, size 400, index -1, binding -1, stages 1, numMembers 7
+MultipleArrays: offset -1, type ffffffff, size 500, index -1, binding -1, stages 1, numMembers 9
+
+Pipeline input reflection:
+gl_InstanceID: offset 0, type 1404, size 0, index 0, binding -1, stages 1
+
+Pipeline output reflection:
+outval: offset 0, type 1406, size 0, index 0, binding -1, stages 1
+

+ 111 - 67
3rdparty/glslang/Test/baseResults/reflection.vert.out

@@ -11,108 +11,152 @@ scalarAfterm23: offset 48, type 1404, size 1, index 0, binding -1, stages 1
 c_m23: offset 16, type 8b67, size 1, index 2, binding -1, stages 1
 c_m23: offset 16, type 8b67, size 1, index 2, binding -1, stages 1
 c_scalarAfterm23: offset 64, type 1404, size 1, index 2, binding -1, stages 1
 c_scalarAfterm23: offset 64, type 1404, size 1, index 2, binding -1, stages 1
 scalarBeforeArray: offset 96, type 1404, size 1, index 0, binding -1, stages 1
 scalarBeforeArray: offset 96, type 1404, size 1, index 0, binding -1, stages 1
-floatArray: offset 112, type 1406, size 5, index 0, binding -1, stages 1
+floatArray: offset 112, type 1406, size 5, index 0, binding -1, stages 1, arrayStride 16, topLevelArrayStride 16
 scalarAfterArray: offset 192, type 1404, size 1, index 0, binding -1, stages 1
 scalarAfterArray: offset 192, type 1404, size 1, index 0, binding -1, stages 1
 named.memvec2: offset 48, type 8b50, size 1, index 1, binding -1, stages 1
 named.memvec2: offset 48, type 8b50, size 1, index 1, binding -1, stages 1
 named.memf1: offset 56, type 1406, size 1, index 1, binding -1, stages 1
 named.memf1: offset 56, type 1406, size 1, index 1, binding -1, stages 1
 named.memf2: offset 60, type 8b56, size 1, index 1, binding -1, stages 1
 named.memf2: offset 60, type 8b56, size 1, index 1, binding -1, stages 1
 named.memf3: offset 64, type 1404, size 1, index 1, binding -1, stages 1
 named.memf3: offset 64, type 1404, size 1, index 1, binding -1, stages 1
 named.memvec2a: offset 72, type 8b50, size 1, index 1, binding -1, stages 1
 named.memvec2a: offset 72, type 8b50, size 1, index 1, binding -1, stages 1
-named.m22: offset 80, type 8b5a, size 7, index 1, binding -1, stages 1
-dm22: offset -1, type 8b5a, size 4, index -1, binding -1, stages 1
-m22: offset 208, type 8b5a, size 3, index 0, binding -1, stages 1
+named.m22: offset 80, type 8b5a, size 7, index 1, binding -1, stages 1, arrayStride 32, topLevelArrayStride 32
+dm22: offset -1, type 8b5a, size 4, index -1, binding -1, stages 1, arrayStride 16, topLevelArrayStride 16
+m22: offset 208, type 8b5a, size 3, index 0, binding -1, stages 1, arrayStride 32, topLevelArrayStride 32
 nested.foo.n1.a: offset 0, type 1406, size 1, index 3, binding -1, stages 1
 nested.foo.n1.a: offset 0, type 1406, size 1, index 3, binding -1, stages 1
 nested.foo.n2.b: offset 16, type 1406, size 1, index 3, binding -1, stages 1
 nested.foo.n2.b: offset 16, type 1406, size 1, index 3, binding -1, stages 1
 nested.foo.n2.c: offset 20, type 1406, size 1, index 3, binding -1, stages 1
 nested.foo.n2.c: offset 20, type 1406, size 1, index 3, binding -1, stages 1
 nested.foo.n2.d: offset 24, type 1406, size 1, index 3, binding -1, stages 1
 nested.foo.n2.d: offset 24, type 1406, size 1, index 3, binding -1, stages 1
-deepA[0].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1
-deepA[1].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1
-deepB[1].d2.d1[0].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1
-deepB[1].d2.d1[1].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1
-deepB[1].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1
-deepB[1].d2.d1[3].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1
-deepB[0].d2.d1[0].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1
-deepB[0].d2.d1[1].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1
-deepB[0].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1
-deepB[0].d2.d1[3].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1
-deepC[1].iv4: offset -1, type 8b52, size 1, index -1, binding -1, stages 1
-deepC[1].d2.i: offset -1, type 1404, size 1, index -1, binding -1, stages 1
-deepC[1].d2.d1[0].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1
-deepC[1].d2.d1[0].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
-deepC[1].d2.d1[1].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1
-deepC[1].d2.d1[1].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
-deepC[1].d2.d1[2].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1
-deepC[1].d2.d1[2].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
-deepC[1].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1
-deepC[1].d2.d1[3].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
-deepC[1].v3: offset -1, type 8b54, size 1, index -1, binding -1, stages 1
+deepA[0].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepA[1].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepB[1].d2.d1[0].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepB[1].d2.d1[1].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepB[1].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepB[1].d2.d1[3].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepB[0].d2.d1[0].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepB[0].d2.d1[1].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepB[0].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepB[0].d2.d1[3].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepC[1].iv4: offset -1, type 8b52, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
+deepC[1].d2.i: offset -1, type 1404, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
+deepC[1].d2.d1[0].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepC[1].d2.d1[0].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
+deepC[1].d2.d1[1].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepC[1].d2.d1[1].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
+deepC[1].d2.d1[2].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepC[1].d2.d1[2].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
+deepC[1].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepC[1].d2.d1[3].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
+deepC[1].v3: offset -1, type 8b54, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
 deepD[0].iv4: offset -1, type 8b52, size 1, index -1, binding -1, stages 1
 deepD[0].iv4: offset -1, type 8b52, size 1, index -1, binding -1, stages 1
 deepD[0].d2.i: offset -1, type 1404, size 1, index -1, binding -1, stages 1
 deepD[0].d2.i: offset -1, type 1404, size 1, index -1, binding -1, stages 1
-deepD[0].d2.d1[0].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1
+deepD[0].d2.d1[0].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8
 deepD[0].d2.d1[0].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
 deepD[0].d2.d1[0].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
-deepD[0].d2.d1[1].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1
+deepD[0].d2.d1[1].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8
 deepD[0].d2.d1[1].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
 deepD[0].d2.d1[1].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
-deepD[0].d2.d1[2].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1
+deepD[0].d2.d1[2].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8
 deepD[0].d2.d1[2].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
 deepD[0].d2.d1[2].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
-deepD[0].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1
+deepD[0].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8
 deepD[0].d2.d1[3].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
 deepD[0].d2.d1[3].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
 deepD[0].v3: offset -1, type 8b54, size 1, index -1, binding -1, stages 1
 deepD[0].v3: offset -1, type 8b54, size 1, index -1, binding -1, stages 1
 deepD[1].iv4: offset -1, type 8b52, size 1, index -1, binding -1, stages 1
 deepD[1].iv4: offset -1, type 8b52, size 1, index -1, binding -1, stages 1
 deepD[1].d2.i: offset -1, type 1404, size 1, index -1, binding -1, stages 1
 deepD[1].d2.i: offset -1, type 1404, size 1, index -1, binding -1, stages 1
-deepD[1].d2.d1[0].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1
+deepD[1].d2.d1[0].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8
 deepD[1].d2.d1[0].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
 deepD[1].d2.d1[0].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
-deepD[1].d2.d1[1].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1
+deepD[1].d2.d1[1].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8
 deepD[1].d2.d1[1].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
 deepD[1].d2.d1[1].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
-deepD[1].d2.d1[2].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1
+deepD[1].d2.d1[2].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8
 deepD[1].d2.d1[2].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
 deepD[1].d2.d1[2].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
-deepD[1].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1
+deepD[1].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8
 deepD[1].d2.d1[3].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
 deepD[1].d2.d1[3].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
 deepD[1].v3: offset -1, type 8b54, size 1, index -1, binding -1, stages 1
 deepD[1].v3: offset -1, type 8b54, size 1, index -1, binding -1, stages 1
 abl.foo: offset 0, type 1406, size 1, index 7, binding -1, stages 1
 abl.foo: offset 0, type 1406, size 1, index 7, binding -1, stages 1
 abl2.foo: offset 0, type 1406, size 1, index 11, binding -1, stages 1
 abl2.foo: offset 0, type 1406, size 1, index 11, binding -1, stages 1
-buf1.runtimeArray: offset 4, type 1406, size 4, index 12, binding -1, stages 1
-buf2.runtimeArray.c: offset 8, type 1406, size 1, index 13, binding -1, stages 1
-buf3.runtimeArray: offset 4, type 1406, size 0, index 14, binding -1, stages 1
-buf4.runtimeArray.c: offset 8, type 1406, size 1, index 15, binding -1, stages 1
+buf1.runtimeArray: offset 4, type 1406, size 4, index 12, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4
+buf2.runtimeArray.c: offset 8, type 1406, size 1, index 13, binding -1, stages 1, topLevelArrayStride 12
+buf3.runtimeArray: offset 4, type 1406, size 0, index 14, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4
+buf4.runtimeArray.c: offset 8, type 1406, size 1, index 15, binding -1, stages 1, topLevelArrayStride 12
 nested2.a.n1.a: offset 16, type 1406, size 1, index 16, binding -1, stages 1
 nested2.a.n1.a: offset 16, type 1406, size 1, index 16, binding -1, stages 1
 nested2.a.n2.b: offset 32, type 1406, size 1, index 16, binding -1, stages 1
 nested2.a.n2.b: offset 32, type 1406, size 1, index 16, binding -1, stages 1
 nested2.a.n2.c: offset 36, type 1406, size 1, index 16, binding -1, stages 1
 nested2.a.n2.c: offset 36, type 1406, size 1, index 16, binding -1, stages 1
 nested2.a.n2.d: offset 40, type 1406, size 1, index 16, binding -1, stages 1
 nested2.a.n2.d: offset 40, type 1406, size 1, index 16, binding -1, stages 1
-nested2.b[0].a: offset 48, type 1406, size 1, index 16, binding -1, stages 1
-nested2.b[1].a: offset 64, type 1406, size 1, index 16, binding -1, stages 1
-nested2.b[2].a: offset 80, type 1406, size 1, index 16, binding -1, stages 1
-nested2.b[3].a: offset 96, type 1406, size 1, index 16, binding -1, stages 1
-nested2.c.a: offset 112, type 1406, size 1, index 16, binding -1, stages 1
-nested2.d.a: offset 144, type 1406, size 1, index 16, binding -1, stages 1
+nested2.b[0].a: offset 48, type 1406, size 1, index 16, binding -1, stages 1, topLevelArrayStride 16
+nested2.b[1].a: offset 64, type 1406, size 1, index 16, binding -1, stages 1, topLevelArrayStride 16
+nested2.b[2].a: offset 80, type 1406, size 1, index 16, binding -1, stages 1, topLevelArrayStride 16
+nested2.b[3].a: offset 96, type 1406, size 1, index 16, binding -1, stages 1, topLevelArrayStride 16
+nested2.c.a: offset 112, type 1406, size 1, index 16, binding -1, stages 1, topLevelArrayStride 16
+nested2.d.a: offset 144, type 1406, size 1, index 16, binding -1, stages 1, topLevelArrayStride 16
+t.v.position: offset 0, type 1406, size 1, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t.v[0].position: offset 0, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t.v[1].position: offset 24, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t.v[2].position: offset 48, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t.v[0].normal: offset 12, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t.v[1].normal: offset 36, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t.v[2].normal: offset 60, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[0].v[0].position: offset 0, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[0].v[0].normal: offset 12, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[0].v[1].position: offset 24, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[0].v[1].normal: offset 36, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[0].v[2].position: offset 48, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[0].v[2].normal: offset 60, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[1].v[0].position: offset 72, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[1].v[0].normal: offset 84, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[1].v[1].position: offset 96, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[1].v[1].normal: offset 108, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[1].v[2].position: offset 120, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[1].v[2].normal: offset 132, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[2].v[0].position: offset 144, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[2].v[0].normal: offset 156, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[2].v[1].position: offset 168, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[2].v[1].normal: offset 180, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[2].v[2].position: offset 192, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[2].v[2].normal: offset 204, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[3].v[0].position: offset 216, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[3].v[0].normal: offset 228, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[3].v[1].position: offset 240, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[3].v[1].normal: offset 252, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[3].v[2].position: offset 264, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[3].v[2].normal: offset 276, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[4].v[0].position: offset 288, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[4].v[0].normal: offset 300, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[4].v[1].position: offset 312, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[4].v[1].normal: offset 324, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[4].v[2].position: offset 336, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
+t[4].v[2].normal: offset 348, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
 anonMember1: offset 0, type 8b51, size 1, index 0, binding -1, stages 1
 anonMember1: offset 0, type 8b51, size 1, index 0, binding -1, stages 1
 uf1: offset -1, type 1406, size 1, index -1, binding -1, stages 1
 uf1: offset -1, type 1406, size 1, index -1, binding -1, stages 1
 uf2: offset -1, type 1406, size 1, index -1, binding -1, stages 1
 uf2: offset -1, type 1406, size 1, index -1, binding -1, stages 1
 named.member3: offset 32, type 8b52, size 1, index 1, binding -1, stages 1
 named.member3: offset 32, type 8b52, size 1, index 1, binding -1, stages 1
 
 
 Uniform block reflection:
 Uniform block reflection:
-nameless: offset -1, type ffffffff, size 496, index -1, binding -1, stages 0
-named: offset -1, type ffffffff, size 304, index -1, binding -1, stages 0
-c_nameless: offset -1, type ffffffff, size 112, index -1, binding -1, stages 0
-nested: offset -1, type ffffffff, size 32, index -1, binding -1, stages 0
-abl[0]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
-abl[1]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
-abl[2]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
-abl[3]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
-abl2[0]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
-abl2[1]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
-abl2[2]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
-abl2[3]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
-buf1: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
-buf2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
-buf3: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
-buf4: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
-nested2: offset -1, type ffffffff, size 208, index -1, binding -1, stages 0
+nameless: offset -1, type ffffffff, size 496, index -1, binding -1, stages 1, numMembers 9
+named: offset -1, type ffffffff, size 304, index -1, binding -1, stages 1, numMembers 10
+c_nameless: offset -1, type ffffffff, size 112, index -1, binding -1, stages 1, numMembers 5
+nested: offset -1, type ffffffff, size 32, index -1, binding -1, stages 1, numMembers 4
+abl[0]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
+abl[1]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
+abl[2]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
+abl[3]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
+abl2[0]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
+abl2[1]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
+abl2[2]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
+abl2[3]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1
+buf1: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 2
+buf2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 4
+buf3: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 2
+buf4: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 4
+nested2: offset -1, type ffffffff, size 208, index -1, binding -1, stages 1, numMembers 15
+VertexCollection: offset -1, type ffffffff, size 400, index -1, binding -1, stages 1, numMembers 31
 
 
-Vertex attribute reflection:
-attributeFloat: offset 0, type 1406, size 0, index 0, binding -1, stages 0
-attributeFloat2: offset 0, type 8b50, size 0, index 0, binding -1, stages 0
-attributeFloat3: offset 0, type 8b51, size 0, index 0, binding -1, stages 0
-attributeFloat4: offset 0, type 8b52, size 0, index 0, binding -1, stages 0
-attributeMat4: offset 0, type 8b5c, size 0, index 0, binding -1, stages 0
-gl_InstanceID: offset 0, type 1404, size 0, index 0, binding -1, stages 0
+Buffer variable reflection:
+
+Buffer block reflection:
+
+Pipeline input reflection:
+attributeFloat: offset 0, type 1406, size 0, index 0, binding -1, stages 1
+attributeFloat2: offset 0, type 8b50, size 0, index 0, binding -1, stages 1
+attributeFloat3: offset 0, type 8b51, size 0, index 0, binding -1, stages 1
+attributeFloat4: offset 0, type 8b52, size 0, index 0, binding -1, stages 1
+attributeMat4: offset 0, type 8b5c, size 0, index 0, binding -1, stages 1
+gl_InstanceID: offset 0, type 1404, size 0, index 0, binding -1, stages 1
+
+Pipeline output reflection:
 
 

+ 120 - 0
3rdparty/glslang/Test/baseResults/spv.16bitxfb.vert.out

@@ -0,0 +1,120 @@
+spv.16bitxfb.vert
+// Module Version 10000
+// Generated by (magic number): 80007
+// Id's are bound by 59
+
+                              Capability Shader
+                              Capability Float16
+                              Capability Int16
+                              Capability TransformFeedback
+                              Capability StorageInputOutput16
+                              Extension  "SPV_KHR_16bit_storage"
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Vertex 4  "main" 9 12 18 36 39 46 49
+                              ExecutionMode 4 Xfb
+                              Source GLSL 450
+                              SourceExtension  "GL_AMD_gpu_shader_half_float"
+                              SourceExtension  "GL_AMD_gpu_shader_int16"
+                              Name 4  "main"
+                              Name 9  "of16v3"
+                              Name 12  "if16v4"
+                              Name 16  "F16Out"
+                              MemberName 16(F16Out) 0  "of16"
+                              MemberName 16(F16Out) 1  "of16v2"
+                              Name 18  ""
+                              Name 36  "oi16v3"
+                              Name 39  "ii16v4"
+                              Name 44  "I16Out"
+                              MemberName 44(I16Out) 0  "ou16"
+                              MemberName 44(I16Out) 1  "ou16v2"
+                              Name 46  ""
+                              Name 49  "iu16v4"
+                              Decorate 9(of16v3) Location 0
+                              Decorate 9(of16v3) XfbBuffer 0
+                              Decorate 9(of16v3) XfbStride 6
+                              Decorate 9(of16v3) Offset 0
+                              Decorate 12(if16v4) Location 0
+                              MemberDecorate 16(F16Out) 0 Offset 0
+                              MemberDecorate 16(F16Out) 1 Offset 2
+                              Decorate 16(F16Out) Block
+                              Decorate 18 Location 1
+                              Decorate 18 XfbBuffer 1
+                              Decorate 18 XfbStride 6
+                              Decorate 36(oi16v3) Location 5
+                              Decorate 36(oi16v3) XfbBuffer 2
+                              Decorate 36(oi16v3) XfbStride 6
+                              Decorate 36(oi16v3) Offset 0
+                              Decorate 39(ii16v4) Location 1
+                              MemberDecorate 44(I16Out) 0 Offset 0
+                              MemberDecorate 44(I16Out) 1 Offset 2
+                              Decorate 44(I16Out) Block
+                              Decorate 46 Location 6
+                              Decorate 46 XfbBuffer 3
+                              Decorate 46 XfbStride 6
+                              Decorate 49(iu16v4) Location 2
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 16
+               7:             TypeVector 6(float16_t) 3
+               8:             TypePointer Output 7(f16vec3)
+       9(of16v3):      8(ptr) Variable Output
+              10:             TypeVector 6(float16_t) 4
+              11:             TypePointer Input 10(f16vec4)
+      12(if16v4):     11(ptr) Variable Input
+              15:             TypeVector 6(float16_t) 2
+      16(F16Out):             TypeStruct 6(float16_t) 15(f16vec2)
+              17:             TypePointer Output 16(F16Out)
+              18:     17(ptr) Variable Output
+              19:             TypeInt 32 1
+              20:     19(int) Constant 0
+              21:             TypeInt 32 0
+              22:     21(int) Constant 0
+              23:             TypePointer Input 6(float16_t)
+              26:             TypePointer Output 6(float16_t)
+              28:     19(int) Constant 1
+              31:             TypePointer Output 15(f16vec2)
+              33:             TypeInt 16 1
+              34:             TypeVector 33(int16_t) 3
+              35:             TypePointer Output 34(i16vec3)
+      36(oi16v3):     35(ptr) Variable Output
+              37:             TypeVector 33(int16_t) 4
+              38:             TypePointer Input 37(i16vec4)
+      39(ii16v4):     38(ptr) Variable Input
+              42:             TypeInt 16 0
+              43:             TypeVector 42(int16_t) 2
+      44(I16Out):             TypeStruct 42(int16_t) 43(i16vec2)
+              45:             TypePointer Output 44(I16Out)
+              46:     45(ptr) Variable Output
+              47:             TypeVector 42(int16_t) 4
+              48:             TypePointer Input 47(i16vec4)
+      49(iu16v4):     48(ptr) Variable Input
+              50:             TypePointer Input 42(int16_t)
+              53:             TypePointer Output 42(int16_t)
+              57:             TypePointer Output 43(i16vec2)
+         4(main):           2 Function None 3
+               5:             Label
+              13: 10(f16vec4) Load 12(if16v4)
+              14:  7(f16vec3) VectorShuffle 13 13 0 1 2
+                              Store 9(of16v3) 14
+              24:     23(ptr) AccessChain 12(if16v4) 22
+              25:6(float16_t) Load 24
+              27:     26(ptr) AccessChain 18 20
+                              Store 27 25
+              29: 10(f16vec4) Load 12(if16v4)
+              30: 15(f16vec2) VectorShuffle 29 29 0 1
+              32:     31(ptr) AccessChain 18 28
+                              Store 32 30
+              40: 37(i16vec4) Load 39(ii16v4)
+              41: 34(i16vec3) VectorShuffle 40 40 0 1 2
+                              Store 36(oi16v3) 41
+              51:     50(ptr) AccessChain 49(iu16v4) 22
+              52: 42(int16_t) Load 51
+              54:     53(ptr) AccessChain 46 20
+                              Store 54 52
+              55: 47(i16vec4) Load 49(iu16v4)
+              56: 43(i16vec2) VectorShuffle 55 55 0 1
+              58:     57(ptr) AccessChain 46 28
+                              Store 58 56
+                              Return
+                              FunctionEnd

+ 153 - 131
3rdparty/glslang/Test/baseResults/spv.meshTaskShader.task.out

@@ -1,14 +1,14 @@
 spv.meshTaskShader.task
 spv.meshTaskShader.task
 // Module Version 10000
 // Module Version 10000
 // Generated by (magic number): 80007
 // Generated by (magic number): 80007
-// Id's are bound by 104
+// Id's are bound by 116
 
 
                               Capability StorageImageWriteWithoutFormat
                               Capability StorageImageWriteWithoutFormat
                               Capability MeshShadingNV
                               Capability MeshShadingNV
                               Extension  "SPV_NV_mesh_shader"
                               Extension  "SPV_NV_mesh_shader"
                1:             ExtInstImport  "GLSL.std.450"
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
                               MemoryModel Logical GLSL450
-                              EntryPoint TaskNV 4  "main" 11 17 80 101
+                              EntryPoint TaskNV 4  "main" 11 17 24 25 90 113
                               ExecutionMode 4 LocalSize 32 1 1
                               ExecutionMode 4 LocalSize 32 1 1
                               Source GLSL 450
                               Source GLSL 450
                               SourceExtension  "GL_NV_mesh_shader"
                               SourceExtension  "GL_NV_mesh_shader"
@@ -17,34 +17,42 @@ spv.meshTaskShader.task
                               Name 11  "gl_LocalInvocationID"
                               Name 11  "gl_LocalInvocationID"
                               Name 16  "gid"
                               Name 16  "gid"
                               Name 17  "gl_WorkGroupID"
                               Name 17  "gl_WorkGroupID"
-                              Name 20  "i"
-                              Name 34  "mem"
-                              Name 37  "block0"
-                              MemberName 37(block0) 0  "uni_value"
-                              Name 39  ""
-                              Name 55  "uni_image"
-                              Name 78  "Task"
-                              MemberName 78(Task) 0  "dummy"
-                              MemberName 78(Task) 1  "submesh"
-                              Name 80  "mytask"
-                              Name 101  "gl_TaskCountNV"
+                              Name 20  "viewID"
+                              Name 24  "gl_MeshViewIndicesNV"
+                              Name 25  "gl_MeshViewCountNV"
+                              Name 30  "i"
+                              Name 44  "mem"
+                              Name 47  "block0"
+                              MemberName 47(block0) 0  "uni_value"
+                              Name 49  ""
+                              Name 65  "uni_image"
+                              Name 88  "Task"
+                              MemberName 88(Task) 0  "dummy"
+                              MemberName 88(Task) 1  "submesh"
+                              MemberName 88(Task) 2  "viewID"
+                              Name 90  "mytask"
+                              Name 113  "gl_TaskCountNV"
                               Decorate 11(gl_LocalInvocationID) BuiltIn LocalInvocationId
                               Decorate 11(gl_LocalInvocationID) BuiltIn LocalInvocationId
                               Decorate 17(gl_WorkGroupID) BuiltIn WorkgroupId
                               Decorate 17(gl_WorkGroupID) BuiltIn WorkgroupId
-                              MemberDecorate 37(block0) 0 Offset 0
-                              Decorate 37(block0) Block
-                              Decorate 39 DescriptorSet 0
-                              Decorate 39 Binding 0
-                              Decorate 55(uni_image) DescriptorSet 0
-                              Decorate 55(uni_image) Binding 0
-                              Decorate 55(uni_image) NonReadable
-                              Decorate 77 ArrayStride 8
-                              MemberDecorate 78(Task) 0 PerTaskNV
-                              MemberDecorate 78(Task) 0 Offset 0
-                              MemberDecorate 78(Task) 1 PerTaskNV
-                              MemberDecorate 78(Task) 1 Offset 8
-                              Decorate 78(Task) Block
-                              Decorate 101(gl_TaskCountNV) BuiltIn TaskCountNV
-                              Decorate 103 BuiltIn WorkgroupSize
+                              Decorate 24(gl_MeshViewIndicesNV) BuiltIn MeshViewIndicesNV
+                              Decorate 25(gl_MeshViewCountNV) BuiltIn MeshViewCountNV
+                              MemberDecorate 47(block0) 0 Offset 0
+                              Decorate 47(block0) Block
+                              Decorate 49 DescriptorSet 0
+                              Decorate 49 Binding 0
+                              Decorate 65(uni_image) DescriptorSet 0
+                              Decorate 65(uni_image) Binding 0
+                              Decorate 65(uni_image) NonReadable
+                              Decorate 87 ArrayStride 8
+                              MemberDecorate 88(Task) 0 PerTaskNV
+                              MemberDecorate 88(Task) 0 Offset 0
+                              MemberDecorate 88(Task) 1 PerTaskNV
+                              MemberDecorate 88(Task) 1 Offset 8
+                              MemberDecorate 88(Task) 2 PerTaskNV
+                              MemberDecorate 88(Task) 2 Offset 32
+                              Decorate 88(Task) Block
+                              Decorate 113(gl_TaskCountNV) BuiltIn TaskCountNV
+                              Decorate 115 BuiltIn WorkgroupSize
                2:             TypeVoid
                2:             TypeVoid
                3:             TypeFunction 2
                3:             TypeFunction 2
                6:             TypeInt 32 0
                6:             TypeInt 32 0
@@ -55,119 +63,133 @@ spv.meshTaskShader.task
               12:      6(int) Constant 0
               12:      6(int) Constant 0
               13:             TypePointer Input 6(int)
               13:             TypePointer Input 6(int)
 17(gl_WorkGroupID):     10(ptr) Variable Input
 17(gl_WorkGroupID):     10(ptr) Variable Input
-              27:      6(int) Constant 10
-              28:             TypeBool
-              30:             TypeFloat 32
-              31:             TypeVector 30(float) 4
-              32:             TypeArray 31(fvec4) 27
-              33:             TypePointer Workgroup 32
-         34(mem):     33(ptr) Variable Workgroup
-      37(block0):             TypeStruct 6(int)
-              38:             TypePointer Uniform 37(block0)
-              39:     38(ptr) Variable Uniform
-              40:             TypeInt 32 1
-              41:     40(int) Constant 0
-              42:             TypePointer Uniform 6(int)
-              48:             TypePointer Workgroup 31(fvec4)
-              51:     40(int) Constant 1
-              53:             TypeImage 30(float) 2D nonsampled format:Unknown
-              54:             TypePointer UniformConstant 53
-   55(uni_image):     54(ptr) Variable UniformConstant
-              59:             TypeVector 40(int) 2
-              69:      6(int) Constant 1
-              73:      6(int) Constant 264
-              74:      6(int) Constant 2
-              75:             TypeVector 30(float) 2
-              76:      6(int) Constant 3
-              77:             TypeArray 75(fvec2) 76
-        78(Task):             TypeStruct 75(fvec2) 77
-              79:             TypePointer Output 78(Task)
-      80(mytask):     79(ptr) Variable Output
-              81:   30(float) Constant 1106247680
-              82:   30(float) Constant 1106771968
-              83:   75(fvec2) ConstantComposite 81 82
-              84:             TypePointer Output 75(fvec2)
-              86:   30(float) Constant 1107296256
-              87:   30(float) Constant 1107558400
-              88:   75(fvec2) ConstantComposite 86 87
-              90:   30(float) Constant 1107820544
-              91:   30(float) Constant 1108082688
-              92:   75(fvec2) ConstantComposite 90 91
-              94:     40(int) Constant 2
-             100:             TypePointer Output 6(int)
-101(gl_TaskCountNV):    100(ptr) Variable Output
-             102:      6(int) Constant 32
-             103:    9(ivec3) ConstantComposite 102 69 69
+              21:      6(int) Constant 4
+              22:             TypeArray 6(int) 21
+              23:             TypePointer Input 22
+24(gl_MeshViewIndicesNV):     23(ptr) Variable Input
+25(gl_MeshViewCountNV):     13(ptr) Variable Input
+              37:      6(int) Constant 10
+              38:             TypeBool
+              40:             TypeFloat 32
+              41:             TypeVector 40(float) 4
+              42:             TypeArray 41(fvec4) 37
+              43:             TypePointer Workgroup 42
+         44(mem):     43(ptr) Variable Workgroup
+      47(block0):             TypeStruct 6(int)
+              48:             TypePointer Uniform 47(block0)
+              49:     48(ptr) Variable Uniform
+              50:             TypeInt 32 1
+              51:     50(int) Constant 0
+              52:             TypePointer Uniform 6(int)
+              58:             TypePointer Workgroup 41(fvec4)
+              61:     50(int) Constant 1
+              63:             TypeImage 40(float) 2D nonsampled format:Unknown
+              64:             TypePointer UniformConstant 63
+   65(uni_image):     64(ptr) Variable UniformConstant
+              69:             TypeVector 50(int) 2
+              79:      6(int) Constant 1
+              83:      6(int) Constant 264
+              84:      6(int) Constant 2
+              85:             TypeVector 40(float) 2
+              86:      6(int) Constant 3
+              87:             TypeArray 85(fvec2) 86
+        88(Task):             TypeStruct 85(fvec2) 87 6(int)
+              89:             TypePointer Output 88(Task)
+      90(mytask):     89(ptr) Variable Output
+              91:   40(float) Constant 1106247680
+              92:   40(float) Constant 1106771968
+              93:   85(fvec2) ConstantComposite 91 92
+              94:             TypePointer Output 85(fvec2)
+              96:   40(float) Constant 1107296256
+              97:   40(float) Constant 1107558400
+              98:   85(fvec2) ConstantComposite 96 97
+             100:   40(float) Constant 1107820544
+             101:   40(float) Constant 1108082688
+             102:   85(fvec2) ConstantComposite 100 101
+             104:     50(int) Constant 2
+             111:             TypePointer Output 6(int)
+113(gl_TaskCountNV):    111(ptr) Variable Output
+             114:      6(int) Constant 32
+             115:    9(ivec3) ConstantComposite 114 79 79
          4(main):           2 Function None 3
          4(main):           2 Function None 3
                5:             Label
                5:             Label
           8(iid):      7(ptr) Variable Function
           8(iid):      7(ptr) Variable Function
          16(gid):      7(ptr) Variable Function
          16(gid):      7(ptr) Variable Function
-           20(i):      7(ptr) Variable Function
+      20(viewID):      7(ptr) Variable Function
+           30(i):      7(ptr) Variable Function
               14:     13(ptr) AccessChain 11(gl_LocalInvocationID) 12
               14:     13(ptr) AccessChain 11(gl_LocalInvocationID) 12
               15:      6(int) Load 14
               15:      6(int) Load 14
                               Store 8(iid) 15
                               Store 8(iid) 15
               18:     13(ptr) AccessChain 17(gl_WorkGroupID) 12
               18:     13(ptr) AccessChain 17(gl_WorkGroupID) 12
               19:      6(int) Load 18
               19:      6(int) Load 18
                               Store 16(gid) 19
                               Store 16(gid) 19
-                              Store 20(i) 12
-                              Branch 21
-              21:             Label
-                              LoopMerge 23 24 None
-                              Branch 25
-              25:             Label
-              26:      6(int) Load 20(i)
-              29:    28(bool) ULessThan 26 27
-                              BranchConditional 29 22 23
-              22:               Label
-              35:      6(int)   Load 20(i)
-              36:      6(int)   Load 20(i)
-              43:     42(ptr)   AccessChain 39 41
-              44:      6(int)   Load 43
-              45:      6(int)   IAdd 36 44
-              46:   30(float)   ConvertUToF 45
-              47:   31(fvec4)   CompositeConstruct 46 46 46 46
-              49:     48(ptr)   AccessChain 34(mem) 35
-                                Store 49 47
-                                Branch 24
-              24:               Label
-              50:      6(int)   Load 20(i)
-              52:      6(int)   IAdd 50 51
-                                Store 20(i) 52
-                                Branch 21
-              23:             Label
-              56:          53 Load 55(uni_image)
-              57:      6(int) Load 8(iid)
-              58:     40(int) Bitcast 57
-              60:   59(ivec2) CompositeConstruct 58 58
-              61:      6(int) Load 16(gid)
-              62:     48(ptr) AccessChain 34(mem) 61
-              63:   31(fvec4) Load 62
-                              ImageWrite 56 60 63
-              64:          53 Load 55(uni_image)
-              65:      6(int) Load 8(iid)
-              66:     40(int) Bitcast 65
-              67:   59(ivec2) CompositeConstruct 66 66
-              68:      6(int) Load 16(gid)
-              70:      6(int) IAdd 68 69
-              71:     48(ptr) AccessChain 34(mem) 70
-              72:   31(fvec4) Load 71
-                              ImageWrite 64 67 72
-                              MemoryBarrier 69 73
-                              ControlBarrier 74 74 73
-              85:     84(ptr) AccessChain 80(mytask) 41
-                              Store 85 83
-              89:     84(ptr) AccessChain 80(mytask) 51 41
-                              Store 89 88
-              93:     84(ptr) AccessChain 80(mytask) 51 51
-                              Store 93 92
-              95:      6(int) Load 16(gid)
-              96:      6(int) UMod 95 74
-              97:     84(ptr) AccessChain 80(mytask) 51 96
-              98:   75(fvec2) Load 97
-              99:     84(ptr) AccessChain 80(mytask) 51 94
+              26:      6(int) Load 25(gl_MeshViewCountNV)
+              27:      6(int) UMod 26 21
+              28:     13(ptr) AccessChain 24(gl_MeshViewIndicesNV) 27
+              29:      6(int) Load 28
+                              Store 20(viewID) 29
+                              Store 30(i) 12
+                              Branch 31
+              31:             Label
+                              LoopMerge 33 34 None
+                              Branch 35
+              35:             Label
+              36:      6(int) Load 30(i)
+              39:    38(bool) ULessThan 36 37
+                              BranchConditional 39 32 33
+              32:               Label
+              45:      6(int)   Load 30(i)
+              46:      6(int)   Load 30(i)
+              53:     52(ptr)   AccessChain 49 51
+              54:      6(int)   Load 53
+              55:      6(int)   IAdd 46 54
+              56:   40(float)   ConvertUToF 55
+              57:   41(fvec4)   CompositeConstruct 56 56 56 56
+              59:     58(ptr)   AccessChain 44(mem) 45
+                                Store 59 57
+                                Branch 34
+              34:               Label
+              60:      6(int)   Load 30(i)
+              62:      6(int)   IAdd 60 61
+                                Store 30(i) 62
+                                Branch 31
+              33:             Label
+              66:          63 Load 65(uni_image)
+              67:      6(int) Load 8(iid)
+              68:     50(int) Bitcast 67
+              70:   69(ivec2) CompositeConstruct 68 68
+              71:      6(int) Load 16(gid)
+              72:     58(ptr) AccessChain 44(mem) 71
+              73:   41(fvec4) Load 72
+                              ImageWrite 66 70 73
+              74:          63 Load 65(uni_image)
+              75:      6(int) Load 8(iid)
+              76:     50(int) Bitcast 75
+              77:   69(ivec2) CompositeConstruct 76 76
+              78:      6(int) Load 16(gid)
+              80:      6(int) IAdd 78 79
+              81:     58(ptr) AccessChain 44(mem) 80
+              82:   41(fvec4) Load 81
+                              ImageWrite 74 77 82
+                              MemoryBarrier 79 83
+                              ControlBarrier 84 84 83
+              95:     94(ptr) AccessChain 90(mytask) 51
+                              Store 95 93
+              99:     94(ptr) AccessChain 90(mytask) 61 51
                               Store 99 98
                               Store 99 98
-                              MemoryBarrier 69 73
-                              ControlBarrier 74 74 73
-                              Store 101(gl_TaskCountNV) 76
+             103:     94(ptr) AccessChain 90(mytask) 61 61
+                              Store 103 102
+             105:      6(int) Load 16(gid)
+             106:      6(int) UMod 105 84
+             107:     94(ptr) AccessChain 90(mytask) 61 106
+             108:   85(fvec2) Load 107
+             109:     94(ptr) AccessChain 90(mytask) 61 104
+                              Store 109 108
+             110:      6(int) Load 20(viewID)
+             112:    111(ptr) AccessChain 90(mytask) 104
+                              Store 112 110
+                              MemoryBarrier 79 83
+                              ControlBarrier 84 84 83
+                              Store 113(gl_TaskCountNV) 86
                               Return
                               Return
                               FunctionEnd
                               FunctionEnd

+ 2 - 4
3rdparty/glslang/Test/baseResults/spv.xfbOffsetOnStructMembersAssignment.vert.out

@@ -27,16 +27,14 @@ spv.xfbOffsetOnStructMembersAssignment.vert
                               Name 34  ""
                               Name 34  ""
                               Name 38  "gl_VertexID"
                               Name 38  "gl_VertexID"
                               Name 39  "gl_InstanceID"
                               Name 39  "gl_InstanceID"
-                              MemberDecorate 7(S) 0 Offset 16
-                              MemberDecorate 7(S) 1 Offset 20
                               Decorate 9(s1) Location 0
                               Decorate 9(s1) Location 0
                               Decorate 9(s1) XfbBuffer 2
                               Decorate 9(s1) XfbBuffer 2
                               Decorate 9(s1) XfbStride 24
                               Decorate 9(s1) XfbStride 24
-                              MemberDecorate 19(S2) 0 Offset 8
-                              MemberDecorate 19(S2) 1 Offset 12
+                              Decorate 9(s1) Offset 16
                               Decorate 21(s2) Location 5
                               Decorate 21(s2) Location 5
                               Decorate 21(s2) XfbBuffer 1
                               Decorate 21(s2) XfbBuffer 1
                               Decorate 21(s2) XfbStride 28
                               Decorate 21(s2) XfbStride 28
+                              Decorate 21(s2) Offset 8
                               MemberDecorate 32(gl_PerVertex) 0 BuiltIn Position
                               MemberDecorate 32(gl_PerVertex) 0 BuiltIn Position
                               MemberDecorate 32(gl_PerVertex) 1 BuiltIn PointSize
                               MemberDecorate 32(gl_PerVertex) 1 BuiltIn PointSize
                               MemberDecorate 32(gl_PerVertex) 2 BuiltIn ClipDistance
                               MemberDecorate 32(gl_PerVertex) 2 BuiltIn ClipDistance

+ 8 - 0
3rdparty/glslang/Test/reflection.frag

@@ -0,0 +1,8 @@
+#version 440 core
+
+in float inval;
+
+void main()
+{
+    float f = inval;
+}

+ 19 - 0
3rdparty/glslang/Test/reflection.linked.frag

@@ -0,0 +1,19 @@
+#version 440 core
+
+layout(binding = 0, std140) uniform ubo_block {
+	float unused_uniform;
+	float shared_uniform;
+	float vsonly_uniform;
+	float fsonly_uniform;
+} ubo;
+
+in float vertout;
+
+out float fragout;
+
+void main()
+{
+    fragout = vertout;
+    fragout += ubo.shared_uniform;
+    fragout += ubo.fsonly_uniform;
+}

+ 19 - 0
3rdparty/glslang/Test/reflection.linked.vert

@@ -0,0 +1,19 @@
+#version 440 core
+
+layout(binding = 0, std140) uniform ubo_block {
+	float unused_uniform;
+	float shared_uniform;
+	float vsonly_uniform;
+	float fsonly_uniform;
+} ubo;
+
+in float vertin;
+
+out float vertout;
+
+void main()
+{
+    vertout = vertin;
+    vertout += ubo.shared_uniform;
+    vertout += ubo.vsonly_uniform;
+}

+ 44 - 0
3rdparty/glslang/Test/reflection.options.vert

@@ -0,0 +1,44 @@
+#version 440 core
+
+struct VertexInfo {
+    float position[3];
+    float normal[3];
+};
+
+struct TriangleInfo {
+    VertexInfo v[3];
+};
+
+buffer VertexCollection {
+    TriangleInfo t[5];
+    uint padding[10];
+};
+
+buffer MultipleArrays {
+    TriangleInfo tri[5];
+    VertexInfo vert[5];
+    float f[5];
+} multiarray;
+
+uniform UBO {
+    VertexInfo verts[2];
+    float flt[8];
+    uvec4 unused;
+} ubo;
+
+out float outval;
+
+void main()
+{
+    float f;
+    f += t[0].v[0].position[0];
+    f += t[gl_InstanceID].v[gl_InstanceID].position[gl_InstanceID];
+    f += t[gl_InstanceID].v[gl_InstanceID].normal[gl_InstanceID];
+    f += multiarray.tri[gl_InstanceID].v[0].position[0];
+    f += multiarray.vert[gl_InstanceID].position[0];
+    f += multiarray.f[gl_InstanceID];
+    f += ubo.verts[gl_InstanceID].position[0];
+    f += ubo.flt[gl_InstanceID];
+    TriangleInfo tlocal[5] = t;
+    outval = f;
+}

+ 23 - 0
3rdparty/glslang/Test/reflection.vert

@@ -161,6 +161,22 @@ buffer buf4 {
     N2 runtimeArray[];
     N2 runtimeArray[];
 } buf4i;
 } buf4i;
 
 
+struct VertexInfo {
+    float position[3];
+    float normal[3];
+};
+
+struct TriangleInfo {
+    VertexInfo v[3];
+};
+
+buffer VertexCollection {
+    TriangleInfo t[5];
+    uint padding[10];
+};
+
+out float outval;
+
 void main()
 void main()
 {
 {
     liveFunction1(image_ui2D, sampler_2D, sampler_2DMSArray);
     liveFunction1(image_ui2D, sampler_2D, sampler_2DMSArray);
@@ -216,4 +232,11 @@ void main()
     N1 b[4] = nest2.b;
     N1 b[4] = nest2.b;
     f += nest2.c[1].a;
     f += nest2.c[1].a;
     f += nest2.d[gl_InstanceID].a;
     f += nest2.d[gl_InstanceID].a;
+
+    f += t[0].v[0].position[0];
+    f += t[gl_InstanceID].v[gl_InstanceID].position[gl_InstanceID];
+    f += t[gl_InstanceID].v[gl_InstanceID].normal[gl_InstanceID];
+    TriangleInfo tlocal[5] = t;
+
+    outval = f;
 }
 }

+ 10 - 0
3rdparty/glslang/Test/runtests

@@ -32,6 +32,16 @@ diff -b $BASEDIR/badMacroArgs.frag.out $TARGETDIR/badMacroArgs.frag.out || HASER
 echo Running reflection...
 echo Running reflection...
 $EXE -l -q -C reflection.vert > $TARGETDIR/reflection.vert.out
 $EXE -l -q -C reflection.vert > $TARGETDIR/reflection.vert.out
 diff -b $BASEDIR/reflection.vert.out $TARGETDIR/reflection.vert.out || HASERROR=1
 diff -b $BASEDIR/reflection.vert.out $TARGETDIR/reflection.vert.out || HASERROR=1
+$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io --reflect-separate-buffers --reflect-all-block-variables reflection.options.vert > $TARGETDIR/reflection.options.vert.out
+diff -b $BASEDIR/reflection.options.vert.out $TARGETDIR/reflection.options.vert.out || HASERROR=1
+$EXE -l -q -C reflection.frag > $TARGETDIR/reflection.frag.out
+diff -b $BASEDIR/reflection.frag.out $TARGETDIR/reflection.frag.out || HASERROR=1
+$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io --reflect-separate-buffers --reflect-all-block-variables reflection.frag > $TARGETDIR/reflection.options.frag.out
+diff -b $BASEDIR/reflection.options.frag.out $TARGETDIR/reflection.options.frag.out || HASERROR=1
+$EXE -l -q -C reflection.linked.vert reflection.linked.frag > $TARGETDIR/reflection.linked.out
+diff -b $BASEDIR/reflection.linked.out $TARGETDIR/reflection.linked.out || HASERROR=1
+$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io --reflect-separate-buffers --reflect-all-block-variables reflection.linked.vert reflection.linked.frag > $TARGETDIR/reflection.linked.options.out
+diff -b $BASEDIR/reflection.linked.options.out $TARGETDIR/reflection.linked.options.out || HASERROR=1
 $EXE -D -Od -e flizv -l -q -C -V -Od hlsl.reflection.vert > $TARGETDIR/hlsl.reflection.vert.out
 $EXE -D -Od -e flizv -l -q -C -V -Od hlsl.reflection.vert > $TARGETDIR/hlsl.reflection.vert.out
 diff -b $BASEDIR/hlsl.reflection.vert.out $TARGETDIR/hlsl.reflection.vert.out || HASERROR=1
 diff -b $BASEDIR/hlsl.reflection.vert.out $TARGETDIR/hlsl.reflection.vert.out || HASERROR=1
 $EXE -D -Od -e main -l -q -C -V -Od hlsl.reflection.binding.frag > $TARGETDIR/hlsl.reflection.binding.frag.out
 $EXE -D -Od -e main -l -q -C -V -Od hlsl.reflection.binding.frag > $TARGETDIR/hlsl.reflection.binding.frag.out

+ 33 - 0
3rdparty/glslang/Test/spv.16bitxfb.vert

@@ -0,0 +1,33 @@
+#version 450 core
+
+#extension GL_AMD_gpu_shader_half_float: enable
+#extension GL_AMD_gpu_shader_int16: enable
+
+layout(location = 0) in f16vec4 if16v4;
+layout(location = 1) in i16vec4 ii16v4;
+layout(location = 2) in u16vec4 iu16v4;
+
+layout(location = 0, xfb_buffer = 0, xfb_stride = 6, xfb_offset = 0) out f16vec3 of16v3;
+layout(location = 1, xfb_buffer = 1, xfb_stride = 6, xfb_offset = 0) out F16Out
+{
+    float16_t of16;
+    f16vec2   of16v2;
+};
+
+layout(location = 5, xfb_buffer = 2, xfb_stride = 6, xfb_offset = 0) out i16vec3 oi16v3;
+layout(location = 6, xfb_buffer = 3, xfb_stride = 6, xfb_offset = 0) out I16Out
+{
+    uint16_t ou16;
+    u16vec2  ou16v2;
+};
+
+void main()
+{
+    of16v3 = if16v4.xyz;
+    of16   = if16v4.x;
+    of16v2 = if16v4.xy;
+
+    oi16v3 = ii16v4.xyz;
+    ou16   = iu16v4.x;
+    ou16v2 = iu16v4.xy;
+}

+ 5 - 0
3rdparty/glslang/Test/spv.meshTaskShader.task

@@ -1,5 +1,7 @@
 #version 450
 #version 450
 
 
+#define MAX_VIEWS gl_MaxMeshViewCountNV
+
 #define BARRIER() \
 #define BARRIER() \
     memoryBarrierShared(); \
     memoryBarrierShared(); \
     barrier();
     barrier();
@@ -19,12 +21,14 @@ shared vec4 mem[10];
 taskNV out Task {
 taskNV out Task {
     vec2 dummy;
     vec2 dummy;
     vec2 submesh[3];
     vec2 submesh[3];
+    uint viewID;
 } mytask;
 } mytask;
 
 
 void main()
 void main()
 {
 {
     uint iid = gl_LocalInvocationID.x;
     uint iid = gl_LocalInvocationID.x;
     uint gid = gl_WorkGroupID.x;
     uint gid = gl_WorkGroupID.x;
+    uint viewID = gl_MeshViewIndicesNV[gl_MeshViewCountNV%MAX_VIEWS];
 
 
     // 1. shared memory load and stores
     // 1. shared memory load and stores
     for (uint i = 0; i < 10; ++i) {
     for (uint i = 0; i < 10; ++i) {
@@ -41,6 +45,7 @@ void main()
     mytask.submesh[0] = vec2(32.0, 33.0);
     mytask.submesh[0] = vec2(32.0, 33.0);
     mytask.submesh[1] = vec2(34.0, 35.0);
     mytask.submesh[1] = vec2(34.0, 35.0);
     mytask.submesh[2] = mytask.submesh[gid%2];
     mytask.submesh[2] = mytask.submesh[gid%2];
+    mytask.viewID     = viewID;
 
 
     BARRIER();
     BARRIER();
 
 

+ 1 - 1
3rdparty/glslang/glslang/Include/revision.h

@@ -1,3 +1,3 @@
 // This header is generated by the make-revision script.
 // This header is generated by the make-revision script.
 
 
-#define GLSLANG_PATCH_LEVEL 3057
+#define GLSLANG_PATCH_LEVEL 3113

+ 8 - 0
3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp

@@ -5357,6 +5357,9 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "in highp uvec3 gl_GlobalInvocationID;"
             "in highp uvec3 gl_GlobalInvocationID;"
             "in highp uint gl_LocalInvocationIndex;"
             "in highp uint gl_LocalInvocationIndex;"
 
 
+            "in uint gl_MeshViewCountNV;"
+            "in uint gl_MeshViewIndicesNV[4];"
+
             "\n");
             "\n");
     }
     }
 
 
@@ -8843,6 +8846,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             symbolTable.setVariableExtensions("gl_LocalInvocationID",    1, &E_GL_NV_mesh_shader);
             symbolTable.setVariableExtensions("gl_LocalInvocationID",    1, &E_GL_NV_mesh_shader);
             symbolTable.setVariableExtensions("gl_GlobalInvocationID",   1, &E_GL_NV_mesh_shader);
             symbolTable.setVariableExtensions("gl_GlobalInvocationID",   1, &E_GL_NV_mesh_shader);
             symbolTable.setVariableExtensions("gl_LocalInvocationIndex", 1, &E_GL_NV_mesh_shader);
             symbolTable.setVariableExtensions("gl_LocalInvocationIndex", 1, &E_GL_NV_mesh_shader);
+            symbolTable.setVariableExtensions("gl_MeshViewCountNV",      1, &E_GL_NV_mesh_shader);
+            symbolTable.setVariableExtensions("gl_MeshViewIndicesNV",    1, &E_GL_NV_mesh_shader);
 
 
             BuiltInVariable("gl_TaskCountNV",          EbvTaskCountNV,          symbolTable);
             BuiltInVariable("gl_TaskCountNV",          EbvTaskCountNV,          symbolTable);
             BuiltInVariable("gl_WorkGroupSize",        EbvWorkGroupSize,        symbolTable);
             BuiltInVariable("gl_WorkGroupSize",        EbvWorkGroupSize,        symbolTable);
@@ -8850,8 +8855,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             BuiltInVariable("gl_LocalInvocationID",    EbvLocalInvocationId,    symbolTable);
             BuiltInVariable("gl_LocalInvocationID",    EbvLocalInvocationId,    symbolTable);
             BuiltInVariable("gl_GlobalInvocationID",   EbvGlobalInvocationId,   symbolTable);
             BuiltInVariable("gl_GlobalInvocationID",   EbvGlobalInvocationId,   symbolTable);
             BuiltInVariable("gl_LocalInvocationIndex", EbvLocalInvocationIndex, symbolTable);
             BuiltInVariable("gl_LocalInvocationIndex", EbvLocalInvocationIndex, symbolTable);
+            BuiltInVariable("gl_MeshViewCountNV",      EbvMeshViewCountNV,      symbolTable);
+            BuiltInVariable("gl_MeshViewIndicesNV",    EbvMeshViewIndicesNV,    symbolTable);
 
 
             symbolTable.setVariableExtensions("gl_MaxTaskWorkGroupSizeNV", 1, &E_GL_NV_mesh_shader);
             symbolTable.setVariableExtensions("gl_MaxTaskWorkGroupSizeNV", 1, &E_GL_NV_mesh_shader);
+            symbolTable.setVariableExtensions("gl_MaxMeshViewCountNV",     1, &E_GL_NV_mesh_shader);
 
 
             symbolTable.setFunctionExtensions("barrier",                   1, &E_GL_NV_mesh_shader);
             symbolTable.setFunctionExtensions("barrier",                   1, &E_GL_NV_mesh_shader);
             symbolTable.setFunctionExtensions("memoryBarrierShared",       1, &E_GL_NV_mesh_shader);
             symbolTable.setFunctionExtensions("memoryBarrierShared",       1, &E_GL_NV_mesh_shader);

+ 27 - 11
3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp

@@ -5463,14 +5463,23 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
 
 
         // "The offset must be a multiple of the size of the first component of the first
         // "The offset must be a multiple of the size of the first component of the first
         // qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate
         // qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate
-        // containing a double, the offset must also be a multiple of 8..."
-        if (type.containsBasicType(EbtDouble) && ! IsMultipleOfPow2(qualifier.layoutXfbOffset, 8))
-            error(loc, "type contains double; xfb_offset must be a multiple of 8", "xfb_offset", "");
-        // ..., if applied to an aggregate containing a float16_t, the offset must also be a multiple of 2..."
-        else if (type.containsBasicType(EbtFloat16) && !IsMultipleOfPow2(qualifier.layoutXfbOffset, 2))
-            error(loc, "type contains half float; xfb_offset must be a multiple of 2", "xfb_offset", "");
+        // containing a double or 64-bit integer, the offset must also be a multiple of 8..."
+        if ((type.containsBasicType(EbtDouble) || type.containsBasicType(EbtInt64) || type.containsBasicType(EbtUint64)) &&
+            ! IsMultipleOfPow2(qualifier.layoutXfbOffset, 8))
+            error(loc, "type contains double or 64-bit integer; xfb_offset must be a multiple of 8", "xfb_offset", "");
+#ifdef AMD_EXTENSIONS
+        else if ((type.containsBasicType(EbtBool) || type.containsBasicType(EbtFloat) ||
+                  type.containsBasicType(EbtInt) || type.containsBasicType(EbtUint)) &&
+                 ! IsMultipleOfPow2(qualifier.layoutXfbOffset, 4))
+            error(loc, "must be a multiple of size of first component", "xfb_offset", "");
+        // ..., if applied to an aggregate containing a half float or 16-bit integer, the offset must also be a multiple of 2..."
+        else if ((type.containsBasicType(EbtFloat16) || type.containsBasicType(EbtInt16) || type.containsBasicType(EbtUint16)) &&
+                 !IsMultipleOfPow2(qualifier.layoutXfbOffset, 2))
+            error(loc, "type contains half float or 16-bit integer; xfb_offset must be a multiple of 2", "xfb_offset", "");
+#else
         else if (! IsMultipleOfPow2(qualifier.layoutXfbOffset, 4))
         else if (! IsMultipleOfPow2(qualifier.layoutXfbOffset, 4))
             error(loc, "must be a multiple of size of first component", "xfb_offset", "");
             error(loc, "must be a multiple of size of first component", "xfb_offset", "");
+#endif
     }
     }
 
 
     if (qualifier.hasXfbStride() && qualifier.hasXfbBuffer()) {
     if (qualifier.hasXfbStride() && qualifier.hasXfbBuffer()) {
@@ -6235,11 +6244,6 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
     // fix up
     // fix up
     fixOffset(loc, *symbol);
     fixOffset(loc, *symbol);
 
 
-    if (symbol->getType().getBasicType() == EbtStruct) {
-       fixXfbOffsets(symbol->getWritableType().getQualifier(),
-                     *(symbol->getWritableType().getWritableStruct()));
-    }
-
     return initNode;
     return initNode;
 }
 }
 
 
@@ -7287,12 +7291,24 @@ void TParseContext::fixXfbOffsets(TQualifier& qualifier, TTypeList& typeList)
     for (unsigned int member = 0; member < typeList.size(); ++member) {
     for (unsigned int member = 0; member < typeList.size(); ++member) {
         TQualifier& memberQualifier = typeList[member].type->getQualifier();
         TQualifier& memberQualifier = typeList[member].type->getQualifier();
         bool contains64BitType = false;
         bool contains64BitType = false;
+#ifdef AMD_EXTENSIONS
+        bool contains32BitType = false;
+        bool contains16BitType = false;
+        int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, contains64BitType, contains32BitType, contains16BitType);
+#else
         int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, contains64BitType);
         int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, contains64BitType);
+#endif
         // see if we need to auto-assign an offset to this member
         // see if we need to auto-assign an offset to this member
         if (! memberQualifier.hasXfbOffset()) {
         if (! memberQualifier.hasXfbOffset()) {
             // "if applied to an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8"
             // "if applied to an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8"
             if (contains64BitType)
             if (contains64BitType)
                 RoundToPow2(nextOffset, 8);
                 RoundToPow2(nextOffset, 8);
+#ifdef AMD_EXTENSIONS
+            else if (contains32BitType)
+                RoundToPow2(nextOffset, 4);
+            else if (contains16BitType)
+                RoundToPow2(nextOffset, 2);
+#endif
             memberQualifier.layoutXfbOffset = nextOffset;
             memberQualifier.layoutXfbOffset = nextOffset;
         } else
         } else
             nextOffset = memberQualifier.layoutXfbOffset;
             nextOffset = memberQualifier.layoutXfbOffset;

+ 35 - 24
3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp

@@ -1335,7 +1335,7 @@ void ShDestruct(ShHandle handle)
 //
 //
 // Cleanup symbol tables
 // Cleanup symbol tables
 //
 //
-int __fastcall ShFinalize()
+int ShFinalize()
 {
 {
     glslang::GetGlobalLock();
     glslang::GetGlobalLock();
     --NumberOfClients;
     --NumberOfClients;
@@ -1966,12 +1966,27 @@ const char* TProgram::getInfoDebugLog()
 // Reflection implementation.
 // Reflection implementation.
 //
 //
 
 
-bool TProgram::buildReflection()
+bool TProgram::buildReflection(int opts)
 {
 {
     if (! linked || reflection)
     if (! linked || reflection)
         return false;
         return false;
 
 
-    reflection = new TReflection;
+    int firstStage = EShLangVertex, lastStage = EShLangFragment;
+
+    if (opts & EShReflectionIntermediateIO) {
+        // if we're reflecting intermediate I/O, determine the first and last stage linked and use those as the
+        // boundaries for which stages generate pipeline inputs/outputs
+        firstStage = EShLangCount;
+        lastStage = 0;
+        for (int s = 0; s < EShLangCount; ++s) {
+            if (intermediate[s]) {
+                firstStage = std::min(firstStage, s);
+                lastStage = std::max(lastStage, s);
+            }
+        }
+    }
+
+    reflection = new TReflection((EShReflectionOptions)opts, (EShLanguage)firstStage, (EShLanguage)lastStage);
 
 
     for (int s = 0; s < EShLangCount; ++s) {
     for (int s = 0; s < EShLangCount; ++s) {
         if (intermediate[s]) {
         if (intermediate[s]) {
@@ -1983,27 +1998,23 @@ bool TProgram::buildReflection()
     return true;
     return true;
 }
 }
 
 
-int TProgram::getNumLiveUniformVariables() const             { return reflection->getNumUniforms(); }
-int TProgram::getNumLiveUniformBlocks() const                { return reflection->getNumUniformBlocks(); }
-const char* TProgram::getUniformName(int index) const        { return reflection->getUniform(index).name.c_str(); }
-const char* TProgram::getUniformBlockName(int index) const   { return reflection->getUniformBlock(index).name.c_str(); }
-int TProgram::getUniformBlockSize(int index) const           { return reflection->getUniformBlock(index).size; }
-int TProgram::getUniformIndex(const char* name) const        { return reflection->getIndex(name); }
-int TProgram::getUniformBinding(int index) const             { return reflection->getUniform(index).getBinding(); }
-EShLanguageMask TProgram::getUniformStages(int index) const  { return reflection->getUniform(index).stages; }
-int TProgram::getUniformBlockBinding(int index) const        { return reflection->getUniformBlock(index).getBinding(); }
-int TProgram::getUniformBlockIndex(int index) const          { return reflection->getUniform(index).index; }
-int TProgram::getUniformBlockCounterIndex(int index) const   { return reflection->getUniformBlock(index).counterIndex; }
-int TProgram::getUniformType(int index) const                { return reflection->getUniform(index).glDefineType; }
-int TProgram::getUniformBufferOffset(int index) const        { return reflection->getUniform(index).offset; }
-int TProgram::getUniformArraySize(int index) const           { return reflection->getUniform(index).size; }
-int TProgram::getNumLiveAttributes() const                   { return reflection->getNumAttributes(); }
-const char* TProgram::getAttributeName(int index) const      { return reflection->getAttribute(index).name.c_str(); }
-int TProgram::getAttributeType(int index) const              { return reflection->getAttribute(index).glDefineType; }
-const TType* TProgram::getAttributeTType(int index) const    { return reflection->getAttribute(index).getType(); }
-const TType* TProgram::getUniformTType(int index) const      { return reflection->getUniform(index).getType(); }
-const TType* TProgram::getUniformBlockTType(int index) const { return reflection->getUniformBlock(index).getType(); }
-unsigned TProgram::getLocalSize(int dim) const               { return reflection->getLocalSize(dim); }
+unsigned TProgram::getLocalSize(int dim) const                      { return reflection->getLocalSize(dim); }
+int TProgram::getReflectionIndex(const char* name) const            { return reflection->getIndex(name); }
+
+int TProgram::getNumUniformVariables() const                          { return reflection->getNumUniforms(); }
+const TObjectReflection& TProgram::getUniform(int index) const        { return reflection->getUniform(index); }
+int TProgram::getNumUniformBlocks() const                             { return reflection->getNumUniformBlocks(); }
+const TObjectReflection& TProgram::getUniformBlock(int index) const   { return reflection->getUniformBlock(index); }
+int TProgram::getNumPipeInputs() const                                { return reflection->getNumPipeInputs(); }
+const TObjectReflection& TProgram::getPipeInput(int index) const      { return reflection->getPipeInput(index); }
+int TProgram::getNumPipeOutputs() const                               { return reflection->getNumPipeOutputs(); }
+const TObjectReflection& TProgram::getPipeOutput(int index) const     { return reflection->getPipeOutput(index); }
+int TProgram::getNumBufferVariables() const                           { return reflection->getNumBufferVariables(); }
+const TObjectReflection& TProgram::getBufferVariable(int index) const { return reflection->getBufferVariable(index); }
+int TProgram::getNumBufferBlocks() const                              { return reflection->getNumStorageBuffers(); }
+const TObjectReflection& TProgram::getBufferBlock(int index) const    { return reflection->getStorageBufferBlock(index); }
+int TProgram::getNumAtomicCounters() const                            { return reflection->getNumAtomicCounters(); }
+const TObjectReflection& TProgram::getAtomicCounter(int index) const  { return reflection->getAtomicCounter(index); }
 
 
 void TProgram::dumpReflection()                      { reflection->dump(); }
 void TProgram::dumpReflection()                      { reflection->dump(); }
 
 

+ 79 - 1
3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp

@@ -224,6 +224,12 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
         xfbBuffers[b].implicitStride = std::max(xfbBuffers[b].implicitStride, unit.xfbBuffers[b].implicitStride);
         xfbBuffers[b].implicitStride = std::max(xfbBuffers[b].implicitStride, unit.xfbBuffers[b].implicitStride);
         if (unit.xfbBuffers[b].contains64BitType)
         if (unit.xfbBuffers[b].contains64BitType)
             xfbBuffers[b].contains64BitType = true;
             xfbBuffers[b].contains64BitType = true;
+#ifdef AMD_EXTENSIONS
+        if (unit.xfbBuffers[b].contains32BitType)
+            xfbBuffers[b].contains32BitType = true;
+        if (unit.xfbBuffers[b].contains16BitType)
+            xfbBuffers[b].contains16BitType = true;
+#endif
         // TODO: 4.4 link: enhanced layouts: compare ranges
         // TODO: 4.4 link: enhanced layouts: compare ranges
     }
     }
 
 
@@ -636,6 +642,12 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
     for (size_t b = 0; b < xfbBuffers.size(); ++b) {
     for (size_t b = 0; b < xfbBuffers.size(); ++b) {
         if (xfbBuffers[b].contains64BitType)
         if (xfbBuffers[b].contains64BitType)
             RoundToPow2(xfbBuffers[b].implicitStride, 8);
             RoundToPow2(xfbBuffers[b].implicitStride, 8);
+#ifdef AMD_EXTENSIONS
+        else if (xfbBuffers[b].contains32BitType)
+            RoundToPow2(xfbBuffers[b].implicitStride, 4);
+        else if (xfbBuffers[b].contains16BitType)
+            RoundToPow2(xfbBuffers[b].implicitStride, 2);
+#endif
 
 
         // "It is a compile-time or link-time error to have
         // "It is a compile-time or link-time error to have
         // any xfb_offset that overflows xfb_stride, whether stated on declarations before or after the xfb_stride, or
         // any xfb_offset that overflows xfb_stride, whether stated on declarations before or after the xfb_stride, or
@@ -656,12 +668,25 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
             error(infoSink, "xfb_stride must be multiple of 8 for buffer holding a double or 64-bit integer:");
             error(infoSink, "xfb_stride must be multiple of 8 for buffer holding a double or 64-bit integer:");
             infoSink.info.prefix(EPrefixError);
             infoSink.info.prefix(EPrefixError);
             infoSink.info << "    xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
             infoSink.info << "    xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
+#ifdef AMD_EXTENSIONS
+        } else if (xfbBuffers[b].contains32BitType && ! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) {
+#else
         } else if (! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) {
         } else if (! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) {
+#endif
             error(infoSink, "xfb_stride must be multiple of 4:");
             error(infoSink, "xfb_stride must be multiple of 4:");
             infoSink.info.prefix(EPrefixError);
             infoSink.info.prefix(EPrefixError);
             infoSink.info << "    xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
             infoSink.info << "    xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
         }
         }
+#ifdef AMD_EXTENSIONS
+        // "If the buffer is capturing any
+        // outputs with half-precision or 16-bit integer components, the stride must be a multiple of 2"
+        else if (xfbBuffers[b].contains16BitType && ! IsMultipleOfPow2(xfbBuffers[b].stride, 2)) {
+            error(infoSink, "xfb_stride must be multiple of 2 for buffer holding a half float or 16-bit integer:");
+            infoSink.info.prefix(EPrefixError);
+            infoSink.info << "    xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
+        }
 
 
+#endif
         // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
         // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
         // implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents."
         // implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents."
         if (xfbBuffers[b].stride > (unsigned int)(4 * resources.maxTransformFeedbackInterleavedComponents)) {
         if (xfbBuffers[b].stride > (unsigned int)(4 * resources.maxTransformFeedbackInterleavedComponents)) {
@@ -1260,7 +1285,11 @@ int TIntermediate::addXfbBufferOffset(const TType& type)
     TXfbBuffer& buffer = xfbBuffers[qualifier.layoutXfbBuffer];
     TXfbBuffer& buffer = xfbBuffers[qualifier.layoutXfbBuffer];
 
 
     // compute the range
     // compute the range
+#ifdef AMD_EXTENSIONS
+    unsigned int size = computeTypeXfbSize(type, buffer.contains64BitType, buffer.contains32BitType, buffer.contains16BitType);
+#else
     unsigned int size = computeTypeXfbSize(type, buffer.contains64BitType);
     unsigned int size = computeTypeXfbSize(type, buffer.contains64BitType);
+#endif
     buffer.implicitStride = std::max(buffer.implicitStride, qualifier.layoutXfbOffset + size);
     buffer.implicitStride = std::max(buffer.implicitStride, qualifier.layoutXfbOffset + size);
     TRange range(qualifier.layoutXfbOffset, qualifier.layoutXfbOffset + size - 1);
     TRange range(qualifier.layoutXfbOffset, qualifier.layoutXfbOffset + size - 1);
 
 
@@ -1279,9 +1308,16 @@ int TIntermediate::addXfbBufferOffset(const TType& type)
 
 
 // Recursively figure out how many bytes of xfb buffer are used by the given type.
 // Recursively figure out how many bytes of xfb buffer are used by the given type.
 // Return the size of type, in bytes.
 // Return the size of type, in bytes.
-// Sets contains64BitType to true if the type contains a double.
+// Sets contains64BitType to true if the type contains a 64-bit data type.
+#ifdef AMD_EXTENSIONS
+// Sets contains32BitType to true if the type contains a 32-bit data type.
+// Sets contains16BitType to true if the type contains a 16-bit data type.
+// N.B. Caller must set contains64BitType, contains32BitType, and contains16BitType to false before calling.
+unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const
+#else
 // N.B. Caller must set contains64BitType to false before calling.
 // N.B. Caller must set contains64BitType to false before calling.
 unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains64BitType) const
 unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains64BitType) const
+#endif
 {
 {
     // "...if applied to an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8,
     // "...if applied to an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8,
     // and the space taken in the buffer will be a multiple of 8.
     // and the space taken in the buffer will be a multiple of 8.
@@ -1294,22 +1330,44 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
         // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
         // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
         assert(type.isSizedArray());
         assert(type.isSizedArray());
         TType elementType(type, 0);
         TType elementType(type, 0);
+#ifdef AMD_EXTENSIONS
+        return type.getOuterArraySize() * computeTypeXfbSize(elementType, contains64BitType, contains16BitType, contains16BitType);
+#else
         return type.getOuterArraySize() * computeTypeXfbSize(elementType, contains64BitType);
         return type.getOuterArraySize() * computeTypeXfbSize(elementType, contains64BitType);
+#endif
     }
     }
 
 
     if (type.isStruct()) {
     if (type.isStruct()) {
         unsigned int size = 0;
         unsigned int size = 0;
         bool structContains64BitType = false;
         bool structContains64BitType = false;
+#ifdef AMD_EXTENSIONS
+        bool structContains32BitType = false;
+        bool structContains16BitType = false;
+#endif
         for (int member = 0; member < (int)type.getStruct()->size(); ++member) {
         for (int member = 0; member < (int)type.getStruct()->size(); ++member) {
             TType memberType(type, member);
             TType memberType(type, member);
             // "... if applied to
             // "... if applied to
             // an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8,
             // an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8,
             // and the space taken in the buffer will be a multiple of 8."
             // and the space taken in the buffer will be a multiple of 8."
             bool memberContains64BitType = false;
             bool memberContains64BitType = false;
+#ifdef AMD_EXTENSIONS
+            bool memberContains32BitType = false;
+            bool memberContains16BitType = false;
+            int memberSize = computeTypeXfbSize(memberType, memberContains64BitType, memberContains32BitType, memberContains16BitType);
+#else
             int memberSize = computeTypeXfbSize(memberType, memberContains64BitType);
             int memberSize = computeTypeXfbSize(memberType, memberContains64BitType);
+#endif
             if (memberContains64BitType) {
             if (memberContains64BitType) {
                 structContains64BitType = true;
                 structContains64BitType = true;
                 RoundToPow2(size, 8);
                 RoundToPow2(size, 8);
+#ifdef AMD_EXTENSIONS
+            } else if (memberContains32BitType) {
+                structContains32BitType = true;
+                RoundToPow2(size, 4);
+            } else if (memberContains16BitType) {
+                structContains16BitType = true;
+                RoundToPow2(size, 2);
+#endif
             }
             }
             size += memberSize;
             size += memberSize;
         }
         }
@@ -1317,6 +1375,14 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
         if (structContains64BitType) {
         if (structContains64BitType) {
             contains64BitType = true;
             contains64BitType = true;
             RoundToPow2(size, 8);
             RoundToPow2(size, 8);
+#ifdef AMD_EXTENSIONS
+        } else if (structContains32BitType) {
+            contains32BitType = true;
+            RoundToPow2(size, 4);
+        } else if (structContains16BitType) {
+            contains16BitType = true;
+            RoundToPow2(size, 2);
+#endif
         }
         }
         return size;
         return size;
     }
     }
@@ -1336,8 +1402,20 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
     if (type.getBasicType() == EbtDouble || type.getBasicType() == EbtInt64 || type.getBasicType() == EbtUint64) {
     if (type.getBasicType() == EbtDouble || type.getBasicType() == EbtInt64 || type.getBasicType() == EbtUint64) {
         contains64BitType = true;
         contains64BitType = true;
         return 8 * numComponents;
         return 8 * numComponents;
+#ifdef AMD_EXTENSIONS
+    } else if (type.getBasicType() == EbtFloat16 || type.getBasicType() == EbtInt16 || type.getBasicType() == EbtUint16) {
+        contains16BitType = true;
+        return 2 * numComponents;
+    } else if (type.getBasicType() == EbtInt8 || type.getBasicType() == EbtUint8)
+        return numComponents;
+    else {
+        contains32BitType = true;
+        return 4 * numComponents;
+    }
+#else
     } else
     } else
         return 4 * numComponents;
         return 4 * numComponents;
+#endif
 }
 }
 
 
 const int baseAlignmentVec4Std140 = 16;
 const int baseAlignmentVec4Std140 = 16;

+ 13 - 0
3rdparty/glslang/glslang/MachineIndependent/localintermediate.h

@@ -149,11 +149,20 @@ struct TOffsetRange {
 
 
 // Things that need to be tracked per xfb buffer.
 // Things that need to be tracked per xfb buffer.
 struct TXfbBuffer {
 struct TXfbBuffer {
+#ifdef AMD_EXTENSIONS
+    TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), contains64BitType(false),
+                   contains32BitType(false), contains16BitType(false) { }
+#else
     TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), contains64BitType(false) { }
     TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), contains64BitType(false) { }
+#endif
     std::vector<TRange> ranges;  // byte offsets that have already been assigned
     std::vector<TRange> ranges;  // byte offsets that have already been assigned
     unsigned int stride;
     unsigned int stride;
     unsigned int implicitStride;
     unsigned int implicitStride;
     bool contains64BitType;
     bool contains64BitType;
+#ifdef AMD_EXTENSIONS
+    bool contains32BitType;
+    bool contains16BitType;
+#endif
 };
 };
 
 
 // Track a set of strings describing how the module was processed.
 // Track a set of strings describing how the module was processed.
@@ -669,7 +678,11 @@ public:
     }
     }
     unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; }
     unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; }
     int addXfbBufferOffset(const TType&);
     int addXfbBufferOffset(const TType&);
+#ifdef AMD_EXTENSIONS
+    unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const;
+#else
     unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType) const;
     unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType) const;
+#endif
     static int getBaseAlignmentScalar(const TType&, int& size);
     static int getBaseAlignmentScalar(const TType&, int& size);
     static int getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
     static int getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
     static int getScalarAlignment(const TType&, int& size, int& stride, bool rowMajor);
     static int getScalarAlignment(const TType&, int& size, int& stride, bool rowMajor);

+ 294 - 31
3rdparty/glslang/glslang/MachineIndependent/reflection.cpp

@@ -93,11 +93,12 @@ public:
             // Use a degenerate (empty) set of dereferences to immediately put as at the end of
             // Use a degenerate (empty) set of dereferences to immediately put as at the end of
             // the dereference change expected by blowUpActiveAggregate.
             // the dereference change expected by blowUpActiveAggregate.
             TList<TIntermBinary*> derefs;
             TList<TIntermBinary*> derefs;
-            blowUpActiveAggregate(base.getType(), base.getName(), derefs, derefs.end(), -1, -1, 0);
+            blowUpActiveAggregate(base.getType(), base.getName(), derefs, derefs.end(), -1, -1, 0, 0,
+                                  base.getQualifier().storage, true);
         }
         }
     }
     }
 
 
-    void addAttribute(const TIntermSymbol& base)
+    void addPipeInput(const TIntermSymbol& base)
     {
     {
         if (processedDerefs.find(&base) == processedDerefs.end()) {
         if (processedDerefs.find(&base) == processedDerefs.end()) {
             processedDerefs.insert(&base);
             processedDerefs.insert(&base);
@@ -107,8 +108,36 @@ public:
 
 
             TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
             TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
             if (it == reflection.nameToIndex.end()) {
             if (it == reflection.nameToIndex.end()) {
-                reflection.nameToIndex[name.c_str()] = (int)reflection.indexToAttribute.size();
-                reflection.indexToAttribute.push_back(TObjectReflection(name.c_str(), type, 0, mapToGlType(type), 0, 0));
+                reflection.nameToIndex[name.c_str()] = (int)reflection.indexToPipeInput.size();
+                reflection.indexToPipeInput.push_back(TObjectReflection(name.c_str(), type, 0, mapToGlType(type), 0, 0));
+
+                EShLanguageMask& stages = reflection.indexToPipeInput.back().stages;
+                stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
+            } else {
+                EShLanguageMask& stages = reflection.indexToPipeInput[it->second].stages;
+                stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
+            }
+        }
+    }
+
+    void addPipeOutput(const TIntermSymbol& base)
+    {
+        if (processedDerefs.find(&base) == processedDerefs.end()) {
+            processedDerefs.insert(&base);
+
+            const TString &name = base.getName();
+            const TType &type = base.getType();
+
+            TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
+            if (it == reflection.nameToIndex.end()) {
+                reflection.nameToIndex[name.c_str()] = (int)reflection.indexToPipeOutput.size();
+                reflection.indexToPipeOutput.push_back(TObjectReflection(name.c_str(), type, 0, mapToGlType(type), 0, 0));
+
+                EShLanguageMask& stages = reflection.indexToPipeOutput.back().stages;
+                stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
+            } else {
+                EShLanguageMask& stages = reflection.indexToPipeOutput[it->second].stages;
+                stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
             }
             }
         }
         }
     }
     }
@@ -213,6 +242,36 @@ public:
         return lastOffset + lastMemberSize;
         return lastOffset + lastMemberSize;
     }
     }
 
 
+    // count the total number of leaf members from iterating out of a block type
+    int countAggregateMembers(const TType& parentType)
+    {
+        if (! parentType.isStruct())
+            return 1;
+
+        const bool strictArraySuffix = (reflection.options & EShReflectionStrictArraySuffix);
+
+        bool blockParent = (parentType.getBasicType() == EbtBlock && parentType.getQualifier().storage == EvqBuffer);
+
+        const TTypeList &memberList = *parentType.getStruct();
+
+        int ret = 0;
+
+        for (size_t i = 0; i < memberList.size(); i++)
+        {
+            const TType &memberType = *memberList[i].type;
+            int numMembers = countAggregateMembers(memberType);
+            // for sized arrays of structs, apply logic to expand out the same as we would below in
+            // blowUpActiveAggregate
+            if (memberType.isArray() && ! memberType.getArraySizes()->hasUnsized() && memberType.isStruct()) {
+                if (! strictArraySuffix || ! blockParent)
+                    numMembers *= memberType.getArraySizes()->getCumulativeSize();
+            }
+            ret += numMembers;
+        }
+
+        return ret;
+    }
+
     // Traverse the provided deref chain, including the base, and
     // Traverse the provided deref chain, including the base, and
     // - build a full reflection-granularity name, array size, etc. entry out of it, if it goes down to that granularity
     // - build a full reflection-granularity name, array size, etc. entry out of it, if it goes down to that granularity
     // - recursively expand any variable array index in the middle of that traversal
     // - recursively expand any variable array index in the middle of that traversal
@@ -221,8 +280,19 @@ public:
     // arraySize tracks, just for the final dereference in the chain, if there was a specific known size.
     // arraySize tracks, just for the final dereference in the chain, if there was a specific known size.
     // A value of 0 for arraySize will mean to use the full array's size.
     // A value of 0 for arraySize will mean to use the full array's size.
     void blowUpActiveAggregate(const TType& baseType, const TString& baseName, const TList<TIntermBinary*>& derefs,
     void blowUpActiveAggregate(const TType& baseType, const TString& baseName, const TList<TIntermBinary*>& derefs,
-                               TList<TIntermBinary*>::const_iterator deref, int offset, int blockIndex, int arraySize)
+                               TList<TIntermBinary*>::const_iterator deref, int offset, int blockIndex, int arraySize,
+                               int topLevelArrayStride, TStorageQualifier baseStorage, bool active)
     {
     {
+        // when strictArraySuffix is enabled, we closely follow the rules from ARB_program_interface_query.
+        // Broadly:
+        // * arrays-of-structs always have a [x] suffix.
+        // * with array-of-struct variables in the root of a buffer block, only ever return [0].
+        // * otherwise, array suffixes are added whenever we iterate, even if that means expanding out an array.
+        const bool strictArraySuffix = (reflection.options & EShReflectionStrictArraySuffix);
+
+        // is this variable inside a buffer block. This flag is set back to false after we iterate inside the first array element.
+        bool blockParent = (baseType.getBasicType() == EbtBlock && baseType.getQualifier().storage == EvqBuffer);
+
         // process the part of the dereference chain that was explicit in the shader
         // process the part of the dereference chain that was explicit in the shader
         TString name = baseName;
         TString name = baseName;
         const TType* terminalType = &baseType;
         const TType* terminalType = &baseType;
@@ -234,32 +304,48 @@ public:
             case EOpIndexIndirect: {
             case EOpIndexIndirect: {
                 int stride = getArrayStride(baseType, visitNode->getLeft()->getType());
                 int stride = getArrayStride(baseType, visitNode->getLeft()->getType());
 
 
+                if (topLevelArrayStride == 0)
+                    topLevelArrayStride = stride;
+
                 // Visit all the indices of this array, and for each one add on the remaining dereferencing
                 // Visit all the indices of this array, and for each one add on the remaining dereferencing
                 for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) {
                 for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) {
                     TString newBaseName = name;
                     TString newBaseName = name;
-                    if (baseType.getBasicType() != EbtBlock)
+                    if (strictArraySuffix && blockParent)
+                        newBaseName.append(TString("[0]"));
+                    else if (strictArraySuffix || baseType.getBasicType() != EbtBlock)
                         newBaseName.append(TString("[") + String(i) + "]");
                         newBaseName.append(TString("[") + String(i) + "]");
                     TList<TIntermBinary*>::const_iterator nextDeref = deref;
                     TList<TIntermBinary*>::const_iterator nextDeref = deref;
                     ++nextDeref;
                     ++nextDeref;
                     TType derefType(*terminalType, 0);
                     TType derefType(*terminalType, 0);
-                    blowUpActiveAggregate(derefType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize);
+                    blowUpActiveAggregate(derefType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize,
+                                          topLevelArrayStride, baseStorage, active);
 
 
                     if (offset >= 0)
                     if (offset >= 0)
-                      offset += stride;
+                        offset += stride;
                 }
                 }
 
 
                 // it was all completed in the recursive calls above
                 // it was all completed in the recursive calls above
                 return;
                 return;
             }
             }
-            case EOpIndexDirect:
+            case EOpIndexDirect: {
+                int stride = getArrayStride(baseType, visitNode->getLeft()->getType());
+
                 index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
                 index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
-                if (baseType.getBasicType() != EbtBlock) {
+                if (strictArraySuffix && blockParent) {
+                    name.append(TString("[0]"));
+                } else if (strictArraySuffix || baseType.getBasicType() != EbtBlock) {
                     name.append(TString("[") + String(index) + "]");
                     name.append(TString("[") + String(index) + "]");
 
 
                     if (offset >= 0)
                     if (offset >= 0)
-                      offset += getArrayStride(baseType, visitNode->getLeft()->getType()) * index;
+                        offset += stride * index;
                 }
                 }
+
+                if (topLevelArrayStride == 0)
+                    topLevelArrayStride = stride;
+
+                blockParent = false;
                 break;
                 break;
+            }
             case EOpIndexDirectStruct:
             case EOpIndexDirectStruct:
                 index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
                 index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
                 if (offset >= 0)
                 if (offset >= 0)
@@ -286,13 +372,24 @@ public:
                 if (offset >= 0)
                 if (offset >= 0)
                     stride = getArrayStride(baseType, *terminalType);
                     stride = getArrayStride(baseType, *terminalType);
 
 
-                for (int i = 0; i < std::max(terminalType->getOuterArraySize(), 1); ++i) {
+                if (topLevelArrayStride == 0)
+                    topLevelArrayStride = stride;
+
+                int arrayIterateSize = std::max(terminalType->getOuterArraySize(), 1);
+
+                // for top-level arrays in blocks, only expand [0] to avoid explosion of items
+                if (strictArraySuffix && blockParent)
+                    arrayIterateSize = 1;
+
+                for (int i = 0; i < arrayIterateSize; ++i) {
                     TString newBaseName = name;
                     TString newBaseName = name;
                     newBaseName.append(TString("[") + String(i) + "]");
                     newBaseName.append(TString("[") + String(i) + "]");
                     TType derefType(*terminalType, 0);
                     TType derefType(*terminalType, 0);
                     if (offset >= 0)
                     if (offset >= 0)
                         offset = baseOffset + stride * i;
                         offset = baseOffset + stride * i;
-                    blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0);
+
+                    blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0,
+                                          topLevelArrayStride, baseStorage, active);
                 }
                 }
             } else {
             } else {
                 // Visit all members of this aggregate, and for each one,
                 // Visit all members of this aggregate, and for each one,
@@ -308,11 +405,21 @@ public:
 
 
                 for (int i = 0; i < (int)typeList.size(); ++i) {
                 for (int i = 0; i < (int)typeList.size(); ++i) {
                     TString newBaseName = name;
                     TString newBaseName = name;
-                    newBaseName.append(TString(".") + typeList[i].type->getFieldName());
+                    if (newBaseName.size() > 0)
+                        newBaseName.append(".");
+                    newBaseName.append(typeList[i].type->getFieldName());
                     TType derefType(*terminalType, i);
                     TType derefType(*terminalType, i);
                     if (offset >= 0)
                     if (offset >= 0)
                         offset = baseOffset + memberOffsets[i];
                         offset = baseOffset + memberOffsets[i];
-                    blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0);
+
+                    int arrayStride = topLevelArrayStride;
+                    if (terminalType->getBasicType() == EbtBlock && terminalType->getQualifier().storage == EvqBuffer &&
+                        derefType.isArray()) {
+                        arrayStride = getArrayStride(baseType, derefType);
+                    }
+
+                    blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0,
+                                          arrayStride, baseStorage, active);
                 }
                 }
             }
             }
 
 
@@ -320,6 +427,10 @@ public:
             return;
             return;
         }
         }
 
 
+        if ((reflection.options & EShReflectionBasicArraySuffix) && terminalType->isArray()) {
+            name.append(TString("[0]"));
+        }
+
         // Finally, add a full string to the reflection database, and update the array size if necessary.
         // Finally, add a full string to the reflection database, and update the array size if necessary.
         // If the dereferenced entity to record is an array, compute the size and update the maximum size.
         // If the dereferenced entity to record is an array, compute the size and update the maximum size.
 
 
@@ -327,15 +438,39 @@ public:
         if (arraySize == 0)
         if (arraySize == 0)
             arraySize = mapToGlArraySize(*terminalType);
             arraySize = mapToGlArraySize(*terminalType);
 
 
+        TReflection::TMapIndexToReflection& variables = reflection.GetVariableMapForStorage(baseStorage);
+
         TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
         TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
         if (it == reflection.nameToIndex.end()) {
         if (it == reflection.nameToIndex.end()) {
-            reflection.nameToIndex[name.c_str()] = (int)reflection.indexToUniform.size();
-            reflection.indexToUniform.push_back(TObjectReflection(name.c_str(), *terminalType, offset,
-                                                                  mapToGlType(*terminalType),
-                                                                  arraySize, blockIndex));
-        } else if (arraySize > 1) {
-            int& reflectedArraySize = reflection.indexToUniform[it->second].size;
-            reflectedArraySize = std::max(arraySize, reflectedArraySize);
+            int uniformIndex = (int)variables.size();
+            reflection.nameToIndex[name.c_str()] = uniformIndex;
+            variables.push_back(TObjectReflection(name.c_str(), *terminalType, offset, mapToGlType(*terminalType),
+                                                  arraySize, blockIndex));
+            if (terminalType->isArray()) {
+                variables.back().arrayStride = getArrayStride(baseType, *terminalType);
+                if (topLevelArrayStride == 0)
+                    topLevelArrayStride = variables.back().arrayStride;
+            }
+
+            if ((reflection.options & EShReflectionSeparateBuffers) && terminalType->getBasicType() == EbtAtomicUint)
+                reflection.atomicCounterUniformIndices.push_back(uniformIndex);
+
+            variables.back().topLevelArrayStride = topLevelArrayStride;
+            
+            if ((reflection.options & EShReflectionAllBlockVariables) && active) {
+                EShLanguageMask& stages = variables.back().stages;
+                stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
+            }
+        } else {
+            if (arraySize > 1) {
+                int& reflectedArraySize = variables[it->second].size;
+                reflectedArraySize = std::max(arraySize, reflectedArraySize);
+            }
+
+            if ((reflection.options & EShReflectionAllBlockVariables) && active) {
+              EShLanguageMask& stages = variables[it->second].stages;
+              stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
+            }
         }
         }
     }
     }
 
 
@@ -385,6 +520,10 @@ public:
             anonymous = IsAnonymous(base->getName());
             anonymous = IsAnonymous(base->getName());
 
 
             const TString& blockName = base->getType().getTypeName();
             const TString& blockName = base->getType().getTypeName();
+            TString baseName;
+            
+            if (! anonymous)
+                baseName = blockName;
 
 
             if (base->getType().isArray()) {
             if (base->getType().isArray()) {
                 TType derefType(base->getType(), 0);
                 TType derefType(base->getType(), 0);
@@ -393,8 +532,56 @@ public:
                 for (int e = 0; e < base->getType().getCumulativeArraySize(); ++e)
                 for (int e = 0; e < base->getType().getCumulativeArraySize(); ++e)
                     blockIndex = addBlockName(blockName + "[" + String(e) + "]", derefType,
                     blockIndex = addBlockName(blockName + "[" + String(e) + "]", derefType,
                                               getBlockSize(base->getType()));
                                               getBlockSize(base->getType()));
+                baseName.append(TString("[0]"));
             } else
             } else
                 blockIndex = addBlockName(blockName, base->getType(), getBlockSize(base->getType()));
                 blockIndex = addBlockName(blockName, base->getType(), getBlockSize(base->getType()));
+
+            if (reflection.options & EShReflectionAllBlockVariables) {
+                // Use a degenerate (empty) set of dereferences to immediately put as at the end of
+                // the dereference change expected by blowUpActiveAggregate.
+                TList<TIntermBinary*> derefs;
+
+                // because we don't have any derefs, the first thing blowUpActiveAggregate will do is iterate over each
+                // member in the struct definition. This will lose any information about whether the parent was a buffer
+                // block. So if we're using strict array rules which don't expand the first child of a buffer block we
+                // instead iterate over the children here.
+                const bool strictArraySuffix = (reflection.options & EShReflectionStrictArraySuffix);
+                bool blockParent = (base->getType().getBasicType() == EbtBlock && base->getQualifier().storage == EvqBuffer);
+
+                if (strictArraySuffix && blockParent) {
+                    const TTypeList& typeList = *base->getType().getStruct();
+
+                    TVector<int> memberOffsets;
+
+                    memberOffsets.resize(typeList.size());
+                    getOffsets(base->getType(), memberOffsets);
+
+                    for (int i = 0; i < (int)typeList.size(); ++i) {
+                        TType derefType(base->getType(), i);
+                        TString name = baseName;
+                        if (name.size() > 0)
+                            name.append(".");
+                        name.append(typeList[i].type->getFieldName());
+
+                        // if this member is an array, store the top-level array stride but start the explosion from
+                        // the inner struct type.
+                        if (derefType.isArray() && derefType.isStruct()) {
+                            name.append("[0]");
+                            blowUpActiveAggregate(TType(derefType, 0), name, derefs, derefs.end(), memberOffsets[i],
+                                                  blockIndex, 0, getArrayStride(base->getType(), derefType),
+                                                  base->getQualifier().storage, false);
+                        } else {
+                            blowUpActiveAggregate(derefType, name, derefs, derefs.end(), memberOffsets[i], blockIndex,
+                                                  0, 0, base->getQualifier().storage, false);
+                        }
+                    }
+                } else {
+                    // otherwise - if we're not using strict array suffix rules, or this isn't a block so we are
+                    // expanding root arrays anyway, just start the iteration from the base block type.
+                    blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.end(), 0, blockIndex, 0, 0,
+                                          base->getQualifier().storage, false);
+                }
+            }
         }
         }
 
 
         // Process the dereference chain, backward, accumulating the pieces for later forward traversal.
         // Process the dereference chain, backward, accumulating the pieces for later forward traversal.
@@ -424,20 +611,32 @@ public:
             else
             else
                 baseName = base->getName();
                 baseName = base->getName();
         }
         }
-        blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize);
+        blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize, 0,
+                              base->getQualifier().storage, true);
     }
     }
 
 
     int addBlockName(const TString& name, const TType& type, int size)
     int addBlockName(const TString& name, const TType& type, int size)
     {
     {
+        TReflection::TMapIndexToReflection& blocks = reflection.GetBlockMapForStorage(type.getQualifier().storage);
+
         int blockIndex;
         int blockIndex;
         TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
         TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
         if (reflection.nameToIndex.find(name.c_str()) == reflection.nameToIndex.end()) {
         if (reflection.nameToIndex.find(name.c_str()) == reflection.nameToIndex.end()) {
-            blockIndex = (int)reflection.indexToUniformBlock.size();
+            blockIndex = (int)blocks.size();
             reflection.nameToIndex[name.c_str()] = blockIndex;
             reflection.nameToIndex[name.c_str()] = blockIndex;
-            reflection.indexToUniformBlock.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, -1));
-        } else
+            blocks.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, -1));
+
+            blocks.back().numMembers = countAggregateMembers(type);
+
+            EShLanguageMask& stages = blocks.back().stages;
+            stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
+        } else {
             blockIndex = it->second;
             blockIndex = it->second;
 
 
+            EShLanguageMask& stages = blocks[blockIndex].stages;
+            stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
+        }
+
         return blockIndex;
         return blockIndex;
     }
     }
 
 
@@ -828,8 +1027,49 @@ void TReflectionTraverser::visitSymbol(TIntermSymbol* base)
     if (base->getQualifier().storage == EvqUniform)
     if (base->getQualifier().storage == EvqUniform)
         addUniform(*base);
         addUniform(*base);
 
 
-    if (intermediate.getStage() == EShLangVertex && base->getQualifier().isPipeInput())
-        addAttribute(*base);
+    if (intermediate.getStage() == reflection.firstStage && base->getQualifier().isPipeInput())
+        addPipeInput(*base);
+
+    if (intermediate.getStage() == reflection.lastStage && base->getQualifier().isPipeOutput())
+        addPipeOutput(*base);
+}
+
+//
+// Implement TObjectReflection methods.
+//
+
+TObjectReflection::TObjectReflection(const std::string &pName, const TType &pType, int pOffset, int pGLDefineType,
+                                     int pSize, int pIndex)
+    : name(pName), offset(pOffset), glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1),
+      numMembers(-1), arrayStride(0), topLevelArrayStride(0), stages(EShLanguageMask(0)), type(pType.clone())
+{
+}
+
+int TObjectReflection::getBinding() const
+{
+    if (type == nullptr || !type->getQualifier().hasBinding())
+        return -1;
+    return type->getQualifier().layoutBinding;
+}
+
+void TObjectReflection::dump() const
+{
+    printf("%s: offset %d, type %x, size %d, index %d, binding %d, stages %d", name.c_str(), offset, glDefineType, size,
+           index, getBinding(), stages);
+
+    if (counterIndex != -1)
+        printf(", counter %d", counterIndex);
+
+    if (numMembers != -1)
+        printf(", numMembers %d", numMembers);
+
+    if (arrayStride != 0)
+        printf(", arrayStride %d", arrayStride);
+
+    if (topLevelArrayStride != 0)
+        printf(", topLevelArrayStride %d", topLevelArrayStride);
+
+    printf("\n");
 }
 }
 
 
 //
 //
@@ -863,9 +1103,17 @@ void TReflection::buildCounterIndices(const TIntermediate& intermediate)
 // build Shader Stages mask for all uniforms
 // build Shader Stages mask for all uniforms
 void TReflection::buildUniformStageMask(const TIntermediate& intermediate)
 void TReflection::buildUniformStageMask(const TIntermediate& intermediate)
 {
 {
+    if (options & EShReflectionAllBlockVariables)
+        return;
+
     for (int i = 0; i < int(indexToUniform.size()); ++i) {
     for (int i = 0; i < int(indexToUniform.size()); ++i) {
         indexToUniform[i].stages = static_cast<EShLanguageMask>(indexToUniform[i].stages | 1 << intermediate.getStage());
         indexToUniform[i].stages = static_cast<EShLanguageMask>(indexToUniform[i].stages | 1 << intermediate.getStage());
     }
     }
+
+    for (int i = 0; i < int(indexToBufferVariable.size()); ++i) {
+        indexToBufferVariable[i].stages =
+            static_cast<EShLanguageMask>(indexToBufferVariable[i].stages | 1 << intermediate.getStage());
+    }
 }
 }
 
 
 // Merge live symbols from 'intermediate' into the existing reflection database.
 // Merge live symbols from 'intermediate' into the existing reflection database.
@@ -910,9 +1158,24 @@ void TReflection::dump()
         indexToUniformBlock[i].dump();
         indexToUniformBlock[i].dump();
     printf("\n");
     printf("\n");
 
 
-    printf("Vertex attribute reflection:\n");
-    for (size_t i = 0; i < indexToAttribute.size(); ++i)
-        indexToAttribute[i].dump();
+    printf("Buffer variable reflection:\n");
+    for (size_t i = 0; i < indexToBufferVariable.size(); ++i)
+      indexToBufferVariable[i].dump();
+    printf("\n");
+
+    printf("Buffer block reflection:\n");
+    for (size_t i = 0; i < indexToBufferBlock.size(); ++i)
+      indexToBufferBlock[i].dump();
+    printf("\n");
+
+    printf("Pipeline input reflection:\n");
+    for (size_t i = 0; i < indexToPipeInput.size(); ++i)
+        indexToPipeInput[i].dump();
+    printf("\n");
+
+    printf("Pipeline output reflection:\n");
+    for (size_t i = 0; i < indexToPipeOutput.size(); ++i)
+        indexToPipeOutput[i].dump();
     printf("\n");
     printf("\n");
 
 
     if (getLocalSize(0) > 1) {
     if (getLocalSize(0) > 1) {

+ 72 - 49
3rdparty/glslang/glslang/MachineIndependent/reflection.h

@@ -52,51 +52,11 @@ class TIntermediate;
 class TIntermAggregate;
 class TIntermAggregate;
 class TReflectionTraverser;
 class TReflectionTraverser;
 
 
-// Data needed for just a single object at the granularity exchanged by the reflection API
-class TObjectReflection {
-public:
-    TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex) :
-        name(pName), offset(pOffset),
-        glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1), stages(EShLanguageMask(0)), type(pType.clone()) { }
-
-    const TType* getType() const { return type; }
-    int getBinding() const
-    {
-        if (type == nullptr || !type->getQualifier().hasBinding())
-            return -1;
-        return type->getQualifier().layoutBinding;
-    }
-    void dump() const
-    {
-        printf("%s: offset %d, type %x, size %d, index %d, binding %d, stages %d",
-               name.c_str(), offset, glDefineType, size, index, getBinding(), stages );
-
-        if (counterIndex != -1)
-            printf(", counter %d", counterIndex);
-
-        printf("\n");
-    }
-    static TObjectReflection badReflection() { return TObjectReflection(); }
-
-    std::string name;
-    int offset;
-    int glDefineType;
-    int size;         // data size in bytes for a block, array size for a (non-block) object that's an array
-    int index;
-    int counterIndex;
-    EShLanguageMask stages;
-
-protected:
-    TObjectReflection() :
-        offset(-1), glDefineType(-1), size(-1), index(-1), counterIndex(-1), stages(EShLanguageMask(0)), type(nullptr) { }
-
-    const TType* type;
-};
-
 // The full reflection database
 // The full reflection database
 class TReflection {
 class TReflection {
 public:
 public:
-    TReflection() : badReflection(TObjectReflection::badReflection())
+    TReflection(EShReflectionOptions opts, EShLanguage first, EShLanguage last)
+        : options(opts), firstStage(first), lastStage(last), badReflection(TObjectReflection::badReflection())
     { 
     { 
         for (int dim=0; dim<3; ++dim)
         for (int dim=0; dim<3; ++dim)
             localSize[dim] = 0;
             localSize[dim] = 0;
@@ -127,17 +87,57 @@ public:
             return badReflection;
             return badReflection;
     }
     }
 
 
-    // for mapping an attribute index to the attribute's description
-    int getNumAttributes() { return (int)indexToAttribute.size(); }
-    const TObjectReflection& getAttribute(int i) const
+    // for mapping an pipeline input index to the input's description
+    int getNumPipeInputs() { return (int)indexToPipeInput.size(); }
+    const TObjectReflection& getPipeInput(int i) const
+    {
+        if (i >= 0 && i < (int)indexToPipeInput.size())
+            return indexToPipeInput[i];
+        else
+            return badReflection;
+    }
+
+    // for mapping an pipeline output index to the output's description
+    int getNumPipeOutputs() { return (int)indexToPipeOutput.size(); }
+    const TObjectReflection& getPipeOutput(int i) const
     {
     {
-        if (i >= 0 && i < (int)indexToAttribute.size())
-            return indexToAttribute[i];
+        if (i >= 0 && i < (int)indexToPipeOutput.size())
+            return indexToPipeOutput[i];
         else
         else
             return badReflection;
             return badReflection;
     }
     }
 
 
-    // for mapping any name to its index (block names, uniform names and attribute names)
+    // for mapping from an atomic counter to the uniform index
+    int getNumAtomicCounters() const { return (int)atomicCounterUniformIndices.size(); }
+    const TObjectReflection& getAtomicCounter(int i) const
+    {
+        if (i >= 0 && i < (int)atomicCounterUniformIndices.size())
+            return getUniform(atomicCounterUniformIndices[i]);
+        else
+            return badReflection;
+    }
+
+    // for mapping a buffer variable index to a buffer variable object's description
+    int getNumBufferVariables() { return (int)indexToBufferVariable.size(); }
+    const TObjectReflection& getBufferVariable(int i) const
+    {
+        if (i >= 0 && i < (int)indexToBufferVariable.size())
+            return indexToBufferVariable[i];
+        else
+            return badReflection;
+    }
+    
+    // for mapping a storage block index to the storage block's description
+    int getNumStorageBuffers() const { return (int)indexToBufferBlock.size(); }
+    const TObjectReflection&  getStorageBufferBlock(int i) const
+    {
+        if (i >= 0 && i < (int)indexToBufferBlock.size())
+            return indexToBufferBlock[i];
+        else
+            return badReflection;
+    }
+
+    // for mapping any name to its index (block names, uniform names and input/output names)
     int getIndex(const char* name) const
     int getIndex(const char* name) const
     {
     {
         TNameToIndex::const_iterator it = nameToIndex.find(name);
         TNameToIndex::const_iterator it = nameToIndex.find(name);
@@ -165,12 +165,35 @@ protected:
     // Need a TString hash: typedef std::unordered_map<TString, int> TNameToIndex;
     // Need a TString hash: typedef std::unordered_map<TString, int> TNameToIndex;
     typedef std::map<std::string, int> TNameToIndex;
     typedef std::map<std::string, int> TNameToIndex;
     typedef std::vector<TObjectReflection> TMapIndexToReflection;
     typedef std::vector<TObjectReflection> TMapIndexToReflection;
+    typedef std::vector<int> TIndices;
+
+    TMapIndexToReflection& GetBlockMapForStorage(TStorageQualifier storage)
+    {
+        if ((options & EShReflectionSeparateBuffers) && storage == EvqBuffer)
+            return indexToBufferBlock;
+        return indexToUniformBlock;
+    }
+    TMapIndexToReflection& GetVariableMapForStorage(TStorageQualifier storage)
+    {
+        if ((options & EShReflectionSeparateBuffers) && storage == EvqBuffer)
+            return indexToBufferVariable;
+        return indexToUniform;
+    }
+
+    EShReflectionOptions options;
+
+    EShLanguage firstStage;
+    EShLanguage lastStage;
 
 
     TObjectReflection badReflection; // return for queries of -1 or generally out of range; has expected descriptions with in it for this
     TObjectReflection badReflection; // return for queries of -1 or generally out of range; has expected descriptions with in it for this
     TNameToIndex nameToIndex;        // maps names to indexes; can hold all types of data: uniform/buffer and which function names have been processed
     TNameToIndex nameToIndex;        // maps names to indexes; can hold all types of data: uniform/buffer and which function names have been processed
     TMapIndexToReflection indexToUniform;
     TMapIndexToReflection indexToUniform;
     TMapIndexToReflection indexToUniformBlock;
     TMapIndexToReflection indexToUniformBlock;
-    TMapIndexToReflection indexToAttribute;
+    TMapIndexToReflection indexToBufferVariable;
+    TMapIndexToReflection indexToBufferBlock;
+    TMapIndexToReflection indexToPipeInput;
+    TMapIndexToReflection indexToPipeOutput;
+    TIndices atomicCounterUniformIndices;
 
 
     unsigned int localSize[3];
     unsigned int localSize[3];
 };
 };

+ 130 - 25
3rdparty/glslang/glslang/Public/ShaderLang.h

@@ -53,9 +53,6 @@
 #define SH_IMPORT_EXPORT
 #define SH_IMPORT_EXPORT
 #else
 #else
 #define SH_IMPORT_EXPORT
 #define SH_IMPORT_EXPORT
-#ifndef __fastcall
-#define __fastcall
-#endif
 #define C_DECL
 #define C_DECL
 #endif
 #endif
 
 
@@ -83,7 +80,7 @@ SH_IMPORT_EXPORT int ShInitialize();
 //
 //
 // Call this at process shutdown to clean up memory.
 // Call this at process shutdown to clean up memory.
 //
 //
-SH_IMPORT_EXPORT int __fastcall ShFinalize();
+SH_IMPORT_EXPORT int ShFinalize();
 
 
 //
 //
 // Types of languages the compiler can consume.
 // Types of languages the compiler can consume.
@@ -239,6 +236,18 @@ enum EShMessages {
     EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (right now only for samplers)
     EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (right now only for samplers)
 };
 };
 
 
+//
+// Options for building reflection
+//
+typedef enum {
+    EShReflectionDefault           = 0,        // default is original behaviour before options were added
+    EShReflectionStrictArraySuffix = (1 << 0), // reflection will follow stricter rules for array-of-structs suffixes
+    EShReflectionBasicArraySuffix  = (1 << 1), // arrays of basic types will be appended with [0] as in GL reflection
+    EShReflectionIntermediateIO    = (1 << 2), // reflect inputs and outputs to program, even with no vertex shader
+    EShReflectionSeparateBuffers   = (1 << 3), // buffer variables and buffer blocks are reflected separately
+    EShReflectionAllBlockVariables = (1 << 4), // reflect all variables in blocks, even if they are inactive
+} EShReflectionOptions;
+
 //
 //
 // Build a table for bindings.  This can be used for locating
 // Build a table for bindings.  This can be used for locating
 // attributes, uniforms, globals, etc., as needed.
 // attributes, uniforms, globals, etc., as needed.
@@ -599,6 +608,41 @@ private:
     TShader& operator=(TShader&);
     TShader& operator=(TShader&);
 };
 };
 
 
+//
+// A reflection database and its interface, consistent with the OpenGL API reflection queries.
+//
+
+// Data needed for just a single object at the granularity exchanged by the reflection API
+class TObjectReflection {
+public:
+    TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex);
+
+    const TType* getType() const { return type; }
+    int getBinding() const;
+    void dump() const;
+    static TObjectReflection badReflection() { return TObjectReflection(); }
+
+    std::string name;
+    int offset;
+    int glDefineType;
+    int size;                   // data size in bytes for a block, array size for a (non-block) object that's an array
+    int index;
+    int counterIndex;
+    int numMembers;
+    int arrayStride;            // stride of an array variable
+    int topLevelArrayStride;    // stride of the top-level variable in a storage buffer member
+    EShLanguageMask stages;
+
+protected:
+    TObjectReflection()
+        : offset(-1), glDefineType(-1), size(-1), index(-1), counterIndex(-1), numMembers(-1), arrayStride(0),
+          topLevelArrayStride(0), stages(EShLanguageMask(0)), type(nullptr)
+    {
+    }
+
+    const TType* type;
+};
+
 class TReflection;
 class TReflection;
 class TIoMapper;
 class TIoMapper;
 
 
@@ -688,28 +732,89 @@ public:
     TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; }
     TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; }
 
 
     // Reflection Interface
     // Reflection Interface
-    bool buildReflection();                          // call first, to do liveness analysis, index mapping, etc.; returns false on failure
-    int getNumLiveUniformVariables() const;                // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS)
-    int getNumLiveUniformBlocks() const;                   // can be used for glGetProgramiv(GL_ACTIVE_UNIFORM_BLOCKS)
-    const char* getUniformName(int index) const;           // can be used for "name" part of glGetActiveUniform()
-    const char* getUniformBlockName(int blockIndex) const; // can be used for glGetActiveUniformBlockName()
-    int getUniformBlockSize(int blockIndex) const;         // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE)
-    int getUniformIndex(const char* name) const;           // can be used for glGetUniformIndices()
-    int getUniformBinding(int index) const;                // returns the binding number
-    EShLanguageMask getUniformStages(int index) const;     // returns Shaders Stages where a Uniform is present
-    int getUniformBlockBinding(int index) const;           // returns the block binding number
-    int getUniformBlockIndex(int index) const;             // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX)
-    int getUniformBlockCounterIndex(int index) const;      // returns block index of associated counter.
-    int getUniformType(int index) const;                   // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE)
-    int getUniformBufferOffset(int index) const;           // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET)
-    int getUniformArraySize(int index) const;              // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE)
-    int getNumLiveAttributes() const;                      // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES)
+
+    // call first, to do liveness analysis, index mapping, etc.; returns false on failure
+    bool buildReflection(int opts = EShReflectionDefault);    
+
     unsigned getLocalSize(int dim) const;                  // return dim'th local size
     unsigned getLocalSize(int dim) const;                  // return dim'th local size
-    const char *getAttributeName(int index) const;         // can be used for glGetActiveAttrib()
-    int getAttributeType(int index) const;                 // can be used for glGetActiveAttrib()
-    const TType* getUniformTType(int index) const;         // returns a TType*
-    const TType* getUniformBlockTType(int index) const;    // returns a TType*
-    const TType* getAttributeTType(int index) const;       // returns a TType*
+    int getReflectionIndex(const char *name) const;
+
+    int getNumUniformVariables() const;
+    const TObjectReflection& getUniform(int index) const;
+    int getNumUniformBlocks() const;
+    const TObjectReflection& getUniformBlock(int index) const;
+    int getNumPipeInputs() const;
+    const TObjectReflection& getPipeInput(int index) const;
+    int getNumPipeOutputs() const;
+    const TObjectReflection& getPipeOutput(int index) const;
+    int getNumBufferVariables() const;
+    const TObjectReflection& getBufferVariable(int index) const;
+    int getNumBufferBlocks() const;
+    const TObjectReflection& getBufferBlock(int index) const;
+    int getNumAtomicCounters() const;
+    const TObjectReflection& getAtomicCounter(int index) const;
+
+    // Legacy Reflection Interface - expressed in terms of above interface
+
+    // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS)
+    int getNumLiveUniformVariables() const             { return getNumUniformVariables(); }
+
+    // can be used for glGetProgramiv(GL_ACTIVE_UNIFORM_BLOCKS)
+    int getNumLiveUniformBlocks() const                { return getNumUniformBlocks(); }
+
+    // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES)
+    int getNumLiveAttributes() const                   { return getNumPipeInputs(); }
+
+    // can be used for glGetUniformIndices()
+    int getUniformIndex(const char *name) const        { return getReflectionIndex(name); }
+
+    // can be used for "name" part of glGetActiveUniform()
+    const char *getUniformName(int index) const        { return getUniform(index).name.c_str(); }
+
+    // returns the binding number
+    int getUniformBinding(int index) const             { return getUniform(index).getBinding(); }
+
+    // returns Shaders Stages where a Uniform is present
+    EShLanguageMask getUniformStages(int index) const  { return getUniform(index).stages; }
+
+    // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX)
+    int getUniformBlockIndex(int index) const          { return getUniform(index).index; }
+
+    // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE)
+    int getUniformType(int index) const                { return getUniform(index).glDefineType; }
+
+    // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET)
+    int getUniformBufferOffset(int index) const        { return getUniform(index).offset; }
+
+    // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE)
+    int getUniformArraySize(int index) const           { return getUniform(index).size; }
+
+    // returns a TType*
+    const TType *getUniformTType(int index) const      { return getUniform(index).getType(); }
+
+    // can be used for glGetActiveUniformBlockName()
+    const char *getUniformBlockName(int index) const   { return getUniformBlock(index).name.c_str(); }
+
+    // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE)
+    int getUniformBlockSize(int index) const           { return getUniformBlock(index).size; }
+
+    // returns the block binding number
+    int getUniformBlockBinding(int index) const        { return getUniformBlock(index).getBinding(); }
+
+    // returns block index of associated counter.
+    int getUniformBlockCounterIndex(int index) const   { return getUniformBlock(index).counterIndex; }
+
+    // returns a TType*
+    const TType *getUniformBlockTType(int index) const { return getUniformBlock(index).getType(); }
+
+    // can be used for glGetActiveAttrib()
+    const char *getAttributeName(int index) const      { return getPipeInput(index).name.c_str(); }
+
+    // can be used for glGetActiveAttrib()
+    int getAttributeType(int index) const              { return getPipeInput(index).glDefineType; }
+
+    // returns a TType*
+    const TType *getAttributeTType(int index) const    { return getPipeInput(index).getType(); }
 
 
     void dumpReflection();
     void dumpReflection();
 
 

+ 1 - 0
3rdparty/glslang/gtests/Spv.FromFile.cpp

@@ -528,6 +528,7 @@ INSTANTIATE_TEST_CASE_P(
 INSTANTIATE_TEST_CASE_P(
 INSTANTIATE_TEST_CASE_P(
     Glsl, CompileVulkanToSpirvTestAMD,
     Glsl, CompileVulkanToSpirvTestAMD,
     ::testing::ValuesIn(std::vector<std::string>({
     ::testing::ValuesIn(std::vector<std::string>({
+        "spv.16bitxfb.vert",
         "spv.float16.frag",
         "spv.float16.frag",
         "spv.float16Fetch.frag",
         "spv.float16Fetch.frag",
         "spv.imageLoadStoreLod.frag",
         "spv.imageLoadStoreLod.frag",

+ 13 - 0
3rdparty/glslang/hlsl/hlslParseHelper.cpp

@@ -8695,12 +8695,25 @@ void HlslParseContext::fixXfbOffsets(TQualifier& qualifier, TTypeList& typeList)
     for (unsigned int member = 0; member < typeList.size(); ++member) {
     for (unsigned int member = 0; member < typeList.size(); ++member) {
         TQualifier& memberQualifier = typeList[member].type->getQualifier();
         TQualifier& memberQualifier = typeList[member].type->getQualifier();
         bool contains64BitType = false;
         bool contains64BitType = false;
+#ifdef AMD_EXTENSIONS
+        bool contains32BitType = false;
+        bool contains16BitType = false;
+        int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, contains64BitType, contains32BitType, contains16BitType);
+#else
         int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, contains64BitType);
         int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, contains64BitType);
+#endif
         // see if we need to auto-assign an offset to this member
         // see if we need to auto-assign an offset to this member
         if (! memberQualifier.hasXfbOffset()) {
         if (! memberQualifier.hasXfbOffset()) {
             // "if applied to an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8"
             // "if applied to an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8"
             if (contains64BitType)
             if (contains64BitType)
                 RoundToPow2(nextOffset, 8);
                 RoundToPow2(nextOffset, 8);
+#ifdef AMD_EXTENSIONS
+            else if (contains32BitType)
+                RoundToPow2(nextOffset, 4);
+            // "if applied to an aggregate containing a half float or 16-bit integer, the offset must also be a multiple of 2"
+            else if (contains16BitType)
+                RoundToPow2(nextOffset, 2);
+#endif
             memberQualifier.layoutXfbOffset = nextOffset;
             memberQualifier.layoutXfbOffset = nextOffset;
         } else
         } else
             nextOffset = memberQualifier.layoutXfbOffset;
             nextOffset = memberQualifier.layoutXfbOffset;

+ 1 - 1
3rdparty/glslang/known_good.json

@@ -5,7 +5,7 @@
       "site" : "github",
       "site" : "github",
       "subrepo" : "KhronosGroup/SPIRV-Tools",
       "subrepo" : "KhronosGroup/SPIRV-Tools",
       "subdir" : "External/spirv-tools",
       "subdir" : "External/spirv-tools",
-      "commit" : "e2279da7148d19bd21c6d47ffc96ee4176f43dba"
+      "commit" : "117a1fd11f11e9bef9faa563c3d5156cc6ab529c"
     },
     },
     {
     {
       "name" : "spirv-tools/external/spirv-headers",
       "name" : "spirv-tools/external/spirv-headers",