SPV: Fix issue #159: use ExplicitLod forms for non-fragment stages.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 8150997..ed86cc2 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -2236,6 +2236,7 @@
 
     params.coords = arguments[1];
     int extraArgs = 0;
+    bool noImplicitLod = false;
 
     // sort out where Dref is coming from
     if (cubeCompare) {
@@ -2257,7 +2258,11 @@
     if (cracked.lod) {
         params.lod = arguments[2];
         ++extraArgs;
-    } else if (sampler.ms) {
+    } else if (glslangIntermediate->getStage() != EShLangFragment) {
+        // we need to invent the default lod for an explicit lod instruction for a non-fragment stage
+        noImplicitLod = true;
+    }
+    if (sampler.ms) {
         params.sample = arguments[2]; // For MS, "sample" should be specified
         ++extraArgs;
     }
@@ -2295,7 +2300,7 @@
         }
     }
 
-    return builder.createTextureCall(precision, convertGlslangToSpvType(node->getType()), sparse, cracked.fetch, cracked.proj, cracked.gather, params);
+    return builder.createTextureCall(precision, convertGlslangToSpvType(node->getType()), sparse, cracked.fetch, cracked.proj, cracked.gather, noImplicitLod, params);
 }
 
 spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAggregate* node)
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index 10ba32c..2d6e50e 100755
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -1286,7 +1286,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 sparse, bool fetch, bool proj, bool gather, const TextureParameters& parameters)
+Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, bool noImplicitLod, const TextureParameters& parameters)
 {
     static const int maxTextureArgs = 10;
     Id texArgs[maxTextureArgs] = {};
@@ -1295,7 +1295,7 @@
     // Set up the fixed arguments
     //
     int numArgs = 0;
-    bool xplicit = false;
+    bool explicitLod = false;
     texArgs[numArgs++] = parameters.sampler;
     texArgs[numArgs++] = parameters.coords;
     if (parameters.Dref)
@@ -1316,13 +1316,18 @@
     if (parameters.lod) {
         mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);
         texArgs[numArgs++] = parameters.lod;
-        xplicit = true;
-    }
-    if (parameters.gradX) {
+        explicitLod = true;
+    } else if (parameters.gradX) {
         mask = (ImageOperandsMask)(mask | ImageOperandsGradMask);
         texArgs[numArgs++] = parameters.gradX;
         texArgs[numArgs++] = parameters.gradY;
-        xplicit = true;
+        explicitLod = true;
+    } else if (noImplicitLod && ! fetch && ! gather) {
+        // have to explicitly use lod of 0 if not allowed to have them be implicit, and
+        // we would otherwise be about to issue an implicit instruction
+        mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);
+        texArgs[numArgs++] = makeFloatConstant(0.0);
+        explicitLod = true;
     }
     if (parameters.offset) {
         if (isConstant(parameters.offset))
@@ -1354,8 +1359,7 @@
     //
     // Set up the instruction
     //
-    Op opCode;
-    opCode = OpImageSampleImplicitLod;
+    Op opCode = OpNop;  // All paths below need to set this
     if (fetch) {
         if (sparse)
             opCode = OpImageSparseFetch;
@@ -1372,7 +1376,7 @@
                 opCode = OpImageSparseGather;
             else
                 opCode = OpImageGather;
-    } else if (xplicit) {
+    } else if (explicitLod) {
         if (parameters.Dref) {
             if (proj)
                 if (sparse)
diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h
index 074f8d2..b2daffb 100755
--- a/SPIRV/SpvBuilder.h
+++ b/SPIRV/SpvBuilder.h
@@ -323,7 +323,7 @@
     };
 
     // Select the correct texture operation based on all inputs, and emit the correct instruction
-    Id createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, const TextureParameters&);
+    Id createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, bool noImplicit, const TextureParameters&);
 
     // Emit the OpTextureQuery* instruction that was passed in.
     // Figure out the right return value and type, and return it.