Parser & SPV: Implement two extensions regarding GLSL sparse texture.

Implement extension "GL_ARB_sparse_texture2".
Implement extension "GL_ARB_sparse_texture_clamp".
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index 3915b66..4e0c2e8 100755
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -1222,7 +1222,7 @@
 
 // Accept all parameters needed to create a texture instruction.
 // Create the correct instruction based on the inputs, and make the call.
-Id Builder::createTextureCall(Decoration precision, Id resultType, bool fetch, bool proj, bool gather, const TextureParameters& parameters)
+Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, const TextureParameters& parameters)
 {
     static const int maxTextureArgs = 10;
     Id texArgs[maxTextureArgs] = {};
@@ -1275,6 +1275,10 @@
         mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask);
         texArgs[numArgs++] = parameters.sample;
     }
+    if (parameters.lodClamp) {
+        mask = (ImageOperandsMask)(mask | ImageOperandsMinLodMask);
+        texArgs[numArgs++] = parameters.lodClamp;
+    }
     if (mask == ImageOperandsMaskNone)
         --numArgs;  // undo speculative reservation for the mask argument
     else
@@ -1286,35 +1290,68 @@
     Op opCode;
     opCode = OpImageSampleImplicitLod;
     if (fetch) {
-        opCode = OpImageFetch;
+        if (sparse)
+            opCode = OpImageSparseFetch;
+        else
+            opCode = OpImageFetch;
     } else if (gather) {
         if (parameters.Dref)
-            opCode = OpImageDrefGather;
+            if (sparse)
+                opCode = OpImageSparseDrefGather;
+            else
+                opCode = OpImageDrefGather;
         else
-            opCode = OpImageGather;
+            if (sparse)
+                opCode = OpImageSparseGather;
+            else
+                opCode = OpImageGather;
     } else if (xplicit) {
         if (parameters.Dref) {
             if (proj)
-                opCode = OpImageSampleProjDrefExplicitLod;
+                if (sparse)
+                    opCode = OpImageSparseSampleProjDrefExplicitLod;
+                else
+                    opCode = OpImageSampleProjDrefExplicitLod;
             else
-                opCode = OpImageSampleDrefExplicitLod;
+                if (sparse)
+                    opCode = OpImageSparseSampleDrefExplicitLod;
+                else
+                    opCode = OpImageSampleDrefExplicitLod;
         } else {
             if (proj)
-                opCode = OpImageSampleProjExplicitLod;
+                if (sparse)
+                    opCode = OpImageSparseSampleProjExplicitLod;
+                else
+                    opCode = OpImageSampleProjExplicitLod;
             else
-                opCode = OpImageSampleExplicitLod;
+                if (sparse)
+                    opCode = OpImageSparseSampleExplicitLod;
+                else
+                    opCode = OpImageSampleExplicitLod;
         }
     } else {
         if (parameters.Dref) {
             if (proj)
-                opCode = OpImageSampleProjDrefImplicitLod;
+                if (sparse)
+                    opCode = OpImageSparseSampleProjDrefImplicitLod;
+                else
+                    opCode = OpImageSampleProjDrefImplicitLod;
             else
-                opCode = OpImageSampleDrefImplicitLod;
+                if (sparse)
+                    opCode = OpImageSparseSampleDrefImplicitLod;
+                else
+                    opCode = OpImageSampleDrefImplicitLod;
         } else {
             if (proj)
-                opCode = OpImageSampleProjImplicitLod;
+                if (sparse)
+                    opCode = OpImageSparseSampleProjImplicitLod;
+                else
+                    opCode = OpImageSampleProjImplicitLod;
             else
-                opCode = OpImageSampleImplicitLod;
+                if (sparse)
+                    opCode = OpImageSparseSampleImplicitLod;
+                else
+                    opCode = OpImageSampleImplicitLod;
         }
     }
 
@@ -1335,6 +1372,15 @@
         }
     }
 
+    Id typeId0 = 0;
+    Id typeId1 = 0;
+
+    if (sparse) {
+        typeId0 = resultType;
+        typeId1 = getDerefTypeId(parameters.texelOut);
+        resultType = makeStructResultType(typeId0, typeId1);
+    }
+
     // Build the SPIR-V instruction
     Instruction* textureInst = new Instruction(getUniqueId(), resultType, opCode);
     for (int op = 0; op < optArgNum; ++op)
@@ -1348,10 +1394,16 @@
 
     Id resultId = textureInst->getResultId();
 
-    // When a smear is needed, do it, as per what was computed
-    // above when resultType was changed to a scalar type.
-    if (resultType != smearedType)
-        resultId = smearScalar(precision, resultId, smearedType);
+    if (sparse) {
+        // Decode the return type that was a special structure
+        createStore(createCompositeExtract(resultId, typeId1, 1), parameters.texelOut);
+        resultId = createCompositeExtract(resultId, typeId0, 0);
+    } else {
+        // When a smear is needed, do it, as per what was computed
+        // above when resultType was changed to a scalar type.
+        if (resultType != smearedType)
+            resultId = smearScalar(precision, resultId, smearedType);
+    }
 
     return resultId;
 }