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.
diff --git a/Test/baseResults/spv.150.vert.out b/Test/baseResults/spv.150.vert.out
index 2a347b4..3e86aec 100755
--- a/Test/baseResults/spv.150.vert.out
+++ b/Test/baseResults/spv.150.vert.out
@@ -5,13 +5,13 @@
// 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 @@
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 @@
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 @@
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 065275f..686b14b 100644
--- a/Test/spv.150.vert
+++ b/Test/spv.150.vert
@@ -4,6 +4,7 @@
uniform float ps;
uniform int ui;
+uniform sampler2D s2D;
invariant gl_Position;
@@ -27,13 +28,11 @@
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];