Browse Source

Update glslang

--HG--
branch : minor
Alex Szpakowski 8 years ago
parent
commit
ad399cab39
47 changed files with 3824 additions and 1775 deletions
  1. 0 2
      CMakeLists.txt
  2. 0 12
      platform/xcode/liblove.xcodeproj/project.pbxproj
  3. 23 0
      src/libraries/glslang/glslang/Include/BaseTypes.h
  4. 177 170
      src/libraries/glslang/glslang/Include/Types.h
  5. 14 12
      src/libraries/glslang/glslang/Include/arrays.h
  6. 158 5
      src/libraries/glslang/glslang/Include/intermediate.h
  7. 2 2
      src/libraries/glslang/glslang/Include/revision.h
  8. 36 2
      src/libraries/glslang/glslang/MachineIndependent/Constant.cpp
  9. 417 32
      src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp
  10. 5 5
      src/libraries/glslang/glslang/MachineIndependent/Initialize.h
  11. 586 57
      src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp
  12. 2 0
      src/libraries/glslang/glslang/MachineIndependent/LiveTraverser.h
  13. 15 31
      src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp
  14. 179 36
      src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp
  15. 32 21
      src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h
  16. 2 0
      src/libraries/glslang/glslang/MachineIndependent/RemoveTree.h
  17. 33 1
      src/libraries/glslang/glslang/MachineIndependent/Scan.cpp
  18. 2 0
      src/libraries/glslang/glslang/MachineIndependent/ScanContext.h
  19. 32 46
      src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp
  20. 21 2
      src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp
  21. 91 15
      src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h
  22. 41 1
      src/libraries/glslang/glslang/MachineIndependent/Versions.cpp
  23. 7 0
      src/libraries/glslang/glslang/MachineIndependent/Versions.h
  24. 2 0
      src/libraries/glslang/glslang/MachineIndependent/gl_types.h
  25. 480 625
      src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp
  26. 318 321
      src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h
  27. 185 8
      src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp
  28. 410 92
      src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp
  29. 21 7
      src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp
  30. 64 7
      src/libraries/glslang/glslang/MachineIndependent/localintermediate.h
  31. 0 6
      src/libraries/glslang/glslang/MachineIndependent/parseConst.cpp
  32. 2 0
      src/libraries/glslang/glslang/MachineIndependent/parseVersions.h
  33. 29 8
      src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp
  34. 4 0
      src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp
  35. 14 6
      src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h
  36. 0 81
      src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpMemory.cpp
  37. 261 24
      src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp
  38. 0 77
      src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpSymbols.cpp
  39. 20 4
      src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp
  40. 6 2
      src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h
  41. 2 0
      src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.h
  42. 39 1
      src/libraries/glslang/glslang/MachineIndependent/reflection.cpp
  43. 25 3
      src/libraries/glslang/glslang/MachineIndependent/reflection.h
  44. 0 14
      src/libraries/glslang/glslang/OSDependent/Unix/ossource.cpp
  45. 0 15
      src/libraries/glslang/glslang/OSDependent/Windows/ossource.cpp
  46. 0 3
      src/libraries/glslang/glslang/OSDependent/osinclude.h
  47. 67 19
      src/libraries/glslang/glslang/Public/ShaderLang.h

+ 0 - 2
CMakeLists.txt

@@ -1297,9 +1297,7 @@ set(LOVE_SRC_3P_GLSLANG_GLSLANG_MACHINEINDEPENDENT_PREPROCESSOR
 	src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp
 	src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp
 	src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp
 	src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp
 	src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h
 	src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h
-	src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpMemory.cpp
 	src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp
 	src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp
-	src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpSymbols.cpp
 	src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp
 	src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp
 	src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h
 	src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h
 )
 )

+ 0 - 12
platform/xcode/liblove.xcodeproj/project.pbxproj

@@ -1095,12 +1095,8 @@
 		FAF1408E1E20934C00F898D2 /* PpContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FED1E20934C00F898D2 /* PpContext.cpp */; };
 		FAF1408E1E20934C00F898D2 /* PpContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FED1E20934C00F898D2 /* PpContext.cpp */; };
 		FAF1408F1E20934C00F898D2 /* PpContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FED1E20934C00F898D2 /* PpContext.cpp */; };
 		FAF1408F1E20934C00F898D2 /* PpContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FED1E20934C00F898D2 /* PpContext.cpp */; };
 		FAF140901E20934C00F898D2 /* PpContext.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FEE1E20934C00F898D2 /* PpContext.h */; };
 		FAF140901E20934C00F898D2 /* PpContext.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FEE1E20934C00F898D2 /* PpContext.h */; };
-		FAF140911E20934C00F898D2 /* PpMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FEF1E20934C00F898D2 /* PpMemory.cpp */; };
-		FAF140921E20934C00F898D2 /* PpMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FEF1E20934C00F898D2 /* PpMemory.cpp */; };
 		FAF140931E20934C00F898D2 /* PpScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF01E20934C00F898D2 /* PpScanner.cpp */; };
 		FAF140931E20934C00F898D2 /* PpScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF01E20934C00F898D2 /* PpScanner.cpp */; };
 		FAF140941E20934C00F898D2 /* PpScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF01E20934C00F898D2 /* PpScanner.cpp */; };
 		FAF140941E20934C00F898D2 /* PpScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF01E20934C00F898D2 /* PpScanner.cpp */; };
-		FAF140951E20934C00F898D2 /* PpSymbols.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF11E20934C00F898D2 /* PpSymbols.cpp */; };
-		FAF140961E20934C00F898D2 /* PpSymbols.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF11E20934C00F898D2 /* PpSymbols.cpp */; };
 		FAF140971E20934C00F898D2 /* PpTokens.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF21E20934C00F898D2 /* PpTokens.cpp */; };
 		FAF140971E20934C00F898D2 /* PpTokens.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF21E20934C00F898D2 /* PpTokens.cpp */; };
 		FAF140981E20934C00F898D2 /* PpTokens.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF21E20934C00F898D2 /* PpTokens.cpp */; };
 		FAF140981E20934C00F898D2 /* PpTokens.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF21E20934C00F898D2 /* PpTokens.cpp */; };
 		FAF140991E20934C00F898D2 /* PpTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FF31E20934C00F898D2 /* PpTokens.h */; };
 		FAF140991E20934C00F898D2 /* PpTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FF31E20934C00F898D2 /* PpTokens.h */; };
@@ -1914,9 +1910,7 @@
 		FAF13FEC1E20934C00F898D2 /* PpAtom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpAtom.cpp; sourceTree = "<group>"; };
 		FAF13FEC1E20934C00F898D2 /* PpAtom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpAtom.cpp; sourceTree = "<group>"; };
 		FAF13FED1E20934C00F898D2 /* PpContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpContext.cpp; sourceTree = "<group>"; };
 		FAF13FED1E20934C00F898D2 /* PpContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpContext.cpp; sourceTree = "<group>"; };
 		FAF13FEE1E20934C00F898D2 /* PpContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PpContext.h; sourceTree = "<group>"; };
 		FAF13FEE1E20934C00F898D2 /* PpContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PpContext.h; sourceTree = "<group>"; };
-		FAF13FEF1E20934C00F898D2 /* PpMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpMemory.cpp; sourceTree = "<group>"; };
 		FAF13FF01E20934C00F898D2 /* PpScanner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpScanner.cpp; sourceTree = "<group>"; };
 		FAF13FF01E20934C00F898D2 /* PpScanner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpScanner.cpp; sourceTree = "<group>"; };
-		FAF13FF11E20934C00F898D2 /* PpSymbols.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpSymbols.cpp; sourceTree = "<group>"; };
 		FAF13FF21E20934C00F898D2 /* PpTokens.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpTokens.cpp; sourceTree = "<group>"; };
 		FAF13FF21E20934C00F898D2 /* PpTokens.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpTokens.cpp; sourceTree = "<group>"; };
 		FAF13FF31E20934C00F898D2 /* PpTokens.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PpTokens.h; sourceTree = "<group>"; };
 		FAF13FF31E20934C00F898D2 /* PpTokens.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PpTokens.h; sourceTree = "<group>"; };
 		FAF13FF41E20934C00F898D2 /* propagateNoContraction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = propagateNoContraction.cpp; sourceTree = "<group>"; };
 		FAF13FF41E20934C00F898D2 /* propagateNoContraction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = propagateNoContraction.cpp; sourceTree = "<group>"; };
@@ -3471,9 +3465,7 @@
 				FAF13FEC1E20934C00F898D2 /* PpAtom.cpp */,
 				FAF13FEC1E20934C00F898D2 /* PpAtom.cpp */,
 				FAF13FED1E20934C00F898D2 /* PpContext.cpp */,
 				FAF13FED1E20934C00F898D2 /* PpContext.cpp */,
 				FAF13FEE1E20934C00F898D2 /* PpContext.h */,
 				FAF13FEE1E20934C00F898D2 /* PpContext.h */,
-				FAF13FEF1E20934C00F898D2 /* PpMemory.cpp */,
 				FAF13FF01E20934C00F898D2 /* PpScanner.cpp */,
 				FAF13FF01E20934C00F898D2 /* PpScanner.cpp */,
-				FAF13FF11E20934C00F898D2 /* PpSymbols.cpp */,
 				FAF13FF21E20934C00F898D2 /* PpTokens.cpp */,
 				FAF13FF21E20934C00F898D2 /* PpTokens.cpp */,
 				FAF13FF31E20934C00F898D2 /* PpTokens.h */,
 				FAF13FF31E20934C00F898D2 /* PpTokens.h */,
 			);
 			);
@@ -4079,7 +4071,6 @@
 				FAF140AA1E20934C00F898D2 /* SymbolTable.cpp in Sources */,
 				FAF140AA1E20934C00F898D2 /* SymbolTable.cpp in Sources */,
 				FA0B7A8D1A958EA3000E1D17 /* b2DistanceJoint.cpp in Sources */,
 				FA0B7A8D1A958EA3000E1D17 /* b2DistanceJoint.cpp in Sources */,
 				FA0B7A841A958EA3000E1D17 /* b2EdgeAndPolygonContact.cpp in Sources */,
 				FA0B7A841A958EA3000E1D17 /* b2EdgeAndPolygonContact.cpp in Sources */,
-				FAF140921E20934C00F898D2 /* PpMemory.cpp in Sources */,
 				FA0B7E191A95902C000E1D17 /* MotorJoint.cpp in Sources */,
 				FA0B7E191A95902C000E1D17 /* MotorJoint.cpp in Sources */,
 				FAF1406F1E20934C00F898D2 /* Initialize.cpp in Sources */,
 				FAF1406F1E20934C00F898D2 /* Initialize.cpp in Sources */,
 				FA0B7E4F1A95902C000E1D17 /* wrap_Fixture.cpp in Sources */,
 				FA0B7E4F1A95902C000E1D17 /* wrap_Fixture.cpp in Sources */,
@@ -4256,7 +4247,6 @@
 				FA0B7CE31A95902C000E1D17 /* wrap_Audio.cpp in Sources */,
 				FA0B7CE31A95902C000E1D17 /* wrap_Audio.cpp in Sources */,
 				FA0B7B381A958EA3000E1D17 /* wuff_internal.c in Sources */,
 				FA0B7B381A958EA3000E1D17 /* wuff_internal.c in Sources */,
 				FA0B7DF81A95902C000E1D17 /* Body.cpp in Sources */,
 				FA0B7DF81A95902C000E1D17 /* Body.cpp in Sources */,
-				FAF140961E20934C00F898D2 /* PpSymbols.cpp in Sources */,
 				FA4F2BB41DE1E4BD00CA37D7 /* RecordingDevice.cpp in Sources */,
 				FA4F2BB41DE1E4BD00CA37D7 /* RecordingDevice.cpp in Sources */,
 				FA0B7DF51A95902C000E1D17 /* wrap_Mouse.cpp in Sources */,
 				FA0B7DF51A95902C000E1D17 /* wrap_Mouse.cpp in Sources */,
 				FA0B7E861A95902C000E1D17 /* CoreAudioDecoder.cpp in Sources */,
 				FA0B7E861A95902C000E1D17 /* CoreAudioDecoder.cpp in Sources */,
@@ -4440,7 +4430,6 @@
 				FAF140A91E20934C00F898D2 /* SymbolTable.cpp in Sources */,
 				FAF140A91E20934C00F898D2 /* SymbolTable.cpp in Sources */,
 				FA0B7E181A95902C000E1D17 /* MotorJoint.cpp in Sources */,
 				FA0B7E181A95902C000E1D17 /* MotorJoint.cpp in Sources */,
 				FA0B7E4E1A95902C000E1D17 /* wrap_Fixture.cpp in Sources */,
 				FA0B7E4E1A95902C000E1D17 /* wrap_Fixture.cpp in Sources */,
-				FAF140911E20934C00F898D2 /* PpMemory.cpp in Sources */,
 				FA0B7EBE1A95902C000E1D17 /* Thread.cpp in Sources */,
 				FA0B7EBE1A95902C000E1D17 /* Thread.cpp in Sources */,
 				FAF1406E1E20934C00F898D2 /* Initialize.cpp in Sources */,
 				FAF1406E1E20934C00F898D2 /* Initialize.cpp in Sources */,
 				FA0B7EB81A95902C000E1D17 /* Channel.cpp in Sources */,
 				FA0B7EB81A95902C000E1D17 /* Channel.cpp in Sources */,
@@ -4617,7 +4606,6 @@
 				FA0B7DF41A95902C000E1D17 /* wrap_Mouse.cpp in Sources */,
 				FA0B7DF41A95902C000E1D17 /* wrap_Mouse.cpp in Sources */,
 				FA0B7E851A95902C000E1D17 /* CoreAudioDecoder.cpp in Sources */,
 				FA0B7E851A95902C000E1D17 /* CoreAudioDecoder.cpp in Sources */,
 				FA0B7E751A95902C000E1D17 /* wrap_WeldJoint.cpp in Sources */,
 				FA0B7E751A95902C000E1D17 /* wrap_WeldJoint.cpp in Sources */,
-				FAF140951E20934C00F898D2 /* PpSymbols.cpp in Sources */,
 				FA0B7D551A95902C000E1D17 /* Buffer.cpp in Sources */,
 				FA0B7D551A95902C000E1D17 /* Buffer.cpp in Sources */,
 				FA57FB981AE1993600F2AD6D /* noise1234.cpp in Sources */,
 				FA57FB981AE1993600F2AD6D /* noise1234.cpp in Sources */,
 				FA0B7E211A95902C000E1D17 /* PolygonShape.cpp in Sources */,
 				FA0B7E211A95902C000E1D17 /* PolygonShape.cpp in Sources */,

+ 23 - 0
src/libraries/glslang/glslang/Include/BaseTypes.h

@@ -53,6 +53,10 @@ enum TBasicType {
     EbtUint,
     EbtUint,
     EbtInt64,
     EbtInt64,
     EbtUint64,
     EbtUint64,
+#ifdef AMD_EXTENSIONS
+    EbtInt16,
+    EbtUint16,
+#endif
     EbtBool,
     EbtBool,
     EbtAtomicUint,
     EbtAtomicUint,
     EbtSampler,
     EbtSampler,
@@ -203,6 +207,9 @@ enum TBuiltInVariable {
     EbvBaryCoordPullModel,
     EbvBaryCoordPullModel,
 #endif
 #endif
 
 
+    EbvViewIndex,
+    EbvDeviceIndex,
+
 #ifdef NV_EXTENSIONS
 #ifdef NV_EXTENSIONS
     EbvViewportMaskNV,
     EbvViewportMaskNV,
     EbvSecondaryPositionNV,
     EbvSecondaryPositionNV,
@@ -210,10 +217,22 @@ enum TBuiltInVariable {
     EbvPositionPerViewNV,
     EbvPositionPerViewNV,
     EbvViewportMaskPerViewNV,
     EbvViewportMaskPerViewNV,
 #endif 
 #endif 
+
     // HLSL built-ins that live only temporarily, until they get remapped
     // HLSL built-ins that live only temporarily, until they get remapped
     // to one of the above.
     // to one of the above.
     EbvFragDepthGreater,
     EbvFragDepthGreater,
     EbvFragDepthLesser,
     EbvFragDepthLesser,
+    EbvStencilRef,
+    EbvGsOutputStream,
+    EbvOutputPatch,
+    EbvInputPatch,
+
+    // structbuffer types
+    EbvAppendConsume, // no need to differentiate append and consume
+    EbvRWStructuredBuffer,
+    EbvStructuredBuffer,
+    EbvByteAddressBuffer,
+    EbvRWByteAddressBuffer,
 
 
     EbvLast
     EbvLast
 };
 };
@@ -323,6 +342,10 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
     case EbvBaryCoordSmoothSample:      return "BaryCoordSmoothSample";
     case EbvBaryCoordSmoothSample:      return "BaryCoordSmoothSample";
     case EbvBaryCoordPullModel:         return "BaryCoordPullModel";
     case EbvBaryCoordPullModel:         return "BaryCoordPullModel";
 #endif
 #endif
+
+    case EbvViewIndex:                  return "ViewIndex";
+    case EbvDeviceIndex:                return "DeviceIndex";
+
 #ifdef NV_EXTENSIONS
 #ifdef NV_EXTENSIONS
     case EbvViewportMaskNV:             return "ViewportMaskNV";
     case EbvViewportMaskNV:             return "ViewportMaskNV";
     case EbvSecondaryPositionNV:        return "SecondaryPositionNV";
     case EbvSecondaryPositionNV:        return "SecondaryPositionNV";

+ 177 - 170
src/libraries/glslang/glslang/Include/Types.h

@@ -43,6 +43,8 @@
 #include "../Public/ShaderLang.h"
 #include "../Public/ShaderLang.h"
 #include "arrays.h"
 #include "arrays.h"
 
 
+#include <algorithm>
+
 namespace glslang {
 namespace glslang {
 
 
 const int GlslangMaxTypeLength = 200;  // TODO: need to print block/struct one member per line, so this can stay bounded
 const int GlslangMaxTypeLength = 200;  // TODO: need to print block/struct one member per line, so this can stay bounded
@@ -396,11 +398,13 @@ public:
         invariant = false;
         invariant = false;
         noContraction = false;
         noContraction = false;
         makeTemporary();
         makeTemporary();
+        declaredBuiltIn = EbvNone;
     }
     }
 
 
     // drop qualifiers that don't belong in a temporary variable
     // drop qualifiers that don't belong in a temporary variable
     void makeTemporary()
     void makeTemporary()
     {
     {
+        semanticName = nullptr;
         storage = EvqTemporary;
         storage = EvqTemporary;
         builtIn = EbvNone;
         builtIn = EbvNone;
         clearInterstage();
         clearInterstage();
@@ -449,8 +453,10 @@ public:
         specConstant = false;
         specConstant = false;
     }
     }
 
 
+    const char*         semanticName;
     TStorageQualifier   storage   : 6;
     TStorageQualifier   storage   : 6;
     TBuiltInVariable    builtIn   : 8;
     TBuiltInVariable    builtIn   : 8;
+    TBuiltInVariable    declaredBuiltIn : 8;
     TPrecisionQualifier precision : 3;
     TPrecisionQualifier precision : 3;
     bool invariant    : 1; // require canonical treatment for cross-shader invariance
     bool invariant    : 1; // require canonical treatment for cross-shader invariance
     bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects
     bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects
@@ -1302,6 +1308,7 @@ public:
 
 
     virtual TBasicType getBasicType() const { return basicType; }
     virtual TBasicType getBasicType() const { return basicType; }
     virtual const TSampler& getSampler() const { return sampler; }
     virtual const TSampler& getSampler() const { return sampler; }
+    virtual TSampler& getSampler() { return sampler; }
 
 
     virtual       TQualifier& getQualifier()       { return qualifier; }
     virtual       TQualifier& getQualifier()       { return qualifier; }
     virtual const TQualifier& getQualifier() const { return qualifier; }
     virtual const TQualifier& getQualifier() const { return qualifier; }
@@ -1378,127 +1385,84 @@ public:
         return !isPerVertexAndBuiltIn(language);
         return !isPerVertexAndBuiltIn(language);
     }
     }
     
     
+    // return true if this type contains any subtype which satisfies the given predicate.
+    template <typename P> 
+    bool contains(P predicate) const
+    {
+        if (predicate(this))
+            return true;
+
+        const auto hasa = [predicate](const TTypeLoc& tl) { return tl.type->contains(predicate); };
+
+        return structure && std::any_of(structure->begin(), structure->end(), hasa);
+    }
+
     // Recursively checks if the type contains the given basic type
     // Recursively checks if the type contains the given basic type
     virtual bool containsBasicType(TBasicType checkType) const
     virtual bool containsBasicType(TBasicType checkType) const
     {
     {
-        if (basicType == checkType)
-            return true;
-        if (! structure)
-            return false;
-        for (unsigned int i = 0; i < structure->size(); ++i) {
-            if ((*structure)[i].type->containsBasicType(checkType))
-                return true;
-        }
-        return false;
+        return contains([checkType](const TType* t) { return t->basicType == checkType; } );
     }
     }
 
 
     // Recursively check the structure for any arrays, needed for some error checks
     // Recursively check the structure for any arrays, needed for some error checks
     virtual bool containsArray() const
     virtual bool containsArray() const
     {
     {
-        if (isArray())
-            return true;
-        if (structure == nullptr)
-            return false;
-        for (unsigned int i = 0; i < structure->size(); ++i) {
-            if ((*structure)[i].type->containsArray())
-                return true;
-        }
-        return false;
+        return contains([](const TType* t) { return t->isArray(); } );
     }
     }
 
 
     // Check the structure for any structures, needed for some error checks
     // Check the structure for any structures, needed for some error checks
     virtual bool containsStructure() const
     virtual bool containsStructure() const
     {
     {
-        if (structure == nullptr)
-            return false;
-        for (unsigned int i = 0; i < structure->size(); ++i) {
-            if ((*structure)[i].type->structure)
-                return true;
-        }
-        return false;
+        return contains([this](const TType* t) { return t != this && t->isStruct(); } );
     }
     }
 
 
     // Recursively check the structure for any implicitly-sized arrays, needed for triggering a copyUp().
     // Recursively check the structure for any implicitly-sized arrays, needed for triggering a copyUp().
     virtual bool containsImplicitlySizedArray() const
     virtual bool containsImplicitlySizedArray() const
     {
     {
-        if (isImplicitlySizedArray())
-            return true;
-        if (structure == nullptr)
-            return false;
-        for (unsigned int i = 0; i < structure->size(); ++i) {
-            if ((*structure)[i].type->containsImplicitlySizedArray())
-                return true;
-        }
-        return false;
+        return contains([](const TType* t) { return t->isImplicitlySizedArray(); } );
     }
     }
 
 
     virtual bool containsOpaque() const
     virtual bool containsOpaque() const
     {
     {
-        if (isOpaque())
-            return true;
-        if (! structure)
-            return false;
-        for (unsigned int i = 0; i < structure->size(); ++i) {
-            if ((*structure)[i].type->containsOpaque())
-                return true;
-        }
-        return false;
+        return contains([](const TType* t) { return t->isOpaque(); } );
     }
     }
 
 
     // Recursively checks if the type contains an interstage IO builtin
     // Recursively checks if the type contains an interstage IO builtin
     virtual bool containsBuiltInInterstageIO(EShLanguage language) const
     virtual bool containsBuiltInInterstageIO(EShLanguage language) const
     {
     {
-        if (isBuiltInInterstageIO(language))
-            return true;
-
-        if (! structure)
-            return false;
-        for (unsigned int i = 0; i < structure->size(); ++i) {
-            if ((*structure)[i].type->containsBuiltInInterstageIO(language))
-                return true;
-        }
-        return false;
+        return contains([language](const TType* t) { return t->isBuiltInInterstageIO(language); } );
     }
     }
 
 
     virtual bool containsNonOpaque() const
     virtual bool containsNonOpaque() const
     {
     {
-        // list all non-opaque types
-        switch (basicType) {
-        case EbtVoid:
-        case EbtFloat:
-        case EbtDouble:
+        const auto nonOpaque = [](const TType* t) {
+            switch (t->basicType) {
+            case EbtVoid:
+            case EbtFloat:
+            case EbtDouble:
+#ifdef AMD_EXTENSIONS
+            case EbtFloat16:
+#endif
+            case EbtInt:
+            case EbtUint:
+            case EbtInt64:
+            case EbtUint64:
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
-        case EbtFloat16:
+            case EbtInt16:
+            case EbtUint16:
 #endif
 #endif
-        case EbtInt:
-        case EbtUint:
-        case EbtInt64:
-        case EbtUint64:
-        case EbtBool:
+            case EbtBool:
             return true;
             return true;
-        default:
-            break;
-        }
-        if (! structure)
+            default:
             return false;
             return false;
-        for (unsigned int i = 0; i < structure->size(); ++i) {
-            if ((*structure)[i].type->containsNonOpaque())
-                return true;
-        }
-        return false;
+            }
+        };
+
+        return contains(nonOpaque);
     }
     }
 
 
     virtual bool containsSpecializationSize() const
     virtual bool containsSpecializationSize() const
     {
     {
-        if (isArray() && arraySizes->containsNode())
-            return true;
-        if (! structure)
-            return false;
-        for (unsigned int i = 0; i < structure->size(); ++i) {
-            if ((*structure)[i].type->containsSpecializationSize())
-                return true;
-        }
-        return false;
+        return contains([](const TType* t) { return t->isArray() && t->arraySizes->isOuterSpecialization(); } );
     }
     }
 
 
     // Array editing methods.  Array descriptors can be shared across
     // Array editing methods.  Array descriptors can be shared across
@@ -1569,6 +1533,10 @@ public:
         case EbtUint:              return "uint";
         case EbtUint:              return "uint";
         case EbtInt64:             return "int64_t";
         case EbtInt64:             return "int64_t";
         case EbtUint64:            return "uint64_t";
         case EbtUint64:            return "uint64_t";
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:             return "int16_t";
+        case EbtUint16:            return "uint16_t";
+#endif
         case EbtBool:              return "bool";
         case EbtBool:              return "bool";
         case EbtAtomicUint:        return "atomic_uint";
         case EbtAtomicUint:        return "atomic_uint";
         case EbtSampler:           return "sampler/image";
         case EbtSampler:           return "sampler/image";
@@ -1580,10 +1548,11 @@ public:
 
 
     TString getCompleteString() const
     TString getCompleteString() const
     {
     {
-        const int maxSize = GlslangMaxTypeLength;
-        char buf[maxSize];
-        char* p = &buf[0];
-        char* end = &buf[maxSize];
+        TString typeString;
+
+        const auto appendStr  = [&](const char* s)  { typeString.append(s); };
+        const auto appendUint = [&](unsigned int u) { typeString.append(std::to_string(u).c_str()); };
+        const auto appendInt  = [&](int i)          { typeString.append(std::to_string(i).c_str()); };
 
 
         if (qualifier.hasLayout()) {
         if (qualifier.hasLayout()) {
             // To reduce noise, skip this if the only layout is an xfb_buffer
             // To reduce noise, skip this if the only layout is an xfb_buffer
@@ -1591,137 +1560,175 @@ public:
             TQualifier noXfbBuffer = qualifier;
             TQualifier noXfbBuffer = qualifier;
             noXfbBuffer.layoutXfbBuffer = TQualifier::layoutXfbBufferEnd;
             noXfbBuffer.layoutXfbBuffer = TQualifier::layoutXfbBufferEnd;
             if (noXfbBuffer.hasLayout()) {
             if (noXfbBuffer.hasLayout()) {
-                p += snprintf(p, end - p, "layout(");
+                appendStr("layout(");
                 if (qualifier.hasAnyLocation()) {
                 if (qualifier.hasAnyLocation()) {
-                    p += snprintf(p, end - p, "location=%d ", qualifier.layoutLocation);
-                    if (qualifier.hasComponent())
-                        p += snprintf(p, end - p, "component=%d ", qualifier.layoutComponent);
-                    if (qualifier.hasIndex())
-                        p += snprintf(p, end - p, "index=%d ", qualifier.layoutIndex);
+                    appendStr(" location=");
+                    appendUint(qualifier.layoutLocation);
+                    if (qualifier.hasComponent()) {
+                        appendStr(" component=");
+                        appendUint(qualifier.layoutComponent);
+                    }
+                    if (qualifier.hasIndex()) {
+                        appendStr(" index=");
+                        appendUint(qualifier.layoutIndex);
+                    }
+                }
+                if (qualifier.hasSet()) {
+                    appendStr(" set=");
+                    appendUint(qualifier.layoutSet);
+                }
+                if (qualifier.hasBinding()) {
+                    appendStr(" binding=");
+                    appendUint(qualifier.layoutBinding);
+                }
+                if (qualifier.hasStream()) {
+                    appendStr(" stream=");
+                    appendUint(qualifier.layoutStream);
+                }
+                if (qualifier.hasMatrix()) {
+                    appendStr(" ");
+                    appendStr(TQualifier::getLayoutMatrixString(qualifier.layoutMatrix));
+                }
+                if (qualifier.hasPacking()) {
+                    appendStr(" ");
+                    appendStr(TQualifier::getLayoutPackingString(qualifier.layoutPacking));
+                }
+                if (qualifier.hasOffset()) {
+                    appendStr(" offset=");
+                    appendInt(qualifier.layoutOffset);
+                }
+                if (qualifier.hasAlign()) {
+                    appendStr(" align=");
+                    appendInt(qualifier.layoutAlign);
+                }
+                if (qualifier.hasFormat()) {
+                    appendStr(" ");
+                    appendStr(TQualifier::getLayoutFormatString(qualifier.layoutFormat));
+                }
+                if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset()) {
+                    appendStr(" xfb_buffer=");
+                    appendUint(qualifier.layoutXfbBuffer);
+                }
+                if (qualifier.hasXfbOffset()) {
+                    appendStr(" xfb_offset=");
+                    appendUint(qualifier.layoutXfbOffset);
+                }
+                if (qualifier.hasXfbStride()) {
+                    appendStr(" xfb_stride=");
+                    appendUint(qualifier.layoutXfbStride);
+                }
+                if (qualifier.hasAttachment()) {
+                    appendStr(" input_attachment_index=");
+                    appendUint(qualifier.layoutAttachment);
+                }
+                if (qualifier.hasSpecConstantId()) {
+                    appendStr(" constant_id=");
+                    appendUint(qualifier.layoutSpecConstantId);
                 }
                 }
-                if (qualifier.hasSet())
-                    p += snprintf(p, end - p, "set=%d ", qualifier.layoutSet);
-                if (qualifier.hasBinding())
-                    p += snprintf(p, end - p, "binding=%d ", qualifier.layoutBinding);
-                if (qualifier.hasStream())
-                    p += snprintf(p, end - p, "stream=%d ", qualifier.layoutStream);
-                if (qualifier.hasMatrix())
-                    p += snprintf(p, end - p, "%s ", TQualifier::getLayoutMatrixString(qualifier.layoutMatrix));
-                if (qualifier.hasPacking())
-                    p += snprintf(p, end - p, "%s ", TQualifier::getLayoutPackingString(qualifier.layoutPacking));
-                if (qualifier.hasOffset())
-                    p += snprintf(p, end - p, "offset=%d ", qualifier.layoutOffset);
-                if (qualifier.hasAlign())
-                    p += snprintf(p, end - p, "align=%d ", qualifier.layoutAlign);
-                if (qualifier.hasFormat())
-                    p += snprintf(p, end - p, "%s ", TQualifier::getLayoutFormatString(qualifier.layoutFormat));
-                if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset())
-                    p += snprintf(p, end - p, "xfb_buffer=%d ", qualifier.layoutXfbBuffer);
-                if (qualifier.hasXfbOffset())
-                    p += snprintf(p, end - p, "xfb_offset=%d ", qualifier.layoutXfbOffset);
-                if (qualifier.hasXfbStride())
-                    p += snprintf(p, end - p, "xfb_stride=%d ", qualifier.layoutXfbStride);
-                if (qualifier.hasAttachment())
-                    p += snprintf(p, end - p, "input_attachment_index=%d ", qualifier.layoutAttachment);
-                if (qualifier.hasSpecConstantId())
-                    p += snprintf(p, end - p, "constant_id=%d ", qualifier.layoutSpecConstantId);
                 if (qualifier.layoutPushConstant)
                 if (qualifier.layoutPushConstant)
-                    p += snprintf(p, end - p, "push_constant ");
+                    appendStr(" push_constant");
 
 
 #ifdef NV_EXTENSIONS
 #ifdef NV_EXTENSIONS
                 if (qualifier.layoutPassthrough)
                 if (qualifier.layoutPassthrough)
-                    p += snprintf(p, end - p, "passthrough ");
+                    appendStr(" passthrough");
                 if (qualifier.layoutViewportRelative)
                 if (qualifier.layoutViewportRelative)
-                    p += snprintf(p, end - p, "layoutViewportRelative ");
-                if (qualifier.layoutSecondaryViewportRelativeOffset != -2048)
-                    p += snprintf(p, end - p, "layoutSecondaryViewportRelativeOffset=%d ", qualifier.layoutSecondaryViewportRelativeOffset);
+                    appendStr(" layoutViewportRelative");
+                if (qualifier.layoutSecondaryViewportRelativeOffset != -2048) {
+                    appendStr(" layoutSecondaryViewportRelativeOffset=");
+                    appendInt(qualifier.layoutSecondaryViewportRelativeOffset);
+                }
 #endif
 #endif
 
 
-                p += snprintf(p, end - p, ") ");
+                appendStr(")");
             }
             }
         }
         }
 
 
         if (qualifier.invariant)
         if (qualifier.invariant)
-            p += snprintf(p, end - p, "invariant ");
+            appendStr(" invariant");
         if (qualifier.noContraction)
         if (qualifier.noContraction)
-            p += snprintf(p, end - p, "noContraction ");
+            appendStr(" noContraction");
         if (qualifier.centroid)
         if (qualifier.centroid)
-            p += snprintf(p, end - p, "centroid ");
+            appendStr(" centroid");
         if (qualifier.smooth)
         if (qualifier.smooth)
-            p += snprintf(p, end - p, "smooth ");
+            appendStr(" smooth");
         if (qualifier.flat)
         if (qualifier.flat)
-            p += snprintf(p, end - p, "flat ");
+            appendStr(" flat");
         if (qualifier.nopersp)
         if (qualifier.nopersp)
-            p += snprintf(p, end - p, "noperspective ");
+            appendStr(" noperspective");
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
         if (qualifier.explicitInterp)
         if (qualifier.explicitInterp)
-            p += snprintf(p, end - p, "__explicitInterpAMD ");
+            appendStr(" __explicitInterpAMD");
 #endif
 #endif
         if (qualifier.patch)
         if (qualifier.patch)
-            p += snprintf(p, end - p, "patch ");
+            appendStr(" patch");
         if (qualifier.sample)
         if (qualifier.sample)
-            p += snprintf(p, end - p, "sample ");
+            appendStr(" sample");
         if (qualifier.coherent)
         if (qualifier.coherent)
-            p += snprintf(p, end - p, "coherent ");
+            appendStr(" coherent");
         if (qualifier.volatil)
         if (qualifier.volatil)
-            p += snprintf(p, end - p, "volatile ");
+            appendStr(" volatile");
         if (qualifier.restrict)
         if (qualifier.restrict)
-            p += snprintf(p, end - p, "restrict ");
+            appendStr(" restrict");
         if (qualifier.readonly)
         if (qualifier.readonly)
-            p += snprintf(p, end - p, "readonly ");
+            appendStr(" readonly");
         if (qualifier.writeonly)
         if (qualifier.writeonly)
-            p += snprintf(p, end - p, "writeonly ");
+            appendStr(" writeonly");
         if (qualifier.specConstant)
         if (qualifier.specConstant)
-            p += snprintf(p, end - p, "specialization-constant ");
-        p += snprintf(p, end - p, "%s ", getStorageQualifierString());
+            appendStr(" specialization-constant");
+        appendStr(" ");
+        appendStr(getStorageQualifierString());
         if (isArray()) {
         if (isArray()) {
             for(int i = 0; i < (int)arraySizes->getNumDims(); ++i) {
             for(int i = 0; i < (int)arraySizes->getNumDims(); ++i) {
                 int size = arraySizes->getDimSize(i);
                 int size = arraySizes->getDimSize(i);
                 if (size == 0)
                 if (size == 0)
-                    p += snprintf(p, end - p, "implicitly-sized array of ");
-                else
-                    p += snprintf(p, end - p, "%d-element array of ", arraySizes->getDimSize(i));
+                    appendStr(" implicitly-sized array of");
+                else {
+                    appendStr(" ");
+                    appendInt(arraySizes->getDimSize(i));
+                    appendStr("-element array of");
+                }
             }
             }
         }
         }
-        if (qualifier.precision != EpqNone)
-            p += snprintf(p, end - p, "%s ", getPrecisionQualifierString());
-        if (isMatrix())
-            p += snprintf(p, end - p, "%dX%d matrix of ", matrixCols, matrixRows);
-        else if (isVector())
-            p += snprintf(p, end - p, "%d-component vector of ", vectorSize);
+        if (qualifier.precision != EpqNone) {
+            appendStr(" ");
+            appendStr(getPrecisionQualifierString());
+        }
+        if (isMatrix()) {
+            appendStr(" ");
+            appendInt(matrixCols);
+            appendStr("X");
+            appendInt(matrixRows);
+            appendStr(" matrix of");
+        } else if (isVector()) {
+            appendStr(" ");
+            appendInt(vectorSize);
+            appendStr("-component vector of");
+        }
 
 
-        *p = 0;
-        TString s(buf);
-        s.append(getBasicTypeString());
+        appendStr(" ");
+        typeString.append(getBasicTypeString());
 
 
         if (qualifier.builtIn != EbvNone) {
         if (qualifier.builtIn != EbvNone) {
-            s.append(" ");
-            s.append(getBuiltInVariableString());
+            appendStr(" ");
+            appendStr(getBuiltInVariableString());
         }
         }
 
 
         // Add struct/block members
         // Add struct/block members
         if (structure) {
         if (structure) {
-            s.append("{");
+            appendStr("{");
             for (size_t i = 0; i < structure->size(); ++i) {
             for (size_t i = 0; i < structure->size(); ++i) {
-                if (s.size() > 3 * GlslangMaxTypeLength) {
-                    // If we are getting too long, cut it short,
-                    // just need to draw the line somewhere, as there is no limit to
-                    // how large a struct/block type can get.
-                    s.append("...");
-                    break;
-                }
                 if (! (*structure)[i].type->hiddenMember()) {
                 if (! (*structure)[i].type->hiddenMember()) {
-                    s.append((*structure)[i].type->getCompleteString());
-                    s.append(" ");
-                    s.append((*structure)[i].type->getFieldName());
+                    typeString.append((*structure)[i].type->getCompleteString());
+                    typeString.append(" ");
+                    typeString.append((*structure)[i].type->getFieldName());
                     if (i < structure->size() - 1)
                     if (i < structure->size() - 1)
-                        s.append(", ");
+                        appendStr(", ");
                 }
                 }
             }
             }
-            s.append("}");
+            appendStr("}");
         }
         }
 
 
-        return s;
+        return typeString;
     }
     }
 
 
     TString getBasicTypeString() const
     TString getBasicTypeString() const
@@ -1759,7 +1766,7 @@ public:
     }
     }
 
 
     // append this type's mangled name to the passed in 'name'
     // append this type's mangled name to the passed in 'name'
-    void appendMangledName(TString& name)
+    void appendMangledName(TString& name) const
     {
     {
         buildMangledName(name);
         buildMangledName(name);
         name += ';' ;
         name += ';' ;
@@ -1883,7 +1890,7 @@ protected:
     }
     }
 
 
 
 
-    void buildMangledName(TString&);
+    void buildMangledName(TString&) const;
 
 
     TBasicType basicType : 8;
     TBasicType basicType : 8;
     int vectorSize       : 4;  // 1 means either scalar or 1-component vector; see vector1 to disambiguate.
     int vectorSize       : 4;  // 1 means either scalar or 1-component vector; see vector1 to disambiguate.

+ 14 - 12
src/libraries/glslang/glslang/Include/arrays.h

@@ -264,6 +264,20 @@ struct TArraySizes {
 
 
         return false;
         return false;
     }
     }
+    bool isInnerSpecialization() const
+    {
+        for (int d = 1; d < sizes.size(); ++d) {
+            if (sizes.getDimNode(d) != nullptr)
+                return true;
+        }
+
+        return false;
+    }
+    bool isOuterSpecialization()
+    {
+        return sizes.getDimNode(0) != nullptr;
+    }
+
     bool isImplicit() const { return getOuterSize() == UnsizedArraySize || isInnerImplicit(); }
     bool isImplicit() const { return getOuterSize() == UnsizedArraySize || isInnerImplicit(); }
     void addOuterSizes(const TArraySizes& s) { sizes.push_front(s.sizes); }
     void addOuterSizes(const TArraySizes& s) { sizes.push_front(s.sizes); }
     void dereference() { sizes.pop_front(); }
     void dereference() { sizes.pop_front(); }
@@ -288,18 +302,6 @@ struct TArraySizes {
         return true;
         return true;
     }
     }
 
 
-    // Returns true if any of the dimensions of the array is sized with a node
-    // instead of a front-end compile-time constant.
-    bool containsNode()
-    {
-        for (int d = 0; d < sizes.size(); ++d) {
-            if (sizes.getDimNode(d) != nullptr)
-                return true;
-        }
-
-        return false;
-    }
-
     bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; }
     bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; }
     bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; }
     bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; }
 
 

+ 158 - 5
src/libraries/glslang/glslang/Include/intermediate.h

@@ -141,6 +141,42 @@ enum TOperator {
     EOpConvFloat16ToDouble,
     EOpConvFloat16ToDouble,
     EOpConvFloat16ToInt64,
     EOpConvFloat16ToInt64,
     EOpConvFloat16ToUint64,
     EOpConvFloat16ToUint64,
+
+    EOpConvBoolToInt16,
+    EOpConvIntToInt16,
+    EOpConvUintToInt16,
+    EOpConvFloatToInt16,
+    EOpConvDoubleToInt16,
+    EOpConvFloat16ToInt16,
+    EOpConvInt64ToInt16,
+    EOpConvUint64ToInt16,
+    EOpConvUint16ToInt16,
+    EOpConvInt16ToBool,
+    EOpConvInt16ToInt,
+    EOpConvInt16ToUint,
+    EOpConvInt16ToFloat,
+    EOpConvInt16ToDouble,
+    EOpConvInt16ToFloat16,
+    EOpConvInt16ToInt64,
+    EOpConvInt16ToUint64,
+
+    EOpConvBoolToUint16,
+    EOpConvIntToUint16,
+    EOpConvUintToUint16,
+    EOpConvFloatToUint16,
+    EOpConvDoubleToUint16,
+    EOpConvFloat16ToUint16,
+    EOpConvInt64ToUint16,
+    EOpConvUint64ToUint16,
+    EOpConvInt16ToUint16,
+    EOpConvUint16ToBool,
+    EOpConvUint16ToInt,
+    EOpConvUint16ToUint,
+    EOpConvUint16ToFloat,
+    EOpConvUint16ToDouble,
+    EOpConvUint16ToFloat16,
+    EOpConvUint16ToInt64,
+    EOpConvUint16ToUint64,
 #endif
 #endif
 
 
     //
     //
@@ -183,6 +219,7 @@ enum TOperator {
     EOpVectorSwizzle,
     EOpVectorSwizzle,
 
 
     EOpMethod,
     EOpMethod,
+    EOpScoping,
 
 
     //
     //
     // Built-in functions mapped to operators
     // Built-in functions mapped to operators
@@ -243,6 +280,12 @@ enum TOperator {
     EOpDoubleBitsToUint64,
     EOpDoubleBitsToUint64,
     EOpInt64BitsToDouble,
     EOpInt64BitsToDouble,
     EOpUint64BitsToDouble,
     EOpUint64BitsToDouble,
+#ifdef AMD_EXTENSIONS
+    EOpFloat16BitsToInt16,
+    EOpFloat16BitsToUint16,
+    EOpInt16BitsToFloat16,
+    EOpUint16BitsToFloat16,
+#endif
     EOpPackSnorm2x16,
     EOpPackSnorm2x16,
     EOpUnpackSnorm2x16,
     EOpUnpackSnorm2x16,
     EOpPackUnorm2x16,
     EOpPackUnorm2x16,
@@ -262,6 +305,14 @@ enum TOperator {
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
     EOpPackFloat2x16,
     EOpPackFloat2x16,
     EOpUnpackFloat2x16,
     EOpUnpackFloat2x16,
+    EOpPackInt2x16,
+    EOpUnpackInt2x16,
+    EOpPackUint2x16,
+    EOpUnpackUint2x16,
+    EOpPackInt4x16,
+    EOpUnpackInt4x16,
+    EOpPackUint4x16,
+    EOpUnpackUint4x16,
 #endif
 #endif
 
 
     EOpLength,
     EOpLength,
@@ -393,15 +444,27 @@ enum TOperator {
     EOpConstructUint,
     EOpConstructUint,
     EOpConstructInt64,
     EOpConstructInt64,
     EOpConstructUint64,
     EOpConstructUint64,
+#ifdef AMD_EXTENSIONS
+    EOpConstructInt16,
+    EOpConstructUint16,
+#endif
     EOpConstructBool,
     EOpConstructBool,
     EOpConstructFloat,
     EOpConstructFloat,
     EOpConstructDouble,
     EOpConstructDouble,
+#ifdef AMD_EXTENSIONS
+    EOpConstructFloat16,
+#endif
     EOpConstructVec2,
     EOpConstructVec2,
     EOpConstructVec3,
     EOpConstructVec3,
     EOpConstructVec4,
     EOpConstructVec4,
     EOpConstructDVec2,
     EOpConstructDVec2,
     EOpConstructDVec3,
     EOpConstructDVec3,
     EOpConstructDVec4,
     EOpConstructDVec4,
+#ifdef AMD_EXTENSIONS
+    EOpConstructF16Vec2,
+    EOpConstructF16Vec3,
+    EOpConstructF16Vec4,
+#endif
     EOpConstructBVec2,
     EOpConstructBVec2,
     EOpConstructBVec3,
     EOpConstructBVec3,
     EOpConstructBVec4,
     EOpConstructBVec4,
@@ -417,6 +480,14 @@ enum TOperator {
     EOpConstructU64Vec2,
     EOpConstructU64Vec2,
     EOpConstructU64Vec3,
     EOpConstructU64Vec3,
     EOpConstructU64Vec4,
     EOpConstructU64Vec4,
+#ifdef AMD_EXTENSIONS
+    EOpConstructI16Vec2,
+    EOpConstructI16Vec3,
+    EOpConstructI16Vec4,
+    EOpConstructU16Vec2,
+    EOpConstructU16Vec3,
+    EOpConstructU16Vec4,
+#endif
     EOpConstructMat2x2,
     EOpConstructMat2x2,
     EOpConstructMat2x3,
     EOpConstructMat2x3,
     EOpConstructMat2x4,
     EOpConstructMat2x4,
@@ -435,11 +506,34 @@ enum TOperator {
     EOpConstructDMat4x2,
     EOpConstructDMat4x2,
     EOpConstructDMat4x3,
     EOpConstructDMat4x3,
     EOpConstructDMat4x4,
     EOpConstructDMat4x4,
+    EOpConstructIMat2x2,
+    EOpConstructIMat2x3,
+    EOpConstructIMat2x4,
+    EOpConstructIMat3x2,
+    EOpConstructIMat3x3,
+    EOpConstructIMat3x4,
+    EOpConstructIMat4x2,
+    EOpConstructIMat4x3,
+    EOpConstructIMat4x4,
+    EOpConstructUMat2x2,
+    EOpConstructUMat2x3,
+    EOpConstructUMat2x4,
+    EOpConstructUMat3x2,
+    EOpConstructUMat3x3,
+    EOpConstructUMat3x4,
+    EOpConstructUMat4x2,
+    EOpConstructUMat4x3,
+    EOpConstructUMat4x4,
+    EOpConstructBMat2x2,
+    EOpConstructBMat2x3,
+    EOpConstructBMat2x4,
+    EOpConstructBMat3x2,
+    EOpConstructBMat3x3,
+    EOpConstructBMat3x4,
+    EOpConstructBMat4x2,
+    EOpConstructBMat4x3,
+    EOpConstructBMat4x4,
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
-    EOpConstructFloat16,
-    EOpConstructF16Vec2,
-    EOpConstructF16Vec3,
-    EOpConstructF16Vec4,
     EOpConstructF16Mat2x2,
     EOpConstructF16Mat2x2,
     EOpConstructF16Mat2x3,
     EOpConstructF16Mat2x3,
     EOpConstructF16Mat2x4,
     EOpConstructF16Mat2x4,
@@ -539,6 +633,11 @@ enum TOperator {
     EOpTextureOffsetClamp,
     EOpTextureOffsetClamp,
     EOpTextureGradClamp,
     EOpTextureGradClamp,
     EOpTextureGradOffsetClamp,
     EOpTextureGradOffsetClamp,
+#ifdef AMD_EXTENSIONS
+    EOpTextureGatherLod,
+    EOpTextureGatherLodOffset,
+    EOpTextureGatherLodOffsets,
+#endif
 
 
     EOpSparseTextureGuardBegin,
     EOpSparseTextureGuardBegin,
 
 
@@ -558,6 +657,11 @@ enum TOperator {
     EOpSparseTextureOffsetClamp,
     EOpSparseTextureOffsetClamp,
     EOpSparseTextureGradClamp,
     EOpSparseTextureGradClamp,
     EOpSparseTextureGradOffsetClamp,
     EOpSparseTextureGradOffsetClamp,
+#ifdef AMD_EXTENSIONS
+    EOpSparseTextureGatherLod,
+    EOpSparseTextureGatherLodOffset,
+    EOpSparseTextureGatherLodOffsets,
+#endif
 
 
     EOpSparseTextureGuardEnd,
     EOpSparseTextureGuardEnd,
     EOpSamplingGuardEnd,
     EOpSamplingGuardEnd,
@@ -624,6 +728,19 @@ enum TOperator {
     EOpMethodCalculateLevelOfDetail,     // ...
     EOpMethodCalculateLevelOfDetail,     // ...
     EOpMethodCalculateLevelOfDetailUnclamped,     // ...
     EOpMethodCalculateLevelOfDetailUnclamped,     // ...
 
 
+    // Load already defined above for textures
+    EOpMethodLoad2,                      // Structure buffer object methods.  These are translated to existing
+    EOpMethodLoad3,                      // AST methods, and exist to represent HLSL semantics until that
+    EOpMethodLoad4,                      // translation is performed.  See HlslParseContext::decomposeSampleMethods().
+    EOpMethodStore,                      // ...
+    EOpMethodStore2,                     // ...
+    EOpMethodStore3,                     // ...
+    EOpMethodStore4,                     // ...
+    EOpMethodIncrementCounter,           // ...
+    EOpMethodDecrementCounter,           // ...
+    // EOpMethodAppend is defined for geo shaders below
+    EOpMethodConsume,
+
     // SM5 texture methods
     // SM5 texture methods
     EOpMethodGatherRed,                  // These are covered under the above EOpMethodSample comment about
     EOpMethodGatherRed,                  // These are covered under the above EOpMethodSample comment about
     EOpMethodGatherGreen,                // translation to existing AST opcodes.  They exist temporarily
     EOpMethodGatherGreen,                // translation to existing AST opcodes.  They exist temporarily
@@ -744,6 +861,15 @@ protected:
     TType type;
     TType type;
 };
 };
 
 
+//
+// Loop control hints
+//
+enum TLoopControl {
+    ELoopControlNone,
+    ELoopControlUnroll,
+    ELoopControlDontUnroll,
+};
+
 //
 //
 // Handle for, do-while, and while loops.
 // Handle for, do-while, and while loops.
 //
 //
@@ -753,17 +879,25 @@ public:
         body(aBody),
         body(aBody),
         test(aTest),
         test(aTest),
         terminal(aTerminal),
         terminal(aTerminal),
-        first(testFirst) { }
+        first(testFirst),
+        control(ELoopControlNone)
+    { }
+
     virtual void traverse(TIntermTraverser*);
     virtual void traverse(TIntermTraverser*);
     TIntermNode*  getBody() const { return body; }
     TIntermNode*  getBody() const { return body; }
     TIntermTyped* getTest() const { return test; }
     TIntermTyped* getTest() const { return test; }
     TIntermTyped* getTerminal() const { return terminal; }
     TIntermTyped* getTerminal() const { return terminal; }
     bool testFirst() const { return first; }
     bool testFirst() const { return first; }
+
+    void setLoopControl(TLoopControl c) { control = c; }
+    TLoopControl getLoopControl() const { return control; }
+
 protected:
 protected:
     TIntermNode* body;       // code to loop over
     TIntermNode* body;       // code to loop over
     TIntermTyped* test;      // exit condition associated with loop, could be 0 for 'for' loops
     TIntermTyped* test;      // exit condition associated with loop, could be 0 for 'for' loops
     TIntermTyped* terminal;  // exists for for-loops
     TIntermTyped* terminal;  // exists for for-loops
     bool first;              // true for while and for, not for do-while
     bool first;              // true for while and for, not for do-while
+    TLoopControl control;    // loop control hint
 };
 };
 
 
 //
 //
@@ -1017,6 +1151,25 @@ public:
             cracked.gather = true;
             cracked.gather = true;
             cracked.offsets = true;
             cracked.offsets = true;
             break;
             break;
+#ifdef AMD_EXTENSIONS
+        case EOpTextureGatherLod:
+        case EOpSparseTextureGatherLod:
+            cracked.gather = true;
+            cracked.lod    = true;
+            break;
+        case EOpTextureGatherLodOffset:
+        case EOpSparseTextureGatherLodOffset:
+            cracked.gather = true;
+            cracked.offset = true;
+            cracked.lod    = true;
+            break;
+        case EOpTextureGatherLodOffsets:
+        case EOpSparseTextureGatherLodOffsets:
+            cracked.gather  = true;
+            cracked.offsets = true;
+            cracked.lod     = true;
+            break;
+#endif
         case EOpSubpassLoad:
         case EOpSubpassLoad:
         case EOpSubpassLoadMS:
         case EOpSubpassLoadMS:
             cracked.subpass = true;
             cracked.subpass = true;

+ 2 - 2
src/libraries/glslang/glslang/Include/revision.h

@@ -2,5 +2,5 @@
 // For the version, it uses the latest git tag followed by the number of commits.
 // For the version, it uses the latest git tag followed by the number of commits.
 // For the date, it uses the current date (when then script is run).
 // For the date, it uses the current date (when then script is run).
 
 
-#define GLSLANG_REVISION "Overload400-PrecQual.1843"
-#define GLSLANG_DATE "18-Feb-2017"
+#define GLSLANG_REVISION "Overload400-PrecQual.2000"
+#define GLSLANG_DATE "12-Apr-2017"

+ 36 - 2
src/libraries/glslang/glslang/MachineIndependent/Constant.cpp

@@ -193,7 +193,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
 
 
             case EbtUint:
             case EbtUint:
                 if (rightUnionArray[i] == 0) {
                 if (rightUnionArray[i] == 0) {
-                    newConstArray[i].setUConst(0xFFFFFFFF);
+                    newConstArray[i].setUConst(0xFFFFFFFFu);
                 } else
                 } else
                     newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
                     newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
                 break;
                 break;
@@ -213,6 +213,23 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
                 } else
                 } else
                     newConstArray[i].setU64Const(leftUnionArray[i].getU64Const() / rightUnionArray[i].getU64Const());
                     newConstArray[i].setU64Const(leftUnionArray[i].getU64Const() / rightUnionArray[i].getU64Const());
                 break;
                 break;
+#ifdef AMD_EXTENSIONS
+            case EbtInt16:
+                if (rightUnionArray[i] == 0)
+                    newConstArray[i].setIConst(0x7FFF);
+                else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == (int)0x8000)
+                    newConstArray[i].setIConst(0x8000);
+                else
+                    newConstArray[i].setIConst(leftUnionArray[i].getIConst() / rightUnionArray[i].getIConst());
+                break;
+
+            case EbtUint16:
+                if (rightUnionArray[i] == 0) {
+                    newConstArray[i].setUConst(0xFFFFu);
+                } else
+                    newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
+                break;
+#endif
             default:
             default:
                 return 0;
                 return 0;
             }
             }
@@ -457,10 +474,16 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
             case EbtFloat16:
             case EbtFloat16:
 #endif
 #endif
             case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
             case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
+#ifdef AMD_EXTENSIONS
+            case EbtInt16:
+#endif
             case EbtInt:   newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
             case EbtInt:   newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
+#ifdef AMD_EXTENSIONS
+            case EbtUint16:
+#endif
             case EbtUint:  newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst())));  break;
             case EbtUint:  newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst())));  break;
             case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break;
             case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break;
-            case EbtUint64: newConstArray[i].setU64Const(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getU64Const())));  break;
+            case EbtUint64: newConstArray[i].setU64Const(static_cast<unsigned long long>(-static_cast<long long>(unionArray[i].getU64Const())));  break;
             default:
             default:
                 return 0;
                 return 0;
             }
             }
@@ -610,6 +633,14 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
         case EOpUintBitsToFloat:
         case EOpUintBitsToFloat:
         case EOpDoubleBitsToInt64:
         case EOpDoubleBitsToInt64:
         case EOpDoubleBitsToUint64:
         case EOpDoubleBitsToUint64:
+        case EOpInt64BitsToDouble:
+        case EOpUint64BitsToDouble:
+#ifdef AMD_EXTENSIONS
+        case EOpFloat16BitsToInt16:
+        case EOpFloat16BitsToUint16:
+        case EOpInt16BitsToFloat16:
+        case EOpUint16BitsToFloat16:
+#endif
 
 
         default:
         default:
             return 0;
             return 0;
@@ -702,6 +733,9 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
 #endif
 #endif
                            children[0]->getAsTyped()->getBasicType() == EbtDouble;
                            children[0]->getAsTyped()->getBasicType() == EbtDouble;
     bool isSigned = children[0]->getAsTyped()->getBasicType() == EbtInt ||
     bool isSigned = children[0]->getAsTyped()->getBasicType() == EbtInt ||
+#ifdef AMD_EXTENSIONS
+                    children[0]->getAsTyped()->getBasicType() == EbtInt16 ||
+#endif
                     children[0]->getAsTyped()->getBasicType() == EbtInt64;
                     children[0]->getAsTyped()->getBasicType() == EbtInt64;
     bool isInt64 = children[0]->getAsTyped()->getBasicType() == EbtInt64 ||
     bool isInt64 = children[0]->getAsTyped()->getBasicType() == EbtInt64 ||
                    children[0]->getAsTyped()->getBasicType() == EbtUint64;
                    children[0]->getAsTyped()->getBasicType() == EbtUint64;

+ 417 - 32
src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp

@@ -103,6 +103,7 @@ TBuiltIns::~TBuiltIns()
 {
 {
 }
 }
 
 
+
 //
 //
 // Add all context-independent built-in functions and variables that are present
 // Add all context-independent built-in functions and variables that are present
 // for the given version and profile.  Share common ones across stages, otherwise
 // for the given version and profile.  Share common ones across stages, otherwise
@@ -2615,6 +2616,157 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
 
 
             "\n");
             "\n");
     }
     }
+
+    // GL_AMD_gpu_shader_int16
+    if (profile != EEsProfile && version >= 450) {
+        commonBuiltins.append(
+            "int16_t abs(int16_t);"
+            "i16vec2 abs(i16vec2);"
+            "i16vec3 abs(i16vec3);"
+            "i16vec4 abs(i16vec4);"
+
+            "int16_t sign(int16_t);"
+            "i16vec2 sign(i16vec2);"
+            "i16vec3 sign(i16vec3);"
+            "i16vec4 sign(i16vec4);"
+
+            "int16_t  min(int16_t,  int16_t);"
+            "i16vec2  min(i16vec2,  int16_t);"
+            "i16vec3  min(i16vec3,  int16_t);"
+            "i16vec4  min(i16vec4,  int16_t);"
+            "i16vec2  min(i16vec2,  i16vec2);"
+            "i16vec3  min(i16vec3,  i16vec3);"
+            "i16vec4  min(i16vec4,  i16vec4);"
+            "uint16_t min(uint16_t, uint16_t);"
+            "u16vec2  min(u16vec2,  uint16_t);"
+            "u16vec3  min(u16vec3,  uint16_t);"
+            "u16vec4  min(u16vec4,  uint16_t);"
+            "u16vec2  min(u16vec2,  u16vec2);"
+            "u16vec3  min(u16vec3,  u16vec3);"
+            "u16vec4  min(u16vec4,  u16vec4);"
+
+            "int16_t  max(int16_t,  int16_t);"
+            "i16vec2  max(i16vec2,  int16_t);"
+            "i16vec3  max(i16vec3,  int16_t);"
+            "i16vec4  max(i16vec4,  int16_t);"
+            "i16vec2  max(i16vec2,  i16vec2);"
+            "i16vec3  max(i16vec3,  i16vec3);"
+            "i16vec4  max(i16vec4,  i16vec4);"
+            "uint16_t max(uint16_t, uint16_t);"
+            "u16vec2  max(u16vec2,  uint16_t);"
+            "u16vec3  max(u16vec3,  uint16_t);"
+            "u16vec4  max(u16vec4,  uint16_t);"
+            "u16vec2  max(u16vec2,  u16vec2);"
+            "u16vec3  max(u16vec3,  u16vec3);"
+            "u16vec4  max(u16vec4,  u16vec4);"
+
+            "int16_t  clamp(int16_t,  int16_t,  int16_t);"
+            "i16vec2  clamp(i16vec2,  int16_t,  int16_t);"
+            "i16vec3  clamp(i16vec3,  int16_t,  int16_t);"
+            "i16vec4  clamp(i16vec4,  int16_t,  int16_t);"
+            "i16vec2  clamp(i16vec2,  i16vec2,  i16vec2);"
+            "i16vec3  clamp(i16vec3,  i16vec3,  i16vec3);"
+            "i16vec4  clamp(i16vec4,  i16vec4,  i16vec4);"
+            "uint16_t clamp(uint16_t, uint16_t, uint16_t);"
+            "u16vec2  clamp(u16vec2,  uint16_t, uint16_t);"
+            "u16vec3  clamp(u16vec3,  uint16_t, uint16_t);"
+            "u16vec4  clamp(u16vec4,  uint16_t, uint16_t);"
+            "u16vec2  clamp(u16vec2,  u16vec2,  u16vec2);"
+            "u16vec3  clamp(u16vec3,  u16vec3,  u16vec3);"
+            "u16vec4  clamp(u16vec4,  u16vec4,  u16vec4);"
+
+            "int16_t  mix(int16_t,  int16_t,  bool);"
+            "i16vec2  mix(i16vec2,  i16vec2,  bvec2);"
+            "i16vec3  mix(i16vec3,  i16vec3,  bvec3);"
+            "i16vec4  mix(i16vec4,  i16vec4,  bvec4);"
+            "uint16_t mix(uint16_t, uint16_t, bool);"
+            "u16vec2  mix(u16vec2,  u16vec2,  bvec2);"
+            "u16vec3  mix(u16vec3,  u16vec3,  bvec3);"
+            "u16vec4  mix(u16vec4,  u16vec4,  bvec4);"
+
+            "float16_t frexp(float16_t, out int16_t);"
+            "f16vec2   frexp(f16vec2,   out i16vec2);"
+            "f16vec3   frexp(f16vec3,   out i16vec3);"
+            "f16vec4   frexp(f16vec4,   out i16vec4);"
+
+            "float16_t ldexp(float16_t, int16_t);"
+            "f16vec2   ldexp(f16vec2,   i16vec2);"
+            "f16vec3   ldexp(f16vec3,   i16vec3);"
+            "f16vec4   ldexp(f16vec4,   i16vec4);"
+
+            "int16_t float16BitsToInt16(float16_t);"
+            "i16vec2 float16BitsToInt16(f16vec2);"
+            "i16vec3 float16BitsToInt16(f16vec3);"
+            "i16vec4 float16BitsToInt16(f16vec4);"
+
+            "uint16_t float16BitsToUint16(float16_t);"
+            "u16vec2  float16BitsToUint16(f16vec2);"
+            "u16vec3  float16BitsToUint16(f16vec3);"
+            "u16vec4  float16BitsToUint16(f16vec4);"
+
+            "float16_t int16BitsToFloat16(int16_t);"
+            "f16vec2   int16BitsToFloat16(i16vec2);"
+            "f16vec3   int16BitsToFloat16(i16vec3);"
+            "f16vec4   int16BitsToFloat16(i16vec4);"
+
+            "float16_t uint16BitsToFloat16(uint16_t);"
+            "f16vec2   uint16BitsToFloat16(u16vec2);"
+            "f16vec3   uint16BitsToFloat16(u16vec3);"
+            "f16vec4   uint16BitsToFloat16(u16vec4);"
+
+            "int      packInt2x16(i16vec2);"
+            "uint     packUint2x16(u16vec2);"
+            "int64_t  packInt4x16(i16vec4);"
+            "uint64_t packUint4x16(u16vec4);"
+            "i16vec2  unpackInt2x16(int);"
+            "u16vec2  unpackUint2x16(uint);"
+            "i16vec4  unpackInt4x16(int64_t);"
+            "u16vec4  unpackUint4x16(uint64_t);"
+
+            "bvec2 lessThan(i16vec2, i16vec2);"
+            "bvec3 lessThan(i16vec3, i16vec3);"
+            "bvec4 lessThan(i16vec4, i16vec4);"
+            "bvec2 lessThan(u16vec2, u16vec2);"
+            "bvec3 lessThan(u16vec3, u16vec3);"
+            "bvec4 lessThan(u16vec4, u16vec4);"
+
+            "bvec2 lessThanEqual(i16vec2, i16vec2);"
+            "bvec3 lessThanEqual(i16vec3, i16vec3);"
+            "bvec4 lessThanEqual(i16vec4, i16vec4);"
+            "bvec2 lessThanEqual(u16vec2, u16vec2);"
+            "bvec3 lessThanEqual(u16vec3, u16vec3);"
+            "bvec4 lessThanEqual(u16vec4, u16vec4);"
+
+            "bvec2 greaterThan(i16vec2, i16vec2);"
+            "bvec3 greaterThan(i16vec3, i16vec3);"
+            "bvec4 greaterThan(i16vec4, i16vec4);"
+            "bvec2 greaterThan(u16vec2, u16vec2);"
+            "bvec3 greaterThan(u16vec3, u16vec3);"
+            "bvec4 greaterThan(u16vec4, u16vec4);"
+
+            "bvec2 greaterThanEqual(i16vec2, i16vec2);"
+            "bvec3 greaterThanEqual(i16vec3, i16vec3);"
+            "bvec4 greaterThanEqual(i16vec4, i16vec4);"
+            "bvec2 greaterThanEqual(u16vec2, u16vec2);"
+            "bvec3 greaterThanEqual(u16vec3, u16vec3);"
+            "bvec4 greaterThanEqual(u16vec4, u16vec4);"
+
+            "bvec2 equal(i16vec2, i16vec2);"
+            "bvec3 equal(i16vec3, i16vec3);"
+            "bvec4 equal(i16vec4, i16vec4);"
+            "bvec2 equal(u16vec2, u16vec2);"
+            "bvec3 equal(u16vec3, u16vec3);"
+            "bvec4 equal(u16vec4, u16vec4);"
+
+            "bvec2 notEqual(i16vec2, i16vec2);"
+            "bvec3 notEqual(i16vec3, i16vec3);"
+            "bvec4 notEqual(i16vec4, i16vec4);"
+            "bvec2 notEqual(u16vec2, u16vec2);"
+            "bvec3 notEqual(u16vec3, u16vec3);"
+            "bvec4 notEqual(u16vec4, u16vec4);"
+
+            "\n");
+    }
 #endif
 #endif
 
 
     //============================================================================
     //============================================================================
@@ -3137,6 +3289,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "\n");
             "\n");
     }
     }
 
 
+    if ((profile != EEsProfile && version >= 140) ||
+        (profile == EEsProfile && version >= 310)) {
+        stageBuiltins[EShLangCompute].append(
+            "in highp int gl_DeviceIndex;"     // GL_EXT_device_group
+            "\n");
+    }
+
     //============================================================================
     //============================================================================
     //
     //
     // Define the interface to the vertex shader.
     // Define the interface to the vertex shader.
@@ -3261,11 +3420,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             stageBuiltins[EShLangVertex].append(
             stageBuiltins[EShLangVertex].append(
                 "out int gl_ViewportIndex;"
                 "out int gl_ViewportIndex;"
                 "out int gl_Layer;"
                 "out int gl_Layer;"
-                "out int gl_ViewportMask[];"
-                "out int gl_SecondaryViewportMaskNV[];"
-                "out vec4 gl_SecondaryPositionNV;"
-                "out vec4 gl_PositionPerViewNV[];"
-                "out int  gl_ViewportMaskPerViewNV[];"
+                "out int gl_ViewportMask[];"             // GL_NV_viewport_array2
+                "out int gl_SecondaryViewportMaskNV[];"  // GL_NV_stereo_view_rendering
+                "out vec4 gl_SecondaryPositionNV;"       // GL_NV_stereo_view_rendering
+                "out vec4 gl_PositionPerViewNV[];"       // GL_NVX_multiview_per_view_attributes
+                "out int  gl_ViewportMaskPerViewNV[];"   // GL_NVX_multiview_per_view_attributes
                 );
                 );
 #endif
 #endif
 
 
@@ -3302,6 +3461,15 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
         }
         }
     }
     }
 
 
+    if ((profile != EEsProfile && version >= 140) ||
+        (profile == EEsProfile && version >= 310)) {
+        stageBuiltins[EShLangVertex].append(
+            "in highp int gl_DeviceIndex;"     // GL_EXT_device_group
+            "in highp int gl_ViewIndex;"       // GL_EXT_multiview
+            "\n");
+    }
+
+
     //============================================================================
     //============================================================================
     //
     //
     // Define the interface to the geometry shader.
     // Define the interface to the geometry shader.
@@ -3329,8 +3497,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             stageBuiltins[EShLangGeometry].append(
             stageBuiltins[EShLangGeometry].append(
                 "float gl_CullDistance[];"
                 "float gl_CullDistance[];"
 #ifdef NV_EXTENSIONS
 #ifdef NV_EXTENSIONS
-                "vec4 gl_SecondaryPositionNV;"
-                "vec4 gl_PositionPerViewNV[];"
+                "vec4 gl_SecondaryPositionNV;"   // GL_NV_stereo_view_rendering
+                "vec4 gl_PositionPerViewNV[];"   // GL_NVX_multiview_per_view_attributes
 #endif
 #endif
                 );
                 );
         stageBuiltins[EShLangGeometry].append(
         stageBuiltins[EShLangGeometry].append(
@@ -3380,11 +3548,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
 #ifdef NV_EXTENSIONS
 #ifdef NV_EXTENSIONS
         if (version >= 450)
         if (version >= 450)
             stageBuiltins[EShLangGeometry].append(
             stageBuiltins[EShLangGeometry].append(
-                "out int gl_ViewportMask[];"
-                "out int gl_SecondaryViewportMaskNV[];"
-                "out vec4 gl_SecondaryPositionNV;"
-                "out vec4 gl_PositionPerViewNV[];"
-                "out int  gl_ViewportMaskPerViewNV[];"
+                "out int gl_ViewportMask[];"               // GL_NV_viewport_array2
+                "out int gl_SecondaryViewportMaskNV[];"    // GL_NV_stereo_view_rendering
+                "out vec4 gl_SecondaryPositionNV;"         // GL_NV_stereo_view_rendering
+                "out vec4 gl_PositionPerViewNV[];"         // GL_NVX_multiview_per_view_attributes
+                "out int  gl_ViewportMaskPerViewNV[];"     // GL_NVX_multiview_per_view_attributes
             );
             );
 #endif
 #endif
 
 
@@ -3410,6 +3578,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             );
             );
     }
     }
 
 
+    if ((profile != EEsProfile && version >= 140) ||
+        (profile == EEsProfile && version >= 310)) {
+        stageBuiltins[EShLangGeometry].append(
+            "in highp int gl_DeviceIndex;"     // GL_EXT_device_group
+            "in highp int gl_ViewIndex;"       // GL_EXT_multiview
+            "\n");
+    }
+
     //============================================================================
     //============================================================================
     //
     //
     // Define the interface to the tessellation control shader.
     // Define the interface to the tessellation control shader.
@@ -3446,11 +3622,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
 #ifdef NV_EXTENSIONS
 #ifdef NV_EXTENSIONS
                 "int  gl_ViewportIndex;"
                 "int  gl_ViewportIndex;"
                 "int  gl_Layer;"
                 "int  gl_Layer;"
-                "int  gl_ViewportMask[];"
-                "vec4 gl_SecondaryPositionNV;"
-                "int  gl_SecondaryViewportMaskNV[];"
-                "vec4 gl_PositionPerViewNV[];"
-                "int  gl_ViewportMaskPerViewNV[];"
+                "int  gl_ViewportMask[];"             // GL_NV_viewport_array2
+                "vec4 gl_SecondaryPositionNV;"        // GL_NV_stereo_view_rendering
+                "int  gl_SecondaryViewportMaskNV[];"  // GL_NV_stereo_view_rendering
+                "vec4 gl_PositionPerViewNV[];"        // GL_NVX_multiview_per_view_attributes
+                "int  gl_ViewportMaskPerViewNV[];"    // GL_NVX_multiview_per_view_attributes
 #endif
 #endif
                 );
                 );
         stageBuiltins[EShLangTessControl].append(
         stageBuiltins[EShLangTessControl].append(
@@ -3481,6 +3657,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "\n");
             "\n");
     }
     }
 
 
+    if ((profile != EEsProfile && version >= 140) ||
+        (profile == EEsProfile && version >= 310)) {
+        stageBuiltins[EShLangTessControl].append(
+            "in highp int gl_DeviceIndex;"     // GL_EXT_device_group
+            "in highp int gl_ViewIndex;"       // GL_EXT_multiview
+            "\n");
+    }
+
     //============================================================================
     //============================================================================
     //
     //
     // Define the interface to the tessellation evaluation shader.
     // Define the interface to the tessellation evaluation shader.
@@ -3527,11 +3711,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             stageBuiltins[EShLangTessEvaluation].append(
             stageBuiltins[EShLangTessEvaluation].append(
                 "out int  gl_ViewportIndex;"
                 "out int  gl_ViewportIndex;"
                 "out int  gl_Layer;"
                 "out int  gl_Layer;"
-                "out int  gl_ViewportMask[];"
-                "out vec4 gl_SecondaryPositionNV;"
-                "out int  gl_SecondaryViewportMaskNV[];"
-                "out vec4 gl_PositionPerViewNV[];"
-                "out int  gl_ViewportMaskPerViewNV[];"
+                "out int  gl_ViewportMask[];"             // GL_NV_viewport_array2
+                "out vec4 gl_SecondaryPositionNV;"        // GL_NV_stereo_view_rendering
+                "out int  gl_SecondaryViewportMaskNV[];"  // GL_NV_stereo_view_rendering
+                "out vec4 gl_PositionPerViewNV[];"        // GL_NVX_multiview_per_view_attributes
+                "out int  gl_ViewportMaskPerViewNV[];"    // GL_NVX_multiview_per_view_attributes
                 );
                 );
 #endif
 #endif
 
 
@@ -3556,6 +3740,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "\n");
             "\n");
     }
     }
 
 
+    if ((profile != EEsProfile && version >= 140) ||
+        (profile == EEsProfile && version >= 310)) {
+        stageBuiltins[EShLangTessEvaluation].append(
+            "in highp int gl_DeviceIndex;"     // GL_EXT_device_group
+            "in highp int gl_ViewIndex;"       // GL_EXT_multiview
+            "\n");
+    }
+
     //============================================================================
     //============================================================================
     //
     //
     // Define the interface to the fragment shader.
     // Define the interface to the fragment shader.
@@ -3713,6 +3905,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "\n");
             "\n");
     }
     }
 
 
+    if ((profile != EEsProfile && version >= 140) ||
+        (profile == EEsProfile && version >= 310)) {
+        stageBuiltins[EShLangFragment].append(
+            "flat in highp int gl_DeviceIndex;"     // GL_EXT_device_group
+            "flat in highp int gl_ViewIndex;"       // GL_EXT_multiview
+            "\n");
+    }
+
     // printf("%s\n", commonBuiltins.c_str());
     // printf("%s\n", commonBuiltins.c_str());
     // printf("%s\n", stageBuiltins[EShLangFragment].c_str());
     // printf("%s\n", stageBuiltins[EShLangFragment].c_str());
 }
 }
@@ -3808,6 +4008,17 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c
                             else {
                             else {
                                 addSamplingFunctions(sampler, typeName, version, profile);
                                 addSamplingFunctions(sampler, typeName, version, profile);
                                 addGatherFunctions(sampler, typeName, version, profile);
                                 addGatherFunctions(sampler, typeName, version, profile);
+
+                                if (spvVersion.vulkan > 0 && sampler.dim == EsdBuffer && sampler.isCombined()) {
+                                    // Vulkan wants a textureBuffer to allow texelFetch() --
+                                    // a sampled image with no sampler.
+                                    // So, add sampling functions for both the
+                                    // samplerBuffer and textureBuffer types.
+                                    sampler.setTexture(sampler.type, sampler.dim, sampler.arrayed, sampler.shadow,
+                                                       sampler.ms);
+                                    TString textureTypeName = sampler.getString();
+                                    addSamplingFunctions(sampler, textureTypeName, version, profile);
+                                }
                             }
                             }
                         }
                         }
                     }
                     }
@@ -3831,7 +4042,7 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c
 //
 //
 // Add all the query functions for the given type.
 // Add all the query functions for the given type.
 //
 //
-void TBuiltIns::addQueryFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
+void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile)
 {
 {
     if (sampler.image && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 430)))
     if (sampler.image && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 430)))
         return;
         return;
@@ -3908,7 +4119,7 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, TString& typeName, int versi
 //
 //
 // Add all the image access functions for the given type.
 // Add all the image access functions for the given type.
 //
 //
-void TBuiltIns::addImageFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
+void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile)
 {
 {
     int dims = dimMap[sampler.dim];
     int dims = dimMap[sampler.dim];
     // most things with an array add a dimension, except for cubemaps
     // most things with an array add a dimension, except for cubemaps
@@ -4001,7 +4212,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, TString& typeName, int versi
 //
 //
 // Add all the subpass access functions for the given type.
 // Add all the subpass access functions for the given type.
 //
 //
-void TBuiltIns::addSubpassSampling(TSampler sampler, TString& typeName, int /*version*/, EProfile /*profile*/)
+void TBuiltIns::addSubpassSampling(TSampler sampler, const TString& typeName, int /*version*/, EProfile /*profile*/)
 {
 {
     stageBuiltins[EShLangFragment].append(prefixes[sampler.type]);
     stageBuiltins[EShLangFragment].append(prefixes[sampler.type]);
     stageBuiltins[EShLangFragment].append("vec4 subpassLoad");
     stageBuiltins[EShLangFragment].append("vec4 subpassLoad");
@@ -4018,7 +4229,7 @@ void TBuiltIns::addSubpassSampling(TSampler sampler, TString& typeName, int /*ve
 //
 //
 // Add all the texture lookup functions for the given type.
 // Add all the texture lookup functions for the given type.
 //
 //
-void TBuiltIns::addSamplingFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
+void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile)
 {
 {
     //
     //
     // texturing
     // texturing
@@ -4248,7 +4459,7 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, TString& typeName, int ve
 //
 //
 // Add all the texture gather functions for the given type.
 // Add all the texture gather functions for the given type.
 //
 //
-void TBuiltIns::addGatherFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
+void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile)
 {
 {
     switch (sampler.dim) {
     switch (sampler.dim) {
     case Esd2D:
     case Esd2D:
@@ -4303,6 +4514,7 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, TString& typeName, int vers
                 default:
                 default:
                     break;
                     break;
                 }
                 }
+
                 if (sparse)
                 if (sparse)
                     s.append("ARB");
                     s.append("ARB");
                 s.append("(");
                 s.append("(");
@@ -4342,6 +4554,116 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, TString& typeName, int vers
             }
             }
         }
         }
     }
     }
+
+#ifdef AMD_EXTENSIONS
+    if (sampler.dim == EsdRect || sampler.shadow)
+        return;
+
+    if (profile == EEsProfile || version < 450)
+        return;
+
+    for (int bias = 0; bias < 2; ++bias) { // loop over presence of bias argument
+
+        for (int lod = 0; lod < 2; ++lod) { // loop over presence of lod argument
+
+            if ((lod && bias) || (lod == 0 && bias == 0))
+                continue;
+
+            for (int offset = 0; offset < 3; ++offset) { // loop over three forms of offset in the call name:  none, Offset, and Offsets
+
+                for (int comp = 0; comp < 2; ++comp) { // loop over presence of comp argument
+
+                    if (comp == 0 && bias)
+                        continue;
+
+                    if (offset > 0 && sampler.dim == EsdCube)
+                        continue;
+
+                    for (int sparse = 0; sparse <= 1; ++sparse) { // loop over "bool" sparse or not
+                        if (sparse && (profile == EEsProfile || version < 450))
+                            continue;
+
+                        TString s;
+
+                        // return type
+                        if (sparse)
+                            s.append("int ");
+                        else {
+                            s.append(prefixes[sampler.type]);
+                            s.append("vec4 ");
+                        }
+
+                        // name
+                        if (sparse)
+                            s.append("sparseTextureGather");
+                        else
+                            s.append("textureGather");
+
+                        if (lod)
+                            s.append("Lod");
+
+                        switch (offset) {
+                        case 1:
+                            s.append("Offset");
+                            break;
+                        case 2:
+                            s.append("Offsets");
+                        default:
+                            break;
+                        }
+
+                        if (lod)
+                            s.append("AMD");
+                        else if (sparse)
+                            s.append("ARB");
+
+                        s.append("(");
+
+                        // sampler type argument
+                        s.append(typeName);
+
+                        // P coordinate argument
+                        s.append(",vec");
+                        int totalDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0);
+                        s.append(postfixes[totalDims]);
+
+                        // lod argument
+                        if (lod)
+                            s.append(",float");
+
+                        // offset argument
+                        if (offset > 0) {
+                            s.append(",ivec2");
+                            if (offset == 2)
+                                s.append("[4]");
+                        }
+
+                        // texel out (for sparse texture)
+                        if (sparse) {
+                            s.append(",out ");
+                            s.append(prefixes[sampler.type]);
+                            s.append("vec4 ");
+                        }
+
+                        // comp argument
+                        if (comp)
+                            s.append(",int");
+
+                        // bias argument
+                        if (bias)
+                            s.append(",float");
+
+                        s.append(");\n");
+                        if (bias)
+                            stageBuiltins[EShLangFragment].append(s);
+                        else
+                            commonBuiltins.append(s);
+                    }
+                }
+            }
+        }
+    }
+#endif
 }
 }
 
 
 //
 //
@@ -4469,8 +4791,8 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
                         "highp vec4 gl_Position;"
                         "highp vec4 gl_Position;"
                         "highp float gl_PointSize;"
                         "highp float gl_PointSize;"
 #ifdef NV_EXTENSIONS
 #ifdef NV_EXTENSIONS
-                        "highp vec4 gl_SecondaryPositionNV;"
-                        "highp vec4 gl_PositionPerViewNV[];"
+                        "highp vec4 gl_SecondaryPositionNV;"  // GL_NV_stereo_view_rendering
+                        "highp vec4 gl_PositionPerViewNV[];"  // GL_NVX_multiview_per_view_attributes
 #endif
 #endif
                     "} gl_in[gl_MaxPatchVertices];"
                     "} gl_in[gl_MaxPatchVertices];"
                     "\n");
                     "\n");
@@ -4659,8 +4981,8 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
                     s.append(
                     s.append(
                         "float gl_CullDistance[];"
                         "float gl_CullDistance[];"
 #ifdef NV_EXTENSIONS
 #ifdef NV_EXTENSIONS
-                        "vec4 gl_SecondaryPositionNV;"
-                        "vec4 gl_PositionPerViewNV[];"
+                        "vec4 gl_SecondaryPositionNV;"  // GL_NV_stereo_view_rendering
+                        "vec4 gl_PositionPerViewNV[];"  // GL_NVX_multiview_per_view_attributes
 #endif
 #endif
                        );
                        );
                 s.append(
                 s.append(
@@ -5127,13 +5449,29 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
         //        symbolTable.setVariableExtensions("gl_PointSize", Num_AEP_tessellation_point_size, AEP_tessellation_point_size);
         //        symbolTable.setVariableExtensions("gl_PointSize", Num_AEP_tessellation_point_size, AEP_tessellation_point_size);
         //}
         //}
 
 
+        if ((profile != EEsProfile && version >= 140) ||
+            (profile == EEsProfile && version >= 310)) {
+            symbolTable.setVariableExtensions("gl_DeviceIndex",  1, &E_GL_EXT_device_group);
+            BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable);
+            symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview);
+            BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable);
+        }
+
         break;
         break;
 
 
     case EShLangFragment:
     case EShLangFragment:
         SpecialQualifier("gl_FrontFacing",      EvqFace,       EbvFace,             symbolTable);
         SpecialQualifier("gl_FrontFacing",      EvqFace,       EbvFace,             symbolTable);
         SpecialQualifier("gl_FragCoord",        EvqFragCoord,  EbvFragCoord,        symbolTable);
         SpecialQualifier("gl_FragCoord",        EvqFragCoord,  EbvFragCoord,        symbolTable);
         SpecialQualifier("gl_PointCoord",       EvqPointCoord, EbvPointCoord,       symbolTable);
         SpecialQualifier("gl_PointCoord",       EvqPointCoord, EbvPointCoord,       symbolTable);
-        SpecialQualifier("gl_FragColor",        EvqFragColor,  EbvFragColor,        symbolTable);
+        if (spvVersion.spv == 0)
+            SpecialQualifier("gl_FragColor",    EvqFragColor,  EbvFragColor,        symbolTable);
+        else {
+            TSymbol* symbol = symbolTable.find("gl_FragColor");
+            if (symbol) {
+                symbol->getWritableType().getQualifier().storage = EvqVaryingOut;
+                symbol->getWritableType().getQualifier().layoutLocation = 0;
+            }
+        }
         SpecialQualifier("gl_FragDepth",        EvqFragDepth,  EbvFragDepth,        symbolTable);
         SpecialQualifier("gl_FragDepth",        EvqFragDepth,  EbvFragDepth,        symbolTable);
         SpecialQualifier("gl_FragDepthEXT",     EvqFragDepth,  EbvFragDepth,        symbolTable);
         SpecialQualifier("gl_FragDepthEXT",     EvqFragDepth,  EbvFragDepth,        symbolTable);
         SpecialQualifier("gl_HelperInvocation", EvqVaryingIn,  EbvHelperInvocation, symbolTable);
         SpecialQualifier("gl_HelperInvocation", EvqVaryingIn,  EbvHelperInvocation, symbolTable);
@@ -5325,6 +5663,16 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             BuiltInVariable("gl_BaryCoordSmoothSampleAMD",      EbvBaryCoordSmoothSample,    symbolTable);
             BuiltInVariable("gl_BaryCoordSmoothSampleAMD",      EbvBaryCoordSmoothSample,    symbolTable);
             BuiltInVariable("gl_BaryCoordPullModelAMD",         EbvBaryCoordPullModel,       symbolTable);
             BuiltInVariable("gl_BaryCoordPullModelAMD",         EbvBaryCoordPullModel,       symbolTable);
         }
         }
+
+        // E_GL_AMD_texture_gather_bias_lod
+        if (profile != EEsProfile) {
+            symbolTable.setFunctionExtensions("textureGatherLodAMD",                1, &E_GL_AMD_texture_gather_bias_lod);
+            symbolTable.setFunctionExtensions("textureGatherLodOffsetAMD",          1, &E_GL_AMD_texture_gather_bias_lod);
+            symbolTable.setFunctionExtensions("textureGatherLodOffsetsAMD",         1, &E_GL_AMD_texture_gather_bias_lod);
+            symbolTable.setFunctionExtensions("sparseTextureGatherLodAMD",          1, &E_GL_AMD_texture_gather_bias_lod);
+            symbolTable.setFunctionExtensions("sparseTextureGatherLodOffsetAMD",    1, &E_GL_AMD_texture_gather_bias_lod);
+            symbolTable.setFunctionExtensions("sparseTextureGatherLodOffsetsAMD",   1, &E_GL_AMD_texture_gather_bias_lod);
+        }
 #endif
 #endif
 
 
         symbolTable.setVariableExtensions("gl_FragDepthEXT", 1, &E_GL_EXT_frag_depth);
         symbolTable.setVariableExtensions("gl_FragDepthEXT", 1, &E_GL_EXT_frag_depth);
@@ -5344,6 +5692,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             symbolTable.setFunctionExtensions("imageAtomicExchange", 1, &E_GL_OES_shader_image_atomic);
             symbolTable.setFunctionExtensions("imageAtomicExchange", 1, &E_GL_OES_shader_image_atomic);
             symbolTable.setFunctionExtensions("imageAtomicCompSwap", 1, &E_GL_OES_shader_image_atomic);
             symbolTable.setFunctionExtensions("imageAtomicCompSwap", 1, &E_GL_OES_shader_image_atomic);
         }
         }
+
+        symbolTable.setVariableExtensions("gl_DeviceIndex",  1, &E_GL_EXT_device_group);
+        BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable);
+        symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview);
+        BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable);
         break;
         break;
 
 
     case EShLangCompute:
     case EShLangCompute:
@@ -5377,6 +5730,15 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             symbolTable.setFunctionExtensions("memoryBarrierShared",        1, &E_GL_ARB_compute_shader);
             symbolTable.setFunctionExtensions("memoryBarrierShared",        1, &E_GL_ARB_compute_shader);
             symbolTable.setFunctionExtensions("groupMemoryBarrier",         1, &E_GL_ARB_compute_shader);
             symbolTable.setFunctionExtensions("groupMemoryBarrier",         1, &E_GL_ARB_compute_shader);
         }
         }
+
+        if ((profile != EEsProfile && version >= 140) ||
+            (profile == EEsProfile && version >= 310)) {
+            symbolTable.setVariableExtensions("gl_DeviceIndex",  1, &E_GL_EXT_device_group);
+            BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable);
+            symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview);
+            BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable);
+        }
+
         break;
         break;
 
 
     default:
     default:
@@ -5462,6 +5824,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
     symbolTable.relateToOperator("doubleBitsToUint64", EOpDoubleBitsToUint64);
     symbolTable.relateToOperator("doubleBitsToUint64", EOpDoubleBitsToUint64);
     symbolTable.relateToOperator("int64BitsToDouble",  EOpInt64BitsToDouble);
     symbolTable.relateToOperator("int64BitsToDouble",  EOpInt64BitsToDouble);
     symbolTable.relateToOperator("uint64BitsToDouble", EOpUint64BitsToDouble);
     symbolTable.relateToOperator("uint64BitsToDouble", EOpUint64BitsToDouble);
+#ifdef AMD_EXTENSIONS
+    symbolTable.relateToOperator("float16BitsToInt16",  EOpFloat16BitsToInt16);
+    symbolTable.relateToOperator("float16BitsToUint16", EOpFloat16BitsToUint16);
+    symbolTable.relateToOperator("int16BitsToFloat16",  EOpInt16BitsToFloat16);
+    symbolTable.relateToOperator("uint16BitsToFloat16", EOpUint16BitsToFloat16);
+#endif
 
 
     symbolTable.relateToOperator("packSnorm2x16",   EOpPackSnorm2x16);
     symbolTable.relateToOperator("packSnorm2x16",   EOpPackSnorm2x16);
     symbolTable.relateToOperator("unpackSnorm2x16", EOpUnpackSnorm2x16);
     symbolTable.relateToOperator("unpackSnorm2x16", EOpUnpackSnorm2x16);
@@ -5485,6 +5853,16 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
     symbolTable.relateToOperator("unpackUint2x32",  EOpUnpackUint2x32);
     symbolTable.relateToOperator("unpackUint2x32",  EOpUnpackUint2x32);
 
 
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
+    symbolTable.relateToOperator("packInt2x16",     EOpPackInt2x16);
+    symbolTable.relateToOperator("unpackInt2x16",   EOpUnpackInt2x16);
+    symbolTable.relateToOperator("packUint2x16",    EOpPackUint2x16);
+    symbolTable.relateToOperator("unpackUint2x16",  EOpUnpackUint2x16);
+
+    symbolTable.relateToOperator("packInt4x16",     EOpPackInt4x16);
+    symbolTable.relateToOperator("unpackInt4x16",   EOpUnpackInt4x16);
+    symbolTable.relateToOperator("packUint4x16",    EOpPackUint4x16);
+    symbolTable.relateToOperator("unpackUint4x16",  EOpUnpackUint4x16);
+
     symbolTable.relateToOperator("packFloat2x16",   EOpPackFloat2x16);
     symbolTable.relateToOperator("packFloat2x16",   EOpPackFloat2x16);
     symbolTable.relateToOperator("unpackFloat2x16", EOpUnpackFloat2x16);
     symbolTable.relateToOperator("unpackFloat2x16", EOpUnpackFloat2x16);
 #endif
 #endif
@@ -5706,6 +6084,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             symbolTable.relateToOperator("cubeFaceIndexAMD",    EOpCubeFaceIndex);
             symbolTable.relateToOperator("cubeFaceIndexAMD",    EOpCubeFaceIndex);
             symbolTable.relateToOperator("cubeFaceCoordAMD",    EOpCubeFaceCoord);
             symbolTable.relateToOperator("cubeFaceCoordAMD",    EOpCubeFaceCoord);
             symbolTable.relateToOperator("timeAMD",             EOpTime);
             symbolTable.relateToOperator("timeAMD",             EOpTime);
+
+            symbolTable.relateToOperator("textureGatherLodAMD",                 EOpTextureGatherLod);
+            symbolTable.relateToOperator("textureGatherLodOffsetAMD",           EOpTextureGatherLodOffset);
+            symbolTable.relateToOperator("textureGatherLodOffsetsAMD",          EOpTextureGatherLodOffsets);
+            symbolTable.relateToOperator("sparseTextureGatherLodAMD",           EOpSparseTextureGatherLod);
+            symbolTable.relateToOperator("sparseTextureGatherLodOffsetAMD",     EOpSparseTextureGatherLodOffset);
+            symbolTable.relateToOperator("sparseTextureGatherLodOffsetsAMD",    EOpSparseTextureGatherLodOffsets);
 #endif
 #endif
         }
         }
     }
     }

+ 5 - 5
src/libraries/glslang/glslang/MachineIndependent/Initialize.h

@@ -94,11 +94,11 @@ public:
 
 
 protected:
 protected:
     void add2ndGenerationSamplingImaging(int version, EProfile profile, const SpvVersion& spvVersion);
     void add2ndGenerationSamplingImaging(int version, EProfile profile, const SpvVersion& spvVersion);
-    void addSubpassSampling(TSampler, TString& typeName, int version, EProfile profile);
-    void addQueryFunctions(TSampler, TString& typeName, int version, EProfile profile);
-    void addImageFunctions(TSampler, TString& typeName, int version, EProfile profile);
-    void addSamplingFunctions(TSampler, TString& typeName, int version, EProfile profile);
-    void addGatherFunctions(TSampler, TString& typeName, int version, EProfile profile);
+    void addSubpassSampling(TSampler, const TString& typeName, int version, EProfile profile);
+    void addQueryFunctions(TSampler, const TString& typeName, int version, EProfile profile);
+    void addImageFunctions(TSampler, const TString& typeName, int version, EProfile profile);
+    void addSamplingFunctions(TSampler, const TString& typeName, int version, EProfile profile);
+    void addGatherFunctions(TSampler, const TString& typeName, int version, EProfile profile);
 
 
     // Helpers for making textual representations of the permutations
     // Helpers for making textual representations of the permutations
     // of texturing/imaging functions.
     // of texturing/imaging functions.

+ 586 - 57
src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp

@@ -130,8 +130,9 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
     }
     }
 
 
     // Convert the children's type shape to be compatible.
     // Convert the children's type shape to be compatible.
-    right = addShapeConversion(op,  left->getType(), right);
-    left  = addShapeConversion(op, right->getType(),  left);
+    addBiShapeConversion(op, left, right);
+    if (left == nullptr || right == nullptr)
+        return nullptr;
 
 
     //
     //
     // Need a new node holding things together.  Make
     // Need a new node holding things together.  Make
@@ -147,8 +148,8 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
     // If they are both (non-specialization) constants, they must be folded.
     // If they are both (non-specialization) constants, they must be folded.
     // (Unless it's the sequence (comma) operator, but that's handled in addComma().)
     // (Unless it's the sequence (comma) operator, but that's handled in addComma().)
     //
     //
-    TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
-    TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
+    TIntermConstantUnion *leftTempConstant = node->getLeft()->getAsConstantUnion();
+    TIntermConstantUnion *rightTempConstant = node->getRight()->getAsConstantUnion();
     if (leftTempConstant && rightTempConstant) {
     if (leftTempConstant && rightTempConstant) {
         TIntermTyped* folded = leftTempConstant->fold(node->getOp(), rightTempConstant);
         TIntermTyped* folded = leftTempConstant->fold(node->getOp(), rightTempConstant);
         if (folded)
         if (folded)
@@ -157,7 +158,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
 
 
     // If can propagate spec-constantness and if the operation is an allowed
     // If can propagate spec-constantness and if the operation is an allowed
     // specialization-constant operation, make a spec-constant.
     // specialization-constant operation, make a spec-constant.
-    if (specConstantPropagates(*left, *right) && isSpecializationOperation(*node))
+    if (specConstantPropagates(*node->getLeft(), *node->getRight()) && isSpecializationOperation(*node))
         node->getWritableType().getQualifier().makeSpecConstant();
         node->getWritableType().getQualifier().makeSpecConstant();
 
 
     return node;
     return node;
@@ -238,7 +239,7 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm
         return nullptr;
         return nullptr;
 
 
     // convert shape
     // convert shape
-    right = addShapeConversion(op, left->getType(), right);
+    right = addUniShapeConversion(op, left->getType(), right);
 
 
     // build the node
     // build the node
     TIntermBinary* node = addBinaryNode(op, left, right, loc);
     TIntermBinary* node = addBinaryNode(op, left, right, loc);
@@ -307,6 +308,10 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo
     case EOpConstructUint:   newType = EbtUint;   break;
     case EOpConstructUint:   newType = EbtUint;   break;
     case EOpConstructInt64:  newType = EbtInt64;  break;
     case EOpConstructInt64:  newType = EbtInt64;  break;
     case EOpConstructUint64: newType = EbtUint64; break;
     case EOpConstructUint64: newType = EbtUint64; break;
+#ifdef AMD_EXTENSIONS
+    case EOpConstructInt16:  newType = EbtInt16;  break;
+    case EOpConstructUint16: newType = EbtUint16; break;
+#endif
     case EOpConstructBool:   newType = EbtBool;   break;
     case EOpConstructBool:   newType = EbtBool;   break;
     case EOpConstructFloat:  newType = EbtFloat;  break;
     case EOpConstructFloat:  newType = EbtFloat;  break;
     case EOpConstructDouble: newType = EbtDouble; break;
     case EOpConstructDouble: newType = EbtDouble; break;
@@ -335,6 +340,10 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo
     case EOpConstructUint:
     case EOpConstructUint:
     case EOpConstructInt64:
     case EOpConstructInt64:
     case EOpConstructUint64:
     case EOpConstructUint64:
+#ifdef AMD_EXTENSIONS
+    case EOpConstructInt16:
+    case EOpConstructUint16:
+#endif
     case EOpConstructBool:
     case EOpConstructBool:
     case EOpConstructFloat:
     case EOpConstructFloat:
     case EOpConstructDouble:
     case EOpConstructDouble:
@@ -356,12 +365,12 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo
     node->updatePrecision();
     node->updatePrecision();
 
 
     // If it's a (non-specialization) constant, it must be folded.
     // If it's a (non-specialization) constant, it must be folded.
-    if (child->getAsConstantUnion())
-        return child->getAsConstantUnion()->fold(op, node->getType());
+    if (node->getOperand()->getAsConstantUnion())
+        return node->getOperand()->getAsConstantUnion()->fold(op, node->getType());
 
 
     // If it's a specialization constant, the result is too,
     // If it's a specialization constant, the result is too,
     // if the operation is allowed for specialization constants.
     // if the operation is allowed for specialization constants.
-    if (child->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*node))
+    if (node->getOperand()->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*node))
         node->getWritableType().getQualifier().makeSpecConstant();
         node->getWritableType().getQualifier().makeSpecConstant();
 
 
     return node;
     return node;
@@ -527,6 +536,14 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
     case EOpConstructUint64:
     case EOpConstructUint64:
         promoteTo = EbtUint64;
         promoteTo = EbtUint64;
         break;
         break;
+#ifdef AMD_EXTENSIONS
+    case EOpConstructInt16:
+        promoteTo = EbtInt16;
+        break;
+    case EOpConstructUint16:
+        promoteTo = EbtUint16;
+        break;
+#endif
 
 
     //
     //
     // List all the binary ops that can implicitly convert one operand to the other's type;
     // List all the binary ops that can implicitly convert one operand to the other's type;
@@ -615,15 +632,26 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
     case EOpRightShiftAssign:
     case EOpRightShiftAssign:
         if ((type.getBasicType() == EbtInt ||
         if ((type.getBasicType() == EbtInt ||
              type.getBasicType() == EbtUint ||
              type.getBasicType() == EbtUint ||
+#ifdef AMD_EXTENSIONS
+             type.getBasicType() == EbtInt16 ||
+             type.getBasicType() == EbtUint16 ||
+#endif
              type.getBasicType() == EbtInt64 ||
              type.getBasicType() == EbtInt64 ||
              type.getBasicType() == EbtUint64) &&
              type.getBasicType() == EbtUint64) &&
             (node->getType().getBasicType() == EbtInt ||
             (node->getType().getBasicType() == EbtInt ||
              node->getType().getBasicType() == EbtUint ||
              node->getType().getBasicType() == EbtUint ||
+#ifdef AMD_EXTENSIONS
+             node->getType().getBasicType() == EbtInt16 ||
+             node->getType().getBasicType() == EbtUint16 ||
+#endif
              node->getType().getBasicType() == EbtInt64 ||
              node->getType().getBasicType() == EbtInt64 ||
              node->getType().getBasicType() == EbtUint64))
              node->getType().getBasicType() == EbtUint64))
 
 
             return node;
             return node;
-        else
+        else if (source == EShSourceHlsl && node->getType().getBasicType() == EbtBool) {
+            promoteTo = type.getBasicType();
+            break;
+        } else
             return nullptr;
             return nullptr;
 
 
     default:
     default:
@@ -659,6 +687,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
 #endif
 #endif
         case EbtInt64: newOp = EOpConvInt64ToDouble; break;
         case EbtInt64: newOp = EOpConvInt64ToDouble; break;
         case EbtUint64: newOp = EOpConvUint64ToDouble; break;
         case EbtUint64: newOp = EOpConvUint64ToDouble; break;
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:  newOp = EOpConvInt16ToDouble;  break;
+        case EbtUint16: newOp = EOpConvUint16ToDouble; break;
+#endif
         default:
         default:
             return nullptr;
             return nullptr;
         }
         }
@@ -674,6 +706,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
 #endif
 #endif
         case EbtInt64:  newOp = EOpConvInt64ToFloat;  break;
         case EbtInt64:  newOp = EOpConvInt64ToFloat;  break;
         case EbtUint64: newOp = EOpConvUint64ToFloat; break;
         case EbtUint64: newOp = EOpConvUint64ToFloat; break;
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:  newOp = EOpConvInt16ToFloat;  break;
+        case EbtUint16: newOp = EOpConvUint16ToFloat; break;
+#endif
         default:
         default:
             return nullptr;
             return nullptr;
         }
         }
@@ -688,6 +724,8 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
         case EbtDouble: newOp = EOpConvDoubleToFloat16; break;
         case EbtDouble: newOp = EOpConvDoubleToFloat16; break;
         case EbtInt64:  newOp = EOpConvInt64ToFloat16;  break;
         case EbtInt64:  newOp = EOpConvInt64ToFloat16;  break;
         case EbtUint64: newOp = EOpConvUint64ToFloat16; break;
         case EbtUint64: newOp = EOpConvUint64ToFloat16; break;
+        case EbtInt16:  newOp = EOpConvInt16ToFloat16;  break;
+        case EbtUint16: newOp = EOpConvUint16ToFloat16; break;
         default:
         default:
             return nullptr;
             return nullptr;
         }
         }
@@ -704,6 +742,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
 #endif
 #endif
         case EbtInt64:  newOp = EOpConvInt64ToBool;  break;
         case EbtInt64:  newOp = EOpConvInt64ToBool;  break;
         case EbtUint64: newOp = EOpConvUint64ToBool; break;
         case EbtUint64: newOp = EOpConvUint64ToBool; break;
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:  newOp = EOpConvInt16ToBool;  break;
+        case EbtUint16: newOp = EOpConvUint16ToBool; break;
+#endif
         default:
         default:
             return nullptr;
             return nullptr;
         }
         }
@@ -719,6 +761,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
 #endif
 #endif
         case EbtInt64:  newOp = EOpConvInt64ToInt;  break;
         case EbtInt64:  newOp = EOpConvInt64ToInt;  break;
         case EbtUint64: newOp = EOpConvUint64ToInt; break;
         case EbtUint64: newOp = EOpConvUint64ToInt; break;
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:  newOp = EOpConvInt16ToInt;  break;
+        case EbtUint16: newOp = EOpConvUint16ToInt; break;
+#endif
         default:
         default:
             return nullptr;
             return nullptr;
         }
         }
@@ -734,6 +780,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
 #endif
 #endif
         case EbtInt64:  newOp = EOpConvInt64ToUint;  break;
         case EbtInt64:  newOp = EOpConvInt64ToUint;  break;
         case EbtUint64: newOp = EOpConvUint64ToUint; break;
         case EbtUint64: newOp = EOpConvUint64ToUint; break;
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:  newOp = EOpConvInt16ToUint;  break;
+        case EbtUint16: newOp = EOpConvUint16ToUint; break;
+#endif
         default:
         default:
             return nullptr;
             return nullptr;
         }
         }
@@ -749,6 +799,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
         case EbtFloat16: newOp = EOpConvFloat16ToInt64; break;
         case EbtFloat16: newOp = EOpConvFloat16ToInt64; break;
 #endif
 #endif
         case EbtUint64: newOp = EOpConvUint64ToInt64; break;
         case EbtUint64: newOp = EOpConvUint64ToInt64; break;
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:  newOp = EOpConvInt16ToInt64;  break;
+        case EbtUint16: newOp = EOpConvUint16ToInt64; break;
+#endif
         default:
         default:
             return nullptr;
             return nullptr;
         }
         }
@@ -764,10 +818,46 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
         case EbtFloat16: newOp = EOpConvFloat16ToUint64; break;
         case EbtFloat16: newOp = EOpConvFloat16ToUint64; break;
 #endif
 #endif
         case EbtInt64:  newOp = EOpConvInt64ToUint64;  break;
         case EbtInt64:  newOp = EOpConvInt64ToUint64;  break;
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:  newOp = EOpConvInt16ToUint64;  break;
+        case EbtUint16: newOp = EOpConvUint16ToUint64; break;
+#endif
+        default:
+            return nullptr;
+        }
+        break;
+#ifdef AMD_EXTENSIONS
+    case EbtInt16:
+        switch (node->getBasicType()) {
+        case EbtInt:     newOp = EOpConvIntToInt16;     break;
+        case EbtUint:    newOp = EOpConvUintToInt16;    break;
+        case EbtBool:    newOp = EOpConvBoolToInt16;    break;
+        case EbtFloat:   newOp = EOpConvFloatToInt16;   break;
+        case EbtDouble:  newOp = EOpConvDoubleToInt16;  break;
+        case EbtFloat16: newOp = EOpConvFloat16ToInt16; break;
+        case EbtInt64:   newOp = EOpConvInt64ToInt16;   break;
+        case EbtUint64:  newOp = EOpConvUint64ToInt16;  break;
+        case EbtUint16:  newOp = EOpConvUint16ToInt16;  break;
+        default:
+            return nullptr;
+        }
+        break;
+    case EbtUint16:
+        switch (node->getBasicType()) {
+        case EbtInt:     newOp = EOpConvIntToUint16;     break;
+        case EbtUint:    newOp = EOpConvUintToUint16;    break;
+        case EbtBool:    newOp = EOpConvBoolToUint16;    break;
+        case EbtFloat:   newOp = EOpConvFloatToUint16;   break;
+        case EbtDouble:  newOp = EOpConvDoubleToUint16;  break;
+        case EbtFloat16: newOp = EOpConvFloat16ToUint16; break;
+        case EbtInt64:   newOp = EOpConvInt64ToUint16;   break;
+        case EbtUint64:  newOp = EOpConvUint64ToUint16;  break;
+        case EbtInt16:   newOp = EOpConvInt16ToUint16;   break;
         default:
         default:
             return nullptr;
             return nullptr;
         }
         }
         break;
         break;
+#endif
     default:
     default:
         return nullptr;
         return nullptr;
     }
     }
@@ -785,7 +875,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
 }
 }
 
 
 // Convert the node's shape of type for the given type, as allowed by the
 // Convert the node's shape of type for the given type, as allowed by the
-// operation involved: 'op'.
+// operation involved: 'op'.  This is for situations where there is only one
+// direction to consider doing the shape conversion.
+//
+// This implements policy, it call addShapeConversion() for the mechanism.
 //
 //
 // Generally, the AST represents allowed GLSL shapes, so this isn't needed
 // Generally, the AST represents allowed GLSL shapes, so this isn't needed
 // for GLSL.  Bad shapes are caught in conversion or promotion.
 // for GLSL.  Bad shapes are caught in conversion or promotion.
@@ -793,7 +886,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
 // Return 'node' if no conversion was done. Promotion handles final shape
 // Return 'node' if no conversion was done. Promotion handles final shape
 // checking.
 // checking.
 //
 //
-TIntermTyped* TIntermediate::addShapeConversion(TOperator op, const TType& type, TIntermTyped* node)
+TIntermTyped* TIntermediate::addUniShapeConversion(TOperator op, const TType& type, TIntermTyped* node)
 {
 {
     // some source languages don't do this
     // some source languages don't do this
     switch (source) {
     switch (source) {
@@ -806,23 +899,142 @@ TIntermTyped* TIntermediate::addShapeConversion(TOperator op, const TType& type,
 
 
     // some operations don't do this
     // some operations don't do this
     switch (op) {
     switch (op) {
+    case EOpFunctionCall:
+    case EOpReturn:
+        break;
+
+    case EOpMulAssign:
+        // want to support vector *= scalar native ops in AST and lower, not smear, similarly for
+        // matrix *= scalar, etc.
+
+    case EOpAddAssign:
+    case EOpSubAssign:
+    case EOpDivAssign:
+    case EOpAndAssign:
+    case EOpInclusiveOrAssign:
+    case EOpExclusiveOrAssign:
+    case EOpRightShiftAssign:
+    case EOpLeftShiftAssign:
+        if (node->getVectorSize() == 1)
+            return node;
+        break;
+
     case EOpAssign:
     case EOpAssign:
+        break;
+
+    case EOpMix:
+        break;
+
+    default:
+        return node;
+    }
+
+    return addShapeConversion(type, node);
+}
+
+// Convert the nodes' shapes to be compatible for the operation 'op'.
+//
+// This implements policy, it call addShapeConversion() for the mechanism.
+//
+// Generally, the AST represents allowed GLSL shapes, so this isn't needed
+// for GLSL.  Bad shapes are caught in conversion or promotion.
+//
+void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode)
+{
+    // some source languages don't do this
+    switch (source) {
+    case EShSourceHlsl:
+        break;
+    case EShSourceGlsl:
+    default:
+        return;
+    }
+
+    // some operations don't do this
+    // 'break' will mean attempt bidirectional conversion
+    switch (op) {
+    case EOpMulAssign:
+    case EOpAssign:
+    case EOpAddAssign:
+    case EOpSubAssign:
+    case EOpDivAssign:
+    case EOpAndAssign:
+    case EOpInclusiveOrAssign:
+    case EOpExclusiveOrAssign:
+    case EOpRightShiftAssign:
+    case EOpLeftShiftAssign:
+        // switch to unidirectional conversion (the lhs can't change)
+        rhsNode = addUniShapeConversion(op, lhsNode->getType(), rhsNode);
+        return;
+
+    case EOpAdd:
+    case EOpSub:
+    case EOpMul:
+    case EOpDiv:
+        // want to support vector * scalar native ops in AST and lower, not smear, similarly for
+        // matrix * vector, etc.
+        if (lhsNode->getVectorSize() == 1 || rhsNode->getVectorSize() == 1)
+            return;
+        break;
+
+    case EOpRightShift:
+    case EOpLeftShift:
+        // can natively support the right operand being a scalar and the left a vector,
+        // but not the reverse
+        if (rhsNode->getVectorSize() == 1)
+            return;
+        break;
+
     case EOpLessThan:
     case EOpLessThan:
     case EOpGreaterThan:
     case EOpGreaterThan:
     case EOpLessThanEqual:
     case EOpLessThanEqual:
     case EOpGreaterThanEqual:
     case EOpGreaterThanEqual:
+
     case EOpEqual:
     case EOpEqual:
     case EOpNotEqual:
     case EOpNotEqual:
-    case EOpFunctionCall:
-    case EOpReturn:
+
     case EOpLogicalAnd:
     case EOpLogicalAnd:
     case EOpLogicalOr:
     case EOpLogicalOr:
     case EOpLogicalXor:
     case EOpLogicalXor:
+
+    case EOpAnd:
+    case EOpInclusiveOr:
+    case EOpExclusiveOr:
+
+    case EOpMix:
         break;
         break;
+
     default:
     default:
-        return node;
+        return;
     }
     }
 
 
+    // Do bidirectional conversions
+    if (lhsNode->getType().isScalarOrVec1() || rhsNode->getType().isScalarOrVec1()) {
+        if (lhsNode->getType().isScalarOrVec1())
+            lhsNode = addShapeConversion(rhsNode->getType(), lhsNode);
+        else
+            rhsNode = addShapeConversion(lhsNode->getType(), rhsNode);
+    }
+    lhsNode = addShapeConversion(rhsNode->getType(), lhsNode);
+    rhsNode = addShapeConversion(lhsNode->getType(), rhsNode);
+}
+
+// Convert the node's shape of type for the given type. It's not necessarily
+// an error if they are different and not converted, as some operations accept
+// mixed types.  Promotion will do final shape checking.
+//
+// If there is a chance of two nodes, with conversions possible in each direction,
+// the policy for what to ask for must be in the caller; this will do what is asked.
+//
+// Return 'node' if no conversion was done. Promotion handles final shape
+// checking.
+//
+TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped* node)
+{
+    // no conversion needed
+    if (node->getType() == type)
+        return node;
+
     // structures and arrays don't change shape, either to or from
     // structures and arrays don't change shape, either to or from
     if (node->getType().isStruct() || node->getType().isArray() ||
     if (node->getType().isStruct() || node->getType().isArray() ||
         type.isStruct() || type.isArray())
         type.isStruct() || type.isArray())
@@ -831,12 +1043,12 @@ TIntermTyped* TIntermediate::addShapeConversion(TOperator op, const TType& type,
     // The new node that handles the conversion
     // The new node that handles the conversion
     TOperator constructorOp = mapTypeToConstructorOp(type);
     TOperator constructorOp = mapTypeToConstructorOp(type);
 
 
-    // scalar -> smeared -> vector, or
-    // vec1 -> scalar, or
-    // bigger vector -> smaller vector or scalar
-    if ((type.isVector() && node->getType().isScalar()) ||
-        (node->getType().isVector() && node->getVectorSize() == 1 && type.isScalar()) ||
-        (node->getVectorSize() > type.getVectorSize() && type.isVector()))
+    // scalar -> vector or vec1 -> vector or
+    // vector -> scalar or
+    // bigger vector -> smaller vector
+    if ((node->getType().isScalarOrVec1() && type.isVector()) ||
+        (node->getType().isVector() && type.isScalar()) ||
+        (node->isVector() && type.isVector() && node->getVectorSize() > type.getVectorSize()))
         return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
         return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc());
 
 
     return node;
     return node;
@@ -894,6 +1106,10 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
         case EbtUint:
         case EbtUint:
         case EbtInt64:
         case EbtInt64:
         case EbtUint64:
         case EbtUint64:
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:
+        case EbtUint16:
+#endif
         case EbtFloat:
         case EbtFloat:
         case EbtDouble:
         case EbtDouble:
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
@@ -907,6 +1123,10 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
         switch (from) {
         switch (from) {
         case EbtInt:
         case EbtInt:
         case EbtUint:
         case EbtUint:
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:
+        case EbtUint16:
+#endif
         case EbtFloat:
         case EbtFloat:
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
         case EbtFloat16:
         case EbtFloat16:
@@ -920,8 +1140,12 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
     case EbtUint:
     case EbtUint:
         switch (from) {
         switch (from) {
         case EbtInt:
         case EbtInt:
-            return version >= 400;
+            return version >= 400 || (source == EShSourceHlsl);
         case EbtUint:
         case EbtUint:
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:
+        case EbtUint16:
+#endif
             return true;
             return true;
         case EbtBool:
         case EbtBool:
             return (source == EShSourceHlsl);
             return (source == EShSourceHlsl);
@@ -931,6 +1155,9 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
     case EbtInt:
     case EbtInt:
         switch (from) {
         switch (from) {
         case EbtInt:
         case EbtInt:
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:
+#endif
             return true;
             return true;
         case EbtBool:
         case EbtBool:
             return (source == EShSourceHlsl);
             return (source == EShSourceHlsl);
@@ -943,6 +1170,10 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
         case EbtUint:
         case EbtUint:
         case EbtInt64:
         case EbtInt64:
         case EbtUint64:
         case EbtUint64:
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:
+        case EbtUint16:
+#endif
             return true;
             return true;
         default:
         default:
             return false;
             return false;
@@ -951,10 +1182,32 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
         switch (from) {
         switch (from) {
         case EbtInt:
         case EbtInt:
         case EbtInt64:
         case EbtInt64:
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:
+#endif
+            return true;
+        default:
+            return false;
+        }
+#ifdef AMD_EXTENSIONS
+    case EbtFloat16:
+        switch (from) {
+        case EbtInt16:
+        case EbtUint16:
+        case EbtFloat16:
             return true;
             return true;
         default:
         default:
             return false;
             return false;
         }
         }
+    case EbtUint16:
+        switch (from) {
+        case EbtInt16:
+        case EbtUint16:
+            return true;
+        default:
+            return false;
+        }
+#endif
     default:
     default:
         return false;
         return false;
     }
     }
@@ -1094,21 +1347,79 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
         break;
         break;
 #endif
 #endif
     case EbtInt:
     case EbtInt:
-        switch(type.getVectorSize()) {
-        case 1: op = EOpConstructInt;   break;
-        case 2: op = EOpConstructIVec2; break;
-        case 3: op = EOpConstructIVec3; break;
-        case 4: op = EOpConstructIVec4; break;
-        default: break; // some compilers want this
+        if (type.getMatrixCols()) {
+            switch (type.getMatrixCols()) {
+            case 2:
+                switch (type.getMatrixRows()) {
+                case 2: op = EOpConstructIMat2x2; break;
+                case 3: op = EOpConstructIMat2x3; break;
+                case 4: op = EOpConstructIMat2x4; break;
+                default: break; // some compilers want this
+                }
+                break;
+            case 3:
+                switch (type.getMatrixRows()) {
+                case 2: op = EOpConstructIMat3x2; break;
+                case 3: op = EOpConstructIMat3x3; break;
+                case 4: op = EOpConstructIMat3x4; break;
+                default: break; // some compilers want this
+                }
+                break;
+            case 4:
+                switch (type.getMatrixRows()) {
+                case 2: op = EOpConstructIMat4x2; break;
+                case 3: op = EOpConstructIMat4x3; break;
+                case 4: op = EOpConstructIMat4x4; break;
+                default: break; // some compilers want this
+                }
+                break;
+            }
+        } else {
+            switch(type.getVectorSize()) {
+            case 1: op = EOpConstructInt;   break;
+            case 2: op = EOpConstructIVec2; break;
+            case 3: op = EOpConstructIVec3; break;
+            case 4: op = EOpConstructIVec4; break;
+            default: break; // some compilers want this
+            }
         }
         }
         break;
         break;
     case EbtUint:
     case EbtUint:
-        switch(type.getVectorSize()) {
-        case 1: op = EOpConstructUint;  break;
-        case 2: op = EOpConstructUVec2; break;
-        case 3: op = EOpConstructUVec3; break;
-        case 4: op = EOpConstructUVec4; break;
-        default: break; // some compilers want this
+        if (type.getMatrixCols()) {
+            switch (type.getMatrixCols()) {
+            case 2:
+                switch (type.getMatrixRows()) {
+                case 2: op = EOpConstructUMat2x2; break;
+                case 3: op = EOpConstructUMat2x3; break;
+                case 4: op = EOpConstructUMat2x4; break;
+                default: break; // some compilers want this
+                }
+                break;
+            case 3:
+                switch (type.getMatrixRows()) {
+                case 2: op = EOpConstructUMat3x2; break;
+                case 3: op = EOpConstructUMat3x3; break;
+                case 4: op = EOpConstructUMat3x4; break;
+                default: break; // some compilers want this
+                }
+                break;
+            case 4:
+                switch (type.getMatrixRows()) {
+                case 2: op = EOpConstructUMat4x2; break;
+                case 3: op = EOpConstructUMat4x3; break;
+                case 4: op = EOpConstructUMat4x4; break;
+                default: break; // some compilers want this
+                }
+                break;
+            }
+        } else {
+            switch(type.getVectorSize()) {
+            case 1: op = EOpConstructUint;  break;
+            case 2: op = EOpConstructUVec2; break;
+            case 3: op = EOpConstructUVec3; break;
+            case 4: op = EOpConstructUVec4; break;
+            default: break; // some compilers want this
+            }
         }
         }
         break;
         break;
     case EbtInt64:
     case EbtInt64:
@@ -1129,15 +1440,64 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
         default: break; // some compilers want this
         default: break; // some compilers want this
         }
         }
         break;
         break;
-    case EbtBool:
+#ifdef AMD_EXTENSIONS
+    case EbtInt16:
         switch(type.getVectorSize()) {
         switch(type.getVectorSize()) {
-        case 1:  op = EOpConstructBool;  break;
-        case 2:  op = EOpConstructBVec2; break;
-        case 3:  op = EOpConstructBVec3; break;
-        case 4:  op = EOpConstructBVec4; break;
+        case 1: op = EOpConstructInt16;   break;
+        case 2: op = EOpConstructI16Vec2; break;
+        case 3: op = EOpConstructI16Vec3; break;
+        case 4: op = EOpConstructI16Vec4; break;
         default: break; // some compilers want this
         default: break; // some compilers want this
         }
         }
         break;
         break;
+    case EbtUint16:
+        switch(type.getVectorSize()) {
+        case 1: op = EOpConstructUint16;  break;
+        case 2: op = EOpConstructU16Vec2; break;
+        case 3: op = EOpConstructU16Vec3; break;
+        case 4: op = EOpConstructU16Vec4; break;
+        default: break; // some compilers want this
+        }
+        break;
+#endif
+    case EbtBool:
+        if (type.getMatrixCols()) {
+            switch (type.getMatrixCols()) {
+            case 2:
+                switch (type.getMatrixRows()) {
+                case 2: op = EOpConstructBMat2x2; break;
+                case 3: op = EOpConstructBMat2x3; break;
+                case 4: op = EOpConstructBMat2x4; break;
+                default: break; // some compilers want this
+                }
+                break;
+            case 3:
+                switch (type.getMatrixRows()) {
+                case 2: op = EOpConstructBMat3x2; break;
+                case 3: op = EOpConstructBMat3x3; break;
+                case 4: op = EOpConstructBMat3x4; break;
+                default: break; // some compilers want this
+                }
+                break;
+            case 4:
+                switch (type.getMatrixRows()) {
+                case 2: op = EOpConstructBMat4x2; break;
+                case 3: op = EOpConstructBMat4x3; break;
+                case 4: op = EOpConstructBMat4x4; break;
+                default: break; // some compilers want this
+                }
+                break;
+            }
+        } else {
+            switch(type.getVectorSize()) {
+            case 1:  op = EOpConstructBool;  break;
+            case 2:  op = EOpConstructBVec2; break;
+            case 3:  op = EOpConstructBVec3; break;
+            case 4:  op = EOpConstructBVec4; break;
+            default: break; // some compilers want this
+            }
+        }
+        break;
     default:
     default:
         break;
         break;
     }
     }
@@ -1158,15 +1518,15 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
         return nullptr;
         return nullptr;
 
 
     TIntermAggregate* aggNode = nullptr;
     TIntermAggregate* aggNode = nullptr;
-    if (left)
+    if (left != nullptr)
         aggNode = left->getAsAggregate();
         aggNode = left->getAsAggregate();
-    if (! aggNode || aggNode->getOp() != EOpNull) {
+    if (aggNode == nullptr || aggNode->getOp() != EOpNull) {
         aggNode = new TIntermAggregate;
         aggNode = new TIntermAggregate;
-        if (left)
+        if (left != nullptr)
             aggNode->getSequence().push_back(left);
             aggNode->getSequence().push_back(left);
     }
     }
 
 
-    if (right)
+    if (right != nullptr)
         aggNode->getSequence().push_back(right);
         aggNode->getSequence().push_back(right);
 
 
     return aggNode;
     return aggNode;
@@ -1271,7 +1631,8 @@ TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type,
 //
 //
 // For "?:" test nodes.  There are three children; a condition,
 // For "?:" test nodes.  There are three children; a condition,
 // a true path, and a false path.  The two paths are specified
 // a true path, and a false path.  The two paths are specified
-// as separate parameters.
+// as separate parameters. For vector 'cond', the true and false
+// are not paths, but vectors to mix.
 //
 //
 // Specialization constant operations include
 // Specialization constant operations include
 //     - The ternary operator ( ? : )
 //     - The ternary operator ( ? : )
@@ -1300,14 +1661,39 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
             return nullptr;
             return nullptr;
     }
     }
 
 
+    // Handle a vector condition as a mix
+    if (!cond->getType().isScalarOrVec1()) {
+        TType targetVectorType(trueBlock->getType().getBasicType(), EvqTemporary,
+                               cond->getType().getVectorSize());
+        // smear true/false operands as needed
+        trueBlock = addUniShapeConversion(EOpMix, targetVectorType, trueBlock);
+        falseBlock = addUniShapeConversion(EOpMix, targetVectorType, falseBlock);
+
+        // After conversion, types have to match.
+        if (falseBlock->getType() != trueBlock->getType())
+            return nullptr;
+
+        // make the mix operation
+        TIntermAggregate* mix = makeAggregate(loc);
+        mix = growAggregate(mix, falseBlock);
+        mix = growAggregate(mix, trueBlock);
+        mix = growAggregate(mix, cond);
+        mix->setType(targetVectorType);
+        mix->setOp(EOpMix);
+
+        return mix;
+    }
+
+    // Now have a scalar condition...
+
+    // Convert true and false expressions to matching types
+    addBiShapeConversion(EOpMix, trueBlock, falseBlock);
+
     // After conversion, types have to match.
     // After conversion, types have to match.
     if (falseBlock->getType() != trueBlock->getType())
     if (falseBlock->getType() != trueBlock->getType())
         return nullptr;
         return nullptr;
 
 
-    //
-    // See if all the operands are constant, then fold it otherwise not.
-    //
-
+    // Eliminate the selection when the condition is a scalar and all operands are constant.
     if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
     if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
         if (cond->getAsConstantUnion()->getConstArray()[0].getBConst())
         if (cond->getAsConstantUnion()->getConstArray()[0].getBConst())
             return trueBlock;
             return trueBlock;
@@ -1381,6 +1767,24 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned long long u64, co
     return addConstantUnion(unionArray, TType(EbtUint64, EvqConst), loc, literal);
     return addConstantUnion(unionArray, TType(EbtUint64, EvqConst), loc, literal);
 }
 }
 
 
+#ifdef AMD_EXTENSIONS
+TIntermConstantUnion* TIntermediate::addConstantUnion(short i16, const TSourceLoc& loc, bool literal) const
+{
+    TConstUnionArray unionArray(1);
+    unionArray[0].setIConst(i16);
+
+    return addConstantUnion(unionArray, TType(EbtInt16, EvqConst), loc, literal);
+}
+
+TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned short u16, const TSourceLoc& loc, bool literal) const
+{
+    TConstUnionArray unionArray(1);
+    unionArray[0].setUConst(u16);
+
+    return addConstantUnion(unionArray, TType(EbtUint16, EvqConst), loc, literal);
+}
+#endif
+
 TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, const TSourceLoc& loc, bool literal) const
 TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, const TSourceLoc& loc, bool literal) const
 {
 {
     TConstUnionArray unionArray(1);
     TConstUnionArray unionArray(1);
@@ -1478,10 +1882,11 @@ const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool
 //
 //
 // Create while and do-while loop nodes.
 // Create while and do-while loop nodes.
 //
 //
-TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc)
+TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TLoopControl control)
 {
 {
     TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
     TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
     node->setLoc(loc);
     node->setLoc(loc);
+    node->setLoopControl(control);
 
 
     return node;
     return node;
 }
 }
@@ -1489,13 +1894,19 @@ TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TInte
 //
 //
 // Create a for-loop sequence.
 // Create a for-loop sequence.
 //
 //
-TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc)
+TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TLoopControl control)
 {
 {
     TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
     TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
     node->setLoc(loc);
     node->setLoc(loc);
-
-    // make a sequence of the initializer and statement
-    TIntermAggregate* loopSequence = makeAggregate(initializer, loc);
+    node->setLoopControl(control);
+
+    // make a sequence of the initializer and statement, but try to reuse the
+    // aggregate already created for whatever is in the initializer, if there is one
+    TIntermAggregate* loopSequence = (initializer == nullptr ||
+                                      initializer->getAsAggregate() == nullptr) ? makeAggregate(initializer, loc)
+                                                                                : initializer->getAsAggregate();
+    if (loopSequence != nullptr && loopSequence->getOp() == EOpSequence)
+        loopSequence->setOp(EOpNull);
     loopSequence = growAggregate(loopSequence, node);
     loopSequence = growAggregate(loopSequence, node);
     loopSequence->setOperator(EOpSequence);
     loopSequence->setOperator(EOpSequence);
 
 
@@ -1535,6 +1946,14 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/)
     // Propagate 'noContraction' label in backward from 'precise' variables.
     // Propagate 'noContraction' label in backward from 'precise' variables.
     glslang::PropagateNoContraction(*this);
     glslang::PropagateNoContraction(*this);
 
 
+    switch (textureSamplerTransformMode) {
+    case EShTexSampTransKeep:
+        break;
+    case EShTexSampTransUpgradeTextureRemoveSampler:
+        performTextureUpgradeAndSamplerRemovalTransformation(root);
+        break;
+    }
+
     return true;
     return true;
 }
 }
 
 
@@ -1725,6 +2144,30 @@ bool TIntermediate::isSpecializationOperation(const TIntermOperator& node) const
     case EOpConvUintToInt64:
     case EOpConvUintToInt64:
     case EOpConvUint64ToInt:
     case EOpConvUint64ToInt:
     case EOpConvIntToUint64:
     case EOpConvIntToUint64:
+#ifdef AMD_EXTENSIONS
+    case EOpConvInt16ToBool:
+    case EOpConvBoolToInt16:
+    case EOpConvInt16ToInt:
+    case EOpConvIntToInt16:
+    case EOpConvInt16ToUint:
+    case EOpConvUintToInt16:
+    case EOpConvInt16ToInt64:
+    case EOpConvInt64ToInt16:
+    case EOpConvInt16ToUint64:
+    case EOpConvUint64ToInt16:
+    case EOpConvUint16ToBool:
+    case EOpConvBoolToUint16:
+    case EOpConvUint16ToInt:
+    case EOpConvIntToUint16:
+    case EOpConvUint16ToUint:
+    case EOpConvUintToUint16:
+    case EOpConvUint16ToInt64:
+    case EOpConvInt64ToUint16:
+    case EOpConvUint16ToUint64:
+    case EOpConvUint64ToUint16:
+    case EOpConvInt16ToUint16:
+    case EOpConvUint16ToInt16:
+#endif
 
 
     // unary operations
     // unary operations
     case EOpNegative:
     case EOpNegative:
@@ -1853,6 +2296,10 @@ bool TIntermediate::promoteUnary(TIntermUnary& node)
     case EOpBitwiseNot:
     case EOpBitwiseNot:
         if (operand->getBasicType() != EbtInt &&
         if (operand->getBasicType() != EbtInt &&
             operand->getBasicType() != EbtUint &&
             operand->getBasicType() != EbtUint &&
+#ifdef AMD_EXTENSIONS
+            operand->getBasicType() != EbtInt16 &&
+            operand->getBasicType() != EbtUint16 &&
+#endif
             operand->getBasicType() != EbtInt64 &&
             operand->getBasicType() != EbtInt64 &&
             operand->getBasicType() != EbtUint64)
             operand->getBasicType() != EbtUint64)
 
 
@@ -1867,6 +2314,10 @@ bool TIntermediate::promoteUnary(TIntermUnary& node)
             operand->getBasicType() != EbtUint &&
             operand->getBasicType() != EbtUint &&
             operand->getBasicType() != EbtInt64 &&
             operand->getBasicType() != EbtInt64 &&
             operand->getBasicType() != EbtUint64 &&
             operand->getBasicType() != EbtUint64 &&
+#ifdef AMD_EXTENSIONS
+            operand->getBasicType() != EbtInt16 &&
+            operand->getBasicType() != EbtUint16 &&
+#endif
             operand->getBasicType() != EbtFloat &&
             operand->getBasicType() != EbtFloat &&
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
             operand->getBasicType() != EbtFloat16 &&
             operand->getBasicType() != EbtFloat16 &&
@@ -1967,6 +2418,42 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
     // We now have only scalars, vectors, and matrices to worry about.
     // We now have only scalars, vectors, and matrices to worry about.
     //
     //
 
 
+    // HLSL implicitly promotes bool -> int for numeric operations.
+    // (Implicit conversions to make the operands match each other's types were already done.)
+    if (getSource() == EShSourceHlsl &&
+        (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool)) {
+        switch (op) {
+        case EOpLessThan:
+        case EOpGreaterThan:
+        case EOpLessThanEqual:
+        case EOpGreaterThanEqual:
+
+        case EOpRightShift:
+        case EOpLeftShift:
+
+        case EOpMod:
+
+        case EOpAnd:
+        case EOpInclusiveOr:
+        case EOpExclusiveOr:
+
+        case EOpAdd:
+        case EOpSub:
+        case EOpDiv:
+        case EOpMul:
+            left = addConversion(op, TType(EbtInt, EvqTemporary, left->getVectorSize()), left);
+            right = addConversion(op, TType(EbtInt, EvqTemporary, right->getVectorSize()), right);
+            if (left == nullptr || right == nullptr)
+                return false;
+            node.setLeft(left);
+            node.setRight(right);
+            break;
+
+        default:
+            break;
+        }
+    }
+
     // Do general type checks against individual operands (comparing left and right is coming up, checking mixed shapes after that)
     // Do general type checks against individual operands (comparing left and right is coming up, checking mixed shapes after that)
     switch (op) {
     switch (op) {
     case EOpLessThan:
     case EOpLessThan:
@@ -2037,8 +2524,14 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
 
 
         // Check for integer-only operands.
         // Check for integer-only operands.
         if ((left->getBasicType() != EbtInt &&  left->getBasicType() != EbtUint &&
         if ((left->getBasicType() != EbtInt &&  left->getBasicType() != EbtUint &&
-             left->getBasicType() != EbtInt64 &&  left->getBasicType() != EbtUint64) ||
+#ifdef AMD_EXTENSIONS
+             left->getBasicType() != EbtInt16 && left->getBasicType() != EbtUint16 &&
+#endif
+             left->getBasicType() != EbtInt64 && left->getBasicType() != EbtUint64) ||
             (right->getBasicType() != EbtInt && right->getBasicType() != EbtUint &&
             (right->getBasicType() != EbtInt && right->getBasicType() != EbtUint &&
+#ifdef AMD_EXTENSIONS
+             right->getBasicType() != EbtInt16 && right->getBasicType() != EbtUint16 &&
+#endif
              right->getBasicType() != EbtInt64 && right->getBasicType() != EbtUint64))
              right->getBasicType() != EbtInt64 && right->getBasicType() != EbtUint64))
             return false;
             return false;
         if (left->isMatrix() || right->isMatrix())
         if (left->isMatrix() || right->isMatrix())
@@ -2079,8 +2572,6 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
     case EOpLogicalXor:
     case EOpLogicalXor:
         return left->getType() == right->getType();
         return left->getType() == right->getType();
 
 
-    // no shifts: they can mix types (scalar int can shift a vector uint, etc.)
-
     case EOpMod:
     case EOpMod:
     case EOpModAssign:
     case EOpModAssign:
 
 
@@ -2094,6 +2585,7 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
     case EOpAdd:
     case EOpAdd:
     case EOpSub:
     case EOpSub:
     case EOpDiv:
     case EOpDiv:
+
     case EOpAddAssign:
     case EOpAddAssign:
     case EOpSubAssign:
     case EOpSubAssign:
     case EOpDivAssign:
     case EOpDivAssign:
@@ -2118,7 +2610,7 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
         return true;
         return true;
 
 
     // Finish handling the case, for all ops, where there are two vectors of different sizes
     // Finish handling the case, for all ops, where there are two vectors of different sizes
-    if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize())
+    if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize() && right->getVectorSize() > 1)
         return false;
         return false;
 
 
     //
     //
@@ -2667,4 +3159,41 @@ bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TInt
            (node2.getType().getQualifier().isSpecConstant() && node1.getType().getQualifier().isConstant());
            (node2.getType().getQualifier().isSpecConstant() && node1.getType().getQualifier().isConstant());
 }
 }
 
 
+struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser {
+    bool visitAggregate(TVisit, TIntermAggregate* ag) override {
+        using namespace std;
+        TIntermSequence& seq = ag->getSequence();
+        // remove pure sampler variables
+        TIntermSequence::iterator newEnd = remove_if(seq.begin(), seq.end(), [](TIntermNode* node) {
+            TIntermSymbol* symbol = node->getAsSymbolNode();
+            if (!symbol)
+                return false;
+
+            return (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isPureSampler());
+        });
+        seq.erase(newEnd, seq.end());
+        // replace constructors with sampler/textures
+        // update textures into sampled textures
+        for_each(seq.begin(), seq.end(), [](TIntermNode*& node) {
+            TIntermSymbol* symbol = node->getAsSymbolNode();
+            if (!symbol) {
+                TIntermAggregate *constructor = node->getAsAggregate();
+                if (constructor && constructor->getOp() == EOpConstructTextureSampler) {
+                    if (!constructor->getSequence().empty())
+                        node = constructor->getSequence()[0];
+                }
+            } else if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) {
+                symbol->getWritableType().getSampler().combined = true;
+            }
+        });
+        return true;
+    }
+};
+
+void TIntermediate::performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root)
+{
+    TextureUpgradeAndSamplerRemovalTransform transform;
+    root->traverse(&transform);
+}
+
 } // end namespace glslang
 } // end namespace glslang

+ 2 - 0
src/libraries/glslang/glslang/MachineIndependent/LiveTraverser.h

@@ -33,6 +33,8 @@
 // POSSIBILITY OF SUCH DAMAGE.
 // POSSIBILITY OF SUCH DAMAGE.
 //
 //
 
 
+#pragma once
+
 #include "../Include/Common.h"
 #include "../Include/Common.h"
 #include "reflection.h"
 #include "reflection.h"
 #include "localintermediate.h"
 #include "localintermediate.h"

+ 15 - 31
src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp

@@ -226,7 +226,8 @@ void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op,
 // Add 'symbol' to the list of deferred linkage symbols, which
 // Add 'symbol' to the list of deferred linkage symbols, which
 // are later processed in finish(), at which point the symbol
 // are later processed in finish(), at which point the symbol
 // must still be valid.
 // must still be valid.
-// It is okay if the symbol's type will be subsequently edited.
+// It is okay if the symbol's type will be subsequently edited;
+// the modifications will be tracked.
 void TParseContextBase::trackLinkage(TSymbol& symbol)
 void TParseContextBase::trackLinkage(TSymbol& symbol)
 {
 {
     if (!parsingBuiltins)
     if (!parsingBuiltins)
@@ -530,21 +531,20 @@ void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TStrin
 // Make the passed-in variable information become a member of the
 // Make the passed-in variable information become a member of the
 // global uniform block.  If this doesn't exist yet, make it.
 // global uniform block.  If this doesn't exist yet, make it.
 //
 //
-void TParseContextBase::growGlobalUniformBlock(TSourceLoc& loc, TType& memberType, TString& memberName, TTypeList* typeList)
+void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& memberType, const TString& memberName, TTypeList* typeList)
 {
 {
-    // make the global block, if not yet made
+    // Make the global block, if not yet made.
     if (globalUniformBlock == nullptr) {
     if (globalUniformBlock == nullptr) {
-        TString& blockName = *NewPoolTString(getGlobalUniformBlockName());
         TQualifier blockQualifier;
         TQualifier blockQualifier;
         blockQualifier.clear();
         blockQualifier.clear();
         blockQualifier.storage = EvqUniform;
         blockQualifier.storage = EvqUniform;
-        TType blockType(new TTypeList, blockName, blockQualifier);
-        TString* instanceName = NewPoolTString("");
-        globalUniformBlock = new TVariable(instanceName, blockType, true);
+        TType blockType(new TTypeList, *NewPoolTString(getGlobalUniformBlockName()), blockQualifier);
+        setUniformBlockDefaults(blockType);
+        globalUniformBlock = new TVariable(NewPoolTString(""), blockType, true);
         firstNewMember = 0;
         firstNewMember = 0;
     }
     }
 
 
-    // add the requested member as a member to the block
+    // Add the requested member as a member to the global block.
     TType* type = new TType;
     TType* type = new TType;
     type->shallowCopy(memberType);
     type->shallowCopy(memberType);
     type->setFieldName(memberName);
     type->setFieldName(memberName);
@@ -552,36 +552,20 @@ void TParseContextBase::growGlobalUniformBlock(TSourceLoc& loc, TType& memberTyp
         type->setStruct(typeList);
         type->setStruct(typeList);
     TTypeLoc typeLoc = {type, loc};
     TTypeLoc typeLoc = {type, loc};
     globalUniformBlock->getType().getWritableStruct()->push_back(typeLoc);
     globalUniformBlock->getType().getWritableStruct()->push_back(typeLoc);
-}
-
-//
-// Insert into the symbol table the global uniform block created in
-// growGlobalUniformBlock(). The variables added as members won't be
-// found unless this is done.
-//
-bool TParseContextBase::insertGlobalUniformBlock()
-{
-    if (globalUniformBlock == nullptr)
-        return true;
 
 
-    int numMembers = (int)globalUniformBlock->getType().getStruct()->size();
-    bool inserted = false;
+    // Insert into the symbol table.
     if (firstNewMember == 0) {
     if (firstNewMember == 0) {
         // This is the first request; we need a normal symbol table insert
         // This is the first request; we need a normal symbol table insert
-        inserted = symbolTable.insert(*globalUniformBlock);
-        if (inserted)
+        if (symbolTable.insert(*globalUniformBlock))
             trackLinkage(*globalUniformBlock);
             trackLinkage(*globalUniformBlock);
-    } else if (firstNewMember <= numMembers) {
+        else
+            error(loc, "failed to insert the global constant buffer", "uniform", "");
+    } else {
         // This is a follow-on request; we need to amend the first insert
         // This is a follow-on request; we need to amend the first insert
-        inserted = symbolTable.amend(*globalUniformBlock, firstNewMember);
-    }
-
-    if (inserted) {
-        finalizeGlobalUniformBlockLayout(*globalUniformBlock);
-        firstNewMember = numMembers;
+        symbolTable.amend(*globalUniformBlock, firstNewMember);
     }
     }
 
 
-    return inserted;
+    ++firstNewMember;
 }
 }
 
 
 void TParseContextBase::finish()
 void TParseContextBase::finish()

+ 179 - 36
src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp

@@ -51,8 +51,8 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b
                              int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
                              int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
                              TInfoSink& infoSink, bool forwardCompatible, EShMessages messages) :
                              TInfoSink& infoSink, bool forwardCompatible, EShMessages messages) :
             TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
             TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
-            contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), statementNestingLevel(0),
-            inMain(false), postMainReturn(false), currentFunctionType(nullptr), blockName(nullptr),
+            inMain(false),
+            blockName(nullptr),
             limits(resources.limits),
             limits(resources.limits),
             atomicUintOffsets(nullptr), anyIndexLimits(false)
             atomicUintOffsets(nullptr), anyIndexLimits(false)
 {
 {
@@ -255,6 +255,10 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>&
             error(loc, "\")\" expected to end 'debug' pragma", "#pragma", "");
             error(loc, "\")\" expected to end 'debug' pragma", "#pragma", "");
             return;
             return;
         }
         }
+    } else if (spvVersion.spv > 0 && tokens[0].compare("use_storage_buffer") == 0) {
+        if (tokens.size() != 1)
+            error(loc, "extra tokens", "#pragma", "");
+        intermediate.setUseStorageBuffer();
     }
     }
 }
 }
 
 
@@ -342,10 +346,8 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
     TIntermTyped* result = nullptr;
     TIntermTyped* result = nullptr;
 
 
     int indexValue = 0;
     int indexValue = 0;
-    if (index->getQualifier().isFrontEndConstant()) {
+    if (index->getQualifier().isFrontEndConstant())
         indexValue = index->getAsConstantUnion()->getConstArray()[0].getIConst();
         indexValue = index->getAsConstantUnion()->getConstArray()[0].getIConst();
-        checkIndex(loc, base->getType(), indexValue);
-    }
 
 
     variableCheck(base);
     variableCheck(base);
     if (! base->isArray() && ! base->isMatrix() && ! base->isVector()) {
     if (! base->isArray() && ! base->isMatrix() && ! base->isVector()) {
@@ -353,10 +355,12 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
             error(loc, " left of '[' is not of type array, matrix, or vector ", base->getAsSymbolNode()->getName().c_str(), "");
             error(loc, " left of '[' is not of type array, matrix, or vector ", base->getAsSymbolNode()->getName().c_str(), "");
         else
         else
             error(loc, " left of '[' is not of type array, matrix, or vector ", "expression", "");
             error(loc, " left of '[' is not of type array, matrix, or vector ", "expression", "");
-    } else if (base->getType().getQualifier().isFrontEndConstant() && index->getQualifier().isFrontEndConstant())
+    } else if (base->getType().getQualifier().isFrontEndConstant() && index->getQualifier().isFrontEndConstant()) {
+        // both base and index are front-end constants
+        checkIndex(loc, base->getType(), indexValue);
         return intermediate.foldDereference(base, indexValue, loc);
         return intermediate.foldDereference(base, indexValue, loc);
-    else {
-        // at least one of base and index is variable...
+    } else {
+        // at least one of base and index is not a front-end constant variable...
 
 
         if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
         if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
             handleIoResizeArrayAccess(loc, base);
             handleIoResizeArrayAccess(loc, base);
@@ -364,6 +368,8 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
         if (index->getQualifier().isFrontEndConstant()) {
         if (index->getQualifier().isFrontEndConstant()) {
             if (base->getType().isImplicitlySizedArray())
             if (base->getType().isImplicitlySizedArray())
                 updateImplicitArraySize(loc, base, indexValue);
                 updateImplicitArraySize(loc, base, indexValue);
+            else
+                checkIndex(loc, base->getType(), indexValue);
             result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
             result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
         } else {
         } else {
             if (base->getType().isImplicitlySizedArray()) {
             if (base->getType().isImplicitlySizedArray()) {
@@ -906,7 +912,7 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc,
     loopNestingLevel = 0;
     loopNestingLevel = 0;
     statementNestingLevel = 0;
     statementNestingLevel = 0;
     controlFlowNestingLevel = 0;
     controlFlowNestingLevel = 0;
-    postMainReturn = false;
+    postEntryPointReturn = false;
 
 
     return paramNodes;
     return paramNodes;
 }
 }
@@ -1187,7 +1193,7 @@ void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op)
                 error(loc, "tessellation control barrier() cannot be placed within flow control", "", "");
                 error(loc, "tessellation control barrier() cannot be placed within flow control", "", "");
             if (! inMain)
             if (! inMain)
                 error(loc, "tessellation control barrier() must be in main()", "", "");
                 error(loc, "tessellation control barrier() must be in main()", "", "");
-            else if (postMainReturn)
+            else if (postEntryPointReturn)
                 error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", "");
                 error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", "");
         }
         }
         break;
         break;
@@ -1436,9 +1442,56 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
                 error(loc, "must be a compile-time constant:", feature, "component argument");
                 error(loc, "must be a compile-time constant:", feature, "component argument");
         }
         }
 
 
+#ifdef AMD_EXTENSIONS
+        bool bias = false;
+        if (callNode.getOp() == EOpTextureGather)
+            bias = fnCandidate.getParamCount() > 3;
+        else if (callNode.getOp() == EOpTextureGatherOffset ||
+                 callNode.getOp() == EOpTextureGatherOffsets)
+            bias = fnCandidate.getParamCount() > 4;
+
+        if (bias) {
+            TString biasFeatureString = fnCandidate.getName() + "with bias argument";
+            const char* feature = biasFeatureString.c_str();
+            profileRequires(loc, ~EEsProfile, 450, nullptr, feature);
+            requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature);
+        }
+#endif
+
         break;
         break;
     }
     }
 
 
+#ifdef AMD_EXTENSIONS
+    case EOpSparseTextureGather:
+    case EOpSparseTextureGatherOffset:
+    case EOpSparseTextureGatherOffsets:
+    {
+        bool bias = false;
+        if (callNode.getOp() == EOpSparseTextureGather)
+            bias = fnCandidate.getParamCount() > 4;
+        else if (callNode.getOp() == EOpSparseTextureGatherOffset ||
+                 callNode.getOp() == EOpSparseTextureGatherOffsets)
+            bias = fnCandidate.getParamCount() > 5;
+
+        if (bias) {
+            TString featureString = fnCandidate.getName() + "with bias argument";
+            const char* feature = featureString.c_str();
+            profileRequires(loc, ~EEsProfile, 450, nullptr, feature);
+            requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature);
+        }
+
+        break;
+    }
+
+    case EOpSparseTextureGatherLod:
+    case EOpSparseTextureGatherLodOffset:
+    case EOpSparseTextureGatherLodOffsets:
+    {
+        requireExtensions(loc, 1, &E_GL_ARB_sparse_texture2, fnCandidate.getName().c_str());
+        break;
+    }
+#endif
+
     case EOpTextureOffset:
     case EOpTextureOffset:
     case EOpTextureFetchOffset:
     case EOpTextureFetchOffset:
     case EOpTextureProjOffset:
     case EOpTextureProjOffset:
@@ -2096,6 +2149,17 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
     case EOpConstructDMat4x2:
     case EOpConstructDMat4x2:
     case EOpConstructDMat4x3:
     case EOpConstructDMat4x3:
     case EOpConstructDMat4x4:
     case EOpConstructDMat4x4:
+#ifdef AMD_EXTENSIONS
+    case EOpConstructF16Mat2x2:
+    case EOpConstructF16Mat2x3:
+    case EOpConstructF16Mat2x4:
+    case EOpConstructF16Mat3x2:
+    case EOpConstructF16Mat3x3:
+    case EOpConstructF16Mat3x4:
+    case EOpConstructF16Mat4x2:
+    case EOpConstructF16Mat4x3:
+    case EOpConstructF16Mat4x4:
+#endif
         constructingMatrix = true;
         constructingMatrix = true;
         break;
         break;
     default:
     default:
@@ -2156,6 +2220,10 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
             case EOpConstructUint:
             case EOpConstructUint:
             case EOpConstructInt64:
             case EOpConstructInt64:
             case EOpConstructUint64:
             case EOpConstructUint64:
+#ifdef AMD_EXTENSIONS
+            case EOpConstructInt16:
+            case EOpConstructUint16:
+#endif
             case EOpConstructBool:
             case EOpConstructBool:
             case EOpConstructBVec2:
             case EOpConstructBVec2:
             case EOpConstructBVec3:
             case EOpConstructBVec3:
@@ -2172,6 +2240,14 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
             case EOpConstructU64Vec2:
             case EOpConstructU64Vec2:
             case EOpConstructU64Vec3:
             case EOpConstructU64Vec3:
             case EOpConstructU64Vec4:
             case EOpConstructU64Vec4:
+#ifdef AMD_EXTENSIONS
+            case EOpConstructI16Vec2:
+            case EOpConstructI16Vec3:
+            case EOpConstructI16Vec4:
+            case EOpConstructU16Vec2:
+            case EOpConstructU16Vec3:
+            case EOpConstructU16Vec4:
+#endif
                 // This was the list of valid ones, if they aren't converting from float
                 // This was the list of valid ones, if they aren't converting from float
                 // and aren't making an array.
                 // and aren't making an array.
                 makeSpecConst = ! floatArgument && ! type.isArray();
                 makeSpecConst = ! floatArgument && ! type.isArray();
@@ -2464,6 +2540,9 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
     }
     }
 
 
     if (publicType.basicType == EbtInt   || publicType.basicType == EbtUint   ||
     if (publicType.basicType == EbtInt   || publicType.basicType == EbtUint   ||
+#ifdef AMD_EXTENSIONS
+        publicType.basicType == EbtInt16 || publicType.basicType == EbtUint16 ||
+#endif
         publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64 ||
         publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64 ||
         publicType.basicType == EbtDouble)
         publicType.basicType == EbtDouble)
         profileRequires(loc, EEsProfile, 300, nullptr, "shader input/output");
         profileRequires(loc, EEsProfile, 300, nullptr, "shader input/output");
@@ -2474,6 +2553,9 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
     if (!qualifier.flat) {
     if (!qualifier.flat) {
 #endif
 #endif
         if (publicType.basicType == EbtInt    || publicType.basicType == EbtUint   ||
         if (publicType.basicType == EbtInt    || publicType.basicType == EbtUint   ||
+#ifdef AMD_EXTENSIONS
+            publicType.basicType == EbtInt16  || publicType.basicType == EbtUint16 ||
+#endif
             publicType.basicType == EbtInt64  || publicType.basicType == EbtUint64 ||
             publicType.basicType == EbtInt64  || publicType.basicType == EbtUint64 ||
             publicType.basicType == EbtDouble ||
             publicType.basicType == EbtDouble ||
             (publicType.userDef && (publicType.userDef->containsBasicType(EbtInt)    ||
             (publicType.userDef && (publicType.userDef->containsBasicType(EbtInt)    ||
@@ -2894,7 +2976,7 @@ void TParseContext::structArrayCheck(const TSourceLoc& /*loc*/, const TType& typ
     }
     }
 }
 }
 
 
-void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& qualifier, const TArraySizes* arraySizes, bool initializer, bool lastMember)
+void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qualifier, const TArraySizes* arraySizes, bool initializer, bool lastMember)
 {
 {
     assert(arraySizes);
     assert(arraySizes);
 
 
@@ -2906,10 +2988,13 @@ void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& q
     if (initializer)
     if (initializer)
         return;
         return;
 
 
-    // No environment lets any non-outer-dimension that's to be implicitly sized
+    // No environment allows any non-outer-dimension to be implicitly sized
     if (arraySizes->isInnerImplicit())
     if (arraySizes->isInnerImplicit())
         error(loc, "only outermost dimension of an array of arrays can be implicitly sized", "[]", "");
         error(loc, "only outermost dimension of an array of arrays can be implicitly sized", "[]", "");
 
 
+    if (arraySizes->isInnerSpecialization())
+        error(loc, "only outermost dimension of an array of arrays can be a specialization constant", "[]", "");
+
     // desktop always allows outer-dimension-unsized variable arrays,
     // desktop always allows outer-dimension-unsized variable arrays,
     if (profile != EEsProfile)
     if (profile != EEsProfile)
         return;
         return;
@@ -2990,7 +3075,7 @@ void TParseContext::arrayDimMerge(TType& type, const TArraySizes* sizes)
 // Do all the semantic checking for declaring or redeclaring an array, with and
 // Do all the semantic checking for declaring or redeclaring an array, with and
 // without a size, and make the right changes to the symbol table.
 // without a size, and make the right changes to the symbol table.
 //
 //
-void TParseContext::declareArray(const TSourceLoc& loc, TString& identifier, const TType& type, TSymbol*& symbol)
+void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifier, const TType& type, TSymbol*& symbol)
 {
 {
     if (symbol == nullptr) {
     if (symbol == nullptr) {
         bool currentScope;
         bool currentScope;
@@ -4196,6 +4281,10 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
         if (id.compare(0, 11, "local_size_") == 0) {
         if (id.compare(0, 11, "local_size_") == 0) {
             profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize");
             profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize");
             profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize");
             profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize");
+            if (id.size() == 12 && value == 0) {
+                error(loc, "must be at least 1", id.c_str(), "");
+                return;
+            }
             if (id == "local_size_x") {
             if (id == "local_size_x") {
                 publicType.shaderQualifiers.localSize[0] = value;
                 publicType.shaderQualifiers.localSize[0] = value;
                 return;
                 return;
@@ -4246,7 +4335,6 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
 // This is also true for overriding layout-qualifier-names, where one
 // This is also true for overriding layout-qualifier-names, where one
 // overrides the other (e.g., row_major vs. column_major); only the last
 // overrides the other (e.g., row_major vs. column_major); only the last
 // occurrence has any effect."
 // occurrence has any effect."
-//
 void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifier& src, bool inheritOnly)
 void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifier& src, bool inheritOnly)
 {
 {
     if (src.hasMatrix())
     if (src.hasMatrix())
@@ -4328,6 +4416,25 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb
         }
         }
     }
     }
 
 
+    // user-variable location check, which are required for SPIR-V in/out:
+    //  - variables have it directly,
+    //  - blocks have it on each member (already enforced), so check first one
+    if (spvVersion.spv > 0 && !parsingBuiltins && qualifier.builtIn == EbvNone &&
+        !qualifier.hasLocation() && !intermediate.getAutoMapLocations()) {
+
+        switch (qualifier.storage) {
+        case EvqVaryingIn:
+        case EvqVaryingOut:
+            if (type.getBasicType() != EbtBlock || 
+                (!(*type.getStruct())[0].type->getQualifier().hasLocation() && 
+                  (*type.getStruct())[0].type->getQualifier().builtIn == EbvNone))
+                error(loc, "SPIR-V requires location for user input/output", "location", "");
+            break;
+        default:
+            break;
+        }
+    }
+
     // Check packing and matrix
     // Check packing and matrix
     if (qualifier.hasUniformLayout()) {
     if (qualifier.hasUniformLayout()) {
         switch (qualifier.storage) {
         switch (qualifier.storage) {
@@ -4355,6 +4462,22 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb
     }
     }
 }
 }
 
 
+// "For some blocks declared as arrays, the location can only be applied at the block level:
+// When a block is declared as an array where additional locations are needed for each member
+// for each block array element, it is a compile-time error to specify locations on the block
+// members.  That is, when locations would be under specified by applying them on block members,
+// they are not allowed on block members.  For arrayed interfaces (those generally having an
+// extra level of arrayness due to interface expansion), the outer array is stripped before
+// applying this rule."
+void TParseContext::layoutMemberLocationArrayCheck(const TSourceLoc& loc, bool memberWithLocation, TArraySizes* arraySizes)
+{
+    if (memberWithLocation && arraySizes != nullptr) {
+        if (arraySizes->getNumDims() > (currentBlockQualifier.isArrayedIo(language) ? 1 : 0))
+            error(loc, "cannot use in a block array where new locations are needed for each block element",
+                       "location", "");
+    }
+}
+
 // Do layout error checking with respect to a type.
 // Do layout error checking with respect to a type.
 void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
 void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
 {
 {
@@ -4500,7 +4623,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
             }
             }
         }
         }
     } else if (type.isImage() && ! qualifier.writeonly) {
     } else if (type.isImage() && ! qualifier.writeonly) {
-        const char *explanation = "image variables declared 'writeonly' without a format layout qualifier";
+        const char *explanation = "image variables not declared 'writeonly' and without a format layout qualifier";
         requireProfile(loc, ECoreProfile | ECompatibilityProfile, explanation);
         requireProfile(loc, ECoreProfile | ECompatibilityProfile, explanation);
         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shader_image_load_formatted, explanation);
         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shader_image_load_formatted, explanation);
     }
     }
@@ -4529,6 +4652,10 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
         case EbtUint:
         case EbtUint:
         case EbtInt64:
         case EbtInt64:
         case EbtUint64:
         case EbtUint64:
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:
+        case EbtUint16:
+#endif
         case EbtBool:
         case EbtBool:
         case EbtFloat:
         case EbtFloat:
         case EbtDouble:
         case EbtDouble:
@@ -4692,12 +4819,8 @@ void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol)
                 if (symbol.getType().isExplicitlySizedArray())
                 if (symbol.getType().isExplicitlySizedArray())
                     numOffsets *= symbol.getType().getCumulativeArraySize();
                     numOffsets *= symbol.getType().getCumulativeArraySize();
                 else {
                 else {
-                    // TODO: functionality: implicitly-sized atomic_uint arrays.
-                    // We don't know the full size until later.  This might
-                    // be a specification problem, will report to Khronos.  For the
-                    // cases that is not true, the rest of the checking would need
-                    // to be done at link time instead of compile time.
-                    warn(loc, "implicitly sized atomic_uint array treated as having one element for tracking the default offset", "atomic_uint", "");
+                    // "It is a compile-time error to declare an unsized array of atomic_uint."
+                    error(loc, "array must be explicitly sized", "atomic_uint", "");
                 }
                 }
             }
             }
             int repeated = intermediate.addUsedOffsets(qualifier.layoutBinding, offset, numOffsets);
             int repeated = intermediate.addUsedOffsets(qualifier.layoutBinding, offset, numOffsets);
@@ -4983,7 +5106,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
         arrayDimMerge(type, arraySizes);
         arrayDimMerge(type, arraySizes);
 
 
         // Check that implicit sizing is only where allowed.
         // Check that implicit sizing is only where allowed.
-        arrayUnsizedCheck(loc, type.getQualifier(), &type.getArraySizes(), initializer != nullptr, false);
+        arraySizesCheck(loc, type.getQualifier(), &type.getArraySizes(), initializer != nullptr, false);
 
 
         if (! arrayQualifierError(loc, type.getQualifier()) && ! arrayError(loc, type))
         if (! arrayQualifierError(loc, type.getQualifier()) && ! arrayError(loc, type))
             declareArray(loc, identifier, type, symbol);
             declareArray(loc, identifier, type, symbol);
@@ -5016,6 +5139,8 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
 
 
     // look for errors in layout qualifier use
     // look for errors in layout qualifier use
     layoutObjectCheck(loc, *symbol);
     layoutObjectCheck(loc, *symbol);
+
+    // fix up
     fixOffset(loc, *symbol);
     fixOffset(loc, *symbol);
 
 
     return initNode;
     return initNode;
@@ -5053,7 +5178,7 @@ TVariable* TParseContext::makeInternalVariable(const char* name, const TType& ty
 //
 //
 // Return the successfully declared variable.
 // Return the successfully declared variable.
 //
 //
-TVariable* TParseContext::declareNonArray(const TSourceLoc& loc, TString& identifier, TType& type)
+TVariable* TParseContext::declareNonArray(const TSourceLoc& loc, const TString& identifier, const TType& type)
 {
 {
     // make a new variable
     // make a new variable
     TVariable* variable = new TVariable(&identifier, type);
     TVariable* variable = new TVariable(&identifier, type);
@@ -5477,6 +5602,22 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
         basicOp = EOpConstructUint64;
         basicOp = EOpConstructUint64;
         break;
         break;
 
 
+#ifdef AMD_EXTENSIONS
+    case EOpConstructI16Vec2:
+    case EOpConstructI16Vec3:
+    case EOpConstructI16Vec4:
+    case EOpConstructInt16:
+        basicOp = EOpConstructInt16;
+        break;
+
+    case EOpConstructU16Vec2:
+    case EOpConstructU16Vec3:
+    case EOpConstructU16Vec4:
+    case EOpConstructUint16:
+        basicOp = EOpConstructUint16;
+        break;
+#endif
+
     case EOpConstructBVec2:
     case EOpConstructBVec2:
     case EOpConstructBVec3:
     case EOpConstructBVec3:
     case EOpConstructBVec4:
     case EOpConstructBVec4:
@@ -5533,7 +5674,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
     blockStageIoCheck(loc, currentBlockQualifier);
     blockStageIoCheck(loc, currentBlockQualifier);
     blockQualifierCheck(loc, currentBlockQualifier, instanceName != nullptr);
     blockQualifierCheck(loc, currentBlockQualifier, instanceName != nullptr);
     if (arraySizes) {
     if (arraySizes) {
-        arrayUnsizedCheck(loc, currentBlockQualifier, arraySizes, false, false);
+        arraySizesCheck(loc, currentBlockQualifier, arraySizes, false, false);
         arrayDimCheck(loc, arraySizes, 0);
         arrayDimCheck(loc, arraySizes, 0);
         if (arraySizes->getNumDims() > 1)
         if (arraySizes->getNumDims() > 1)
             requireProfile(loc, ~EEsProfile, "array-of-array of block");
             requireProfile(loc, ~EEsProfile, "array-of-array of block");
@@ -5551,7 +5692,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
         if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
         if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
             error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
             error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
         if (memberType.isArray())
         if (memberType.isArray())
-            arrayUnsizedCheck(memberLoc, currentBlockQualifier, &memberType.getArraySizes(), false, member == typeList.size() - 1);
+            arraySizesCheck(memberLoc, currentBlockQualifier, &memberType.getArraySizes(), false, member == typeList.size() - 1);
         if (memberQualifier.hasOffset()) {
         if (memberQualifier.hasOffset()) {
             if (spvVersion.spv == 0) {
             if (spvVersion.spv == 0) {
                 requireProfile(memberLoc, ~EEsProfile, "offset on block member");
                 requireProfile(memberLoc, ~EEsProfile, "offset on block member");
@@ -5597,11 +5738,10 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
 
 
     mergeObjectLayoutQualifiers(defaultQualification, currentBlockQualifier, true);
     mergeObjectLayoutQualifiers(defaultQualification, currentBlockQualifier, true);
 
 
-    // "The offset qualifier can only be used on block members of blocks declared with std140 or std430 layouts."
     // "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
     // "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
-    if (currentBlockQualifier.hasAlign() || currentBlockQualifier.hasAlign()) {
+    if (currentBlockQualifier.hasAlign()) {
         if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430) {
         if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430) {
-            error(loc, "can only be used with std140 or std430 layout packing", "offset/align", "");
+            error(loc, "can only be used with std140 or std430 layout packing", "align", "");
             defaultQualification.layoutAlign = -1;
             defaultQualification.layoutAlign = -1;
         }
         }
     }
     }
@@ -5643,9 +5783,12 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
             }
             }
         } else
         } else
             memberWithoutLocation = true;
             memberWithoutLocation = true;
-        if (memberQualifier.hasAlign()) {
+
+        // "The offset qualifier can only be used on block members of blocks declared with std140 or std430 layouts."
+        // "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
+        if (memberQualifier.hasAlign() || memberQualifier.hasOffset()) {
             if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430)
             if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430)
-                error(memberLoc, "can only be used with std140 or std430 layout packing", "align", "");
+                error(memberLoc, "can only be used with std140 or std430 layout packing", "offset/align", "");
         }
         }
 
 
         TQualifier newMemberQualification = defaultQualification;
         TQualifier newMemberQualification = defaultQualification;
@@ -5653,6 +5796,8 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
         memberQualifier = newMemberQualification;
         memberQualifier = newMemberQualification;
     }
     }
 
 
+    layoutMemberLocationArrayCheck(loc, memberWithLocation, arraySizes);
+
     // Process the members
     // Process the members
     fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
     fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
     fixBlockXfbOffsets(currentBlockQualifier, typeList);
     fixBlockXfbOffsets(currentBlockQualifier, typeList);
@@ -5720,6 +5865,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
     // Check for general layout qualifier errors
     // Check for general layout qualifier errors
     layoutObjectCheck(loc, variable);
     layoutObjectCheck(loc, variable);
 
 
+    // fix up
     if (isIoResizeArray(blockType)) {
     if (isIoResizeArray(blockType)) {
         ioArraySymbolResizeList.push_back(&variable);
         ioArraySymbolResizeList.push_back(&variable);
         checkIoArraysConsistency(loc, true);
         checkIoArraysConsistency(loc, true);
@@ -5768,7 +5914,7 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q
 }
 }
 
 
 // Do all block-declaration checking regarding its qualifiers.
 // Do all block-declaration checking regarding its qualifiers.
-void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier, bool instanceName)
+void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier, bool /*instanceName*/)
 {
 {
     // The 4.5 specification says:
     // The 4.5 specification says:
     //
     //
@@ -5795,11 +5941,8 @@ void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier&
         error(loc, "cannot use sample qualifier on an interface block", "sample", "");
         error(loc, "cannot use sample qualifier on an interface block", "sample", "");
     if (qualifier.invariant)
     if (qualifier.invariant)
         error(loc, "cannot use invariant qualifier on an interface block", "invariant", "");
         error(loc, "cannot use invariant qualifier on an interface block", "invariant", "");
-    if (qualifier.layoutPushConstant) {
+    if (qualifier.layoutPushConstant)
         intermediate.addPushConstantCount();
         intermediate.addPushConstantCount();
-        if (! instanceName)
-            error(loc, "requires an instance name", "push_constant", "");
-    }
 }
 }
 
 
 //
 //
@@ -5837,7 +5980,7 @@ void TParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qualifi
                     if (nextLocation >= (int)TQualifier::layoutLocationEnd)
                     if (nextLocation >= (int)TQualifier::layoutLocationEnd)
                         error(memberLoc, "location is too large", "location", "");
                         error(memberLoc, "location is too large", "location", "");
                     memberQualifier.layoutLocation = nextLocation;
                     memberQualifier.layoutLocation = nextLocation;
-                    memberQualifier.layoutComponent = 0;
+                    memberQualifier.layoutComponent = TQualifier::layoutComponentEnd;
                 }
                 }
                 nextLocation = memberQualifier.layoutLocation + intermediate.computeTypeLocationSize(*typeList[member].type);
                 nextLocation = memberQualifier.layoutLocation + intermediate.computeTypeLocationSize(*typeList[member].type);
             }
             }

+ 32 - 21
src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h

@@ -77,6 +77,10 @@ public:
                       TInfoSink& infoSink, bool forwardCompatible, EShMessages messages)
                       TInfoSink& infoSink, bool forwardCompatible, EShMessages messages)
           : TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
           : TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
             symbolTable(symbolTable),
             symbolTable(symbolTable),
+            statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
+            postEntryPointReturn(false),
+            contextPragma(true, false),
+            limits(resources.limits),
             parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
             parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
             globalUniformBlock(nullptr)
             globalUniformBlock(nullptr)
     { }
     { }
@@ -133,18 +137,31 @@ public:
             extensionCallback(line, extension, behavior);
             extensionCallback(line, extension, behavior);
     }
     }
 
 
-    TSymbolTable& symbolTable;   // symbol table that goes with the current language, version, and profile
-
     // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
     // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
-    // TODO: This could perhaps get its own object, but the current design doesn't work
-    // yet when new uniform variables are declared between function definitions, so
-    // this is pending getting a fully functional design.
-    virtual void growGlobalUniformBlock(TSourceLoc&, TType&, TString& memberName, TTypeList* typeList = nullptr);
-    virtual bool insertGlobalUniformBlock();
+    virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
 
 
     virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
     virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
     virtual void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
     virtual void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
 
 
+    const char* const scopeMangler = "::";
+
+    // Basic parsing state, easily accessible to the grammar
+
+    TSymbolTable& symbolTable;        // symbol table that goes with the current language, version, and profile
+    int statementNestingLevel;        // 0 if outside all flow control or compound statements
+    int loopNestingLevel;             // 0 if outside all loops
+    int structNestingLevel;           // 0 if outside blocks and structures
+    int controlFlowNestingLevel;      // 0 if outside all flow control
+    const TType* currentFunctionType; // the return type of the function that's currently being parsed
+    bool functionReturnsValue;        // true if a non-void function has a return
+    // if inside a function, true if the function is the entry point and this is after a return statement
+    bool postEntryPointReturn;
+    // case, node, case, case, node, ...; ensure only one node between cases;   stack of them for nesting
+    TList<TIntermSequence*> switchSequenceStack;
+    // the statementNestingLevel the current switch statement is at, which must match the level of its case statements
+    TList<int> switchLevel;
+    struct TPragma contextPragma;
+
 protected:
 protected:
     TParseContextBase(TParseContextBase&);
     TParseContextBase(TParseContextBase&);
     TParseContextBase& operator=(TParseContextBase&);
     TParseContextBase& operator=(TParseContextBase&);
@@ -153,6 +170,8 @@ protected:
     TVector<TSymbol*> linkageSymbols; // these need to be transferred to 'linkage', after all editing is done
     TVector<TSymbol*> linkageSymbols; // these need to be transferred to 'linkage', after all editing is done
     TScanContext* scanContext;
     TScanContext* scanContext;
     TPpContext* ppContext;
     TPpContext* ppContext;
+    TBuiltInResource resources;
+    TLimits& limits;
 
 
     // These, if set, will be called when a line, pragma ... is preprocessed.
     // These, if set, will be called when a line, pragma ... is preprocessed.
     // They will be called with any parameters to the original directive.
     // They will be called with any parameters to the original directive.
@@ -175,7 +194,8 @@ protected:
     TVariable* globalUniformBlock;   // the actual block, inserted into the symbol table
     TVariable* globalUniformBlock;   // the actual block, inserted into the symbol table
     int firstNewMember;              // the index of the first member not yet inserted into the symbol table
     int firstNewMember;              // the index of the first member not yet inserted into the symbol table
     // override this to set the language-specific name
     // override this to set the language-specific name
-    virtual const char* getGlobalUniformBlockName() { return ""; }
+    virtual const char* getGlobalUniformBlockName() const { return ""; }
+    virtual void setUniformBlockDefaults(TType&) const { }
     virtual void finalizeGlobalUniformBlockLayout(TVariable&) { }
     virtual void finalizeGlobalUniformBlockLayout(TVariable&) { }
     virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
     virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
                                const char* szExtraInfoFormat, TPrefixType prefix,
                                const char* szExtraInfoFormat, TPrefixType prefix,
@@ -297,7 +317,7 @@ public:
     bool arrayError(const TSourceLoc&, const TType&);
     bool arrayError(const TSourceLoc&, const TType&);
     void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&);
     void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&);
     void structArrayCheck(const TSourceLoc&, const TType& structure);
     void structArrayCheck(const TSourceLoc&, const TType& structure);
-    void arrayUnsizedCheck(const TSourceLoc&, const TQualifier&, const TArraySizes*, bool initializer, bool lastMember);
+    void arraySizesCheck(const TSourceLoc&, const TQualifier&, const TArraySizes*, bool initializer, bool lastMember);
     void arrayOfArrayVersionCheck(const TSourceLoc&);
     void arrayOfArrayVersionCheck(const TSourceLoc&);
     void arrayDimCheck(const TSourceLoc&, const TArraySizes* sizes1, const TArraySizes* sizes2);
     void arrayDimCheck(const TSourceLoc&, const TArraySizes* sizes1, const TArraySizes* sizes2);
     void arrayDimCheck(const TSourceLoc&, const TType*, const TArraySizes*);
     void arrayDimCheck(const TSourceLoc&, const TType*, const TArraySizes*);
@@ -339,6 +359,7 @@ public:
     void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&, const TIntermTyped*);
     void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&, const TIntermTyped*);
     void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
     void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
     void layoutObjectCheck(const TSourceLoc&, const TSymbol&);
     void layoutObjectCheck(const TSourceLoc&, const TSymbol&);
+    void layoutMemberLocationArrayCheck(const TSourceLoc&, bool memberWithLocation, TArraySizes* arraySizes);
     void layoutTypeCheck(const TSourceLoc&, const TType&);
     void layoutTypeCheck(const TSourceLoc&, const TType&);
     void layoutQualifierCheck(const TSourceLoc&, const TQualifier&);
     void layoutQualifierCheck(const TSourceLoc&, const TQualifier&);
     void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
     void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
@@ -372,8 +393,8 @@ protected:
     void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
     void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
     void inheritGlobalDefaults(TQualifier& dst) const;
     void inheritGlobalDefaults(TQualifier& dst) const;
     TVariable* makeInternalVariable(const char* name, const TType&) const;
     TVariable* makeInternalVariable(const char* name, const TType&) const;
-    TVariable* declareNonArray(const TSourceLoc&, TString& identifier, TType&);
-    void declareArray(const TSourceLoc&, TString& identifier, const TType&, TSymbol*&);
+    TVariable* declareNonArray(const TSourceLoc&, const TString& identifier, const TType&);
+    void declareArray(const TSourceLoc&, const TString& identifier, const TType&, TSymbol*&);
     TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
     TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
     TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
     TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
     void finish() override;
     void finish() override;
@@ -384,17 +405,7 @@ public:
     //
     //
 
 
     // Current state of parsing
     // Current state of parsing
-    struct TPragma contextPragma;
-    int loopNestingLevel;        // 0 if outside all loops
-    int structNestingLevel;      // 0 if outside blocks and structures
-    int controlFlowNestingLevel; // 0 if outside all flow control
-    int statementNestingLevel;   // 0 if outside all flow control or compound statements
-    TList<TIntermSequence*> switchSequenceStack;  // case, node, case, case, node, ...; ensure only one node between cases;   stack of them for nesting
-    TList<int> switchLevel;      // the statementNestingLevel the current switch statement is at, which must match the level of its case statements
     bool inMain;                 // if inside a function, true if the function is main
     bool inMain;                 // if inside a function, true if the function is main
-    bool postMainReturn;         // if inside a function, true if the function is main and this is after a return statement
-    const TType* currentFunctionType;  // the return type of the function that's currently being parsed
-    bool functionReturnsValue;   // true if a non-void function has a return
     const TString* blockName;
     const TString* blockName;
     TQualifier currentBlockQualifier;
     TQualifier currentBlockQualifier;
     TPrecisionQualifier defaultPrecision[EbtNumTypes];
     TPrecisionQualifier defaultPrecision[EbtNumTypes];

+ 2 - 0
src/libraries/glslang/glslang/MachineIndependent/RemoveTree.h

@@ -32,6 +32,8 @@
 // POSSIBILITY OF SUCH DAMAGE.
 // POSSIBILITY OF SUCH DAMAGE.
 //
 //
 
 
+#pragma once
+
 namespace glslang {
 namespace glslang {
 
 
 void RemoveAllTreeNodes(TIntermNode*);
 void RemoveAllTreeNodes(TIntermNode*);

+ 33 - 1
src/libraries/glslang/glslang/MachineIndependent/Scan.cpp

@@ -175,7 +175,7 @@ bool TInputScanner::scanVersion(int& version, EProfile& profile, bool& notFirstT
 
 
     bool versionNotFirst = false;  // means not first WRT comments and white space, nothing more
     bool versionNotFirst = false;  // means not first WRT comments and white space, nothing more
     notFirstToken = false;         // means not first WRT to real tokens
     notFirstToken = false;         // means not first WRT to real tokens
-    version = 0;  // means not found
+    version = 0;                   // means not found
     profile = ENoProfile;
     profile = ENoProfile;
 
 
     bool foundNonSpaceTab = false;
     bool foundNonSpaceTab = false;
@@ -464,6 +464,15 @@ void TScanContext::fillInKeywordMap()
     (*KeywordMap)["u64vec4"] =                 U64VEC4;
     (*KeywordMap)["u64vec4"] =                 U64VEC4;
 
 
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
+    (*KeywordMap)["int16_t"] =                 INT16_T;
+    (*KeywordMap)["uint16_t"] =                UINT16_T;
+    (*KeywordMap)["i16vec2"] =                 I16VEC2;
+    (*KeywordMap)["i16vec3"] =                 I16VEC3;
+    (*KeywordMap)["i16vec4"] =                 I16VEC4;
+    (*KeywordMap)["u16vec2"] =                 U16VEC2;
+    (*KeywordMap)["u16vec3"] =                 U16VEC3;
+    (*KeywordMap)["u16vec4"] =                 U16VEC4;
+
     (*KeywordMap)["float16_t"] =               FLOAT16_T;
     (*KeywordMap)["float16_t"] =               FLOAT16_T;
     (*KeywordMap)["f16vec2"] =                 F16VEC2;
     (*KeywordMap)["f16vec2"] =                 F16VEC2;
     (*KeywordMap)["f16vec3"] =                 F16VEC3;
     (*KeywordMap)["f16vec3"] =                 F16VEC3;
@@ -701,10 +710,18 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
         case PpAtomDecrement:          return DEC_OP;
         case PpAtomDecrement:          return DEC_OP;
         case PpAtomIncrement:          return INC_OP;
         case PpAtomIncrement:          return INC_OP;
 
 
+        case PpAtomColonColon:
+            parseContext.error(loc, "not supported", "::", "");
+            break;
+
         case PpAtomConstInt:           parserToken->sType.lex.i   = ppToken.ival;       return INTCONSTANT;
         case PpAtomConstInt:           parserToken->sType.lex.i   = ppToken.ival;       return INTCONSTANT;
         case PpAtomConstUint:          parserToken->sType.lex.i   = ppToken.ival;       return UINTCONSTANT;
         case PpAtomConstUint:          parserToken->sType.lex.i   = ppToken.ival;       return UINTCONSTANT;
         case PpAtomConstInt64:         parserToken->sType.lex.i64 = ppToken.i64val;     return INT64CONSTANT;
         case PpAtomConstInt64:         parserToken->sType.lex.i64 = ppToken.i64val;     return INT64CONSTANT;
         case PpAtomConstUint64:        parserToken->sType.lex.i64 = ppToken.i64val;     return UINT64CONSTANT;
         case PpAtomConstUint64:        parserToken->sType.lex.i64 = ppToken.i64val;     return UINT64CONSTANT;
+#ifdef AMD_EXTENSIONS
+        case PpAtomConstInt16:         parserToken->sType.lex.i   = ppToken.ival;       return INT16CONSTANT;
+        case PpAtomConstUint16:        parserToken->sType.lex.i   = ppToken.ival;       return UINT16CONSTANT;
+#endif
         case PpAtomConstFloat:         parserToken->sType.lex.d   = ppToken.dval;       return FLOATCONSTANT;
         case PpAtomConstFloat:         parserToken->sType.lex.d   = ppToken.dval;       return FLOATCONSTANT;
         case PpAtomConstDouble:        parserToken->sType.lex.d   = ppToken.dval;       return DOUBLECONSTANT;
         case PpAtomConstDouble:        parserToken->sType.lex.d   = ppToken.dval;       return DOUBLECONSTANT;
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
@@ -969,6 +986,21 @@ int TScanContext::tokenizeIdentifier()
         return identifierOrType();
         return identifierOrType();
 
 
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
+    case INT16_T:
+    case UINT16_T:
+    case I16VEC2:
+    case I16VEC3:
+    case I16VEC4:
+    case U16VEC2:
+    case U16VEC3:
+    case U16VEC4:
+        afterType = true;
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            (parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) &&
+             parseContext.profile != EEsProfile && parseContext.version >= 450))
+            return keyword;
+        return identifierOrType();
+
     case FLOAT16_T:
     case FLOAT16_T:
     case F16VEC2:
     case F16VEC2:
     case F16VEC3:
     case F16VEC3:

+ 2 - 0
src/libraries/glslang/glslang/MachineIndependent/ScanContext.h

@@ -38,6 +38,8 @@
 // sits between the preprocessor scanner and parser.
 // sits between the preprocessor scanner and parser.
 //
 //
 
 
+#pragma once
+
 #include "ParseHelper.h"
 #include "ParseHelper.h"
 
 
 namespace glslang {
 namespace glslang {

+ 32 - 46
src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp

@@ -442,7 +442,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
     bool correct = true;
     bool correct = true;
 
 
     if (source == EShSourceHlsl) {
     if (source == EShSourceHlsl) {
-        version = 450;          // TODO: GLSL parser is still used for builtins.
+        version = 500;          // shader model; currently a characteristic of glslang, not the input
         profile = ECoreProfile; // allow doubles in prototype parsing
         profile = ECoreProfile; // allow doubles in prototype parsing
         return correct;
         return correct;
     }
     }
@@ -566,41 +566,6 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
         }
         }
     }
     }
 
 
-    // A meta check on the condition of the compiler itself...
-    switch (version) {
-
-    // ES versions
-    case 100:
-    case 300:
-        // versions are complete
-        break;
-
-    // Desktop versions
-    case 110:
-    case 120:
-    case 130:
-    case 140:
-    case 150:
-    case 330:
-        // versions are complete
-        break;
-
-    case 310:
-    case 400:
-    case 410:
-    case 420:
-    case 430:
-    case 440:
-    case 450:
-        infoSink.info << "Warning, version " << version << " is not yet complete; most version-specific features are present, but some are missing.\n";
-        break;
-
-    default:
-        infoSink.info << "Warning, version " << version << " is unknown.\n";
-        break;
-
-    }
-
     return correct;
     return correct;
 }
 }
 
 
@@ -679,13 +644,13 @@ bool ProcessDeferred(
     // First, without using the preprocessor or parser, find the #version, so we know what
     // First, without using the preprocessor or parser, find the #version, so we know what
     // symbol tables, processing rules, etc. to set up.  This does not need the extra strings
     // symbol tables, processing rules, etc. to set up.  This does not need the extra strings
     // outlined above, just the user shader.
     // outlined above, just the user shader.
-    int version;
-    EProfile profile;
     glslang::TInputScanner userInput(numStrings, &strings[numPre], &lengths[numPre]);  // no preamble
     glslang::TInputScanner userInput(numStrings, &strings[numPre], &lengths[numPre]);  // no preamble
-    bool versionNotFirstToken;
-    bool versionNotFirst = userInput.scanVersion(version, profile, versionNotFirstToken);
+    int version = 0;
+    EProfile profile = ENoProfile;
+    bool versionNotFirstToken = false;
+    bool versionNotFirst = (messages & EShMsgReadHlsl) ? true : userInput.scanVersion(version, profile, versionNotFirstToken);
     bool versionNotFound = version == 0;
     bool versionNotFound = version == 0;
-    if (forceDefaultVersionAndProfile) {
+    if (forceDefaultVersionAndProfile && (messages & EShMsgReadHlsl) == 0) {
         if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound &&
         if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound &&
             (version != defaultVersion || profile != defaultProfile)) {
             (version != defaultVersion || profile != defaultProfile)) {
             compiler->infoSink.info << "Warning, (version, profile) forced to be ("
             compiler->infoSink.info << "Warning, (version, profile) forced to be ("
@@ -726,6 +691,13 @@ bool ProcessDeferred(
     intermediate.setSpv(spvVersion);
     intermediate.setSpv(spvVersion);
     if (spvVersion.vulkan >= 100)
     if (spvVersion.vulkan >= 100)
         intermediate.setOriginUpperLeft();
         intermediate.setOriginUpperLeft();
+    if ((messages & EShMsgHlslOffsets) || (messages & EShMsgReadHlsl))
+        intermediate.setHlslOffsets();
+    if (messages & EShMsgDebugInfo) {
+        intermediate.setSourceFile(names[numPre]);
+        for (int s = 0; s < numStrings; ++s)
+            intermediate.addSourceText(strings[numPre]);
+    }
     SetupBuiltinSymbolTable(version, profile, spvVersion, source);
     SetupBuiltinSymbolTable(version, profile, spvVersion, source);
 
 
     TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
     TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
@@ -1553,13 +1525,30 @@ void TShader::setSourceEntryPoint(const char* name)
     sourceEntryPointName = name;
     sourceEntryPointName = name;
 }
 }
 
 
+// Set binding base for sampler types
 void TShader::setShiftSamplerBinding(unsigned int base) { intermediate->setShiftSamplerBinding(base); }
 void TShader::setShiftSamplerBinding(unsigned int base) { intermediate->setShiftSamplerBinding(base); }
+// Set binding base for texture types (SRV)
 void TShader::setShiftTextureBinding(unsigned int base) { intermediate->setShiftTextureBinding(base); }
 void TShader::setShiftTextureBinding(unsigned int base) { intermediate->setShiftTextureBinding(base); }
+// Set binding base for image types
 void TShader::setShiftImageBinding(unsigned int base)   { intermediate->setShiftImageBinding(base); }
 void TShader::setShiftImageBinding(unsigned int base)   { intermediate->setShiftImageBinding(base); }
+// Set binding base for uniform buffer objects (CBV)
 void TShader::setShiftUboBinding(unsigned int base)     { intermediate->setShiftUboBinding(base); }
 void TShader::setShiftUboBinding(unsigned int base)     { intermediate->setShiftUboBinding(base); }
+// Synonym for setShiftUboBinding, to match HLSL language.
+void TShader::setShiftCbufferBinding(unsigned int base) { intermediate->setShiftUboBinding(base); }
+// Set binding base for UAV (unordered access view)
+void TShader::setShiftUavBinding(unsigned int base)     { intermediate->setShiftUavBinding(base); }
+// Set binding base for SSBOs
+void TShader::setShiftSsboBinding(unsigned int base)    { intermediate->setShiftSsboBinding(base); }
+// Enables binding automapping using TIoMapper
 void TShader::setAutoMapBindings(bool map)              { intermediate->setAutoMapBindings(map); }
 void TShader::setAutoMapBindings(bool map)              { intermediate->setAutoMapBindings(map); }
+// Fragile: currently within one stage: simple auto-assignment of location
+void TShader::setAutoMapLocations(bool map)              { intermediate->setAutoMapLocations(map); }
+// See comment above TDefaultHlslIoMapper in iomapper.cpp:
+void TShader::setHlslIoMapping(bool hlslIoMap)          { intermediate->setHlslIoMapping(hlslIoMap); }
 void TShader::setFlattenUniformArrays(bool flatten)     { intermediate->setFlattenUniformArrays(flatten); }
 void TShader::setFlattenUniformArrays(bool flatten)     { intermediate->setFlattenUniformArrays(flatten); }
 void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
 void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
+void TShader::setResourceSetBinding(const std::vector<std::string>& base)   { intermediate->setResourceSetBinding(base); }
+void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); }
 
 
 //
 //
 // Turn the shader strings into a parse tree in the TIntermediate.
 // Turn the shader strings into a parse tree in the TIntermediate.
@@ -1583,11 +1572,6 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
                            forwardCompatible, messages, *intermediate, includer, sourceEntryPointName);
                            forwardCompatible, messages, *intermediate, includer, sourceEntryPointName);
 }
 }
 
 
-bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages)
-{
-    return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages);
-}
-
 // Fill in a string with the result of preprocessing ShaderStrings
 // Fill in a string with the result of preprocessing ShaderStrings
 // Returns true if all extensions, pragmas and version strings were valid.
 // Returns true if all extensions, pragmas and version strings were valid.
 bool TShader::preprocess(const TBuiltInResource* builtInResources,
 bool TShader::preprocess(const TBuiltInResource* builtInResources,
@@ -1775,6 +1759,7 @@ const char* TProgram::getUniformBlockName(int index) const   { return reflection
 int TProgram::getUniformBlockSize(int index) const           { return reflection->getUniformBlock(index).size; }
 int TProgram::getUniformBlockSize(int index) const           { return reflection->getUniformBlock(index).size; }
 int TProgram::getUniformIndex(const char* name) const        { return reflection->getIndex(name); }
 int TProgram::getUniformIndex(const char* name) const        { return reflection->getIndex(name); }
 int TProgram::getUniformBlockIndex(int index) const          { return reflection->getUniform(index).index; }
 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::getUniformType(int index) const                { return reflection->getUniform(index).glDefineType; }
 int TProgram::getUniformBufferOffset(int index) const        { return reflection->getUniform(index).offset; }
 int TProgram::getUniformBufferOffset(int index) const        { return reflection->getUniform(index).offset; }
 int TProgram::getUniformArraySize(int index) const           { return reflection->getUniform(index).size; }
 int TProgram::getUniformArraySize(int index) const           { return reflection->getUniform(index).size; }
@@ -1784,6 +1769,7 @@ int TProgram::getAttributeType(int index) const              { return reflection
 const TType* TProgram::getAttributeTType(int index) const    { return reflection->getAttribute(index).getType(); }
 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::getUniformTType(int index) const      { return reflection->getUniform(index).getType(); }
 const TType* TProgram::getUniformBlockTType(int index) const { return reflection->getUniformBlock(index).getType(); }
 const TType* TProgram::getUniformBlockTType(int index) const { return reflection->getUniformBlock(index).getType(); }
+unsigned TProgram::getLocalSize(int dim) const               { return reflection->getLocalSize(dim); }
 
 
 void TProgram::dumpReflection()                      { reflection->dump(); }
 void TProgram::dumpReflection()                      { reflection->dump(); }
 
 

+ 21 - 2
src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp

@@ -50,7 +50,7 @@ namespace glslang {
 //
 //
 // Recursively generate mangled names.
 // Recursively generate mangled names.
 //
 //
-void TType::buildMangledName(TString& mangledName)
+void TType::buildMangledName(TString& mangledName) const
 {
 {
     if (isMatrix())
     if (isMatrix())
         mangledName += 'm';
         mangledName += 'm';
@@ -67,6 +67,10 @@ void TType::buildMangledName(TString& mangledName)
     case EbtUint:               mangledName += 'u';      break;
     case EbtUint:               mangledName += 'u';      break;
     case EbtInt64:              mangledName += "i64";    break;
     case EbtInt64:              mangledName += "i64";    break;
     case EbtUint64:             mangledName += "u64";    break;
     case EbtUint64:             mangledName += "u64";    break;
+#ifdef AMD_EXTENSIONS
+    case EbtInt16:              mangledName += "i16";    break;
+    case EbtUint16:             mangledName += "u16";    break;
+#endif
     case EbtBool:               mangledName += 'b';      break;
     case EbtBool:               mangledName += 'b';      break;
     case EbtAtomicUint:         mangledName += "au";     break;
     case EbtAtomicUint:         mangledName += "au";     break;
     case EbtSampler:
     case EbtSampler:
@@ -99,11 +103,23 @@ void TType::buildMangledName(TString& mangledName)
         case EsdSubpass:  mangledName += "P";  break;
         case EsdSubpass:  mangledName += "P";  break;
         default: break; // some compilers want this
         default: break; // some compilers want this
         }
         }
+
+        switch (sampler.vectorSize) {
+        case 1: mangledName += "1"; break;
+        case 2: mangledName += "2"; break;
+        case 3: mangledName += "3"; break;
+        case 4: break; // default to prior name mangle behavior
+        }
+
         if (sampler.ms)
         if (sampler.ms)
             mangledName += "M";
             mangledName += "M";
         break;
         break;
     case EbtStruct:
     case EbtStruct:
-        mangledName += "struct-";
+    case EbtBlock:
+        if (basicType == EbtStruct)
+            mangledName += "struct-";
+        else
+            mangledName += "block-";
         if (typeName)
         if (typeName)
             mangledName += *typeName;
             mangledName += *typeName;
         for (unsigned int i = 0; i < structure->size(); ++i) {
         for (unsigned int i = 0; i < structure->size(); ++i) {
@@ -295,6 +311,8 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
     op = copyOf.op;
     op = copyOf.op;
     defined = copyOf.defined;
     defined = copyOf.defined;
     prototyped = copyOf.prototyped;
     prototyped = copyOf.prototyped;
+    implicitThis = copyOf.implicitThis;
+    illegalImplicitThis = copyOf.illegalImplicitThis;
     defaultParamCount = copyOf.defaultParamCount;
     defaultParamCount = copyOf.defaultParamCount;
 }
 }
 
 
@@ -319,6 +337,7 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
 {
 {
     TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
     TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
     symTableLevel->anonId = anonId;
     symTableLevel->anonId = anonId;
+    symTableLevel->thisLevel = thisLevel;
     std::vector<bool> containerCopied(anonId, false);
     std::vector<bool> containerCopied(anonId, false);
     tLevel::const_iterator iter;
     tLevel::const_iterator iter;
     for (iter = level.begin(); iter != level.end(); ++iter) {
     for (iter = level.begin(); iter != level.end(); ++iter) {

+ 91 - 15
src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h

@@ -198,7 +198,6 @@ struct TParameter {
     TString *name;
     TString *name;
     TType* type;
     TType* type;
     TIntermTyped* defaultValue;
     TIntermTyped* defaultValue;
-    TBuiltInVariable declaredBuiltIn;
     void copyParam(const TParameter& param)
     void copyParam(const TParameter& param)
     {
     {
         if (param.name)
         if (param.name)
@@ -207,8 +206,8 @@ struct TParameter {
             name = 0;
             name = 0;
         type = param.type->clone();
         type = param.type->clone();
         defaultValue = param.defaultValue;
         defaultValue = param.defaultValue;
-        declaredBuiltIn = param.declaredBuiltIn;
     }
     }
+    TBuiltInVariable getDeclaredBuiltIn() const { return type->getQualifier().declaredBuiltIn; }
 };
 };
 
 
 //
 //
@@ -219,48 +218,70 @@ public:
     explicit TFunction(TOperator o) :
     explicit TFunction(TOperator o) :
         TSymbol(0),
         TSymbol(0),
         op(o),
         op(o),
-        defined(false), prototyped(false), defaultParamCount(0) { }
+        defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0) { }
     TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) :
     TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) :
         TSymbol(name),
         TSymbol(name),
         mangledName(*name + '('),
         mangledName(*name + '('),
         op(tOp),
         op(tOp),
-        defined(false), prototyped(false), defaultParamCount(0)
+        defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0)
     {
     {
         returnType.shallowCopy(retType);
         returnType.shallowCopy(retType);
         declaredBuiltIn = retType.getQualifier().builtIn;
         declaredBuiltIn = retType.getQualifier().builtIn;
     }
     }
-    virtual TFunction* clone() const;
+    virtual TFunction* clone() const override;
     virtual ~TFunction();
     virtual ~TFunction();
 
 
-    virtual TFunction* getAsFunction() { return this; }
-    virtual const TFunction* getAsFunction() const { return this; }
+    virtual TFunction* getAsFunction() override { return this; }
+    virtual const TFunction* getAsFunction() const override { return this; }
 
 
+    // Install 'p' as the (non-'this') last parameter.
+    // Non-'this' parameters are reflected in both the list of parameters and the
+    // mangled name.
     virtual void addParameter(TParameter& p)
     virtual void addParameter(TParameter& p)
     {
     {
         assert(writable);
         assert(writable);
-        p.declaredBuiltIn = p.type->getQualifier().builtIn;
         parameters.push_back(p);
         parameters.push_back(p);
         p.type->appendMangledName(mangledName);
         p.type->appendMangledName(mangledName);
 
 
         if (p.defaultValue != nullptr)
         if (p.defaultValue != nullptr)
             defaultParamCount++;
             defaultParamCount++;
     }
     }
+
+    // Install 'this' as the first parameter.
+    // 'this' is reflected in the list of parameters, but not the mangled name.
+    virtual void addThisParameter(TType& type, const char* name)
+    {
+        TParameter p = { NewPoolTString(name), new TType, nullptr };
+        p.type->shallowCopy(type);
+        parameters.insert(parameters.begin(), p);
+    }
+
     virtual void addPrefix(const char* prefix) override
     virtual void addPrefix(const char* prefix) override
     {
     {
         TSymbol::addPrefix(prefix);
         TSymbol::addPrefix(prefix);
         mangledName.insert(0, prefix);
         mangledName.insert(0, prefix);
     }
     }
 
 
-    virtual const TString& getMangledName() const { return mangledName; }
-    virtual const TType& getType() const { return returnType; }
+    virtual void removePrefix(const TString& prefix)
+    {
+        assert(mangledName.compare(0, prefix.size(), prefix) == 0);
+        mangledName.erase(0, prefix.size());
+    }
+
+    virtual const TString& getMangledName() const override { return mangledName; }
+    virtual const TType& getType() const override { return returnType; }
     virtual TBuiltInVariable getDeclaredBuiltInType() const { return declaredBuiltIn; }
     virtual TBuiltInVariable getDeclaredBuiltInType() const { return declaredBuiltIn; }
-    virtual TType& getWritableType() { return returnType; }
+    virtual TType& getWritableType() override { return returnType; }
     virtual void relateToOperator(TOperator o) { assert(writable); op = o; }
     virtual void relateToOperator(TOperator o) { assert(writable); op = o; }
     virtual TOperator getBuiltInOp() const { return op; }
     virtual TOperator getBuiltInOp() const { return op; }
     virtual void setDefined() { assert(writable); defined = true; }
     virtual void setDefined() { assert(writable); defined = true; }
     virtual bool isDefined() const { return defined; }
     virtual bool isDefined() const { return defined; }
     virtual void setPrototyped() { assert(writable); prototyped = true; }
     virtual void setPrototyped() { assert(writable); prototyped = true; }
     virtual bool isPrototyped() const { return prototyped; }
     virtual bool isPrototyped() const { return prototyped; }
+    virtual void setImplicitThis() { assert(writable); implicitThis = true; }
+    virtual bool hasImplicitThis() const { return implicitThis; }
+    virtual void setIllegalImplicitThis() { assert(writable); illegalImplicitThis = true; }
+    virtual bool hasIllegalImplicitThis() const { return illegalImplicitThis; }
 
 
     // Return total number of parameters
     // Return total number of parameters
     virtual int getParamCount() const { return static_cast<int>(parameters.size()); }
     virtual int getParamCount() const { return static_cast<int>(parameters.size()); }
@@ -272,7 +293,7 @@ public:
     virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
     virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
     virtual const TParameter& operator[](int i) const { return parameters[i]; }
     virtual const TParameter& operator[](int i) const { return parameters[i]; }
 
 
-    virtual void dump(TInfoSink &infoSink) const;
+    virtual void dump(TInfoSink &infoSink) const override;
 
 
 protected:
 protected:
     explicit TFunction(const TFunction&);
     explicit TFunction(const TFunction&);
@@ -287,6 +308,11 @@ protected:
     TOperator op;
     TOperator op;
     bool defined;
     bool defined;
     bool prototyped;
     bool prototyped;
+    bool implicitThis;         // True if this function is allowed to see all members of 'this'
+    bool illegalImplicitThis;  // True if this function is not supposed to have access to dynamic members of 'this',
+                               // even if it finds member variables in the symbol table.
+                               // This is important for a static member function that has member variables in scope,
+                               // but is not allowed to use them, or see hidden symbols instead.
     int  defaultParamCount;
     int  defaultParamCount;
 };
 };
 
 
@@ -334,7 +360,7 @@ protected:
 class TSymbolTableLevel {
 class TSymbolTableLevel {
 public:
 public:
     POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
     POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
-    TSymbolTableLevel() : defaultPrecision(0), anonId(0) { }
+    TSymbolTableLevel() : defaultPrecision(0), anonId(0), thisLevel(false) { }
     ~TSymbolTableLevel();
     ~TSymbolTableLevel();
 
 
     bool insert(TSymbol& symbol, bool separateNameSpaces)
     bool insert(TSymbol& symbol, bool separateNameSpaces)
@@ -492,6 +518,9 @@ public:
     TSymbolTableLevel* clone() const;
     TSymbolTableLevel* clone() const;
     void readOnly();
     void readOnly();
 
 
+    void setThisLevel() { thisLevel = true; }
+    bool isThisLevel() const { return thisLevel; }
+
 protected:
 protected:
     explicit TSymbolTableLevel(TSymbolTableLevel&);
     explicit TSymbolTableLevel(TSymbolTableLevel&);
     TSymbolTableLevel& operator=(TSymbolTableLevel&);
     TSymbolTableLevel& operator=(TSymbolTableLevel&);
@@ -503,6 +532,8 @@ protected:
     tLevel level;  // named mappings
     tLevel level;  // named mappings
     TPrecisionQualifier *defaultPrecision;
     TPrecisionQualifier *defaultPrecision;
     int anonId;
     int anonId;
+    bool thisLevel;  // True if this level of the symbol table is a structure scope containing member function
+                     // that are supposed to see anonymous access to member variables.
 };
 };
 
 
 class TSymbolTable {
 class TSymbolTable {
@@ -559,6 +590,20 @@ public:
         table.push_back(new TSymbolTableLevel);
         table.push_back(new TSymbolTableLevel);
     }
     }
 
 
+    // Make a new symbol-table level to represent the scope introduced by a structure
+    // containing member functions, such that the member functions can find anonymous
+    // references to member variables.
+    //
+    // 'thisSymbol' should have a name of "" to trigger anonymous structure-member
+    // symbol finds.
+    void pushThis(TSymbol& thisSymbol)
+    {
+        assert(thisSymbol.getName().size() == 0);
+        table.push_back(new TSymbolTableLevel);
+        table.back()->setThisLevel();
+        insert(thisSymbol);
+    }
+
     void pop(TPrecisionQualifier *p)
     void pop(TPrecisionQualifier *p)
     {
     {
         table[currentLevel()]->getPreviousDefaultPrecisions(p);
         table[currentLevel()]->getPreviousDefaultPrecisions(p);
@@ -645,19 +690,50 @@ public:
         }
         }
     }
     }
 
 
-    TSymbol* find(const TString& name, bool* builtIn = 0, bool *currentScope = 0)
+    // Normal find of a symbol, that can optionally say whether the symbol was found
+    // at a built-in level or the current top-scope level.
+    TSymbol* find(const TString& name, bool* builtIn = 0, bool* currentScope = 0, int* thisDepthP = 0)
     {
     {
         int level = currentLevel();
         int level = currentLevel();
         TSymbol* symbol;
         TSymbol* symbol;
+        int thisDepth = 0;
         do {
         do {
+            if (table[level]->isThisLevel())
+                ++thisDepth;
             symbol = table[level]->find(name);
             symbol = table[level]->find(name);
             --level;
             --level;
-        } while (symbol == 0 && level >= 0);
+        } while (symbol == nullptr && level >= 0);
         level++;
         level++;
         if (builtIn)
         if (builtIn)
             *builtIn = isBuiltInLevel(level);
             *builtIn = isBuiltInLevel(level);
         if (currentScope)
         if (currentScope)
             *currentScope = isGlobalLevel(currentLevel()) || level == currentLevel();  // consider shared levels as "current scope" WRT user globals
             *currentScope = isGlobalLevel(currentLevel()) || level == currentLevel();  // consider shared levels as "current scope" WRT user globals
+        if (thisDepthP != nullptr) {
+            if (! table[level]->isThisLevel())
+                thisDepth = 0;
+            *thisDepthP = thisDepth;
+        }
+
+        return symbol;
+    }
+
+    // Find of a symbol that returns how many layers deep of nested
+    // structures-with-member-functions ('this' scopes) deep the symbol was
+    // found in.
+    TSymbol* find(const TString& name, int& thisDepth)
+    {
+        int level = currentLevel();
+        TSymbol* symbol;
+        thisDepth = 0;
+        do {
+            if (table[level]->isThisLevel())
+                ++thisDepth;
+            symbol = table[level]->find(name);
+            --level;
+        } while (symbol == 0 && level >= 0);
+
+        if (! table[level + 1]->isThisLevel())
+            thisDepth = 0;
 
 
         return symbol;
         return symbol;
     }
     }

+ 41 - 1
src/libraries/glslang/glslang/MachineIndependent/Versions.cpp

@@ -195,6 +195,8 @@ void TParseVersions::initializeExtensionBehavior()
     extensionBehavior[E_GL_AMD_shader_explicit_vertex_parameter]     = EBhDisable;
     extensionBehavior[E_GL_AMD_shader_explicit_vertex_parameter]     = EBhDisable;
     extensionBehavior[E_GL_AMD_gcn_shader]                           = EBhDisable;
     extensionBehavior[E_GL_AMD_gcn_shader]                           = EBhDisable;
     extensionBehavior[E_GL_AMD_gpu_shader_half_float]                = EBhDisable;
     extensionBehavior[E_GL_AMD_gpu_shader_half_float]                = EBhDisable;
+    extensionBehavior[E_GL_AMD_texture_gather_bias_lod]              = EBhDisable;
+    extensionBehavior[E_GL_AMD_gpu_shader_int16]                     = EBhDisable;
 #endif
 #endif
 
 
 #ifdef NV_EXTENSIONS
 #ifdef NV_EXTENSIONS
@@ -233,6 +235,10 @@ void TParseVersions::initializeExtensionBehavior()
     extensionBehavior[E_GL_OES_tessellation_point_size]  = EBhDisable;
     extensionBehavior[E_GL_OES_tessellation_point_size]  = EBhDisable;
     extensionBehavior[E_GL_OES_texture_buffer]           = EBhDisable;
     extensionBehavior[E_GL_OES_texture_buffer]           = EBhDisable;
     extensionBehavior[E_GL_OES_texture_cube_map_array]   = EBhDisable;
     extensionBehavior[E_GL_OES_texture_cube_map_array]   = EBhDisable;
+
+    // EXT extensions
+    extensionBehavior[E_GL_EXT_device_group]             = EBhDisable;
+    extensionBehavior[E_GL_EXT_multiview]                = EBhDisable;
 }
 }
 
 
 // Get code that is not part of a shared symbol table, is specific to this shader,
 // Get code that is not part of a shared symbol table, is specific to this shader,
@@ -315,6 +321,8 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#define GL_AMD_shader_explicit_vertex_parameter 1\n"
             "#define GL_AMD_shader_explicit_vertex_parameter 1\n"
             "#define GL_AMD_gcn_shader 1\n"
             "#define GL_AMD_gcn_shader 1\n"
             "#define GL_AMD_gpu_shader_half_float 1\n"
             "#define GL_AMD_gpu_shader_half_float 1\n"
+            "#define GL_AMD_texture_gather_bias_lod 1\n"
+            "#define GL_AMD_gpu_shader_int16 1\n"
 #endif
 #endif
 
 
 #ifdef NV_EXTENSIONS
 #ifdef NV_EXTENSIONS
@@ -323,6 +331,22 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#define GL_NV_viewport_array2 1\n"
             "#define GL_NV_viewport_array2 1\n"
 #endif
 #endif
             ;
             ;
+
+        if (version >= 150) {
+            // define GL_core_profile and GL_compatibility_profile
+            preamble += "#define GL_core_profile 1\n";
+
+            if (profile == ECompatibilityProfile)
+                preamble += "#define GL_compatibility_profile 1\n";
+        }
+    }
+
+    if ((profile != EEsProfile && version >= 140) ||
+        (profile == EEsProfile && version >= 310)) {
+        preamble += 
+            "#define GL_EXT_device_group 1\n"
+            "#define GL_EXT_multiview 1\n"
+            ;
     }
     }
 
 
     // #line and #include
     // #line and #include
@@ -481,6 +505,11 @@ void TParseVersions::requireNotRemoved(const TSourceLoc& loc, int profileMask, i
     }
     }
 }
 }
 
 
+void TParseVersions::unimplemented(const TSourceLoc& loc, const char* featureDesc)
+{
+    error(loc, "feature not yet implemented", featureDesc, "");
+}
+
 // Returns true if at least one of the extensions in the extensions parameter is requested. Otherwise, returns false.
 // Returns true if at least one of the extensions in the extensions parameter is requested. Otherwise, returns false.
 // Warns appropriately if the requested behavior of an extension is "warn".
 // Warns appropriately if the requested behavior of an extension is "warn".
 bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
 bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
@@ -686,10 +715,21 @@ void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op)
 }
 }
 
 
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
+// Call for any operation needing GLSL 16-bit integer data-type support.
+void TParseVersions::int16Check(const TSourceLoc& loc, const char* op, bool builtIn)
+{
+    if (! builtIn) {
+        requireExtensions(loc, 1, &E_GL_AMD_gpu_shader_int16, "shader int16");
+        requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
+        profileRequires(loc, ECoreProfile, 450, nullptr, op);
+        profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
+    }
+}
+
 // Call for any operation needing GLSL float16 data-type support.
 // Call for any operation needing GLSL float16 data-type support.
 void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool builtIn)
 void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool builtIn)
 {
 {
-    if (!builtIn) {
+    if (! builtIn) {
         requireExtensions(loc, 1, &E_GL_AMD_gpu_shader_half_float, "shader half float");
         requireExtensions(loc, 1, &E_GL_AMD_gpu_shader_half_float, "shader half float");
         requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
         requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
         profileRequires(loc, ECoreProfile, 450, nullptr, op);
         profileRequires(loc, ECoreProfile, 450, nullptr, op);

+ 7 - 0
src/libraries/glslang/glslang/MachineIndependent/Versions.h

@@ -133,6 +133,10 @@ const char* const E_GL_ARB_sparse_texture_clamp         = "GL_ARB_sparse_texture
 const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers";
 const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers";
 const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
 const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
 
 
+// EXT extensions
+const char* const E_GL_EXT_device_group                 = "GL_EXT_device_group";
+const char* const E_GL_EXT_multiview                    = "GL_EXT_multiview";
+
 // #line and #include
 // #line and #include
 const char* const E_GL_GOOGLE_cpp_style_line_directive          = "GL_GOOGLE_cpp_style_line_directive";
 const char* const E_GL_GOOGLE_cpp_style_line_directive          = "GL_GOOGLE_cpp_style_line_directive";
 const char* const E_GL_GOOGLE_include_directive                 = "GL_GOOGLE_include_directive";
 const char* const E_GL_GOOGLE_include_directive                 = "GL_GOOGLE_include_directive";
@@ -143,7 +147,10 @@ const char* const E_GL_AMD_shader_trinary_minmax                = "GL_AMD_shader
 const char* const E_GL_AMD_shader_explicit_vertex_parameter     = "GL_AMD_shader_explicit_vertex_parameter";
 const char* const E_GL_AMD_shader_explicit_vertex_parameter     = "GL_AMD_shader_explicit_vertex_parameter";
 const char* const E_GL_AMD_gcn_shader                           = "GL_AMD_gcn_shader";
 const char* const E_GL_AMD_gcn_shader                           = "GL_AMD_gcn_shader";
 const char* const E_GL_AMD_gpu_shader_half_float                = "GL_AMD_gpu_shader_half_float";
 const char* const E_GL_AMD_gpu_shader_half_float                = "GL_AMD_gpu_shader_half_float";
+const char* const E_GL_AMD_texture_gather_bias_lod              = "GL_AMD_texture_gather_bias_lod";
+const char* const E_GL_AMD_gpu_shader_int16                     = "GL_AMD_gpu_shader_int16";
 #endif
 #endif
+
 #ifdef NV_EXTENSIONS
 #ifdef NV_EXTENSIONS
 
 
 const char* const E_GL_NV_sample_mask_override_coverage         = "GL_NV_sample_mask_override_coverage";
 const char* const E_GL_NV_sample_mask_override_coverage         = "GL_NV_sample_mask_override_coverage";

+ 2 - 0
src/libraries/glslang/glslang/MachineIndependent/gl_types.h

@@ -21,6 +21,8 @@
 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 */
 */
 
 
+#pragma once
+
 #define GL_FLOAT                          0x1406
 #define GL_FLOAT                          0x1406
 #define GL_FLOAT_VEC2                     0x8B50
 #define GL_FLOAT_VEC2                     0x8B50
 #define GL_FLOAT_VEC3                     0x8B51
 #define GL_FLOAT_VEC3                     0x8B51

File diff suppressed because it is too large
+ 480 - 625
src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp


+ 318 - 321
src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h

@@ -1,19 +1,19 @@
-/* A Bison parser, made by GNU Bison 2.7.  */
+/* A Bison parser, made by GNU Bison 3.0.4.  */
 
 
 /* Bison interface for Yacc-like parsers in C
 /* Bison interface for Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
-   
+
+   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+
    This program is free software: you can redistribute it and/or modify
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
@@ -26,13 +26,13 @@
    special exception, which will cause the skeleton and the resulting
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
    License without this special exception.
-   
+
    This special exception was added by the Free Software Foundation in
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
    version 2.2 of Bison.  */
 
 
-#ifndef YY_YY_GLSLANG_TAB_CPP_H_INCLUDED
-# define YY_YY_GLSLANG_TAB_CPP_H_INCLUDED
-/* Enabling traces.  */
+#ifndef YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED
+# define YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED
+/* Debug traces.  */
 #ifndef YYDEBUG
 #ifndef YYDEBUG
 # define YYDEBUG 1
 # define YYDEBUG 1
 #endif
 #endif
@@ -40,306 +40,315 @@
 extern int yydebug;
 extern int yydebug;
 #endif
 #endif
 
 
-/* Tokens.  */
+/* Token type.  */
 #ifndef YYTOKENTYPE
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
 # define YYTOKENTYPE
-   /* Put the tokens into the symbol table, so that GDB and other debuggers
-      know about them.  */
-   enum yytokentype {
-     ATTRIBUTE = 258,
-     VARYING = 259,
-     CONST = 260,
-     BOOL = 261,
-     FLOAT = 262,
-     DOUBLE = 263,
-     INT = 264,
-     UINT = 265,
-     INT64_T = 266,
-     UINT64_T = 267,
-     FLOAT16_T = 268,
-     BREAK = 269,
-     CONTINUE = 270,
-     DO = 271,
-     ELSE = 272,
-     FOR = 273,
-     IF = 274,
-     DISCARD = 275,
-     RETURN = 276,
-     SWITCH = 277,
-     CASE = 278,
-     DEFAULT = 279,
-     SUBROUTINE = 280,
-     BVEC2 = 281,
-     BVEC3 = 282,
-     BVEC4 = 283,
-     IVEC2 = 284,
-     IVEC3 = 285,
-     IVEC4 = 286,
-     I64VEC2 = 287,
-     I64VEC3 = 288,
-     I64VEC4 = 289,
-     UVEC2 = 290,
-     UVEC3 = 291,
-     UVEC4 = 292,
-     U64VEC2 = 293,
-     U64VEC3 = 294,
-     U64VEC4 = 295,
-     VEC2 = 296,
-     VEC3 = 297,
-     VEC4 = 298,
-     MAT2 = 299,
-     MAT3 = 300,
-     MAT4 = 301,
-     CENTROID = 302,
-     IN = 303,
-     OUT = 304,
-     INOUT = 305,
-     UNIFORM = 306,
-     PATCH = 307,
-     SAMPLE = 308,
-     BUFFER = 309,
-     SHARED = 310,
-     COHERENT = 311,
-     VOLATILE = 312,
-     RESTRICT = 313,
-     READONLY = 314,
-     WRITEONLY = 315,
-     DVEC2 = 316,
-     DVEC3 = 317,
-     DVEC4 = 318,
-     DMAT2 = 319,
-     DMAT3 = 320,
-     DMAT4 = 321,
-     F16VEC2 = 322,
-     F16VEC3 = 323,
-     F16VEC4 = 324,
-     F16MAT2 = 325,
-     F16MAT3 = 326,
-     F16MAT4 = 327,
-     NOPERSPECTIVE = 328,
-     FLAT = 329,
-     SMOOTH = 330,
-     LAYOUT = 331,
-     __EXPLICITINTERPAMD = 332,
-     MAT2X2 = 333,
-     MAT2X3 = 334,
-     MAT2X4 = 335,
-     MAT3X2 = 336,
-     MAT3X3 = 337,
-     MAT3X4 = 338,
-     MAT4X2 = 339,
-     MAT4X3 = 340,
-     MAT4X4 = 341,
-     DMAT2X2 = 342,
-     DMAT2X3 = 343,
-     DMAT2X4 = 344,
-     DMAT3X2 = 345,
-     DMAT3X3 = 346,
-     DMAT3X4 = 347,
-     DMAT4X2 = 348,
-     DMAT4X3 = 349,
-     DMAT4X4 = 350,
-     F16MAT2X2 = 351,
-     F16MAT2X3 = 352,
-     F16MAT2X4 = 353,
-     F16MAT3X2 = 354,
-     F16MAT3X3 = 355,
-     F16MAT3X4 = 356,
-     F16MAT4X2 = 357,
-     F16MAT4X3 = 358,
-     F16MAT4X4 = 359,
-     ATOMIC_UINT = 360,
-     SAMPLER1D = 361,
-     SAMPLER2D = 362,
-     SAMPLER3D = 363,
-     SAMPLERCUBE = 364,
-     SAMPLER1DSHADOW = 365,
-     SAMPLER2DSHADOW = 366,
-     SAMPLERCUBESHADOW = 367,
-     SAMPLER1DARRAY = 368,
-     SAMPLER2DARRAY = 369,
-     SAMPLER1DARRAYSHADOW = 370,
-     SAMPLER2DARRAYSHADOW = 371,
-     ISAMPLER1D = 372,
-     ISAMPLER2D = 373,
-     ISAMPLER3D = 374,
-     ISAMPLERCUBE = 375,
-     ISAMPLER1DARRAY = 376,
-     ISAMPLER2DARRAY = 377,
-     USAMPLER1D = 378,
-     USAMPLER2D = 379,
-     USAMPLER3D = 380,
-     USAMPLERCUBE = 381,
-     USAMPLER1DARRAY = 382,
-     USAMPLER2DARRAY = 383,
-     SAMPLER2DRECT = 384,
-     SAMPLER2DRECTSHADOW = 385,
-     ISAMPLER2DRECT = 386,
-     USAMPLER2DRECT = 387,
-     SAMPLERBUFFER = 388,
-     ISAMPLERBUFFER = 389,
-     USAMPLERBUFFER = 390,
-     SAMPLERCUBEARRAY = 391,
-     SAMPLERCUBEARRAYSHADOW = 392,
-     ISAMPLERCUBEARRAY = 393,
-     USAMPLERCUBEARRAY = 394,
-     SAMPLER2DMS = 395,
-     ISAMPLER2DMS = 396,
-     USAMPLER2DMS = 397,
-     SAMPLER2DMSARRAY = 398,
-     ISAMPLER2DMSARRAY = 399,
-     USAMPLER2DMSARRAY = 400,
-     SAMPLEREXTERNALOES = 401,
-     SAMPLER = 402,
-     SAMPLERSHADOW = 403,
-     TEXTURE1D = 404,
-     TEXTURE2D = 405,
-     TEXTURE3D = 406,
-     TEXTURECUBE = 407,
-     TEXTURE1DARRAY = 408,
-     TEXTURE2DARRAY = 409,
-     ITEXTURE1D = 410,
-     ITEXTURE2D = 411,
-     ITEXTURE3D = 412,
-     ITEXTURECUBE = 413,
-     ITEXTURE1DARRAY = 414,
-     ITEXTURE2DARRAY = 415,
-     UTEXTURE1D = 416,
-     UTEXTURE2D = 417,
-     UTEXTURE3D = 418,
-     UTEXTURECUBE = 419,
-     UTEXTURE1DARRAY = 420,
-     UTEXTURE2DARRAY = 421,
-     TEXTURE2DRECT = 422,
-     ITEXTURE2DRECT = 423,
-     UTEXTURE2DRECT = 424,
-     TEXTUREBUFFER = 425,
-     ITEXTUREBUFFER = 426,
-     UTEXTUREBUFFER = 427,
-     TEXTURECUBEARRAY = 428,
-     ITEXTURECUBEARRAY = 429,
-     UTEXTURECUBEARRAY = 430,
-     TEXTURE2DMS = 431,
-     ITEXTURE2DMS = 432,
-     UTEXTURE2DMS = 433,
-     TEXTURE2DMSARRAY = 434,
-     ITEXTURE2DMSARRAY = 435,
-     UTEXTURE2DMSARRAY = 436,
-     SUBPASSINPUT = 437,
-     SUBPASSINPUTMS = 438,
-     ISUBPASSINPUT = 439,
-     ISUBPASSINPUTMS = 440,
-     USUBPASSINPUT = 441,
-     USUBPASSINPUTMS = 442,
-     IMAGE1D = 443,
-     IIMAGE1D = 444,
-     UIMAGE1D = 445,
-     IMAGE2D = 446,
-     IIMAGE2D = 447,
-     UIMAGE2D = 448,
-     IMAGE3D = 449,
-     IIMAGE3D = 450,
-     UIMAGE3D = 451,
-     IMAGE2DRECT = 452,
-     IIMAGE2DRECT = 453,
-     UIMAGE2DRECT = 454,
-     IMAGECUBE = 455,
-     IIMAGECUBE = 456,
-     UIMAGECUBE = 457,
-     IMAGEBUFFER = 458,
-     IIMAGEBUFFER = 459,
-     UIMAGEBUFFER = 460,
-     IMAGE1DARRAY = 461,
-     IIMAGE1DARRAY = 462,
-     UIMAGE1DARRAY = 463,
-     IMAGE2DARRAY = 464,
-     IIMAGE2DARRAY = 465,
-     UIMAGE2DARRAY = 466,
-     IMAGECUBEARRAY = 467,
-     IIMAGECUBEARRAY = 468,
-     UIMAGECUBEARRAY = 469,
-     IMAGE2DMS = 470,
-     IIMAGE2DMS = 471,
-     UIMAGE2DMS = 472,
-     IMAGE2DMSARRAY = 473,
-     IIMAGE2DMSARRAY = 474,
-     UIMAGE2DMSARRAY = 475,
-     STRUCT = 476,
-     VOID = 477,
-     WHILE = 478,
-     IDENTIFIER = 479,
-     TYPE_NAME = 480,
-     FLOATCONSTANT = 481,
-     DOUBLECONSTANT = 482,
-     INTCONSTANT = 483,
-     UINTCONSTANT = 484,
-     INT64CONSTANT = 485,
-     UINT64CONSTANT = 486,
-     BOOLCONSTANT = 487,
-     FLOAT16CONSTANT = 488,
-     LEFT_OP = 489,
-     RIGHT_OP = 490,
-     INC_OP = 491,
-     DEC_OP = 492,
-     LE_OP = 493,
-     GE_OP = 494,
-     EQ_OP = 495,
-     NE_OP = 496,
-     AND_OP = 497,
-     OR_OP = 498,
-     XOR_OP = 499,
-     MUL_ASSIGN = 500,
-     DIV_ASSIGN = 501,
-     ADD_ASSIGN = 502,
-     MOD_ASSIGN = 503,
-     LEFT_ASSIGN = 504,
-     RIGHT_ASSIGN = 505,
-     AND_ASSIGN = 506,
-     XOR_ASSIGN = 507,
-     OR_ASSIGN = 508,
-     SUB_ASSIGN = 509,
-     LEFT_PAREN = 510,
-     RIGHT_PAREN = 511,
-     LEFT_BRACKET = 512,
-     RIGHT_BRACKET = 513,
-     LEFT_BRACE = 514,
-     RIGHT_BRACE = 515,
-     DOT = 516,
-     COMMA = 517,
-     COLON = 518,
-     EQUAL = 519,
-     SEMICOLON = 520,
-     BANG = 521,
-     DASH = 522,
-     TILDE = 523,
-     PLUS = 524,
-     STAR = 525,
-     SLASH = 526,
-     PERCENT = 527,
-     LEFT_ANGLE = 528,
-     RIGHT_ANGLE = 529,
-     VERTICAL_BAR = 530,
-     CARET = 531,
-     AMPERSAND = 532,
-     QUESTION = 533,
-     INVARIANT = 534,
-     PRECISE = 535,
-     HIGH_PRECISION = 536,
-     MEDIUM_PRECISION = 537,
-     LOW_PRECISION = 538,
-     PRECISION = 539,
-     PACKED = 540,
-     RESOURCE = 541,
-     SUPERP = 542
-   };
+  enum yytokentype
+  {
+    ATTRIBUTE = 258,
+    VARYING = 259,
+    CONST = 260,
+    BOOL = 261,
+    FLOAT = 262,
+    DOUBLE = 263,
+    INT = 264,
+    UINT = 265,
+    INT64_T = 266,
+    UINT64_T = 267,
+    INT16_T = 268,
+    UINT16_T = 269,
+    FLOAT16_T = 270,
+    BREAK = 271,
+    CONTINUE = 272,
+    DO = 273,
+    ELSE = 274,
+    FOR = 275,
+    IF = 276,
+    DISCARD = 277,
+    RETURN = 278,
+    SWITCH = 279,
+    CASE = 280,
+    DEFAULT = 281,
+    SUBROUTINE = 282,
+    BVEC2 = 283,
+    BVEC3 = 284,
+    BVEC4 = 285,
+    IVEC2 = 286,
+    IVEC3 = 287,
+    IVEC4 = 288,
+    I64VEC2 = 289,
+    I64VEC3 = 290,
+    I64VEC4 = 291,
+    UVEC2 = 292,
+    UVEC3 = 293,
+    UVEC4 = 294,
+    U64VEC2 = 295,
+    U64VEC3 = 296,
+    U64VEC4 = 297,
+    VEC2 = 298,
+    VEC3 = 299,
+    VEC4 = 300,
+    MAT2 = 301,
+    MAT3 = 302,
+    MAT4 = 303,
+    CENTROID = 304,
+    IN = 305,
+    OUT = 306,
+    INOUT = 307,
+    UNIFORM = 308,
+    PATCH = 309,
+    SAMPLE = 310,
+    BUFFER = 311,
+    SHARED = 312,
+    COHERENT = 313,
+    VOLATILE = 314,
+    RESTRICT = 315,
+    READONLY = 316,
+    WRITEONLY = 317,
+    DVEC2 = 318,
+    DVEC3 = 319,
+    DVEC4 = 320,
+    DMAT2 = 321,
+    DMAT3 = 322,
+    DMAT4 = 323,
+    F16VEC2 = 324,
+    F16VEC3 = 325,
+    F16VEC4 = 326,
+    F16MAT2 = 327,
+    F16MAT3 = 328,
+    F16MAT4 = 329,
+    I16VEC2 = 330,
+    I16VEC3 = 331,
+    I16VEC4 = 332,
+    U16VEC2 = 333,
+    U16VEC3 = 334,
+    U16VEC4 = 335,
+    NOPERSPECTIVE = 336,
+    FLAT = 337,
+    SMOOTH = 338,
+    LAYOUT = 339,
+    __EXPLICITINTERPAMD = 340,
+    MAT2X2 = 341,
+    MAT2X3 = 342,
+    MAT2X4 = 343,
+    MAT3X2 = 344,
+    MAT3X3 = 345,
+    MAT3X4 = 346,
+    MAT4X2 = 347,
+    MAT4X3 = 348,
+    MAT4X4 = 349,
+    DMAT2X2 = 350,
+    DMAT2X3 = 351,
+    DMAT2X4 = 352,
+    DMAT3X2 = 353,
+    DMAT3X3 = 354,
+    DMAT3X4 = 355,
+    DMAT4X2 = 356,
+    DMAT4X3 = 357,
+    DMAT4X4 = 358,
+    F16MAT2X2 = 359,
+    F16MAT2X3 = 360,
+    F16MAT2X4 = 361,
+    F16MAT3X2 = 362,
+    F16MAT3X3 = 363,
+    F16MAT3X4 = 364,
+    F16MAT4X2 = 365,
+    F16MAT4X3 = 366,
+    F16MAT4X4 = 367,
+    ATOMIC_UINT = 368,
+    SAMPLER1D = 369,
+    SAMPLER2D = 370,
+    SAMPLER3D = 371,
+    SAMPLERCUBE = 372,
+    SAMPLER1DSHADOW = 373,
+    SAMPLER2DSHADOW = 374,
+    SAMPLERCUBESHADOW = 375,
+    SAMPLER1DARRAY = 376,
+    SAMPLER2DARRAY = 377,
+    SAMPLER1DARRAYSHADOW = 378,
+    SAMPLER2DARRAYSHADOW = 379,
+    ISAMPLER1D = 380,
+    ISAMPLER2D = 381,
+    ISAMPLER3D = 382,
+    ISAMPLERCUBE = 383,
+    ISAMPLER1DARRAY = 384,
+    ISAMPLER2DARRAY = 385,
+    USAMPLER1D = 386,
+    USAMPLER2D = 387,
+    USAMPLER3D = 388,
+    USAMPLERCUBE = 389,
+    USAMPLER1DARRAY = 390,
+    USAMPLER2DARRAY = 391,
+    SAMPLER2DRECT = 392,
+    SAMPLER2DRECTSHADOW = 393,
+    ISAMPLER2DRECT = 394,
+    USAMPLER2DRECT = 395,
+    SAMPLERBUFFER = 396,
+    ISAMPLERBUFFER = 397,
+    USAMPLERBUFFER = 398,
+    SAMPLERCUBEARRAY = 399,
+    SAMPLERCUBEARRAYSHADOW = 400,
+    ISAMPLERCUBEARRAY = 401,
+    USAMPLERCUBEARRAY = 402,
+    SAMPLER2DMS = 403,
+    ISAMPLER2DMS = 404,
+    USAMPLER2DMS = 405,
+    SAMPLER2DMSARRAY = 406,
+    ISAMPLER2DMSARRAY = 407,
+    USAMPLER2DMSARRAY = 408,
+    SAMPLEREXTERNALOES = 409,
+    SAMPLER = 410,
+    SAMPLERSHADOW = 411,
+    TEXTURE1D = 412,
+    TEXTURE2D = 413,
+    TEXTURE3D = 414,
+    TEXTURECUBE = 415,
+    TEXTURE1DARRAY = 416,
+    TEXTURE2DARRAY = 417,
+    ITEXTURE1D = 418,
+    ITEXTURE2D = 419,
+    ITEXTURE3D = 420,
+    ITEXTURECUBE = 421,
+    ITEXTURE1DARRAY = 422,
+    ITEXTURE2DARRAY = 423,
+    UTEXTURE1D = 424,
+    UTEXTURE2D = 425,
+    UTEXTURE3D = 426,
+    UTEXTURECUBE = 427,
+    UTEXTURE1DARRAY = 428,
+    UTEXTURE2DARRAY = 429,
+    TEXTURE2DRECT = 430,
+    ITEXTURE2DRECT = 431,
+    UTEXTURE2DRECT = 432,
+    TEXTUREBUFFER = 433,
+    ITEXTUREBUFFER = 434,
+    UTEXTUREBUFFER = 435,
+    TEXTURECUBEARRAY = 436,
+    ITEXTURECUBEARRAY = 437,
+    UTEXTURECUBEARRAY = 438,
+    TEXTURE2DMS = 439,
+    ITEXTURE2DMS = 440,
+    UTEXTURE2DMS = 441,
+    TEXTURE2DMSARRAY = 442,
+    ITEXTURE2DMSARRAY = 443,
+    UTEXTURE2DMSARRAY = 444,
+    SUBPASSINPUT = 445,
+    SUBPASSINPUTMS = 446,
+    ISUBPASSINPUT = 447,
+    ISUBPASSINPUTMS = 448,
+    USUBPASSINPUT = 449,
+    USUBPASSINPUTMS = 450,
+    IMAGE1D = 451,
+    IIMAGE1D = 452,
+    UIMAGE1D = 453,
+    IMAGE2D = 454,
+    IIMAGE2D = 455,
+    UIMAGE2D = 456,
+    IMAGE3D = 457,
+    IIMAGE3D = 458,
+    UIMAGE3D = 459,
+    IMAGE2DRECT = 460,
+    IIMAGE2DRECT = 461,
+    UIMAGE2DRECT = 462,
+    IMAGECUBE = 463,
+    IIMAGECUBE = 464,
+    UIMAGECUBE = 465,
+    IMAGEBUFFER = 466,
+    IIMAGEBUFFER = 467,
+    UIMAGEBUFFER = 468,
+    IMAGE1DARRAY = 469,
+    IIMAGE1DARRAY = 470,
+    UIMAGE1DARRAY = 471,
+    IMAGE2DARRAY = 472,
+    IIMAGE2DARRAY = 473,
+    UIMAGE2DARRAY = 474,
+    IMAGECUBEARRAY = 475,
+    IIMAGECUBEARRAY = 476,
+    UIMAGECUBEARRAY = 477,
+    IMAGE2DMS = 478,
+    IIMAGE2DMS = 479,
+    UIMAGE2DMS = 480,
+    IMAGE2DMSARRAY = 481,
+    IIMAGE2DMSARRAY = 482,
+    UIMAGE2DMSARRAY = 483,
+    STRUCT = 484,
+    VOID = 485,
+    WHILE = 486,
+    IDENTIFIER = 487,
+    TYPE_NAME = 488,
+    FLOATCONSTANT = 489,
+    DOUBLECONSTANT = 490,
+    INTCONSTANT = 491,
+    UINTCONSTANT = 492,
+    INT64CONSTANT = 493,
+    UINT64CONSTANT = 494,
+    INT16CONSTANT = 495,
+    UINT16CONSTANT = 496,
+    BOOLCONSTANT = 497,
+    FLOAT16CONSTANT = 498,
+    LEFT_OP = 499,
+    RIGHT_OP = 500,
+    INC_OP = 501,
+    DEC_OP = 502,
+    LE_OP = 503,
+    GE_OP = 504,
+    EQ_OP = 505,
+    NE_OP = 506,
+    AND_OP = 507,
+    OR_OP = 508,
+    XOR_OP = 509,
+    MUL_ASSIGN = 510,
+    DIV_ASSIGN = 511,
+    ADD_ASSIGN = 512,
+    MOD_ASSIGN = 513,
+    LEFT_ASSIGN = 514,
+    RIGHT_ASSIGN = 515,
+    AND_ASSIGN = 516,
+    XOR_ASSIGN = 517,
+    OR_ASSIGN = 518,
+    SUB_ASSIGN = 519,
+    LEFT_PAREN = 520,
+    RIGHT_PAREN = 521,
+    LEFT_BRACKET = 522,
+    RIGHT_BRACKET = 523,
+    LEFT_BRACE = 524,
+    RIGHT_BRACE = 525,
+    DOT = 526,
+    COMMA = 527,
+    COLON = 528,
+    EQUAL = 529,
+    SEMICOLON = 530,
+    BANG = 531,
+    DASH = 532,
+    TILDE = 533,
+    PLUS = 534,
+    STAR = 535,
+    SLASH = 536,
+    PERCENT = 537,
+    LEFT_ANGLE = 538,
+    RIGHT_ANGLE = 539,
+    VERTICAL_BAR = 540,
+    CARET = 541,
+    AMPERSAND = 542,
+    QUESTION = 543,
+    INVARIANT = 544,
+    PRECISE = 545,
+    HIGH_PRECISION = 546,
+    MEDIUM_PRECISION = 547,
+    LOW_PRECISION = 548,
+    PRECISION = 549,
+    PACKED = 550,
+    RESOURCE = 551,
+    SUPERP = 552
+  };
 #endif
 #endif
 
 
-
+/* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
+
+union YYSTYPE
 {
 {
-/* Line 2058 of yacc.c  */
-#line 66 "glslang.y"
+#line 68 "MachineIndependent/glslang.y" /* yacc.c:1909  */
 
 
     struct {
     struct {
         glslang::TSourceLoc loc;
         glslang::TSourceLoc loc;
@@ -373,28 +382,16 @@ typedef union YYSTYPE
         };
         };
     } interm;
     } interm;
 
 
+#line 386 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909  */
+};
 
 
-/* Line 2058 of yacc.c  */
-#line 379 "glslang_tab.cpp.h"
-} YYSTYPE;
+typedef union YYSTYPE YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_DECLARED 1
 #endif
 #endif
 
 
 
 
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
+
 int yyparse (glslang::TParseContext* pParseContext);
 int yyparse (glslang::TParseContext* pParseContext);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
 
 
-#endif /* !YY_YY_GLSLANG_TAB_CPP_H_INCLUDED  */
+#endif /* !YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED  */

+ 185 - 8
src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp

@@ -45,11 +45,31 @@
 
 
 namespace {
 namespace {
 
 
-bool is_positive_infinity(double x) {
+bool IsInfinity(double x) {
 #ifdef _MSC_VER
 #ifdef _MSC_VER
-  return _fpclass(x) == _FPCLASS_PINF;
+    switch (_fpclass(x)) {
+    case _FPCLASS_NINF:
+    case _FPCLASS_PINF:
+        return true;
+    default:
+        return false;
+    }
+#else
+    return std::isinf(x);
+#endif
+}
+
+bool IsNan(double x) {
+#ifdef _MSC_VER
+    switch (_fpclass(x)) {
+    case _FPCLASS_SNAN:
+    case _FPCLASS_QNAN:
+        return true;
+    default:
+        return false;
+    }
 #else
 #else
-  return std::isinf(x) && (x >= 0);
+  return std::isnan(x);
 #endif
 #endif
 }
 }
 
 
@@ -288,6 +308,13 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
     case EOpDoubleBitsToUint64: out.debug << "doubleBitsToUint64"; break;
     case EOpDoubleBitsToUint64: out.debug << "doubleBitsToUint64"; break;
     case EOpInt64BitsToDouble:  out.debug << "int64BitsToDouble";  break;
     case EOpInt64BitsToDouble:  out.debug << "int64BitsToDouble";  break;
     case EOpUint64BitsToDouble: out.debug << "uint64BitsToDouble"; break;
     case EOpUint64BitsToDouble: out.debug << "uint64BitsToDouble"; break;
+#ifdef AMD_EXTENSIONS
+    case EOpFloat16BitsToInt16:  out.debug << "float16BitsToInt16";  break;
+    case EOpFloat16BitsToUint16: out.debug << "float16BitsToUint16"; break;
+    case EOpInt16BitsToFloat16:  out.debug << "int16BitsToFloat16";  break;
+    case EOpUint16BitsToFloat16: out.debug << "uint16BitsToFloat16"; break;
+#endif
+
     case EOpPackSnorm2x16:  out.debug << "packSnorm2x16";        break;
     case EOpPackSnorm2x16:  out.debug << "packSnorm2x16";        break;
     case EOpUnpackSnorm2x16:out.debug << "unpackSnorm2x16";      break;
     case EOpUnpackSnorm2x16:out.debug << "unpackSnorm2x16";      break;
     case EOpPackUnorm2x16:  out.debug << "packUnorm2x16";        break;
     case EOpPackUnorm2x16:  out.debug << "packUnorm2x16";        break;
@@ -308,6 +335,16 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
     case EOpUnpackUint2x32:   out.debug << "unpackUint2x32";     break;
     case EOpUnpackUint2x32:   out.debug << "unpackUint2x32";     break;
 
 
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
+    case EOpPackInt2x16:      out.debug << "packInt2x16";        break;
+    case EOpUnpackInt2x16:    out.debug << "unpackInt2x16";      break;
+    case EOpPackUint2x16:     out.debug << "packUint2x16";       break;
+    case EOpUnpackUint2x16:   out.debug << "unpackUint2x16";     break;
+
+    case EOpPackInt4x16:      out.debug << "packInt4x16";        break;
+    case EOpUnpackInt4x16:    out.debug << "unpackInt4x16";      break;
+    case EOpPackUint4x16:     out.debug << "packUint4x16";       break;
+    case EOpUnpackUint4x16:   out.debug << "unpackUint4x16";     break;
+
     case EOpPackFloat2x16:    out.debug << "packFloat2x16";      break;
     case EOpPackFloat2x16:    out.debug << "packFloat2x16";      break;
     case EOpUnpackFloat2x16:  out.debug << "unpackFloat2x16";    break;
     case EOpUnpackFloat2x16:  out.debug << "unpackFloat2x16";    break;
 #endif
 #endif
@@ -370,6 +407,8 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
     case EOpRcp:                    out.debug << "rcp";                   break;
     case EOpRcp:                    out.debug << "rcp";                   break;
     case EOpSaturate:               out.debug << "saturate";              break;
     case EOpSaturate:               out.debug << "saturate";              break;
 
 
+    case EOpSparseTexelsResident:   out.debug << "sparseTexelsResident";  break;
+
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
     case EOpMinInvocations:             out.debug << "minInvocations";              break;
     case EOpMinInvocations:             out.debug << "minInvocations";              break;
     case EOpMaxInvocations:             out.debug << "maxInvocations";              break;
     case EOpMaxInvocations:             out.debug << "maxInvocations";              break;
@@ -411,6 +450,42 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
     case EOpConvFloat16ToDouble:    out.debug << "Convert float16 to double";   break;
     case EOpConvFloat16ToDouble:    out.debug << "Convert float16 to double";   break;
     case EOpConvFloat16ToInt64:     out.debug << "Convert float16 to int64";    break;
     case EOpConvFloat16ToInt64:     out.debug << "Convert float16 to int64";    break;
     case EOpConvFloat16ToUint64:    out.debug << "Convert float16 to uint64";   break;
     case EOpConvFloat16ToUint64:    out.debug << "Convert float16 to uint64";   break;
+
+    case EOpConvBoolToInt16:        out.debug << "Convert bool to int16";       break;
+    case EOpConvIntToInt16:         out.debug << "Convert int to int16";        break;
+    case EOpConvUintToInt16:        out.debug << "Convert uint to int16";       break;
+    case EOpConvFloatToInt16:       out.debug << "Convert float to int16";      break;
+    case EOpConvDoubleToInt16:      out.debug << "Convert double to int16";     break;
+    case EOpConvFloat16ToInt16:     out.debug << "Convert float16 to int16";    break;
+    case EOpConvInt64ToInt16:       out.debug << "Convert int64 to int16";      break;
+    case EOpConvUint64ToInt16:      out.debug << "Convert uint64 to int16";     break;
+    case EOpConvUint16ToInt16:      out.debug << "Convert uint16 to int16";     break;
+    case EOpConvInt16ToBool:        out.debug << "Convert int16 to bool";       break;
+    case EOpConvInt16ToInt:         out.debug << "Convert int16 to int";        break;
+    case EOpConvInt16ToUint:        out.debug << "Convert int16 to uint";       break;
+    case EOpConvInt16ToFloat:       out.debug << "Convert int16 to float";      break;
+    case EOpConvInt16ToDouble:      out.debug << "Convert int16 to double";     break;
+    case EOpConvInt16ToFloat16:     out.debug << "Convert int16 to float16";    break;
+    case EOpConvInt16ToInt64:       out.debug << "Convert int16 to int64";      break;
+    case EOpConvInt16ToUint64:      out.debug << "Convert int16 to uint64";     break;
+
+    case EOpConvBoolToUint16:       out.debug << "Convert bool to uint16";      break;
+    case EOpConvIntToUint16:        out.debug << "Convert int to uint16";       break;
+    case EOpConvUintToUint16:       out.debug << "Convert uint to uint16";      break;
+    case EOpConvFloatToUint16:      out.debug << "Convert float to uint16";     break;
+    case EOpConvDoubleToUint16:     out.debug << "Convert double to uint16";    break;
+    case EOpConvFloat16ToUint16:    out.debug << "Convert float16 to uint16";   break;
+    case EOpConvInt64ToUint16:      out.debug << "Convert int64 to uint16";     break;
+    case EOpConvUint64ToUint16:     out.debug << "Convert uint64 to uint16";    break;
+    case EOpConvInt16ToUint16:      out.debug << "Convert int16 to uint16";     break;
+    case EOpConvUint16ToBool:       out.debug << "Convert uint16 to bool";      break;
+    case EOpConvUint16ToInt:        out.debug << "Convert uint16 to int";       break;
+    case EOpConvUint16ToUint:       out.debug << "Convert uint16 to uint";      break;
+    case EOpConvUint16ToFloat:      out.debug << "Convert uint16 to float";     break;
+    case EOpConvUint16ToDouble:     out.debug << "Convert uint16 to double";    break;
+    case EOpConvUint16ToFloat16:    out.debug << "Convert uint16 to float16";   break;
+    case EOpConvUint16ToInt64:      out.debug << "Convert uint16 to int64";     break;
+    case EOpConvUint16ToUint64:     out.debug << "Convert uint16 to uint64";    break;
 #endif
 #endif
 
 
     default: out.debug.message(EPrefixError, "Bad unary op");
     default: out.debug.message(EPrefixError, "Bad unary op");
@@ -444,9 +519,13 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
 
 
     case EOpConstructFloat: out.debug << "Construct float"; break;
     case EOpConstructFloat: out.debug << "Construct float"; break;
     case EOpConstructDouble:out.debug << "Construct double"; break;
     case EOpConstructDouble:out.debug << "Construct double"; break;
+
     case EOpConstructVec2:  out.debug << "Construct vec2";  break;
     case EOpConstructVec2:  out.debug << "Construct vec2";  break;
     case EOpConstructVec3:  out.debug << "Construct vec3";  break;
     case EOpConstructVec3:  out.debug << "Construct vec3";  break;
     case EOpConstructVec4:  out.debug << "Construct vec4";  break;
     case EOpConstructVec4:  out.debug << "Construct vec4";  break;
+    case EOpConstructDVec2: out.debug << "Construct dvec2";  break;
+    case EOpConstructDVec3: out.debug << "Construct dvec3";  break;
+    case EOpConstructDVec4: out.debug << "Construct dvec4";  break;
     case EOpConstructBool:  out.debug << "Construct bool";  break;
     case EOpConstructBool:  out.debug << "Construct bool";  break;
     case EOpConstructBVec2: out.debug << "Construct bvec2"; break;
     case EOpConstructBVec2: out.debug << "Construct bvec2"; break;
     case EOpConstructBVec3: out.debug << "Construct bvec3"; break;
     case EOpConstructBVec3: out.debug << "Construct bvec3"; break;
@@ -467,6 +546,16 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
     case EOpConstructU64Vec2: out.debug << "Construct u64vec2"; break;
     case EOpConstructU64Vec2: out.debug << "Construct u64vec2"; break;
     case EOpConstructU64Vec3: out.debug << "Construct u64vec3"; break;
     case EOpConstructU64Vec3: out.debug << "Construct u64vec3"; break;
     case EOpConstructU64Vec4: out.debug << "Construct u64vec4"; break;
     case EOpConstructU64Vec4: out.debug << "Construct u64vec4"; break;
+#ifdef AMD_EXTENSIONS
+    case EOpConstructInt16:   out.debug << "Construct int16_t"; break;
+    case EOpConstructI16Vec2: out.debug << "Construct i16vec2"; break;
+    case EOpConstructI16Vec3: out.debug << "Construct i16vec3"; break;
+    case EOpConstructI16Vec4: out.debug << "Construct i16vec4"; break;
+    case EOpConstructUint16:  out.debug << "Construct uint16_t"; break;
+    case EOpConstructU16Vec2: out.debug << "Construct u16vec2"; break;
+    case EOpConstructU16Vec3: out.debug << "Construct u16vec3"; break;
+    case EOpConstructU16Vec4: out.debug << "Construct u16vec4"; break;
+#endif
     case EOpConstructMat2x2:  out.debug << "Construct mat2";    break;
     case EOpConstructMat2x2:  out.debug << "Construct mat2";    break;
     case EOpConstructMat2x3:  out.debug << "Construct mat2x3";  break;
     case EOpConstructMat2x3:  out.debug << "Construct mat2x3";  break;
     case EOpConstructMat2x4:  out.debug << "Construct mat2x4";  break;
     case EOpConstructMat2x4:  out.debug << "Construct mat2x4";  break;
@@ -485,6 +574,33 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
     case EOpConstructDMat4x2: out.debug << "Construct dmat4x2"; break;
     case EOpConstructDMat4x2: out.debug << "Construct dmat4x2"; break;
     case EOpConstructDMat4x3: out.debug << "Construct dmat4x3"; break;
     case EOpConstructDMat4x3: out.debug << "Construct dmat4x3"; break;
     case EOpConstructDMat4x4: out.debug << "Construct dmat4";   break;
     case EOpConstructDMat4x4: out.debug << "Construct dmat4";   break;
+    case EOpConstructIMat2x2: out.debug << "Construct imat2";   break;
+    case EOpConstructIMat2x3: out.debug << "Construct imat2x3"; break;
+    case EOpConstructIMat2x4: out.debug << "Construct imat2x4"; break;
+    case EOpConstructIMat3x2: out.debug << "Construct imat3x2"; break;
+    case EOpConstructIMat3x3: out.debug << "Construct imat3";   break;
+    case EOpConstructIMat3x4: out.debug << "Construct imat3x4"; break;
+    case EOpConstructIMat4x2: out.debug << "Construct imat4x2"; break;
+    case EOpConstructIMat4x3: out.debug << "Construct imat4x3"; break;
+    case EOpConstructIMat4x4: out.debug << "Construct imat4";   break;
+    case EOpConstructUMat2x2: out.debug << "Construct umat2";   break;
+    case EOpConstructUMat2x3: out.debug << "Construct umat2x3"; break;
+    case EOpConstructUMat2x4: out.debug << "Construct umat2x4"; break;
+    case EOpConstructUMat3x2: out.debug << "Construct umat3x2"; break;
+    case EOpConstructUMat3x3: out.debug << "Construct umat3";   break;
+    case EOpConstructUMat3x4: out.debug << "Construct umat3x4"; break;
+    case EOpConstructUMat4x2: out.debug << "Construct umat4x2"; break;
+    case EOpConstructUMat4x3: out.debug << "Construct umat4x3"; break;
+    case EOpConstructUMat4x4: out.debug << "Construct umat4";   break;
+    case EOpConstructBMat2x2: out.debug << "Construct bmat2";   break;
+    case EOpConstructBMat2x3: out.debug << "Construct bmat2x3"; break;
+    case EOpConstructBMat2x4: out.debug << "Construct bmat2x4"; break;
+    case EOpConstructBMat3x2: out.debug << "Construct bmat3x2"; break;
+    case EOpConstructBMat3x3: out.debug << "Construct bmat3";   break;
+    case EOpConstructBMat3x4: out.debug << "Construct bmat3x4"; break;
+    case EOpConstructBMat4x2: out.debug << "Construct bmat4x2"; break;
+    case EOpConstructBMat4x3: out.debug << "Construct bmat4x3"; break;
+    case EOpConstructBMat4x4: out.debug << "Construct bmat4";   break;
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
     case EOpConstructFloat16:   out.debug << "Construct float16_t"; break;
     case EOpConstructFloat16:   out.debug << "Construct float16_t"; break;
     case EOpConstructF16Vec2:   out.debug << "Construct f16vec2";   break;
     case EOpConstructF16Vec2:   out.debug << "Construct f16vec2";   break;
@@ -600,6 +716,37 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
     case EOpTextureGather:              out.debug << "textureGather";         break;
     case EOpTextureGather:              out.debug << "textureGather";         break;
     case EOpTextureGatherOffset:        out.debug << "textureGatherOffset";   break;
     case EOpTextureGatherOffset:        out.debug << "textureGatherOffset";   break;
     case EOpTextureGatherOffsets:       out.debug << "textureGatherOffsets";  break;
     case EOpTextureGatherOffsets:       out.debug << "textureGatherOffsets";  break;
+    case EOpTextureClamp:               out.debug << "textureClamp";          break;
+    case EOpTextureOffsetClamp:         out.debug << "textureOffsetClamp";    break;
+    case EOpTextureGradClamp:           out.debug << "textureGradClamp";      break;
+    case EOpTextureGradOffsetClamp:     out.debug << "textureGradOffsetClamp";  break;
+#ifdef AMD_EXTENSIONS
+    case EOpTextureGatherLod:           out.debug << "textureGatherLod";        break;
+    case EOpTextureGatherLodOffset:     out.debug << "textureGatherLodOffset";  break;
+    case EOpTextureGatherLodOffsets:    out.debug << "textureGatherLodOffsets"; break;
+#endif
+
+    case EOpSparseTexture:                  out.debug << "sparseTexture";                   break;
+    case EOpSparseTextureOffset:            out.debug << "sparseTextureOffset";             break;
+    case EOpSparseTextureLod:               out.debug << "sparseTextureLod";                break;
+    case EOpSparseTextureLodOffset:         out.debug << "sparseTextureLodOffset";          break;
+    case EOpSparseTextureFetch:             out.debug << "sparseTexelFetch";                break;
+    case EOpSparseTextureFetchOffset:       out.debug << "sparseTexelFetchOffset";          break;
+    case EOpSparseTextureGrad:              out.debug << "sparseTextureGrad";               break;
+    case EOpSparseTextureGradOffset:        out.debug << "sparseTextureGradOffset";         break;
+    case EOpSparseTextureGather:            out.debug << "sparseTextureGather";             break;
+    case EOpSparseTextureGatherOffset:      out.debug << "sparseTextureGatherOffset";       break;
+    case EOpSparseTextureGatherOffsets:     out.debug << "sparseTextureGatherOffsets";      break;
+    case EOpSparseImageLoad:                out.debug << "sparseImageLoad";                 break;
+    case EOpSparseTextureClamp:             out.debug << "sparseTextureClamp";              break;
+    case EOpSparseTextureOffsetClamp:       out.debug << "sparseTextureOffsetClamp";        break;
+    case EOpSparseTextureGradClamp:         out.debug << "sparseTextureGradClamp";          break;
+    case EOpSparseTextureGradOffsetClamp:   out.debug << "sparseTextureGradOffsetClam";     break;
+#ifdef AMD_EXTENSIONS
+    case EOpSparseTextureGatherLod:         out.debug << "sparseTextureGatherLod";          break;
+    case EOpSparseTextureGatherLodOffset:   out.debug << "sparseTextureGatherLodOffset";    break;
+    case EOpSparseTextureGatherLodOffsets:  out.debug << "sparseTextureGatherLodOffsets";   break;
+#endif
 
 
     case EOpAddCarry:                   out.debug << "addCarry";              break;
     case EOpAddCarry:                   out.debug << "addCarry";              break;
     case EOpSubBorrow:                  out.debug << "subBorrow";             break;
     case EOpSubBorrow:                  out.debug << "subBorrow";             break;
@@ -694,11 +841,14 @@ static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const
 #endif
 #endif
             {
             {
                 const double value = constUnion[i].getDConst();
                 const double value = constUnion[i].getDConst();
-                // Print infinity in a portable way, for test stability.
-                // Other cases may be needed in the future: negative infinity,
-                // and NaNs.
-                if (is_positive_infinity(value))
-                    out.debug << "inf\n";
+                // Print infinities and NaNs in a portable way.
+                if (IsInfinity(value)) {
+                    if (value < 0)
+                        out.debug << "-1.#INF\n";
+                    else
+                        out.debug << "+1.#INF\n";
+                } else if (IsNan(value))
+                    out.debug << "1.#IND\n";
                 else {
                 else {
                     const int maxSize = 300;
                     const int maxSize = 300;
                     char buf[maxSize];
                     char buf[maxSize];
@@ -744,6 +894,26 @@ static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const
                 out.debug << buf << "\n";
                 out.debug << buf << "\n";
             }
             }
             break;
             break;
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:
+            {
+                const int maxSize = 300;
+                char buf[maxSize];
+                snprintf(buf, maxSize, "%d (%s)", constUnion[i].getIConst(), "const int16_t");
+
+                out.debug << buf << "\n";
+            }
+            break;
+        case EbtUint16:
+            {
+                const int maxSize = 300;
+                char buf[maxSize];
+                snprintf(buf, maxSize, "%u (%s)", constUnion[i].getUConst(), "const uint16_t");
+
+                out.debug << buf << "\n";
+            }
+            break;
+#endif
         default:
         default:
             out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc());
             out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc());
             break;
             break;
@@ -884,6 +1054,13 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
 
 
     case EShLangTessControl:
     case EShLangTessControl:
         infoSink.debug << "vertices = " << vertices << "\n";
         infoSink.debug << "vertices = " << vertices << "\n";
+
+        if (inputPrimitive != ElgNone)
+            infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n";
+        if (vertexSpacing != EvsNone)
+            infoSink.debug << "vertex spacing = " << TQualifier::getVertexSpacingString(vertexSpacing) << "\n";
+        if (vertexOrder != EvoNone)
+            infoSink.debug << "triangle order = " << TQualifier::getVertexOrderString(vertexOrder) << "\n";
         break;
         break;
 
 
     case EShLangTessEvaluation:
     case EShLangTessEvaluation:

+ 410 - 92
src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp

@@ -1,5 +1,5 @@
 //
 //
-// Copyright (C) 2016 LunarG, Inc.
+// Copyright (C) 2016-2017 LunarG, Inc.
 //
 //
 // All rights reserved.
 // All rights reserved.
 //
 //
@@ -66,11 +66,14 @@ namespace glslang {
 
 
 struct TVarEntryInfo
 struct TVarEntryInfo
 {
 {
-    int             id;
-    TIntermSymbol*  symbol;
-    bool            live;
-    int             newBinding;
-    int             newSet;
+    int               id;
+    TIntermSymbol*    symbol;
+    bool              live;
+    int               newBinding;
+    int               newSet;
+    int               newLocation;
+    int               newComponent;
+    int               newIndex;
 
 
     struct TOrderById
     struct TOrderById
     {
     {
@@ -113,70 +116,143 @@ typedef std::vector<TVarEntryInfo> TVarLiveMap;
 class TVarGatherTraverser : public TLiveTraverser
 class TVarGatherTraverser : public TLiveTraverser
 {
 {
 public:
 public:
-    TVarGatherTraverser(const TIntermediate& i, TVarLiveMap& vars, bool traverseDeadCode)
+    TVarGatherTraverser(const TIntermediate& i, bool traverseDeadCode, TVarLiveMap& inList, TVarLiveMap& outList, TVarLiveMap& uniformList)
       : TLiveTraverser(i, traverseDeadCode, true, true, false)
       : TLiveTraverser(i, traverseDeadCode, true, true, false)
-      , varLiveList(vars)
+      , inputList(inList)
+      , outputList(outList)
+      , uniformList(uniformList)
     {
     {
     }
     }
 
 
 
 
     virtual void visitSymbol(TIntermSymbol* base)
     virtual void visitSymbol(TIntermSymbol* base)
     {
     {
-        if (base->getQualifier().storage == EvqUniform) {
+        TVarLiveMap* target = nullptr;
+        if (base->getQualifier().storage == EvqVaryingIn)
+            target = &inputList;
+        else if (base->getQualifier().storage == EvqVaryingOut)
+            target = &outputList;
+        else if (base->getQualifier().isUniformOrBuffer())
+            target = &uniformList;
+
+        if (target) {
             TVarEntryInfo ent = { base->getId(), base, !traverseAll };
             TVarEntryInfo ent = { base->getId(), base, !traverseAll };
-            TVarLiveMap::iterator at = std::lower_bound(varLiveList.begin(), varLiveList.end(), ent, TVarEntryInfo::TOrderById());
-            if (at != varLiveList.end() && at->id == ent.id)
+            TVarLiveMap::iterator at = std::lower_bound(target->begin(), target->end(), ent, TVarEntryInfo::TOrderById());
+            if (at != target->end() && at->id == ent.id)
               at->live = at->live || !traverseAll; // update live state
               at->live = at->live || !traverseAll; // update live state
             else
             else
-              varLiveList.insert(at, ent);
+              target->insert(at, ent);
         }
         }
     }
     }
 
 
 private:
 private:
-    TVarLiveMap&    varLiveList;
+    TVarLiveMap&    inputList;
+    TVarLiveMap&    outputList;
+    TVarLiveMap&    uniformList;
 };
 };
 
 
 class TVarSetTraverser : public TLiveTraverser
 class TVarSetTraverser : public TLiveTraverser
 {
 {
 public:
 public:
-    TVarSetTraverser(const TIntermediate& i, const TVarLiveMap& vars)
+    TVarSetTraverser(const TIntermediate& i, const TVarLiveMap& inList, const TVarLiveMap& outList, const TVarLiveMap& uniformList)
       : TLiveTraverser(i, true, true, true, false)
       : TLiveTraverser(i, true, true, true, false)
-      , varLiveList(vars)
+      , inputList(inList)
+      , outputList(outList)
+      , uniformList(uniformList)
     {
     {
     }
     }
 
 
 
 
     virtual void visitSymbol(TIntermSymbol* base)
     virtual void visitSymbol(TIntermSymbol* base)
     {
     {
+        const TVarLiveMap* source;
+        if (base->getQualifier().storage == EvqVaryingIn)
+            source = &inputList;
+        else if (base->getQualifier().storage == EvqVaryingOut)
+            source = &outputList;
+        else if (base->getQualifier().isUniformOrBuffer())
+            source = &uniformList;
+        else
+            return;
+
         TVarEntryInfo ent = { base->getId() };
         TVarEntryInfo ent = { base->getId() };
-        TVarLiveMap::const_iterator at = std::lower_bound(varLiveList.begin(), varLiveList.end(), ent, TVarEntryInfo::TOrderById());
-        if (at == varLiveList.end())
+        TVarLiveMap::const_iterator at = std::lower_bound(source->begin(), source->end(), ent, TVarEntryInfo::TOrderById());
+        if (at == source->end())
             return;
             return;
-        if (!(at->id == ent.id))
+
+        if (at->id != ent.id)
             return;
             return;
 
 
         if (at->newBinding != -1)
         if (at->newBinding != -1)
             base->getWritableType().getQualifier().layoutBinding = at->newBinding;
             base->getWritableType().getQualifier().layoutBinding = at->newBinding;
         if (at->newSet != -1)
         if (at->newSet != -1)
             base->getWritableType().getQualifier().layoutSet = at->newSet;
             base->getWritableType().getQualifier().layoutSet = at->newSet;
+        if (at->newLocation != -1)
+            base->getWritableType().getQualifier().layoutLocation = at->newLocation;
+        if (at->newComponent != -1)
+            base->getWritableType().getQualifier().layoutComponent = at->newComponent;
+        if (at->newIndex != -1)
+            base->getWritableType().getQualifier().layoutIndex = at->newIndex;
     }
     }
 
 
   private:
   private:
-    const TVarLiveMap&    varLiveList;
+    const TVarLiveMap&    inputList;
+    const TVarLiveMap&    outputList;
+    const TVarLiveMap&    uniformList;
 };
 };
 
 
-struct TResolverAdaptor
+struct TNotifyUniformAdaptor
 {
 {
-    TResolverAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e)
+    EShLanguage stage;
+    TIoMapResolver& resolver;
+    inline TNotifyUniformAdaptor(EShLanguage s, TIoMapResolver& r)
+      : stage(s)
+      , resolver(r)
+    {
+    }
+    inline void operator()(TVarEntryInfo& ent)
+    {
+        resolver.notifyBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
+    }
+private:
+    TNotifyUniformAdaptor& operator=(TNotifyUniformAdaptor&);
+};
+
+struct TNotifyInOutAdaptor
+{
+    EShLanguage stage;
+    TIoMapResolver& resolver;
+    inline TNotifyInOutAdaptor(EShLanguage s, TIoMapResolver& r)
+      : stage(s)
+      , resolver(r)
+    {
+    }
+    inline void operator()(TVarEntryInfo& ent)
+    {
+        resolver.notifyInOut(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
+    }
+private:
+    TNotifyInOutAdaptor& operator=(TNotifyInOutAdaptor&);
+};
+
+struct TResolverUniformAdaptor
+{
+    TResolverUniformAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e, TIntermediate& interm)
       : stage(s)
       : stage(s)
       , resolver(r)
       , resolver(r)
       , infoSink(i)
       , infoSink(i)
       , error(e)
       , error(e)
+      , intermediate(interm)
     {
     {
     }
     }
 
 
     inline void operator()(TVarEntryInfo& ent)
     inline void operator()(TVarEntryInfo& ent)
     {
     {
+        ent.newLocation = -1;
+        ent.newComponent = -1;
+        ent.newBinding = -1;
+        ent.newSet = -1;
+        ent.newIndex = -1;
         const bool isValid = resolver.validateBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
         const bool isValid = resolver.validateBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
         if (isValid) {
         if (isValid) {
             ent.newBinding = resolver.resolveBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
             ent.newBinding = resolver.resolveBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
@@ -209,25 +285,77 @@ struct TResolverAdaptor
     TIoMapResolver& resolver;
     TIoMapResolver& resolver;
     TInfoSink&      infoSink;
     TInfoSink&      infoSink;
     bool&           error;
     bool&           error;
+    TIntermediate&  intermediate;
 
 
 private:
 private:
-    TResolverAdaptor& operator=(TResolverAdaptor&);
+    TResolverUniformAdaptor& operator=(TResolverUniformAdaptor&);
 };
 };
 
 
-/*
- * Basic implementation of glslang::TIoMapResolver that replaces the
- * previous offset behaviour.
- * It does the same, uses the offsets for th corresponding uniform
- * types. Also respects the EOptionAutoMapBindings flag and binds
- * them if needed.
- */
-struct TDefaultIoResolver : public glslang::TIoMapResolver
+struct TResolverInOutAdaptor
+{
+    TResolverInOutAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e, TIntermediate& interm)
+      : stage(s)
+      , resolver(r)
+      , infoSink(i)
+      , error(e)
+      , intermediate(interm)
+    {
+    }
+
+    inline void operator()(TVarEntryInfo& ent)
+    {
+        ent.newLocation = -1;
+        ent.newComponent = -1;
+        ent.newBinding = -1;
+        ent.newSet = -1;
+        ent.newIndex = -1;
+        const bool isValid = resolver.validateInOut(stage,
+                                                    ent.symbol->getName().c_str(),
+                                                    ent.symbol->getType(),
+                                                    ent.live);
+        if (isValid) {
+            ent.newLocation = resolver.resolveInOutLocation(stage,
+                                                            ent.symbol->getName().c_str(),
+                                                            ent.symbol->getType(),
+                                                            ent.live);
+            ent.newComponent = resolver.resolveInOutComponent(stage,
+                                                              ent.symbol->getName().c_str(),
+                                                              ent.symbol->getType(),
+                                                              ent.live);
+            ent.newIndex = resolver.resolveInOutIndex(stage,
+                                                      ent.symbol->getName().c_str(),
+                                                      ent.symbol->getType(),
+                                                      ent.live);
+        } else {
+            TString errorMsg = "Invalid shader In/Out variable semantic: ";
+            errorMsg += ent.symbol->getType().getQualifier().semanticName;
+            infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
+            error = true;
+        }
+    }
+
+    EShLanguage     stage;
+    TIoMapResolver& resolver;
+    TInfoSink&      infoSink;
+    bool&           error;
+    TIntermediate&  intermediate;
+
+private:
+    TResolverInOutAdaptor& operator=(TResolverInOutAdaptor&);
+};
+
+// Base class for shared TIoMapResolver services, used by several derivations.
+struct TDefaultIoResolverBase : public glslang::TIoMapResolver
 {
 {
     int baseSamplerBinding;
     int baseSamplerBinding;
     int baseTextureBinding;
     int baseTextureBinding;
     int baseImageBinding;
     int baseImageBinding;
     int baseUboBinding;
     int baseUboBinding;
-    bool doAutoMapping;
+    int baseSsboBinding;
+    int baseUavBinding;
+    std::vector<std::string> baseResourceSetBinding;
+    bool doAutoBindingMapping;
+    bool doAutoLocationMapping;
     typedef std::vector<int> TSlotSet;
     typedef std::vector<int> TSlotSet;
     typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
     typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
     TSlotSetMap slots;
     TSlotSetMap slots;
@@ -246,7 +374,12 @@ struct TDefaultIoResolver : public glslang::TIoMapResolver
     int reserveSlot(int set, int slot)
     int reserveSlot(int set, int slot)
     {
     {
         TSlotSet::iterator at = findSlot(set, slot);
         TSlotSet::iterator at = findSlot(set, slot);
-        slots[set].insert(at, slot);
+
+        // tolerate aliasing, by not double-recording aliases
+        // (policy about appropriateness of the alias is higher up)
+        if (at == slots[set].end() || *at != slot)
+            slots[set].insert(at, slot);
+
         return slot;
         return slot;
     }
     }
 
 
@@ -263,83 +396,241 @@ struct TDefaultIoResolver : public glslang::TIoMapResolver
         return reserveSlot(set, base);
         return reserveSlot(set, base);
     }
     }
 
 
-    bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
+    virtual bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override = 0;
+
+    virtual int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override = 0;
+
+    int resolveSet(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
+    {
+        if (type.getQualifier().hasSet())
+            return type.getQualifier().layoutSet;
+        return 0;
+    }
+
+    bool validateInOut(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override
+    {
+        return true;
+    }
+    int resolveInOutLocation(EShLanguage /*stage*/, const char* /*name*/, const TType& type, bool /*is_live*/) override
+    {
+        if (!doAutoLocationMapping || type.getQualifier().hasLocation())
+            return -1;
+
+        // Placeholder.
+        // TODO: It would be nice to flesh this out using 
+        // intermediate->computeTypeLocationSize(type), or functions that call it like
+        // intermediate->addUsedLocation()
+        // These in turn would want the intermediate, which is not available here, but
+        // is available in many places, and a lot of copying from it could be saved if
+        // it were just available.
+        return 0;
+    }
+    int resolveInOutComponent(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override
+    {
+        return -1;
+    }
+    int resolveInOutIndex(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override
+    {
+        return -1;
+    }
+
+    void notifyBinding(EShLanguage, const char* /*name*/, const TType&, bool /*is_live*/) override {}
+    void notifyInOut(EShLanguage, const char* /*name*/, const TType&, bool /*is_live*/) override {}
+    void endNotifications() override {}
+
+protected:
+    static int getLayoutSet(const glslang::TType& type) {
+        if (type.getQualifier().hasSet())
+            return type.getQualifier().layoutSet;
+        else
+            return 0;
+    }
+
+    static bool isSamplerType(const glslang::TType& type) {
+        return type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler();
+    }
+
+    static bool isTextureType(const glslang::TType& type) {
+        return type.getBasicType() == glslang::EbtSampler && type.getSampler().isTexture();
+    }
+
+    static bool isUboType(const glslang::TType& type) {
+        return type.getQualifier().storage == EvqUniform;
+    }
+};
+
+/*
+ * Basic implementation of glslang::TIoMapResolver that replaces the
+ * previous offset behavior.
+ * It does the same, uses the offsets for the corresponding uniform
+ * types. Also respects the EOptionAutoMapBindings flag and binds
+ * them if needed.
+ */
+/*
+ * Default resolver
+ */
+struct TDefaultIoResolver : public TDefaultIoResolverBase
+{
+    bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override
     {
     {
+        return true;
+    }
+
+    int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override
+    {
+        const int set = getLayoutSet(type);
+
         if (type.getQualifier().hasBinding()) {
         if (type.getQualifier().hasBinding()) {
-            int set;
-            if (type.getQualifier().hasSet())
-                set = type.getQualifier().layoutSet;
-            else
-                set = 0;
+            if (isImageType(type))
+                return reserveSlot(set, baseImageBinding + type.getQualifier().layoutBinding);
 
 
-            if (type.getBasicType() == glslang::EbtSampler) {
-                const glslang::TSampler& sampler = type.getSampler();
-                if (sampler.isPureSampler())
-                    return checkEmpty(set, baseSamplerBinding + type.getQualifier().layoutBinding);
+            if (isTextureType(type))
+                return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
 
 
-                if (sampler.isTexture())
-                    return checkEmpty(set, baseTextureBinding + type.getQualifier().layoutBinding);
-            }
+            if (isSsboType(type))
+                return reserveSlot(set, baseSsboBinding + type.getQualifier().layoutBinding);
 
 
-            if (type.getQualifier().isUniformOrBuffer())
-                return checkEmpty(set, baseUboBinding + type.getQualifier().layoutBinding);
+            if (isSamplerType(type))
+                return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding);
+
+            if (isUboType(type))
+                return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
+        } else if (is_live && doAutoBindingMapping) {
+            // find free slot, the caller did make sure it passes all vars with binding
+            // first and now all are passed that do not have a binding and needs one
+
+            if (isImageType(type))
+                return getFreeSlot(set, baseImageBinding);
+
+            if (isTextureType(type))
+                return getFreeSlot(set, baseTextureBinding);
+
+            if (isSsboType(type))
+                return getFreeSlot(set, baseSsboBinding);
+
+            if (isSamplerType(type))
+                return getFreeSlot(set, baseSamplerBinding);
+
+            if (isUboType(type))
+                return getFreeSlot(set, baseUboBinding);
         }
         }
+
+        return -1;
+    }
+
+protected:
+    static bool isImageType(const glslang::TType& type) {
+        return type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage();
+    }
+
+    static bool isSsboType(const glslang::TType& type) {
+        return type.getQualifier().storage == EvqBuffer;
+    }
+};
+
+/********************************************************************************
+The following IO resolver maps types in HLSL register space, as follows:
+
+t – for shader resource views (SRV)
+   TEXTURE1D
+   TEXTURE1DARRAY
+   TEXTURE2D
+   TEXTURE2DARRAY
+   TEXTURE3D
+   TEXTURECUBE
+   TEXTURECUBEARRAY
+   TEXTURE2DMS
+   TEXTURE2DMSARRAY
+   STRUCTUREDBUFFER
+   BYTEADDRESSBUFFER
+   BUFFER
+   TBUFFER
+    
+s – for samplers
+   SAMPLER
+   SAMPLER1D
+   SAMPLER2D
+   SAMPLER3D
+   SAMPLERCUBE
+   SAMPLERSTATE
+   SAMPLERCOMPARISONSTATE
+
+u – for unordered access views (UAV)
+   RWBYTEADDRESSBUFFER
+   RWSTRUCTUREDBUFFER
+   APPENDSTRUCTUREDBUFFER
+   CONSUMESTRUCTUREDBUFFER
+   RWBUFFER
+   RWTEXTURE1D
+   RWTEXTURE1DARRAY
+   RWTEXTURE2D
+   RWTEXTURE2DARRAY
+   RWTEXTURE3D
+
+b – for constant buffer views (CBV)
+   CBUFFER
+   CONSTANTBUFFER
+ ********************************************************************************/
+struct TDefaultHlslIoResolver : public TDefaultIoResolverBase
+{
+    bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override
+    {
         return true;
         return true;
     }
     }
 
 
     int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override
     int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override
     {
     {
-        int set;
-        if (type.getQualifier().hasSet())
-            set = type.getQualifier().layoutSet;
-        else
-            set = 0;
+        const int set = getLayoutSet(type);
 
 
         if (type.getQualifier().hasBinding()) {
         if (type.getQualifier().hasBinding()) {
-            if (type.getBasicType() == glslang::EbtSampler) {
-                const glslang::TSampler& sampler = type.getSampler();
-                if (sampler.isImage())
-                    return reserveSlot(set, baseImageBinding + type.getQualifier().layoutBinding);
+            if (isUavType(type))
+                return reserveSlot(set, baseUavBinding + type.getQualifier().layoutBinding);
 
 
-                if (sampler.isPureSampler())
-                    return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding);
+            if (isSrvType(type))
+                return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
 
 
-                if (sampler.isTexture())
-                    return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
-            }
+            if (isSamplerType(type))
+                return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding);
 
 
-            if (type.getQualifier().isUniformOrBuffer())
+            if (isUboType(type))
                 return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
                 return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
-        } else if (is_live && doAutoMapping) {
+        } else if (is_live && doAutoBindingMapping) {
             // find free slot, the caller did make sure it passes all vars with binding
             // find free slot, the caller did make sure it passes all vars with binding
             // first and now all are passed that do not have a binding and needs one
             // first and now all are passed that do not have a binding and needs one
-            if (type.getBasicType() == glslang::EbtSampler) {
-                const glslang::TSampler& sampler = type.getSampler();
-                if (sampler.isImage())
-                    return getFreeSlot(set, baseImageBinding);
 
 
-                if (sampler.isPureSampler())
-                    return getFreeSlot(set, baseSamplerBinding);
+            if (isUavType(type))
+                return getFreeSlot(set, baseUavBinding);
 
 
-                if (sampler.isTexture())
-                    return getFreeSlot(set, baseTextureBinding);
-            }
+            if (isSrvType(type))
+                return getFreeSlot(set, baseTextureBinding);
+
+            if (isSamplerType(type))
+                return getFreeSlot(set, baseSamplerBinding);
 
 
-            if (type.getQualifier().isUniformOrBuffer())
+            if (isUboType(type))
                 return getFreeSlot(set, baseUboBinding);
                 return getFreeSlot(set, baseUboBinding);
         }
         }
 
 
         return -1;
         return -1;
     }
     }
 
 
-    int resolveSet(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
-    {
-        if (type.getQualifier().hasSet())
-            return type.getQualifier().layoutSet;
-        return 0;
+protected:
+    // Return true if this is a SRV (shader resource view) type:
+    static bool isSrvType(const glslang::TType& type) {
+        return isTextureType(type) || type.getQualifier().storage == EvqBuffer;
+    }
+
+    // Return true if this is a UAV (unordered access view) type:
+    static bool isUavType(const glslang::TType& type) {
+        if (type.getQualifier().readonly)
+            return false;
+
+        return (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage()) ||
+            (type.getQualifier().storage == EvqBuffer);
     }
     }
 };
 };
 
 
+
 // Map I/O variables to provided offsets, and make bindings for
 // Map I/O variables to provided offsets, and make bindings for
 // unbound but live variables.
 // unbound but live variables.
 //
 //
@@ -351,7 +642,11 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
         intermediate.getShiftTextureBinding() == 0 &&
         intermediate.getShiftTextureBinding() == 0 &&
         intermediate.getShiftImageBinding() == 0 &&
         intermediate.getShiftImageBinding() == 0 &&
         intermediate.getShiftUboBinding() == 0 &&
         intermediate.getShiftUboBinding() == 0 &&
+        intermediate.getShiftSsboBinding() == 0 &&
+        intermediate.getShiftUavBinding() == 0 &&
+        intermediate.getResourceSetBinding().empty() &&
         intermediate.getAutoMapBindings() == false &&
         intermediate.getAutoMapBindings() == false &&
+        intermediate.getAutoMapLocations() == false &&
         resolver == nullptr)
         resolver == nullptr)
         return true;
         return true;
 
 
@@ -364,19 +659,33 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
 
 
     // if no resolver is provided, use the default resolver with the given shifts and auto map settings
     // if no resolver is provided, use the default resolver with the given shifts and auto map settings
     TDefaultIoResolver defaultResolver;
     TDefaultIoResolver defaultResolver;
+    TDefaultHlslIoResolver defaultHlslResolver;
+
     if (resolver == nullptr) {
     if (resolver == nullptr) {
-        defaultResolver.baseSamplerBinding = intermediate.getShiftSamplerBinding();
-        defaultResolver.baseTextureBinding = intermediate.getShiftTextureBinding();
-        defaultResolver.baseImageBinding = intermediate.getShiftImageBinding();
-        defaultResolver.baseUboBinding = intermediate.getShiftUboBinding();
-        defaultResolver.doAutoMapping = intermediate.getAutoMapBindings();
+        TDefaultIoResolverBase* resolverBase;
 
 
-        resolver = &defaultResolver;
+        // TODO: use a passed in IO mapper for this
+        if (intermediate.usingHlslIoMapping())
+            resolverBase = &defaultHlslResolver;
+        else
+            resolverBase = &defaultResolver;
+
+        resolverBase->baseSamplerBinding = intermediate.getShiftSamplerBinding();
+        resolverBase->baseTextureBinding = intermediate.getShiftTextureBinding();
+        resolverBase->baseImageBinding = intermediate.getShiftImageBinding();
+        resolverBase->baseUboBinding = intermediate.getShiftUboBinding();
+        resolverBase->baseSsboBinding = intermediate.getShiftSsboBinding();
+        resolverBase->baseUavBinding = intermediate.getShiftUavBinding();
+        resolverBase->baseResourceSetBinding = intermediate.getResourceSetBinding();
+        resolverBase->doAutoBindingMapping = intermediate.getAutoMapBindings();
+        resolverBase->doAutoLocationMapping = intermediate.getAutoMapLocations();
+
+        resolver = resolverBase;
     }
     }
 
 
-    TVarLiveMap varMap;
-    TVarGatherTraverser iter_binding_all(intermediate, varMap, true);
-    TVarGatherTraverser iter_binding_live(intermediate, varMap, false);
+    TVarLiveMap inVarMap, outVarMap, uniformVarMap;
+    TVarGatherTraverser iter_binding_all(intermediate, true, inVarMap, outVarMap, uniformVarMap);
+    TVarGatherTraverser iter_binding_live(intermediate, false, inVarMap, outVarMap, uniformVarMap);
 
 
     root->traverse(&iter_binding_all);
     root->traverse(&iter_binding_all);
     iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
     iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
@@ -388,16 +697,25 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
     }
     }
 
 
     // sort entries by priority. see TVarEntryInfo::TOrderByPriority for info.
     // sort entries by priority. see TVarEntryInfo::TOrderByPriority for info.
-    std::sort(varMap.begin(), varMap.end(), TVarEntryInfo::TOrderByPriority());
+    std::sort(uniformVarMap.begin(), uniformVarMap.end(), TVarEntryInfo::TOrderByPriority());
 
 
     bool hadError = false;
     bool hadError = false;
-    TResolverAdaptor doResolve(stage, *resolver, infoSink, hadError);
-    std::for_each(varMap.begin(), varMap.end(), doResolve);
+    TNotifyInOutAdaptor inOutNotify(stage, *resolver);
+    TNotifyUniformAdaptor uniformNotify(stage, *resolver);
+    TResolverUniformAdaptor uniformResolve(stage, *resolver, infoSink, hadError, intermediate);
+    TResolverInOutAdaptor inOutResolve(stage, *resolver, infoSink, hadError, intermediate);
+    std::for_each(inVarMap.begin(), inVarMap.end(), inOutNotify);
+    std::for_each(outVarMap.begin(), outVarMap.end(), inOutNotify);
+    std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformNotify);
+    resolver->endNotifications();
+    std::for_each(inVarMap.begin(), inVarMap.end(), inOutResolve);
+    std::for_each(outVarMap.begin(), outVarMap.end(), inOutResolve);
+    std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformResolve);
 
 
     if (!hadError) {
     if (!hadError) {
         // sort by id again, so we can use lower bound to find entries
         // sort by id again, so we can use lower bound to find entries
-        std::sort(varMap.begin(), varMap.end(), TVarEntryInfo::TOrderById());
-        TVarSetTraverser iter_iomap(intermediate, varMap);
+        std::sort(uniformVarMap.begin(), uniformVarMap.end(), TVarEntryInfo::TOrderById());
+        TVarSetTraverser iter_iomap(intermediate, inVarMap, outVarMap, uniformVarMap);
         root->traverse(&iter_iomap);
         root->traverse(&iter_iomap);
     }
     }
 
 

+ 21 - 7
src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp

@@ -461,10 +461,12 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
     case EShLangTessEvaluation:
     case EShLangTessEvaluation:
         if (inputPrimitive == ElgNone)
         if (inputPrimitive == ElgNone)
             error(infoSink, "At least one shader must specify an input layout primitive");
             error(infoSink, "At least one shader must specify an input layout primitive");
-        if (vertexSpacing == EvsNone)
-            vertexSpacing = EvsEqual;
-        if (vertexOrder == EvoNone)
-            vertexOrder = EvoCcw;
+        if (source == EShSourceGlsl) {
+            if (vertexSpacing == EvsNone)
+                vertexSpacing = EvsEqual;
+            if (vertexOrder == EvoNone)
+                vertexOrder = EvoCcw;
+        }
         break;
         break;
     case EShLangGeometry:
     case EShLangGeometry:
         if (inputPrimitive == ElgNone)
         if (inputPrimitive == ElgNone)
@@ -858,7 +860,7 @@ int TIntermediate::checkLocationRange(int set, const TIoRange& range, const TTyp
     return -1; // no collision
     return -1; // no collision
 }
 }
 
 
-// Accumulate locations used for inputs, outputs, and uniforms, and check for collisions
+// Accumulate bindings and offsets, and check for collisions
 // as the accumulation is done.
 // as the accumulation is done.
 //
 //
 // Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
 // Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
@@ -1045,9 +1047,9 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
 
 
 const int baseAlignmentVec4Std140 = 16;
 const int baseAlignmentVec4Std140 = 16;
 
 
-// Return the size and alignment of a scalar.
+// Return the size and alignment of a component of the given type.
 // The size is returned in the 'size' parameter
 // The size is returned in the 'size' parameter
-// Return value is the alignment of the type.
+// Return value is the alignment..
 int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
 int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
 {
 {
     switch (type.getBasicType()) {
     switch (type.getBasicType()) {
@@ -1055,6 +1057,8 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
     case EbtUint64:
     case EbtUint64:
     case EbtDouble:  size = 8; return 8;
     case EbtDouble:  size = 8; return 8;
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
+    case EbtInt16:
+    case EbtUint16:
     case EbtFloat16: size = 2; return 2;
     case EbtFloat16: size = 2; return 2;
 #endif
 #endif
     default:         size = 4; return 4;
     default:         size = 4; return 4;
@@ -1217,4 +1221,14 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
     return baseAlignmentVec4Std140;
     return baseAlignmentVec4Std140;
 }
 }
 
 
+// To aid the basic HLSL rule about crossing vec4 boundaries.
+bool TIntermediate::improperStraddle(const TType& type, int size, int offset)
+{
+    if (! type.isVector() || type.isArray())
+        return false;
+
+    return size <= 16 ? offset / 16 != (offset + size - 1) / 16
+                      : offset % 16 != 0;
+}
+
 } // end namespace glslang
 } // end namespace glslang

+ 64 - 7
src/libraries/glslang/glslang/MachineIndependent/localintermediate.h

@@ -174,9 +174,16 @@ public:
         shiftTextureBinding(0),
         shiftTextureBinding(0),
         shiftImageBinding(0),
         shiftImageBinding(0),
         shiftUboBinding(0),
         shiftUboBinding(0),
+        shiftSsboBinding(0),
+        shiftUavBinding(0),
         autoMapBindings(false),
         autoMapBindings(false),
+        autoMapLocations(false),
         flattenUniformArrays(false),
         flattenUniformArrays(false),
-        useUnknownFormat(false)
+        useUnknownFormat(false),
+        hlslOffsets(false),
+        useStorageBuffer(false),
+        hlslIoMapping(false),
+        textureSamplerTransformMode(EShTexSampTransKeep)
     {
     {
         localSize[0] = 1;
         localSize[0] = 1;
         localSize[1] = 1;
         localSize[1] = 1;
@@ -207,12 +214,27 @@ public:
     unsigned int getShiftImageBinding() const { return shiftImageBinding; }
     unsigned int getShiftImageBinding() const { return shiftImageBinding; }
     void setShiftUboBinding(unsigned int shift)     { shiftUboBinding = shift; }
     void setShiftUboBinding(unsigned int shift)     { shiftUboBinding = shift; }
     unsigned int getShiftUboBinding()     const { return shiftUboBinding; }
     unsigned int getShiftUboBinding()     const { return shiftUboBinding; }
-    void setAutoMapBindings(bool map)               { autoMapBindings = map; }
+    void setShiftSsboBinding(unsigned int shift)     { shiftSsboBinding = shift; }
+    unsigned int getShiftSsboBinding()  const { return shiftSsboBinding; }
+    void setShiftUavBinding(unsigned int shift) { shiftUavBinding = shift; }
+    unsigned int getShiftUavBinding()  const { return shiftUavBinding; }
+    void setResourceSetBinding(const std::vector<std::string>& shift) { resourceSetBinding = shift; }
+    const std::vector<std::string>& getResourceSetBinding() const { return resourceSetBinding; }
+    void setAutoMapBindings(bool map)           { autoMapBindings = map; }
     bool getAutoMapBindings()             const { return autoMapBindings; }
     bool getAutoMapBindings()             const { return autoMapBindings; }
-    void setFlattenUniformArrays(bool flatten)      { flattenUniformArrays = flatten; }
+    void setAutoMapLocations(bool map)          { autoMapLocations = map; }
+    bool getAutoMapLocations()            const { return autoMapLocations; }
+    void setFlattenUniformArrays(bool flatten)  { flattenUniformArrays = flatten; }
     bool getFlattenUniformArrays()        const { return flattenUniformArrays; }
     bool getFlattenUniformArrays()        const { return flattenUniformArrays; }
     void setNoStorageFormat(bool b)             { useUnknownFormat = b; }
     void setNoStorageFormat(bool b)             { useUnknownFormat = b; }
     bool getNoStorageFormat()             const { return useUnknownFormat; }
     bool getNoStorageFormat()             const { return useUnknownFormat; }
+    void setHlslOffsets()         { hlslOffsets = true; }
+    bool usingHlslOFfsets() const { return hlslOffsets; }
+    void setUseStorageBuffer() { useStorageBuffer = true; }
+    bool usingStorageBuffer() const { return useStorageBuffer; }
+    void setHlslIoMapping(bool b) { hlslIoMapping = b; }
+    bool usingHlslIoMapping()     { return hlslIoMapping; }
+    void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
 
 
     void setVersion(int v) { version = v; }
     void setVersion(int v) { version = v; }
     int getVersion() const { return version; }
     int getVersion() const { return version; }
@@ -237,7 +259,9 @@ public:
     TIntermSymbol* addSymbol(const TType&, const TSourceLoc&);
     TIntermSymbol* addSymbol(const TType&, const TSourceLoc&);
     TIntermSymbol* addSymbol(const TIntermSymbol&);
     TIntermSymbol* addSymbol(const TIntermSymbol&);
     TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const;
     TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const;
-    TIntermTyped* addShapeConversion(TOperator, const TType&, TIntermTyped*);
+    TIntermTyped* addUniShapeConversion(TOperator, const TType&, TIntermTyped*);
+    void addBiShapeConversion(TOperator, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode);
+    TIntermTyped* addShapeConversion(const TType&, TIntermTyped*);
     TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
     TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
     TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
     TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
     TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
     TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
@@ -261,13 +285,18 @@ public:
     TIntermConstantUnion* addConstantUnion(unsigned int, const TSourceLoc&, bool literal = false) const;
     TIntermConstantUnion* addConstantUnion(unsigned int, const TSourceLoc&, bool literal = false) const;
     TIntermConstantUnion* addConstantUnion(long long, const TSourceLoc&, bool literal = false) const;
     TIntermConstantUnion* addConstantUnion(long long, const TSourceLoc&, bool literal = false) const;
     TIntermConstantUnion* addConstantUnion(unsigned long long, const TSourceLoc&, bool literal = false) const;
     TIntermConstantUnion* addConstantUnion(unsigned long long, const TSourceLoc&, bool literal = false) const;
+#ifdef AMD_EXTENSIONS
+    TIntermConstantUnion* addConstantUnion(short, const TSourceLoc&, bool literal = false) const;
+    TIntermConstantUnion* addConstantUnion(unsigned short, const TSourceLoc&, bool literal = false) const;
+    
+#endif
     TIntermConstantUnion* addConstantUnion(bool, const TSourceLoc&, bool literal = false) const;
     TIntermConstantUnion* addConstantUnion(bool, const TSourceLoc&, bool literal = false) const;
     TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const;
     TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const;
     TIntermConstantUnion* addConstantUnion(const TString*, const TSourceLoc&, bool literal = false) const;
     TIntermConstantUnion* addConstantUnion(const TString*, const TSourceLoc&, bool literal = false) const;
     TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
     TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
     bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
     bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
-    TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);
-    TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);
+    TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&, TLoopControl = ELoopControlNone);
+    TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&, TLoopControl = ELoopControlNone);
     TIntermBranch* addBranch(TOperator, const TSourceLoc&);
     TIntermBranch* addBranch(TOperator, const TSourceLoc&);
     TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
     TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
     template<typename selectorType> TIntermTyped* addSwizzle(TSwizzleSelectors<selectorType>&, const TSourceLoc&);
     template<typename selectorType> TIntermTyped* addSwizzle(TSwizzleSelectors<selectorType>&, const TSourceLoc&);
@@ -410,7 +439,9 @@ public:
     }
     }
     int addXfbBufferOffset(const TType&);
     int addXfbBufferOffset(const TType&);
     unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
     unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
+    static int getBaseAlignmentScalar(const TType&, int& size);
     static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor);
     static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor);
+    static bool improperStraddle(const TType& type, int size, int offset);
     bool promote(TIntermOperator*);
     bool promote(TIntermOperator*);
 
 
 #ifdef NV_EXTENSIONS
 #ifdef NV_EXTENSIONS
@@ -420,6 +451,18 @@ public:
     bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
     bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
 #endif
 #endif
 
 
+    const char* addSemanticName(const TString& name)
+    {
+        return semanticNameSet.insert(name).first->c_str();
+    }
+
+    void setSourceFile(const char* file) { sourceFile = file; }
+    const std::string& getSourceFile() const { return sourceFile; }
+    void addSourceText(const char* text) { sourceText = sourceText + text; }
+    const std::string& getSourceText() const { return sourceText; }
+
+    const char* const implicitThisName = "@this";
+
 protected:
 protected:
     TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
     TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
     void error(TInfoSink& infoSink, const char*);
     void error(TInfoSink& infoSink, const char*);
@@ -433,7 +476,6 @@ protected:
     void inOutLocationCheck(TInfoSink&);
     void inOutLocationCheck(TInfoSink&);
     TIntermSequence& findLinkerObjects() const;
     TIntermSequence& findLinkerObjects() const;
     bool userOutputUsed() const;
     bool userOutputUsed() const;
-    static int getBaseAlignmentScalar(const TType&, int& size);
     bool isSpecializationOperation(const TIntermOperator&) const;
     bool isSpecializationOperation(const TIntermOperator&) const;
     bool promoteUnary(TIntermUnary&);
     bool promoteUnary(TIntermUnary&);
     bool promoteBinary(TIntermBinary&);
     bool promoteBinary(TIntermBinary&);
@@ -442,6 +484,7 @@ protected:
     void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&);
     void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&);
     void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&);
     void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&);
     bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
     bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
+    void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root);
 
 
     const EShLanguage language;  // stage, known at construction time
     const EShLanguage language;  // stage, known at construction time
     EShSource source;            // source language, known a bit later
     EShSource source;            // source language, known a bit later
@@ -485,9 +528,16 @@ protected:
     unsigned int shiftTextureBinding;
     unsigned int shiftTextureBinding;
     unsigned int shiftImageBinding;
     unsigned int shiftImageBinding;
     unsigned int shiftUboBinding;
     unsigned int shiftUboBinding;
+    unsigned int shiftSsboBinding;
+    unsigned int shiftUavBinding;
+    std::vector<std::string> resourceSetBinding;
     bool autoMapBindings;
     bool autoMapBindings;
+    bool autoMapLocations;
     bool flattenUniformArrays;
     bool flattenUniformArrays;
     bool useUnknownFormat;
     bool useUnknownFormat;
+    bool hlslOffsets;
+    bool useStorageBuffer;
+    bool hlslIoMapping;
 
 
     typedef std::list<TCall> TGraph;
     typedef std::list<TCall> TGraph;
     TGraph callGraph;
     TGraph callGraph;
@@ -497,6 +547,13 @@ protected:
     std::vector<TOffsetRange> usedAtomics;  // sets of bindings used by atomic counters
     std::vector<TOffsetRange> usedAtomics;  // sets of bindings used by atomic counters
     std::vector<TXfbBuffer> xfbBuffers;     // all the data we need to track per xfb buffer
     std::vector<TXfbBuffer> xfbBuffers;     // all the data we need to track per xfb buffer
     std::unordered_set<int> usedConstantId; // specialization constant ids used
     std::unordered_set<int> usedConstantId; // specialization constant ids used
+    std::set<TString> semanticNameSet;
+
+    EShTextureSamplerTransformMode textureSamplerTransformMode;
+
+    // source code of shader, useful as part of debug information
+    std::string sourceFile;
+    std::string sourceText;
 
 
 private:
 private:
     void operator=(TIntermediate&); // prevent assignments
     void operator=(TIntermediate&); // prevent assignments

+ 0 - 6
src/libraries/glslang/glslang/MachineIndependent/parseConst.cpp

@@ -76,12 +76,6 @@ bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
         return false;
         return false;
     }
     }
 
 
-    if (node->getSequence().size() == 0) {
-        error = true;
-
-        return false;
-    }
-
     bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
     bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
     if (flag) {
     if (flag) {
         singleConstantParam = true;
         singleConstantParam = true;

+ 2 - 0
src/libraries/glslang/glslang/MachineIndependent/parseVersions.h

@@ -68,6 +68,7 @@ public:
     virtual void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc);
     virtual void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc);
     virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc);
     virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc);
     virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc);
     virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc);
+    virtual void unimplemented(const TSourceLoc&, const char* featureDesc);
     virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
     virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
     virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
     virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
     virtual TExtensionBehavior getExtensionBehavior(const char*);
     virtual TExtensionBehavior getExtensionBehavior(const char*);
@@ -77,6 +78,7 @@ public:
     virtual void fullIntegerCheck(const TSourceLoc&, const char* op);
     virtual void fullIntegerCheck(const TSourceLoc&, const char* op);
     virtual void doubleCheck(const TSourceLoc&, const char* op);
     virtual void doubleCheck(const TSourceLoc&, const char* op);
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
+    virtual void int16Check(const TSourceLoc& loc, const char* op, bool builtIn = false);
     virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false);
     virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false);
 #endif
 #endif
     virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false);
     virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false);

+ 29 - 8
src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp

@@ -76,7 +76,9 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
 NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 \****************************************************************************/
 \****************************************************************************/
 
 
+#ifndef _CRT_SECURE_NO_WARNINGS
 #define _CRT_SECURE_NO_WARNINGS
 #define _CRT_SECURE_NO_WARNINGS
+#endif
 
 
 #include <sstream>
 #include <sstream>
 #include <cstdlib>
 #include <cstdlib>
@@ -391,6 +393,14 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo
     TSourceLoc loc = ppToken->loc;  // because we sometimes read the newline before reporting the error
     TSourceLoc loc = ppToken->loc;  // because we sometimes read the newline before reporting the error
     if (token == PpAtomIdentifier) {
     if (token == PpAtomIdentifier) {
         if (strcmp("defined", ppToken->name) == 0) {
         if (strcmp("defined", ppToken->name) == 0) {
+            if (! parseContext.isReadingHLSL() && isMacroInput()) {
+                if (parseContext.relaxedErrors())
+                    parseContext.ppWarn(ppToken->loc, "nonportable when expanded from macros for preprocessor expression",
+                                                      "defined", "");
+                else
+                    parseContext.ppError(ppToken->loc, "cannot use in preprocessor expression when expanded from macros",
+                                                       "defined", "");
+            }
             bool needclose = 0;
             bool needclose = 0;
             token = scanToken(ppToken);
             token = scanToken(ppToken);
             if (token == '(') {
             if (token == '(') {
@@ -611,14 +621,14 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
     TShader::Includer::IncludeResult* res = nullptr;
     TShader::Includer::IncludeResult* res = nullptr;
     if (startWithLocalSearch)
     if (startWithLocalSearch)
         res = includer.includeLocal(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
         res = includer.includeLocal(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
-    if (! res || res->headerName.empty()) {
+    if (res == nullptr || res->headerName.empty()) {
         includer.releaseInclude(res);
         includer.releaseInclude(res);
         res = includer.includeSystem(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
         res = includer.includeSystem(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
     }
     }
 
 
     // Process the results
     // Process the results
-    if (res && !res->headerName.empty()) {
-        if (res->headerData && res->headerLength) {
+    if (res != nullptr && !res->headerName.empty()) {
+        if (res->headerData != nullptr && res->headerLength > 0) {
             // path for processing one or more tokens from an included header, hand off 'res'
             // path for processing one or more tokens from an included header, hand off 'res'
             const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
             const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
             std::ostringstream prologue;
             std::ostringstream prologue;
@@ -636,8 +646,8 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
     } else {
     } else {
         // error path, clean up
         // error path, clean up
         std::string message =
         std::string message =
-            res ? std::string(res->headerData, res->headerLength)
-                : std::string("Could not process include directive");
+            res != nullptr ? std::string(res->headerData, res->headerLength)
+                           : std::string("Could not process include directive");
         parseContext.ppError(directiveLoc, message.c_str(), "#include", "for header name: %s", filename.c_str());
         parseContext.ppError(directiveLoc, message.c_str(), "#include", "for header name: %s", filename.c_str());
         includer.releaseInclude(res);
         includer.releaseInclude(res);
     }
     }
@@ -714,6 +724,7 @@ int TPpContext::CPPerror(TPpToken* ppToken)
         if (token == PpAtomConstInt   || token == PpAtomConstUint   ||
         if (token == PpAtomConstInt   || token == PpAtomConstUint   ||
             token == PpAtomConstInt64 || token == PpAtomConstUint64 ||
             token == PpAtomConstInt64 || token == PpAtomConstUint64 ||
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
+            token == PpAtomConstInt16 || token == PpAtomConstUint16 ||
             token == PpAtomConstFloat16 ||
             token == PpAtomConstFloat16 ||
 #endif
 #endif
             token == PpAtomConstFloat || token == PpAtomConstDouble) {
             token == PpAtomConstFloat || token == PpAtomConstDouble) {
@@ -748,6 +759,10 @@ int TPpContext::CPPpragma(TPpToken* ppToken)
         case PpAtomConstUint:
         case PpAtomConstUint:
         case PpAtomConstInt64:
         case PpAtomConstInt64:
         case PpAtomConstUint64:
         case PpAtomConstUint64:
+#ifdef AMD_EXTENSIONS
+        case PpAtomConstInt16:
+        case PpAtomConstUint16:
+#endif
         case PpAtomConstFloat:
         case PpAtomConstFloat:
         case PpAtomConstDouble:
         case PpAtomConstDouble:
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
@@ -776,8 +791,12 @@ int TPpContext::CPPversion(TPpToken* ppToken)
 {
 {
     int token = scanToken(ppToken);
     int token = scanToken(ppToken);
 
 
-    if (errorOnVersion || versionSeen)
-        parseContext.ppError(ppToken->loc, "must occur first in shader", "#version", "");
+    if (errorOnVersion || versionSeen) {
+        if (parseContext.isReadingHLSL())
+            parseContext.ppError(ppToken->loc, "invalid preprocessor command", "#version", "");
+        else
+            parseContext.ppError(ppToken->loc, "must occur first in shader", "#version", "");
+    }
     versionSeen = true;
     versionSeen = true;
 
 
     if (token == '\n') {
     if (token == '\n') {
@@ -986,6 +1005,8 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken*
     int token;
     int token;
     while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) {
     while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) {
         token = tokenPaste(token, *ppToken);
         token = tokenPaste(token, *ppToken);
+        if (token == tMarkerInput::marker || token == EndOfInput)
+            break;
         if (token == PpAtomIdentifier && MacroExpand(ppToken, false, newLineOkay) != 0)
         if (token == PpAtomIdentifier && MacroExpand(ppToken, false, newLineOkay) != 0)
             continue;
             continue;
         expandedArg->putToken(token, ppToken);
         expandedArg->putToken(token, ppToken);
@@ -1050,7 +1071,7 @@ int TPpContext::tMacroInput::scan(TPpToken* ppToken)
     // TODO: preprocessor:  properly handle whitespace (or lack of it) between tokens when expanding
     // TODO: preprocessor:  properly handle whitespace (or lack of it) between tokens when expanding
     if (token == PpAtomIdentifier) {
     if (token == PpAtomIdentifier) {
         int i;
         int i;
-        for (i = mac->args.size() - 1; i >= 0; i--)
+        for (i = (int)mac->args.size() - 1; i >= 0; i--)
             if (strcmp(pp->atomStrings.getString(mac->args[i]), ppToken->name) == 0)
             if (strcmp(pp->atomStrings.getString(mac->args[i]), ppToken->name) == 0)
                 break;
                 break;
         if (i >= 0) {
         if (i >= 0) {

+ 4 - 0
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp

@@ -76,7 +76,9 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
 NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 \****************************************************************************/
 \****************************************************************************/
 
 
+#ifndef _CRT_SECURE_NO_WARNINGS
 #define _CRT_SECURE_NO_WARNINGS
 #define _CRT_SECURE_NO_WARNINGS
+#endif
 
 
 #include <cassert>
 #include <cassert>
 #include <cstdlib>
 #include <cstdlib>
@@ -120,6 +122,8 @@ const struct {
     { PpAtomDecrement,      "--" },
     { PpAtomDecrement,      "--" },
     { PpAtomIncrement,      "++" },
     { PpAtomIncrement,      "++" },
 
 
+    { PpAtomColonColon,     "::" },
+
     { PpAtomDefine,         "define" },
     { PpAtomDefine,         "define" },
     { PpAtomUndef,          "undef" },
     { PpAtomUndef,          "undef" },
     { PpAtomIf,             "if" },
     { PpAtomIf,             "if" },

+ 14 - 6
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h

@@ -92,7 +92,7 @@ namespace glslang {
 
 
 class TPpToken {
 class TPpToken {
 public:
 public:
-    TPpToken() : space(false), ival(0), dval(0.0), i64val(0)
+    TPpToken() : space(false), i64val(0)
     {
     {
         loc.init();
         loc.init();
         name[0] = 0;
         name[0] = 0;
@@ -108,10 +108,14 @@ public:
     bool operator!=(const TPpToken& right) { return ! operator==(right); }
     bool operator!=(const TPpToken& right) { return ! operator==(right); }
 
 
     TSourceLoc loc;
     TSourceLoc loc;
-    bool   space;  // true if a space (for white space or a removed comment) should also be recognized, in front of the token returned
-    int    ival;
-    double dval;
-    long long i64val;
+    bool space;  // true if a space (for white space or a removed comment) should also be recognized, in front of the token returned
+
+    union {
+        int ival;
+        double dval;
+        long long i64val;
+    };
+
     char   name[MaxTokenLength + 1];
     char   name[MaxTokenLength + 1];
 };
 };
 
 
@@ -196,6 +200,7 @@ public:
         virtual void ungetch() = 0;
         virtual void ungetch() = 0;
         virtual bool peekPasting() { return false; }          // true when about to see ##
         virtual bool peekPasting() { return false; }          // true when about to see ##
         virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define)
         virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define)
+        virtual bool isMacroInput() { return false; }
 
 
         // Will be called when we start reading tokens from this instance
         // Will be called when we start reading tokens from this instance
         virtual void notifyActivated() {}
         virtual void notifyActivated() {}
@@ -236,7 +241,7 @@ public:
         void reset() { current = 0; }
         void reset() { current = 0; }
 
 
     protected:
     protected:
-        void putSubtoken(int);
+        void putSubtoken(char);
         int getSubtoken();
         int getSubtoken();
         void ungetSubtoken();
         void ungetSubtoken();
 
 
@@ -302,6 +307,7 @@ protected:
     void ungetChar() { inputStack.back()->ungetch(); }
     void ungetChar() { inputStack.back()->ungetch(); }
     bool peekPasting() { return !inputStack.empty() && inputStack.back()->peekPasting(); }
     bool peekPasting() { return !inputStack.empty() && inputStack.back()->peekPasting(); }
     bool endOfReplacementList() { return inputStack.empty() || inputStack.back()->endOfReplacementList(); }
     bool endOfReplacementList() { return inputStack.empty() || inputStack.back()->endOfReplacementList(); }
+    bool isMacroInput() { return inputStack.size() > 0 && inputStack.back()->isMacroInput(); }
 
 
     static const int maxIfNesting = 64;
     static const int maxIfNesting = 64;
 
 
@@ -325,6 +331,7 @@ protected:
         virtual void ungetch() override { assert(0); }
         virtual void ungetch() override { assert(0); }
         bool peekPasting() override { return prepaste; }
         bool peekPasting() override { return prepaste; }
         bool endOfReplacementList() override { return mac->body.atEnd(); }
         bool endOfReplacementList() override { return mac->body.atEnd(); }
+        bool isMacroInput() override { return true; }
 
 
         MacroSymbol *mac;
         MacroSymbol *mac;
         TVector<TokenStream*> args;
         TVector<TokenStream*> args;
@@ -584,6 +591,7 @@ protected:
     int ScanFromString(char* s);
     int ScanFromString(char* s);
     void missingEndifCheck();
     void missingEndifCheck();
     int lFloatConst(int len, int ch, TPpToken* ppToken);
     int lFloatConst(int len, int ch, TPpToken* ppToken);
+    int characterLiteral(TPpToken* ppToken);
 
 
     void push_include(TShader::Includer::IncludeResult* result)
     void push_include(TShader::Includer::IncludeResult* result)
     {
     {

+ 0 - 81
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpMemory.cpp

@@ -1,81 +0,0 @@
-//
-// Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
-// Copyright (C) 2013 LunarG, Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-//    Redistributions of source code must retain the above copyright
-//    notice, this list of conditions and the following disclaimer.
-//
-//    Redistributions in binary form must reproduce the above
-//    copyright notice, this list of conditions and the following
-//    disclaimer in the documentation and/or other materials provided
-//    with the distribution.
-//
-//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-//    contributors may be used to endorse or promote products derived
-//    from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms.  If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-
-namespace glslang {
-
-} // end namespace glslang

+ 261 - 24
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp

@@ -76,7 +76,9 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
 NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 \****************************************************************************/
 \****************************************************************************/
 
 
+#ifndef _CRT_SECURE_NO_WARNINGS
 #define _CRT_SECURE_NO_WARNINGS
 #define _CRT_SECURE_NO_WARNINGS
+#endif
 
 
 #include <cstdlib>
 #include <cstdlib>
 #include <cstring>
 #include <cstring>
@@ -101,9 +103,16 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
 {
 {
     bool HasDecimalOrExponent = false;
     bool HasDecimalOrExponent = false;
     int isDouble = 0;
     int isDouble = 0;
+    bool generateFloat16 = false;
+    bool acceptFloat16 = parseContext.intermediate.getSource() == EShSourceHlsl;
+    bool isFloat16 = false;
+    bool requireHF = false;
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
-    int isFloat16 = 0;
-    bool enableFloat16 = parseContext.version >= 450 && parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float);
+    if (parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float)) {
+        acceptFloat16 = true;
+        generateFloat16 = true;
+        requireHF = true;
+    }
 #endif
 #endif
 
 
     const auto saveName = [&](int ch) {
     const auto saveName = [&](int ch) {
@@ -117,6 +126,35 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
         HasDecimalOrExponent = true;
         HasDecimalOrExponent = true;
         saveName(ch);
         saveName(ch);
         ch = getChar();
         ch = getChar();
+
+        // 1.#INF or -1.#INF
+        if (ch == '#') {
+            if ((len <  2) ||
+                (len == 2 && ppToken->name[0] != '1') ||
+                (len == 3 && ppToken->name[1] != '1' && !(ppToken->name[0] == '-' || ppToken->name[0] == '+')) ||
+                (len >  3))
+                parseContext.ppError(ppToken->loc, "unexpected use of", "#", "");
+            else {
+                // we have 1.# or -1.# or +1.#, check for 'INF'
+                if ((ch = getChar()) != 'I' ||
+                    (ch = getChar()) != 'N' ||
+                    (ch = getChar()) != 'F')
+                    parseContext.ppError(ppToken->loc, "expected 'INF'", "#", "");
+                else {
+                    // we have [+-].#INF, and we are targeting IEEE 754, so wrap it up:
+                    saveName('I');
+                    saveName('N');
+                    saveName('F');
+                    ppToken->name[len] = '\0';
+                    if (ppToken->name[0] == '-')
+                        ppToken->i64val = 0xfff0000000000000; // -Infinity
+                    else
+                        ppToken->i64val = 0x7ff0000000000000; // +Infinity
+                    return PpAtomConstFloat;
+                }
+            }
+        }
+
         while (ch >= '0' && ch <= '9') {
         while (ch >= '0' && ch <= '9') {
             saveName(ch);
             saveName(ch);
             ch = getChar();
             ch = getChar();
@@ -158,21 +196,27 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
             saveName(ch2);
             saveName(ch2);
             isDouble = 1;
             isDouble = 1;
         }
         }
+    } else if (acceptFloat16 && (ch == 'h' || ch == 'H')) {
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
-    } else if (enableFloat16 && (ch == 'h' || ch == 'H')) {
-        parseContext.float16Check(ppToken->loc, "half floating-point suffix");
+        if (generateFloat16)
+            parseContext.float16Check(ppToken->loc, "half floating-point suffix");
+#endif
         if (!HasDecimalOrExponent)
         if (!HasDecimalOrExponent)
             parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
             parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
-        int ch2 = getChar();
-        if (ch2 != 'f' && ch2 != 'F') {
-            ungetChar();
-            ungetChar();
+        if (requireHF) {
+            int ch2 = getChar();
+            if (ch2 != 'f' && ch2 != 'F') {
+                ungetChar();
+                ungetChar();
+            } else {
+                saveName(ch);
+                saveName(ch2);
+                isFloat16 = generateFloat16;
+            }
         } else {
         } else {
             saveName(ch);
             saveName(ch);
-            saveName(ch2);
-            isFloat16 = 1;
+            isFloat16 = generateFloat16;
         }
         }
-#endif
     } else if (ch == 'f' || ch == 'F') {
     } else if (ch == 'f' || ch == 'F') {
         parseContext.profileRequires(ppToken->loc,  EEsProfile, 300, nullptr, "floating-point suffix");
         parseContext.profileRequires(ppToken->loc,  EEsProfile, 300, nullptr, "floating-point suffix");
         if (! parseContext.relaxedErrors())
         if (! parseContext.relaxedErrors())
@@ -197,14 +241,88 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
     // Return the right token type
     // Return the right token type
     if (isDouble)
     if (isDouble)
         return PpAtomConstDouble;
         return PpAtomConstDouble;
-#ifdef AMD_EXTENSIONS
     else if (isFloat16)
     else if (isFloat16)
         return PpAtomConstFloat16;
         return PpAtomConstFloat16;
-#endif
     else
     else
         return PpAtomConstFloat;
         return PpAtomConstFloat;
 }
 }
 
 
+// Recognize a character literal.
+//
+// The first ' has already been accepted, read the rest, through the closing '.
+//
+// Always returns PpAtomConstInt.
+//
+int TPpContext::characterLiteral(TPpToken* ppToken)
+{
+    ppToken->name[0] = 0;
+    ppToken->ival = 0;
+
+    if (parseContext.intermediate.getSource() != EShSourceHlsl) {
+        // illegal, except in macro definition, for which case we report the character
+        return '\'';
+    }
+
+    int ch = getChar();
+    switch (ch) {
+    case '\'':
+        // As empty sequence:  ''
+        parseContext.ppError(ppToken->loc, "unexpected", "\'", "");
+        return PpAtomConstInt;
+    case '\\':
+        // As escape sequence:  '\XXX'
+        switch (ch = getChar()) {
+        case 'a':
+            ppToken->ival = 7;
+            break;
+        case 'b':
+            ppToken->ival = 8;
+            break;
+        case 't':
+            ppToken->ival = 9;
+            break;
+        case 'n':
+            ppToken->ival = 10;
+            break;
+        case 'v':
+            ppToken->ival = 11;
+            break;
+        case 'f':
+            ppToken->ival = 12;
+            break;
+        case 'r':
+            ppToken->ival = 13;
+            break;
+        case 'x':
+        case '0':
+            parseContext.ppError(ppToken->loc, "octal and hex sequences not supported", "\\", "");
+            break;
+        default:
+            // This catches '\'', '\"', '\?', etc.
+            // Also, things like '\C' mean the same thing as 'C'
+            // (after the above cases are filtered out).
+            ppToken->ival = ch;
+            break;
+        }
+        break;
+    default:
+        ppToken->ival = ch;
+        break;
+    }
+    ppToken->name[0] = (char)ppToken->ival;
+    ppToken->name[1] = '\0';
+    ch = getChar();
+    if (ch != '\'') {
+        parseContext.ppError(ppToken->loc, "expected", "\'", "");
+        // Look ahead for a closing '
+        do {
+            ch = getChar();
+        } while (ch != '\'' && ch != EndOfInput && ch != '\n');
+    }
+
+    return PpAtomConstInt;
+}
+
 //
 //
 // Scanner used to tokenize source stream.
 // Scanner used to tokenize source stream.
 //
 //
@@ -216,6 +334,18 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
     int ii = 0;
     int ii = 0;
     unsigned long long ival = 0;
     unsigned long long ival = 0;
     bool enableInt64 = pp->parseContext.version >= 450 && pp->parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64);
     bool enableInt64 = pp->parseContext.version >= 450 && pp->parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64);
+#ifdef AMD_EXTENSIONS
+    bool enableInt16 = pp->parseContext.version >= 450 && pp->parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16);
+#endif
+    bool acceptHalf = pp->parseContext.intermediate.getSource() == EShSourceHlsl;
+#ifdef AMD_EXTENSIONS
+    if (pp->parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float))
+        acceptHalf = true;
+#endif
+
+    const auto floatingPointChar = [&](int ch) { return ch == '.' || ch == 'e' || ch == 'E' ||
+                                                                     ch == 'f' || ch == 'F' ||
+                                                     (acceptHalf && (ch == 'h' || ch == 'H')); };
 
 
     ppToken->ival = 0;
     ppToken->ival = 0;
     ppToken->i64val = 0;
     ppToken->i64val = 0;
@@ -279,6 +409,9 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
 
 
                 bool isUnsigned = false;
                 bool isUnsigned = false;
                 bool isInt64 = false;
                 bool isInt64 = false;
+#ifdef AMD_EXTENSIONS
+                bool isInt16 = false;
+#endif
                 ppToken->name[len++] = (char)ch;
                 ppToken->name[len++] = (char)ch;
                 ch = getch();
                 ch = getch();
                 if ((ch >= '0' && ch <= '9') ||
                 if ((ch >= '0' && ch <= '9') ||
@@ -287,7 +420,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
 
 
                     ival = 0;
                     ival = 0;
                     do {
                     do {
-                        if (ival <= 0x0fffffff || (enableInt64 && ival <= 0x0fffffffffffffffull)) {
+                        if (ival <= 0x0fffffffu || (enableInt64 && ival <= 0x0fffffffffffffffull)) {
                             ppToken->name[len++] = (char)ch;
                             ppToken->name[len++] = (char)ch;
                             if (ch >= '0' && ch <= '9') {
                             if (ch >= '0' && ch <= '9') {
                                 ii = ch - '0';
                                 ii = ch - '0';
@@ -326,11 +459,28 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
                         } else
                         } else
                             ungetch();
                             ungetch();
                     }
                     }
-                }
-                else if (enableInt64 && (ch == 'l' || ch == 'L')) {
+
+#ifdef AMD_EXTENSIONS
+                    if (enableInt16) {
+                        int nextCh = getch();
+                        if ((ch == 'u' && nextCh == 's') || (ch == 'U' && nextCh == 'S')) {
+                            if (len < MaxTokenLength)
+                                ppToken->name[len++] = (char)nextCh;
+                            isInt16 = true;
+                        } else
+                            ungetch();
+                    }
+#endif
+                } else if (enableInt64 && (ch == 'l' || ch == 'L')) {
                     if (len < MaxTokenLength)
                     if (len < MaxTokenLength)
                         ppToken->name[len++] = (char)ch;
                         ppToken->name[len++] = (char)ch;
                     isInt64 = true;
                     isInt64 = true;
+#ifdef AMD_EXTENSIONS
+                } else if (enableInt16 && (ch == 's' || ch == 'S')) {
+                    if (len < MaxTokenLength)
+                        ppToken->name[len++] = (char)ch;
+                    isInt16 = true;
+#endif
                 } else
                 } else
                     ungetch();
                     ungetch();
                 ppToken->name[len] = '\0';
                 ppToken->name[len] = '\0';
@@ -338,6 +488,11 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
                 if (isInt64) {
                 if (isInt64) {
                     ppToken->i64val = ival;
                     ppToken->i64val = ival;
                     return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64;
                     return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64;
+#ifdef AMD_EXTENSIONS
+                } else if (isInt16) {
+                    ppToken->ival = (int)ival;
+                    return isUnsigned ? PpAtomConstUint16 : PpAtomConstInt16;
+#endif
                 } else {
                 } else {
                     ppToken->ival = (int)ival;
                     ppToken->ival = (int)ival;
                     return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
                     return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
@@ -347,6 +502,9 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
 
 
                 bool isUnsigned = false;
                 bool isUnsigned = false;
                 bool isInt64 = false;
                 bool isInt64 = false;
+#ifdef AMD_EXTENSIONS
+                bool isInt16 = false;
+#endif
                 bool octalOverflow = false;
                 bool octalOverflow = false;
                 bool nonOctal = false;
                 bool nonOctal = false;
                 ival = 0;
                 ival = 0;
@@ -359,7 +517,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
                         pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", "");
                         pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", "");
                         AlreadyComplained = 1;
                         AlreadyComplained = 1;
                     }
                     }
-                    if (ival <= 0x1fffffff || (enableInt64 && ival <= 0x1fffffffffffffffull)) {
+                    if (ival <= 0x1fffffffu || (enableInt64 && ival <= 0x1fffffffffffffffull)) {
                         ii = ch - '0';
                         ii = ch - '0';
                         ival = (ival << 3) | ii;
                         ival = (ival << 3) | ii;
                     } else
                     } else
@@ -380,7 +538,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
                         ch = getch();
                         ch = getch();
                     } while (ch >= '0' && ch <= '9');
                     } while (ch >= '0' && ch <= '9');
                 }
                 }
-                if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'E' || ch == 'F')
+                if (floatingPointChar(ch))
                     return pp->lFloatConst(len, ch, ppToken);
                     return pp->lFloatConst(len, ch, ppToken);
 
 
                 // wasn't a float, so must be octal...
                 // wasn't a float, so must be octal...
@@ -401,11 +559,28 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
                         } else
                         } else
                             ungetch();
                             ungetch();
                     }
                     }
-                }
-                else if (enableInt64 && (ch == 'l' || ch == 'L')) {
+
+#ifdef AMD_EXTENSIONS
+                    if (enableInt16) {
+                        int nextCh = getch();
+                        if ((ch == 'u' && nextCh == 's') || (ch == 'U' && nextCh == 'S')) {
+                            if (len < MaxTokenLength)
+                                ppToken->name[len++] = (char)nextCh;
+                            isInt16 = true;
+                        } else
+                            ungetch();
+                    }
+#endif
+                } else if (enableInt64 && (ch == 'l' || ch == 'L')) {
                     if (len < MaxTokenLength)
                     if (len < MaxTokenLength)
                         ppToken->name[len++] = (char)ch;
                         ppToken->name[len++] = (char)ch;
                     isInt64 = true;
                     isInt64 = true;
+#ifdef AMD_EXTENSIONS
+                } else if (enableInt16 && (ch == 's' || ch == 'S')) {
+                    if (len < MaxTokenLength)
+                        ppToken->name[len++] = (char)ch;
+                    isInt16 = true;
+#endif
                 } else
                 } else
                     ungetch();
                     ungetch();
                 ppToken->name[len] = '\0';
                 ppToken->name[len] = '\0';
@@ -416,6 +591,11 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
                 if (isInt64) {
                 if (isInt64) {
                     ppToken->i64val = ival;
                     ppToken->i64val = ival;
                     return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64;
                     return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64;
+#ifdef AMD_EXTENSIONS
+                } else if (isInt16) {
+                    ppToken->ival = (int)ival;
+                    return isUnsigned ? PpAtomConstUint16 : PpAtomConstInt16;
+#endif
                 } else {
                 } else {
                     ppToken->ival = (int)ival;
                     ppToken->ival = (int)ival;
                     return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
                     return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
@@ -435,13 +615,16 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
                 }
                 }
                 ch = getch();
                 ch = getch();
             } while (ch >= '0' && ch <= '9');
             } while (ch >= '0' && ch <= '9');
-            if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'E' || ch == 'F') {
+            if (floatingPointChar(ch))
                 return pp->lFloatConst(len, ch, ppToken);
                 return pp->lFloatConst(len, ch, ppToken);
-            } else {
+            else {
                 // Finish handling signed and unsigned integers
                 // Finish handling signed and unsigned integers
                 int numericLen = len;
                 int numericLen = len;
                 bool isUnsigned = false;
                 bool isUnsigned = false;
                 bool isInt64 = false;
                 bool isInt64 = false;
+#ifdef AMD_EXTENSIONS
+                bool isInt16 = false;
+#endif
                 if (ch == 'u' || ch == 'U') {
                 if (ch == 'u' || ch == 'U') {
                     if (len < MaxTokenLength)
                     if (len < MaxTokenLength)
                         ppToken->name[len++] = (char)ch;
                         ppToken->name[len++] = (char)ch;
@@ -456,10 +639,28 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
                         } else
                         } else
                             ungetch();
                             ungetch();
                     }
                     }
+
+#ifdef AMD_EXTENSIONS
+                    if (enableInt16) {
+                        int nextCh = getch();
+                        if ((ch == 'u' && nextCh == 's') || (ch == 'U' && nextCh == 'S')) {
+                            if (len < MaxTokenLength)
+                                ppToken->name[len++] = (char)nextCh;
+                            isInt16 = true;
+                        } else
+                            ungetch();
+                    }
+#endif
                 } else if (enableInt64 && (ch == 'l' || ch == 'L')) {
                 } else if (enableInt64 && (ch == 'l' || ch == 'L')) {
                     if (len < MaxTokenLength)
                     if (len < MaxTokenLength)
                         ppToken->name[len++] = (char)ch;
                         ppToken->name[len++] = (char)ch;
                     isInt64 = true;
                     isInt64 = true;
+#ifdef AMD_EXTENSIONS
+                } else if (enableInt16 && (ch == 's' || ch == 'S')) {
+                    if (len < MaxTokenLength)
+                        ppToken->name[len++] = (char)ch;
+                    isInt16 = true;
+#endif
                 } else
                 } else
                     ungetch();
                     ungetch();
 
 
@@ -469,10 +670,22 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
                 const unsigned remainderMaxInt = 0xFFFFFFFFu - 10 * oneTenthMaxInt;
                 const unsigned remainderMaxInt = 0xFFFFFFFFu - 10 * oneTenthMaxInt;
                 const unsigned long long oneTenthMaxInt64  = 0xFFFFFFFFFFFFFFFFull / 10;
                 const unsigned long long oneTenthMaxInt64  = 0xFFFFFFFFFFFFFFFFull / 10;
                 const unsigned long long remainderMaxInt64 = 0xFFFFFFFFFFFFFFFFull - 10 * oneTenthMaxInt64;
                 const unsigned long long remainderMaxInt64 = 0xFFFFFFFFFFFFFFFFull - 10 * oneTenthMaxInt64;
+#ifdef AMD_EXTENSIONS
+                const unsigned short oneTenthMaxInt16  = 0xFFFFu / 10;
+                const unsigned short remainderMaxInt16 = 0xFFFFu - 10 * oneTenthMaxInt16;
+#endif
                 for (int i = 0; i < numericLen; i++) {
                 for (int i = 0; i < numericLen; i++) {
                     ch = ppToken->name[i] - '0';
                     ch = ppToken->name[i] - '0';
-                    if ((enableInt64 == false && ((ival > oneTenthMaxInt) || (ival == oneTenthMaxInt && (unsigned)ch > remainderMaxInt))) ||
-                        (enableInt64 && ((ival > oneTenthMaxInt64) || (ival == oneTenthMaxInt64 && (unsigned long long)ch > remainderMaxInt64)))) {
+                    bool overflow = false;
+                    if (isInt64)
+                        overflow = (ival > oneTenthMaxInt64 || (ival == oneTenthMaxInt64 && (unsigned long long)ch > remainderMaxInt64));
+#ifdef AMD_EXTENSIONS
+                    else if (isInt16)
+                        overflow = (ival > oneTenthMaxInt16 || (ival == oneTenthMaxInt16 && (unsigned short)ch > remainderMaxInt16));
+#endif
+                    else
+                        overflow = (ival > oneTenthMaxInt || (ival == oneTenthMaxInt && (unsigned)ch > remainderMaxInt));
+                    if (overflow) {
                         pp->parseContext.ppError(ppToken->loc, "numeric literal too big", "", "");
                         pp->parseContext.ppError(ppToken->loc, "numeric literal too big", "", "");
                         ival = 0xFFFFFFFFFFFFFFFFull;
                         ival = 0xFFFFFFFFFFFFFFFFull;
                         break;
                         break;
@@ -483,6 +696,11 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
                 if (isInt64) {
                 if (isInt64) {
                     ppToken->i64val = ival;
                     ppToken->i64val = ival;
                     return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64;
                     return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64;
+#ifdef AMD_EXTENSIONS
+                } else if (isInt16) {
+                    ppToken->ival = (int)ival;
+                    return isUnsigned ? PpAtomConstUint16 : PpAtomConstInt16;
+#endif
                 } else {
                 } else {
                     ppToken->ival = (int)ival;
                     ppToken->ival = (int)ival;
                     return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
                     return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
@@ -652,6 +870,8 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
                 return '/';
                 return '/';
             }
             }
             break;
             break;
+        case '\'':
+            return pp->characterLiteral(ppToken);
         case '"':
         case '"':
             // TODO: If this gets enhanced to handle escape sequences, or
             // TODO: If this gets enhanced to handle escape sequences, or
             // anything that is different than what #include needs, then
             // anything that is different than what #include needs, then
@@ -671,6 +891,12 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
                 pp->parseContext.ppError(ppToken->loc, "End of line in string", "string", "");
                 pp->parseContext.ppError(ppToken->loc, "End of line in string", "string", "");
             }
             }
             return PpAtomConstString;
             return PpAtomConstString;
+        case ':':
+            ch = getch();
+            if (ch == ':')
+                return PpAtomColonColon;
+            ungetch();
+            return ':';
         }
         }
 
 
         ch = getch();
         ch = getch();
@@ -724,6 +950,10 @@ int TPpContext::tokenize(TPpToken& ppToken)
         case PpAtomConstFloat:
         case PpAtomConstFloat:
         case PpAtomConstInt64:
         case PpAtomConstInt64:
         case PpAtomConstUint64:
         case PpAtomConstUint64:
+#ifdef AMD_EXTENSIONS
+        case PpAtomConstInt16:
+        case PpAtomConstUint16:
+#endif
         case PpAtomConstDouble:
         case PpAtomConstDouble:
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
         case PpAtomConstFloat16:
         case PpAtomConstFloat16:
@@ -773,6 +1003,7 @@ int TPpContext::tokenPaste(int token, TPpToken& ppToken)
         token = scanToken(&pastedPpToken);
         token = scanToken(&pastedPpToken);
         assert(token == PpAtomPaste);
         assert(token == PpAtomPaste);
 
 
+        // This covers end of macro expansion
         if (endOfReplacementList()) {
         if (endOfReplacementList()) {
             parseContext.ppError(ppToken.loc, "unexpected location; end of replacement list", "##", "");
             parseContext.ppError(ppToken.loc, "unexpected location; end of replacement list", "##", "");
             break;
             break;
@@ -781,6 +1012,12 @@ int TPpContext::tokenPaste(int token, TPpToken& ppToken)
         // get the token after the ##
         // get the token after the ##
         token = scanToken(&pastedPpToken);
         token = scanToken(&pastedPpToken);
 
 
+        // This covers end of argument expansion
+        if (token == tMarkerInput::marker) {
+            parseContext.ppError(ppToken.loc, "unexpected location; end of argument", "##", "");
+            break;
+        }
+
         // get the token text
         // get the token text
         switch (resultToken) {
         switch (resultToken) {
         case PpAtomIdentifier:
         case PpAtomIdentifier:

+ 0 - 77
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpSymbols.cpp

@@ -1,77 +0,0 @@
-//
-// Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
-// Copyright (C) 2013 LunarG, Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-//    Redistributions of source code must retain the above copyright
-//    notice, this list of conditions and the following disclaimer.
-//
-//    Redistributions in binary form must reproduce the above
-//    copyright notice, this list of conditions and the following
-//    disclaimer in the documentation and/or other materials provided
-//    with the distribution.
-//
-//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-//    contributors may be used to endorse or promote products derived
-//    from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms.  If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/

+ 20 - 4
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp

@@ -80,8 +80,10 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // For recording and playing back the stream of tokens in a macro definition.
 // For recording and playing back the stream of tokens in a macro definition.
 //
 //
 
 
-#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/)
+#ifndef _CRT_SECURE_NO_WARNINGS
 #define _CRT_SECURE_NO_WARNINGS
 #define _CRT_SECURE_NO_WARNINGS
+#endif
+#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/)
 #define snprintf sprintf_s
 #define snprintf sprintf_s
 #endif
 #endif
 
 
@@ -96,9 +98,8 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace glslang {
 namespace glslang {
 
 
 // push onto back of stream
 // push onto back of stream
-void TPpContext::TokenStream::putSubtoken(int subtoken)
+void TPpContext::TokenStream::putSubtoken(char subtoken)
 {
 {
-    assert((subtoken & ~0xff) == 0);
     data.push_back(static_cast<unsigned char>(subtoken));
     data.push_back(static_cast<unsigned char>(subtoken));
 }
 }
 
 
@@ -125,7 +126,8 @@ void TPpContext::TokenStream::putToken(int token, TPpToken* ppToken)
     const char* s;
     const char* s;
     char* str = NULL;
     char* str = NULL;
 
 
-    putSubtoken(token);
+    assert((token & ~0xff) == 0);
+    putSubtoken(static_cast<char>(token));
 
 
     switch (token) {
     switch (token) {
     case PpAtomIdentifier:
     case PpAtomIdentifier:
@@ -139,6 +141,10 @@ void TPpContext::TokenStream::putToken(int token, TPpToken* ppToken)
     case PpAtomConstUint:
     case PpAtomConstUint:
     case PpAtomConstInt64:
     case PpAtomConstInt64:
     case PpAtomConstUint64:
     case PpAtomConstUint64:
+#ifdef AMD_EXTENSIONS
+    case PpAtomConstInt16:
+    case PpAtomConstUint16:
+#endif
     case PpAtomConstFloat:
     case PpAtomConstFloat:
     case PpAtomConstDouble:
     case PpAtomConstDouble:
 #ifdef AMD_EXTENSIONS
 #ifdef AMD_EXTENSIONS
@@ -188,6 +194,10 @@ int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken
     case PpAtomConstUint:
     case PpAtomConstUint:
     case PpAtomConstInt64:
     case PpAtomConstInt64:
     case PpAtomConstUint64:
     case PpAtomConstUint64:
+#ifdef AMD_EXTENSIONS
+    case PpAtomConstInt16:
+    case PpAtomConstUint16:
+#endif
         len = 0;
         len = 0;
         ch = getSubtoken();
         ch = getSubtoken();
         while (ch != 0 && ch != EndOfInput) {
         while (ch != 0 && ch != EndOfInput) {
@@ -215,6 +225,9 @@ int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken
             ppToken->dval = atof(ppToken->name);
             ppToken->dval = atof(ppToken->name);
             break;
             break;
         case PpAtomConstInt:
         case PpAtomConstInt:
+#ifdef AMD_EXTENSIONS
+        case PpAtomConstInt16:
+#endif
             if (len > 0 && ppToken->name[0] == '0') {
             if (len > 0 && ppToken->name[0] == '0') {
                 if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
                 if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
                     ppToken->ival = (int)strtol(ppToken->name, 0, 16);
                     ppToken->ival = (int)strtol(ppToken->name, 0, 16);
@@ -224,6 +237,9 @@ int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken
                 ppToken->ival = atoi(ppToken->name);
                 ppToken->ival = atoi(ppToken->name);
             break;
             break;
         case PpAtomConstUint:
         case PpAtomConstUint:
+#ifdef AMD_EXTENSIONS
+        case PpAtomConstUint16:
+#endif
             if (len > 0 && ppToken->name[0] == '0') {
             if (len > 0 && ppToken->name[0] == '0') {
                 if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
                 if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
                     ppToken->ival = (int)strtoul(ppToken->name, 0, 16);
                     ppToken->ival = (int)strtoul(ppToken->name, 0, 16);

+ 6 - 2
src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h

@@ -117,6 +117,8 @@ enum EFixedAtoms {
     PpAtomDecrement,
     PpAtomDecrement,
     PpAtomIncrement,
     PpAtomIncrement,
 
 
+    PpAtomColonColon,
+
     PpAtomPaste,
     PpAtomPaste,
 
 
     // Constants
     // Constants
@@ -125,11 +127,13 @@ enum EFixedAtoms {
     PpAtomConstUint,
     PpAtomConstUint,
     PpAtomConstInt64,
     PpAtomConstInt64,
     PpAtomConstUint64,
     PpAtomConstUint64,
+#ifdef AMD_EXTENSIONS
+    PpAtomConstInt16,
+    PpAtomConstUint16,
+#endif
     PpAtomConstFloat,
     PpAtomConstFloat,
     PpAtomConstDouble,
     PpAtomConstDouble,
-#ifdef AMD_EXTENSIONS
     PpAtomConstFloat16,
     PpAtomConstFloat16,
-#endif
     PpAtomConstString,
     PpAtomConstString,
 
 
     // Identifiers
     // Identifiers

+ 2 - 0
src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.h

@@ -37,6 +37,8 @@
 // propagate 'noContraction' qualifier.
 // propagate 'noContraction' qualifier.
 //
 //
 
 
+#pragma once
+
 #include "../Include/intermediate.h"
 #include "../Include/intermediate.h"
 
 
 namespace glslang {
 namespace glslang {

+ 39 - 1
src/libraries/glslang/glslang/MachineIndependent/reflection.cpp

@@ -696,14 +696,40 @@ void TReflectionTraverser::visitSymbol(TIntermSymbol* base)
 // Implement TReflection methods.
 // Implement TReflection methods.
 //
 //
 
 
+// Track any required attribute reflection, such as compute shader numthreads.
+//
+void TReflection::buildAttributeReflection(EShLanguage stage, const TIntermediate& intermediate)
+{
+    if (stage == EShLangCompute) {
+        // Remember thread dimensions
+        for (int dim=0; dim<3; ++dim)
+            localSize[dim] = intermediate.getLocalSize(dim);
+    }
+}
+
+// build counter block index associations for buffers
+void TReflection::buildCounterIndices()
+{
+    // search for ones that have counters
+    for (int i = 0; i < int(indexToUniformBlock.size()); ++i) {
+        const TString counterName(indexToUniformBlock[i].name + "@count");
+        const int index = getIndex(counterName);
+
+        if (index >= 0)
+            indexToUniformBlock[i].counterIndex = index;
+    }
+}
+
 // Merge live symbols from 'intermediate' into the existing reflection database.
 // Merge live symbols from 'intermediate' into the existing reflection database.
 //
 //
 // Returns false if the input is too malformed to do this.
 // Returns false if the input is too malformed to do this.
-bool TReflection::addStage(EShLanguage, const TIntermediate& intermediate)
+bool TReflection::addStage(EShLanguage stage, const TIntermediate& intermediate)
 {
 {
     if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive())
     if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive())
         return false;
         return false;
 
 
+    buildAttributeReflection(stage, intermediate);
+
     TReflectionTraverser it(intermediate, *this);
     TReflectionTraverser it(intermediate, *this);
 
 
     // put the entry point on the list of functions to process
     // put the entry point on the list of functions to process
@@ -716,6 +742,8 @@ bool TReflection::addStage(EShLanguage, const TIntermediate& intermediate)
         function->traverse(&it);
         function->traverse(&it);
     }
     }
 
 
+    buildCounterIndices();
+
     return true;
     return true;
 }
 }
 
 
@@ -736,6 +764,16 @@ void TReflection::dump()
         indexToAttribute[i].dump();
         indexToAttribute[i].dump();
     printf("\n");
     printf("\n");
 
 
+    if (getLocalSize(0) > 1) {
+        static const char* axis[] = { "X", "Y", "Z" };
+
+        for (int dim=0; dim<3; ++dim)
+            if (getLocalSize(dim) > 1)
+                printf("Local size %s: %d\n", axis[dim], getLocalSize(dim));
+
+        printf("\n");
+    }
+
     // printf("Live names\n");
     // printf("Live names\n");
     // for (TNameToIndex::const_iterator it = nameToIndex.begin(); it != nameToIndex.end(); ++it)
     // for (TNameToIndex::const_iterator it = nameToIndex.begin(); it != nameToIndex.end(); ++it)
     //    printf("%s: %d\n", it->first.c_str(), it->second);
     //    printf("%s: %d\n", it->first.c_str(), it->second);

+ 25 - 3
src/libraries/glslang/glslang/MachineIndependent/reflection.h

@@ -57,11 +57,16 @@ class TObjectReflection {
 public:
 public:
     TObjectReflection(const TString& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex) :
     TObjectReflection(const TString& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex) :
         name(pName), offset(pOffset),
         name(pName), offset(pOffset),
-        glDefineType(pGLDefineType), size(pSize), index(pIndex), type(pType.clone()) { }
+        glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1), type(pType.clone()) { }
 
 
     void dump() const {
     void dump() const {
-        printf("%s: offset %d, type %x, size %d, index %d, binding %d\n",
+        printf("%s: offset %d, type %x, size %d, index %d, binding %d",
                name.c_str(), offset, glDefineType, size, index, getBinding() );
                name.c_str(), offset, glDefineType, size, index, getBinding() );
+
+        if (counterIndex != -1)
+            printf(", counter %d", counterIndex);
+
+        printf("\n");
     }
     }
 
 
     const TType* const getType() const { return type; }
     const TType* const getType() const { return type; }
@@ -71,6 +76,7 @@ public:
     int glDefineType;
     int glDefineType;
     int size;         // data size in bytes for a block, array size for a (non-block) object that's an array
     int size;         // data size in bytes for a block, array size for a (non-block) object that's an array
     int index;
     int index;
+    int counterIndex;
 
 
     static TObjectReflection badReflection() { return TObjectReflection(); }
     static TObjectReflection badReflection() { return TObjectReflection(); }
 
 
@@ -89,7 +95,12 @@ protected:
 // The full reflection database
 // The full reflection database
 class TReflection {
 class TReflection {
 public:
 public:
-    TReflection() : badReflection(TObjectReflection::badReflection()) { }
+    TReflection() : badReflection(TObjectReflection::badReflection())
+    { 
+        for (int dim=0; dim<3; ++dim)
+            localSize[dim] = 0;
+    }
+
     virtual ~TReflection() {}
     virtual ~TReflection() {}
 
 
     // grow the reflection stage by stage
     // grow the reflection stage by stage
@@ -135,11 +146,20 @@ public:
             return it->second;
             return it->second;
     }
     }
 
 
+    // see getIndex(const char*)
+    int getIndex(const TString& name) const { return getIndex(name.c_str()); }
+
+    // Thread local size
+    unsigned getLocalSize(int dim) const { return dim <= 2 ? localSize[dim] : 0; }
+
     void dump();
     void dump();
 
 
 protected:
 protected:
     friend class glslang::TReflectionTraverser;
     friend class glslang::TReflectionTraverser;
 
 
+    void buildCounterIndices();
+    void buildAttributeReflection(EShLanguage, const TIntermediate&);
+
     // 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<TString, int> TNameToIndex;
     typedef std::map<TString, int> TNameToIndex;
     typedef std::vector<TObjectReflection> TMapIndexToReflection;
     typedef std::vector<TObjectReflection> TMapIndexToReflection;
@@ -149,6 +169,8 @@ protected:
     TMapIndexToReflection indexToUniform;
     TMapIndexToReflection indexToUniform;
     TMapIndexToReflection indexToUniformBlock;
     TMapIndexToReflection indexToUniformBlock;
     TMapIndexToReflection indexToAttribute;
     TMapIndexToReflection indexToAttribute;
+
+    unsigned int localSize[3];
 };
 };
 
 
 } // end namespace glslang
 } // end namespace glslang

+ 0 - 14
src/libraries/glslang/glslang/OSDependent/Unix/ossource.cpp

@@ -184,20 +184,6 @@ void ReleaseGlobalLock()
   pthread_mutex_unlock(&gMutex);
   pthread_mutex_unlock(&gMutex);
 }
 }
 
 
-// TODO: non-windows: if we need these on linux, flesh them out
-void* OS_CreateThread(TThreadEntrypoint /*entry*/)
-{
-    return 0;
-}
-
-void OS_WaitForAllThreads(void* /*threads*/, int /*numThreads*/)
-{
-}
-
-void OS_Sleep(int /*milliseconds*/)
-{
-}
-
 void OS_DumpMemoryCounters()
 void OS_DumpMemoryCounters()
 {
 {
 }
 }

+ 0 - 15
src/libraries/glslang/glslang/OSDependent/Windows/ossource.cpp

@@ -131,21 +131,6 @@ unsigned int __stdcall EnterGenericThread (void* entry)
     return ((TThreadEntrypoint)entry)(0);
     return ((TThreadEntrypoint)entry)(0);
 }
 }
 
 
-void* OS_CreateThread(TThreadEntrypoint entry)
-{
-    return (void*)_beginthreadex(0, 0, EnterGenericThread, (void*)entry, 0, 0);
-}
-
-void OS_WaitForAllThreads(void* threads, int numThreads)
-{
-    WaitForMultipleObjects(numThreads, (HANDLE*)threads, true, INFINITE);
-}
-
-void OS_Sleep(int milliseconds)
-{
-    Sleep(milliseconds);
-}
-
 //#define DUMP_COUNTERS
 //#define DUMP_COUNTERS
 
 
 void OS_DumpMemoryCounters()
 void OS_DumpMemoryCounters()

+ 0 - 3
src/libraries/glslang/glslang/OSDependent/osinclude.h

@@ -53,11 +53,8 @@ void GetGlobalLock();
 void ReleaseGlobalLock();
 void ReleaseGlobalLock();
 
 
 typedef unsigned int (*TThreadEntrypoint)(void*);
 typedef unsigned int (*TThreadEntrypoint)(void*);
-void* OS_CreateThread(TThreadEntrypoint);
-void OS_WaitForAllThreads(void* threads, int numThreads);
 
 
 void OS_CleanupThreadData(void);
 void OS_CleanupThreadData(void);
-void OS_Sleep(int milliseconds);
 
 
 void OS_DumpMemoryCounters();
 void OS_DumpMemoryCounters();
 
 

+ 67 - 19
src/libraries/glslang/glslang/Public/ShaderLang.h

@@ -40,6 +40,7 @@
 #include "../MachineIndependent/Versions.h"
 #include "../MachineIndependent/Versions.h"
 
 
 #include <cstring>
 #include <cstring>
+#include <vector>
 
 
 #ifdef _WIN32
 #ifdef _WIN32
 #define C_DECL __cdecl
 #define C_DECL __cdecl
@@ -133,6 +134,14 @@ typedef enum {
     EShOptFull,         // Optimizations that will take more time
     EShOptFull,         // Optimizations that will take more time
 } EShOptimizationLevel;
 } EShOptimizationLevel;
 
 
+//
+// Texture and Sampler transformation mode.
+//
+typedef enum {
+    EShTexSampTransKeep,   // keep textures and samplers as is (default)
+    EShTexSampTransUpgradeTextureRemoveSampler,  // change texture w/o embeded sampler into sampled texture and throw away all samplers
+} EShTextureSamplerTransformMode;
+
 //
 //
 // Message choices for what errors and warnings are given.
 // Message choices for what errors and warnings are given.
 //
 //
@@ -147,6 +156,8 @@ enum EShMessages {
     EShMsgReadHlsl         = (1 << 6),  // use HLSL parsing rules and semantics
     EShMsgReadHlsl         = (1 << 6),  // use HLSL parsing rules and semantics
     EShMsgCascadingErrors  = (1 << 7),  // get cascading errors; risks error-recovery issues, instead of an early exit
     EShMsgCascadingErrors  = (1 << 7),  // get cascading errors; risks error-recovery issues, instead of an early exit
     EShMsgKeepUncalled     = (1 << 8),  // for testing, don't eliminate uncalled functions
     EShMsgKeepUncalled     = (1 << 8),  // for testing, don't eliminate uncalled functions
+    EShMsgHlslOffsets      = (1 << 9),  // allow block offsets to follow HLSL rules instead of GLSL rules
+    EShMsgDebugInfo        = (1 << 10), // save debug information
 };
 };
 
 
 //
 //
@@ -203,14 +214,6 @@ SH_IMPORT_EXPORT int ShCompile(
     EShMessages messages = EShMsgDefault // warnings and errors
     EShMessages messages = EShMsgDefault // warnings and errors
     );
     );
 
 
-SH_IMPORT_EXPORT int ShLink(
-    const ShHandle,               // linker object
-    const ShHandle h[],           // compiler objects to link together
-    const int numHandles,
-    ShHandle uniformMap,          // updated with new uniforms
-    short int** uniformsAccessed,  // returned with indexes of uniforms accessed
-    int* numUniformsAccessed);
-
 SH_IMPORT_EXPORT int ShLinkExt(
 SH_IMPORT_EXPORT int ShLinkExt(
     const ShHandle,               // linker object
     const ShHandle,               // linker object
     const ShHandle h[],           // compiler objects to link together
     const ShHandle h[],           // compiler objects to link together
@@ -310,9 +313,16 @@ public:
     void setShiftTextureBinding(unsigned int base);
     void setShiftTextureBinding(unsigned int base);
     void setShiftImageBinding(unsigned int base);
     void setShiftImageBinding(unsigned int base);
     void setShiftUboBinding(unsigned int base);
     void setShiftUboBinding(unsigned int base);
+    void setShiftUavBinding(unsigned int base);
+    void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding
+    void setShiftSsboBinding(unsigned int base);
+    void setResourceSetBinding(const std::vector<std::string>& base);
     void setAutoMapBindings(bool map);
     void setAutoMapBindings(bool map);
+    void setAutoMapLocations(bool map);
+    void setHlslIoMapping(bool hlslIoMap);
     void setFlattenUniformArrays(bool flatten);
     void setFlattenUniformArrays(bool flatten);
     void setNoStorageFormat(bool useUnknownFormat);
     void setNoStorageFormat(bool useUnknownFormat);
+    void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
 
 
     // Interface to #include handlers.
     // Interface to #include handlers.
     //
     //
@@ -397,6 +407,9 @@ public:
         virtual void releaseInclude(IncludeResult*) override { }
         virtual void releaseInclude(IncludeResult*) override { }
     };
     };
 
 
+    bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
+               bool forwardCompatible, EShMessages, Includer&);
+
     bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
     bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
                bool forwardCompatible, EShMessages messages)
                bool forwardCompatible, EShMessages messages)
     {
     {
@@ -404,12 +417,18 @@ public:
         return parse(res, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, messages, includer);
         return parse(res, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, messages, includer);
     }
     }
 
 
-    bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
-               bool forwardCompatible, EShMessages, Includer&);
-
     // Equivalent to parse() without a default profile and without forcing defaults.
     // Equivalent to parse() without a default profile and without forcing defaults.
-    // Provided for backwards compatibility.
-    bool parse(const TBuiltInResource*, int defaultVersion, bool forwardCompatible, EShMessages);
+    bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages)
+    {
+        return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages);
+    }
+
+    bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages,
+               Includer& includer)
+    {
+        return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages, includer);
+    }
+
     bool preprocess(const TBuiltInResource* builtInResources,
     bool preprocess(const TBuiltInResource* builtInResources,
                     int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
                     int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
                     bool forwardCompatible, EShMessages message, std::string* outputString,
                     bool forwardCompatible, EShMessages message, std::string* outputString,
@@ -459,10 +478,19 @@ class TIoMapper;
 // and resolveSet are invoked to resolve the binding and descriptor
 // and resolveSet are invoked to resolve the binding and descriptor
 // set index respectively.
 // set index respectively.
 // Invocations happen in a particular order:
 // Invocations happen in a particular order:
-// 1) var with binding and set already defined
-// 2) var with binding but no set defined
-// 3) var with set but no binding defined
-// 4) var with no binding and no set defined
+// 1) all shader inputs
+// 2) all shader outputs
+// 3) all uniforms with binding and set already defined
+// 4) all uniforms with binding but no set defined
+// 5) all uniforms with set but no binding defined
+// 6) all uniforms with no binding and no set defined
+//
+// mapIO will use this resolver in two phases. The first
+// phase is a notification phase, calling the corresponging
+// notifiy callbacks, this phase ends with a call to endNotifications.
+// Phase two starts directly after the call to endNotifications
+// and calls all other callbacks to validate and to get the
+// bindings, sets, locations, component and color indices. 
 //
 //
 // NOTE: that still limit checks are applied to bindings and sets
 // NOTE: that still limit checks are applied to bindings and sets
 // and may result in an error.
 // and may result in an error.
@@ -471,15 +499,33 @@ class TIoMapResolver
 public:
 public:
   virtual ~TIoMapResolver() {}
   virtual ~TIoMapResolver() {}
 
 
-  // Should return true if the resulting/current binding would be ok.
+  // Should return true if the resulting/current binding would be okay.
   // Basic idea is to do aliasing binding checks with this.
   // Basic idea is to do aliasing binding checks with this.
   virtual bool validateBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
   virtual bool validateBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
   // Should return a value >= 0 if the current binding should be overridden.
   // Should return a value >= 0 if the current binding should be overridden.
   // Return -1 if the current binding (including no binding) should be kept.
   // Return -1 if the current binding (including no binding) should be kept.
   virtual int resolveBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
   virtual int resolveBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
-  // Should return a value >= 0 if the current set should be overriden.
+  // Should return a value >= 0 if the current set should be overridden.
   // Return -1 if the current set (including no set) should be kept.
   // Return -1 if the current set (including no set) should be kept.
   virtual int resolveSet(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
   virtual int resolveSet(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+  // Should return true if the resulting/current setup would be okay.
+  // Basic idea is to do aliasing checks and reject invalid semantic names.
+  virtual bool validateInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+  // Should return a value >= 0 if the current location should be overridden.
+  // Return -1 if the current location (including no location) should be kept.
+  virtual int resolveInOutLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+  // Should return a value >= 0 if the current component index should be overridden.
+  // Return -1 if the current component index (including no index) should be kept.
+  virtual int resolveInOutComponent(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+  // Should return a value >= 0 if the current color index should be overridden.
+  // Return -1 if the current color index (including no index) should be kept.
+  virtual int resolveInOutIndex(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+  // Notification of a uniform variable
+  virtual void notifyBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+  // Notification of a in or out variable
+  virtual void notifyInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
+  // Called by mapIO when it has finished the notify pass
+  virtual void endNotifications() = 0;
 };
 };
 
 
 // Make one TProgram per set of shaders that will get linked together.  Add all
 // Make one TProgram per set of shaders that will get linked together.  Add all
@@ -510,10 +556,12 @@ public:
     int getUniformBlockSize(int blockIndex) const;         // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE)
     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 getUniformIndex(const char* name) const;           // can be used for glGetUniformIndices()
     int getUniformBlockIndex(int index) const;             // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX)
     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 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 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 getUniformArraySize(int index) const;              // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE)
     int getNumLiveAttributes() const;                      // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES)
     int getNumLiveAttributes() const;                      // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES)
+    unsigned getLocalSize(int dim) const;                  // return dim'th local size
     const char *getAttributeName(int index) const;         // can be used for glGetActiveAttrib()
     const char *getAttributeName(int index) const;         // can be used for glGetActiveAttrib()
     int getAttributeType(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* getUniformTType(int index) const;         // returns a TType*

Some files were not shown because too many files changed in this diff