diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 81509975..ed86cc2d 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -2236,6 +2236,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO params.coords = arguments[1]; int extraArgs = 0; + bool noImplicitLod = false; // sort out where Dref is coming from if (cubeCompare) { @@ -2257,7 +2258,11 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO 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 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO } } - 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 10ba32ce..2d6e50ec 100755 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -1286,7 +1286,7 @@ Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, std::v // 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 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, // 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 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, 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 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, // // 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 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, 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 074f8d24..b2daffb6 100755 --- a/SPIRV/SpvBuilder.h +++ b/SPIRV/SpvBuilder.h @@ -323,7 +323,7 @@ public: }; // 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. diff --git a/Test/baseResults/spv.150.vert.out b/Test/baseResults/spv.150.vert.out index 2a347b40..3e86aec2 100755 --- a/Test/baseResults/spv.150.vert.out +++ b/Test/baseResults/spv.150.vert.out @@ -5,13 +5,13 @@ Linked vertex stage: // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 50 +// Id's are bound by 67 Capability Shader Capability ClipDistance 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint Vertex 4 "main" 13 17 39 48 49 + EntryPoint Vertex 4 "main" 13 17 39 65 66 Source GLSL 150 Name 4 "main" Name 11 "gl_PerVertex" @@ -30,16 +30,17 @@ Linked vertex stage: MemberName 37(s2) 1 "d" Name 39 "s2out" Name 41 "i" - Name 46 "ui" - Name 48 "gl_VertexID" - Name 49 "gl_InstanceID" + Name 48 "s2D" + Name 63 "ui" + Name 65 "gl_VertexID" + Name 66 "gl_InstanceID" MemberDecorate 11(gl_PerVertex) 0 Invariant MemberDecorate 11(gl_PerVertex) 0 BuiltIn Position MemberDecorate 11(gl_PerVertex) 1 BuiltIn PointSize MemberDecorate 11(gl_PerVertex) 2 BuiltIn ClipDistance Decorate 11(gl_PerVertex) Block - Decorate 48(gl_VertexID) BuiltIn VertexId - Decorate 49(gl_InstanceID) BuiltIn InstanceId + Decorate 65(gl_VertexID) BuiltIn VertexId + Decorate 66(gl_InstanceID) BuiltIn InstanceId 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 @@ -70,11 +71,22 @@ Linked vertex stage: 38: TypePointer Output 37(s2) 39(s2out): 38(ptr) Variable Output 40: TypePointer Function 14(int) - 45: TypePointer UniformConstant 14(int) - 46(ui): 45(ptr) Variable UniformConstant - 47: TypePointer Input 14(int) - 48(gl_VertexID): 47(ptr) Variable Input -49(gl_InstanceID): 47(ptr) Variable Input + 45: TypeImage 6(float) 2D sampled format:Unknown + 46: TypeSampledImage 45 + 47: TypePointer UniformConstant 46 + 48(s2D): 47(ptr) Variable UniformConstant + 50: TypeVector 6(float) 2 + 51: 6(float) Constant 1056964608 + 52: 50(fvec2) ConstantComposite 51 51 + 53: 6(float) Constant 0 + 56: TypeVector 6(float) 3 + 57: 56(fvec3) ConstantComposite 51 51 51 + 60: 6(float) Constant 1078774989 + 62: TypePointer UniformConstant 14(int) + 63(ui): 62(ptr) Variable UniformConstant + 64: TypePointer Input 14(int) + 65(gl_VertexID): 64(ptr) Variable Input +66(gl_InstanceID): 64(ptr) Variable Input 4(main): 2 Function None 3 5: Label 41(i): 40(ptr) Variable Function @@ -92,5 +104,11 @@ Linked vertex stage: 43: 6(float) Load 23(ps) 44: 25(ptr) AccessChain 39(s2out) 21 42 27 27 33 Store 44 43 + 49: 46 Load 48(s2D) + 54: 7(fvec4) ImageSampleExplicitLod 49 52 Lod 53 + 55: 46 Load 48(s2D) + 58: 7(fvec4) ImageSampleProjExplicitLod 55 57 Lod 53 + 59: 46 Load 48(s2D) + 61: 7(fvec4) ImageSampleExplicitLod 59 52 Lod 60 Return FunctionEnd diff --git a/Test/spv.150.vert b/Test/spv.150.vert index 065275f8..686b14b0 100644 --- a/Test/spv.150.vert +++ b/Test/spv.150.vert @@ -4,6 +4,7 @@ in vec4 iv4; uniform float ps; uniform int ui; +uniform sampler2D s2D; invariant gl_Position; @@ -27,13 +28,11 @@ void main() gl_ClipDistance[2] = iv4.x; int i; s2out.d[i].b[2].w = ps; - - // test recovery from nonsupported built-ins - //float n1 = noise1(2.4); - //n1 = noise1(vec4(n1)); - //vec2 n2 = noise2(vec3(n1)); - //vec3 n3 = noise3(n2); - //vec4 n4 = noise4(n3); + + // test non-implicit lod + texture(s2D, vec2(0.5)); + textureProj(s2D, vec3(0.5)); + textureLod(s2D, vec2(0.5), 3.2); } out float gl_ClipDistance[4];