Fix SPIR-V for HLSL EvaluateAttribute* of interpolants in structs
authorGreg Fischer <greg@lunarg.com>
Wed, 31 Mar 2021 21:24:48 +0000 (15:24 -0600)
committerGreg Fischer <greg@lunarg.com>
Thu, 1 Apr 2021 06:31:31 +0000 (00:31 -0600)
Generate load of interpolant for first operand to GLSLstd450
InterpolateAt* SPIR-V ops. This allows the interpolants to
propagate from the input struct in the wrapper around main
into the shader during HLSL legalization. A new pass has been
added to legalization which will remove the load and replace
with the pointer of the load to create valid external
interpolate op.

Fixes #2584

SPIRV/GlslangToSpv.cpp
SPIRV/SpvTools.cpp
Test/baseLegalResults/hlsl.intrinsics.evalfns.frag.out [new file with mode: 0644]
Test/baseResults/hlsl.intrinsics.evalfns.frag.out [deleted file]
Test/hlsl.intrinsics.evalfns.frag
glslang/HLSL/hlslParseHelper.cpp
gtests/Hlsl.FromFile.cpp
known_good.json

index 9137cc0..81aacd1 100644 (file)
@@ -2301,7 +2301,8 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
     if (node->getOp() == glslang::EOpAtomicCounterIncrement ||
         node->getOp() == glslang::EOpAtomicCounterDecrement ||
         node->getOp() == glslang::EOpAtomicCounter          ||
-        node->getOp() == glslang::EOpInterpolateAtCentroid  ||
+        (node->getOp() == glslang::EOpInterpolateAtCentroid &&
+          glslangIntermediate->getSource() != glslang::EShSourceHlsl)  ||
         node->getOp() == glslang::EOpRayQueryProceed        ||
         node->getOp() == glslang::EOpRayQueryGetRayTMin     ||
         node->getOp() == glslang::EOpRayQueryGetRayFlags    ||
@@ -2977,7 +2978,13 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
         case glslang::EOpInterpolateAtOffset:
         case glslang::EOpInterpolateAtVertex:
             if (arg == 0) {
-                lvalue = true;
+                // If GLSL, use the address of the interpolant argument.
+                // If HLSL, use an internal version of OpInterolates that takes
+                // the rvalue of the interpolant. A fixup pass in spirv-opt
+                // legalization will remove the OpLoad and convert to an lvalue.
+                // Had to do this because legalization will only propagate a
+                // builtin into an rvalue.
+                lvalue = glslangIntermediate->getSource() != glslang::EShSourceHlsl;
 
                 // Does it need a swizzle inversion?  If so, evaluation is inverted;
                 // operate first on the swizzle base, then apply the swizzle.
index 5cfc426..8acf9b1 100644 (file)
@@ -207,6 +207,7 @@ void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector
     optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
     optimizer.RegisterPass(spvtools::CreateVectorDCEPass());
     optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass());
+    optimizer.RegisterPass(spvtools::CreateInterpolateFixupPass());
     if (options->optimizeSize) {
         optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass());
     }
diff --git a/Test/baseLegalResults/hlsl.intrinsics.evalfns.frag.out b/Test/baseLegalResults/hlsl.intrinsics.evalfns.frag.out
new file mode 100644 (file)
index 0000000..564f0f4
--- /dev/null
@@ -0,0 +1,110 @@
+hlsl.intrinsics.evalfns.frag
+// Module Version 10000
+// Generated by (magic number): 8000a
+// Id's are bound by 274
+
+                              Capability Shader
+                              Capability InterpolationFunction
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 138 142 146 150 154 157 161
+                              ExecutionMode 4 OriginUpperLeft
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 138  "inF1"
+                              Name 142  "inF2"
+                              Name 146  "inF3"
+                              Name 150  "inF4"
+                              Name 154  "inI2"
+                              Name 157  "i.vPos"
+                              Name 161  "@entryPointOutput"
+                              Decorate 138(inF1) Location 0
+                              Decorate 142(inF2) Location 1
+                              Decorate 146(inF3) Location 2
+                              Decorate 150(inF4) Location 3
+                              Decorate 154(inI2) Flat
+                              Decorate 154(inI2) Location 4
+                              Decorate 157(i.vPos) Location 5
+                              Decorate 161(@entryPointOutput) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               8:             TypeVector 6(float) 2
+              10:             TypeVector 6(float) 3
+              12:             TypeVector 6(float) 4
+              14:             TypeInt 32 1
+              15:             TypeVector 14(int) 2
+              30:    6(float) Constant 3204448256
+              31:    6(float) Constant 3179282432
+              32:    8(fvec2) ConstantComposite 30 31
+              36:    6(float) Constant 0
+              37:    6(float) Constant 1031798784
+              38:    8(fvec2) ConstantComposite 36 37
+              42:    6(float) Constant 1044381696
+              43:    6(float) Constant 3200253952
+              44:    8(fvec2) ConstantComposite 42 43
+              48:    6(float) Constant 1054867456
+              49:    8(fvec2) ConstantComposite 48 30
+              53:     14(int) Constant 28
+              64:             TypeInt 32 0
+              65:     64(int) Constant 3
+             137:             TypePointer Input 6(float)
+       138(inF1):    137(ptr) Variable Input
+             141:             TypePointer Input 8(fvec2)
+       142(inF2):    141(ptr) Variable Input
+             145:             TypePointer Input 10(fvec3)
+       146(inF3):    145(ptr) Variable Input
+             149:             TypePointer Input 12(fvec4)
+       150(inF4):    149(ptr) Variable Input
+             153:             TypePointer Input 15(ivec2)
+       154(inI2):    153(ptr) Variable Input
+     157(i.vPos):    141(ptr) Variable Input
+             160:             TypePointer Output 12(fvec4)
+161(@entryPointOutput):    160(ptr) Variable Output
+             273:   15(ivec2) ConstantComposite 53 53
+         4(main):           2 Function None 3
+               5:             Label
+             155:   15(ivec2) Load 154(inI2)
+             183:    6(float) ExtInst 1(GLSL.std.450) 78(InterpolateAtOffset) 138(inF1) 32
+             185:    8(fvec2) ExtInst 1(GLSL.std.450) 78(InterpolateAtOffset) 142(inF2) 38
+             187:   10(fvec3) ExtInst 1(GLSL.std.450) 78(InterpolateAtOffset) 146(inF3) 44
+             189:   12(fvec4) ExtInst 1(GLSL.std.450) 78(InterpolateAtOffset) 150(inF4) 49
+             193:   15(ivec2) ShiftLeftLogical 155 273
+             195:   15(ivec2) ShiftRightArithmetic 193 273
+             196:    8(fvec2) ConvertSToF 195
+             197:    8(fvec2) VectorTimesScalar 196 37
+             198:    6(float) ExtInst 1(GLSL.std.450) 78(InterpolateAtOffset) 138(inF1) 197
+             200:    6(float) FAdd 183 198
+             202:    6(float) ExtInst 1(GLSL.std.450) 77(InterpolateAtSample) 138(inF1) 65
+             204:    6(float) FAdd 200 202
+             206:    8(fvec2) ExtInst 1(GLSL.std.450) 77(InterpolateAtSample) 142(inF2) 65
+             208:    8(fvec2) FAdd 185 206
+             210:   10(fvec3) ExtInst 1(GLSL.std.450) 77(InterpolateAtSample) 146(inF3) 65
+             212:   10(fvec3) FAdd 187 210
+             214:   12(fvec4) ExtInst 1(GLSL.std.450) 77(InterpolateAtSample) 150(inF4) 65
+             216:   12(fvec4) FAdd 189 214
+             219:     14(int) CompositeExtract 155 0
+             220:     64(int) Bitcast 219
+             221:    6(float) ExtInst 1(GLSL.std.450) 77(InterpolateAtSample) 138(inF1) 220
+             223:    6(float) FAdd 204 221
+             225:    6(float) ExtInst 1(GLSL.std.450) 76(InterpolateAtCentroid) 138(inF1)
+             227:    6(float) FAdd 223 225
+             229:    8(fvec2) ExtInst 1(GLSL.std.450) 76(InterpolateAtCentroid) 142(inF2)
+             231:    8(fvec2) FAdd 208 229
+             233:   10(fvec3) ExtInst 1(GLSL.std.450) 76(InterpolateAtCentroid) 146(inF3)
+             235:   10(fvec3) FAdd 212 233
+             237:   12(fvec4) ExtInst 1(GLSL.std.450) 76(InterpolateAtCentroid) 150(inF4)
+             239:   12(fvec4) FAdd 216 237
+             242:    8(fvec2) ExtInst 1(GLSL.std.450) 78(InterpolateAtOffset) 157(i.vPos) 38
+             244:    8(fvec2) FAdd 231 242
+             247:    8(fvec2) ExtInst 1(GLSL.std.450) 77(InterpolateAtSample) 157(i.vPos) 65
+             249:    8(fvec2) FAdd 244 247
+             252:    8(fvec2) ExtInst 1(GLSL.std.450) 76(InterpolateAtCentroid) 157(i.vPos)
+             254:    8(fvec2) FAdd 249 252
+             257:    6(float) CompositeExtract 254 1
+             259:    6(float) CompositeExtract 235 2
+             261:    6(float) CompositeExtract 239 3
+             262:   12(fvec4) CompositeConstruct 227 257 259 261
+                              Store 161(@entryPointOutput) 262
+                              Return
+                              FunctionEnd
diff --git a/Test/baseResults/hlsl.intrinsics.evalfns.frag.out b/Test/baseResults/hlsl.intrinsics.evalfns.frag.out
deleted file mode 100644 (file)
index 502ad0f..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-hlsl.intrinsics.evalfns.frag
-Shader version: 500
-gl_FragCoord origin is upper left
-0:? Sequence
-0:3  Function Definition: @main(f1;vf2;vf3;vf4;vi2; ( temp void)
-0:3    Function Parameters: 
-0:3      'inF1' ( in float)
-0:3      'inF2' ( in 2-component vector of float)
-0:3      'inF3' ( in 3-component vector of float)
-0:3      'inF4' ( in 4-component vector of float)
-0:3      'inI2' ( in 2-component vector of int)
-0:?     Sequence
-0:4      interpolateAtOffset ( temp float)
-0:4        'inF1' ( in float)
-0:?         Constant:
-0:?           -0.500000
-0:?           -0.062500
-0:5      interpolateAtOffset ( temp 2-component vector of float)
-0:5        'inF2' ( in 2-component vector of float)
-0:?         Constant:
-0:?           0.000000
-0:?           0.062500
-0:6      interpolateAtOffset ( temp 3-component vector of float)
-0:6        'inF3' ( in 3-component vector of float)
-0:?         Constant:
-0:?           0.187500
-0:?           -0.375000
-0:7      interpolateAtOffset ( temp 4-component vector of float)
-0:7        'inF4' ( in 4-component vector of float)
-0:?         Constant:
-0:?           0.437500
-0:?           -0.500000
-0:9      interpolateAtOffset ( temp float)
-0:9        'inF1' ( in float)
-0:9        vector-scale ( temp 2-component vector of float)
-0:9          Convert int to float ( temp 2-component vector of float)
-0:9            right-shift ( temp 2-component vector of int)
-0:9              left-shift ( temp 2-component vector of int)
-0:9                'inI2' ( in 2-component vector of int)
-0:9                Constant:
-0:9                  28 (const int)
-0:9              Constant:
-0:9                28 (const int)
-0:9          Constant:
-0:9            0.062500
-0:3  Function Definition: main( ( temp void)
-0:3    Function Parameters: 
-0:?     Sequence
-0:3      move second child to first child ( temp float)
-0:?         'inF1' ( temp float)
-0:?         'inF1' (layout( location=0) in float)
-0:3      move second child to first child ( temp 2-component vector of float)
-0:?         'inF2' ( temp 2-component vector of float)
-0:?         'inF2' (layout( location=1) in 2-component vector of float)
-0:3      move second child to first child ( temp 3-component vector of float)
-0:?         'inF3' ( temp 3-component vector of float)
-0:?         'inF3' (layout( location=2) in 3-component vector of float)
-0:3      move second child to first child ( temp 4-component vector of float)
-0:?         'inF4' ( temp 4-component vector of float)
-0:?         'inF4' (layout( location=3) in 4-component vector of float)
-0:3      move second child to first child ( temp 2-component vector of int)
-0:?         'inI2' ( temp 2-component vector of int)
-0:?         'inI2' (layout( location=4) flat in 2-component vector of int)
-0:3      Function Call: @main(f1;vf2;vf3;vf4;vi2; ( temp void)
-0:?         'inF1' ( temp float)
-0:?         'inF2' ( temp 2-component vector of float)
-0:?         'inF3' ( temp 3-component vector of float)
-0:?         'inF4' ( temp 4-component vector of float)
-0:?         'inI2' ( temp 2-component vector of int)
-0:?   Linker Objects
-0:?     'inF1' (layout( location=0) in float)
-0:?     'inF2' (layout( location=1) in 2-component vector of float)
-0:?     'inF3' (layout( location=2) in 3-component vector of float)
-0:?     'inF4' (layout( location=3) in 4-component vector of float)
-0:?     'inI2' (layout( location=4) flat in 2-component vector of int)
-
-
-Linked fragment stage:
-
-
-Shader version: 500
-gl_FragCoord origin is upper left
-0:? Sequence
-0:3  Function Definition: @main(f1;vf2;vf3;vf4;vi2; ( temp void)
-0:3    Function Parameters: 
-0:3      'inF1' ( in float)
-0:3      'inF2' ( in 2-component vector of float)
-0:3      'inF3' ( in 3-component vector of float)
-0:3      'inF4' ( in 4-component vector of float)
-0:3      'inI2' ( in 2-component vector of int)
-0:?     Sequence
-0:4      interpolateAtOffset ( temp float)
-0:4        'inF1' ( in float)
-0:?         Constant:
-0:?           -0.500000
-0:?           -0.062500
-0:5      interpolateAtOffset ( temp 2-component vector of float)
-0:5        'inF2' ( in 2-component vector of float)
-0:?         Constant:
-0:?           0.000000
-0:?           0.062500
-0:6      interpolateAtOffset ( temp 3-component vector of float)
-0:6        'inF3' ( in 3-component vector of float)
-0:?         Constant:
-0:?           0.187500
-0:?           -0.375000
-0:7      interpolateAtOffset ( temp 4-component vector of float)
-0:7        'inF4' ( in 4-component vector of float)
-0:?         Constant:
-0:?           0.437500
-0:?           -0.500000
-0:9      interpolateAtOffset ( temp float)
-0:9        'inF1' ( in float)
-0:9        vector-scale ( temp 2-component vector of float)
-0:9          Convert int to float ( temp 2-component vector of float)
-0:9            right-shift ( temp 2-component vector of int)
-0:9              left-shift ( temp 2-component vector of int)
-0:9                'inI2' ( in 2-component vector of int)
-0:9                Constant:
-0:9                  28 (const int)
-0:9              Constant:
-0:9                28 (const int)
-0:9          Constant:
-0:9            0.062500
-0:3  Function Definition: main( ( temp void)
-0:3    Function Parameters: 
-0:?     Sequence
-0:3      move second child to first child ( temp float)
-0:?         'inF1' ( temp float)
-0:?         'inF1' (layout( location=0) in float)
-0:3      move second child to first child ( temp 2-component vector of float)
-0:?         'inF2' ( temp 2-component vector of float)
-0:?         'inF2' (layout( location=1) in 2-component vector of float)
-0:3      move second child to first child ( temp 3-component vector of float)
-0:?         'inF3' ( temp 3-component vector of float)
-0:?         'inF3' (layout( location=2) in 3-component vector of float)
-0:3      move second child to first child ( temp 4-component vector of float)
-0:?         'inF4' ( temp 4-component vector of float)
-0:?         'inF4' (layout( location=3) in 4-component vector of float)
-0:3      move second child to first child ( temp 2-component vector of int)
-0:?         'inI2' ( temp 2-component vector of int)
-0:?         'inI2' (layout( location=4) flat in 2-component vector of int)
-0:3      Function Call: @main(f1;vf2;vf3;vf4;vi2; ( temp void)
-0:?         'inF1' ( temp float)
-0:?         'inF2' ( temp 2-component vector of float)
-0:?         'inF3' ( temp 3-component vector of float)
-0:?         'inF4' ( temp 4-component vector of float)
-0:?         'inI2' ( temp 2-component vector of int)
-0:?   Linker Objects
-0:?     'inF1' (layout( location=0) in float)
-0:?     'inF2' (layout( location=1) in 2-component vector of float)
-0:?     'inF3' (layout( location=2) in 3-component vector of float)
-0:?     'inF4' (layout( location=3) in 4-component vector of float)
-0:?     'inI2' (layout( location=4) flat in 2-component vector of int)
-
-Validation failed
-// Module Version 10000
-// Generated by (magic number): 8000a
-// Id's are bound by 80
-
-                              Capability Shader
-                              Capability InterpolationFunction
-               1:             ExtInstImport  "GLSL.std.450"
-                              MemoryModel Logical GLSL450
-                              EntryPoint Fragment 4  "main" 51 55 59 63 67
-                              ExecutionMode 4 OriginUpperLeft
-                              Source HLSL 500
-                              Name 4  "main"
-                              Name 23  "@main(f1;vf2;vf3;vf4;vi2;"
-                              Name 18  "inF1"
-                              Name 19  "inF2"
-                              Name 20  "inF3"
-                              Name 21  "inF4"
-                              Name 22  "inI2"
-                              Name 49  "inF1"
-                              Name 51  "inF1"
-                              Name 53  "inF2"
-                              Name 55  "inF2"
-                              Name 57  "inF3"
-                              Name 59  "inF3"
-                              Name 61  "inF4"
-                              Name 63  "inF4"
-                              Name 65  "inI2"
-                              Name 67  "inI2"
-                              Name 69  "param"
-                              Name 71  "param"
-                              Name 73  "param"
-                              Name 75  "param"
-                              Name 77  "param"
-                              Decorate 51(inF1) Location 0
-                              Decorate 55(inF2) Location 1
-                              Decorate 59(inF3) Location 2
-                              Decorate 63(inF4) Location 3
-                              Decorate 67(inI2) Flat
-                              Decorate 67(inI2) Location 4
-               2:             TypeVoid
-               3:             TypeFunction 2
-               6:             TypeFloat 32
-               7:             TypePointer Function 6(float)
-               8:             TypeVector 6(float) 2
-               9:             TypePointer Function 8(fvec2)
-              10:             TypeVector 6(float) 3
-              11:             TypePointer Function 10(fvec3)
-              12:             TypeVector 6(float) 4
-              13:             TypePointer Function 12(fvec4)
-              14:             TypeInt 32 1
-              15:             TypeVector 14(int) 2
-              16:             TypePointer Function 15(ivec2)
-              17:             TypeFunction 2 7(ptr) 9(ptr) 11(ptr) 13(ptr) 16(ptr)
-              25:    6(float) Constant 3204448256
-              26:    6(float) Constant 3179282432
-              27:    8(fvec2) ConstantComposite 25 26
-              29:    6(float) Constant 0
-              30:    6(float) Constant 1031798784
-              31:    8(fvec2) ConstantComposite 29 30
-              33:    6(float) Constant 1044381696
-              34:    6(float) Constant 3200253952
-              35:    8(fvec2) ConstantComposite 33 34
-              37:    6(float) Constant 1054867456
-              38:    8(fvec2) ConstantComposite 37 25
-              41:     14(int) Constant 28
-              50:             TypePointer Input 6(float)
-        51(inF1):     50(ptr) Variable Input
-              54:             TypePointer Input 8(fvec2)
-        55(inF2):     54(ptr) Variable Input
-              58:             TypePointer Input 10(fvec3)
-        59(inF3):     58(ptr) Variable Input
-              62:             TypePointer Input 12(fvec4)
-        63(inF4):     62(ptr) Variable Input
-              66:             TypePointer Input 15(ivec2)
-        67(inI2):     66(ptr) Variable Input
-         4(main):           2 Function None 3
-               5:             Label
-        49(inF1):      7(ptr) Variable Function
-        53(inF2):      9(ptr) Variable Function
-        57(inF3):     11(ptr) Variable Function
-        61(inF4):     13(ptr) Variable Function
-        65(inI2):     16(ptr) Variable Function
-       69(param):      7(ptr) Variable Function
-       71(param):      9(ptr) Variable Function
-       73(param):     11(ptr) Variable Function
-       75(param):     13(ptr) Variable Function
-       77(param):     16(ptr) Variable Function
-              52:    6(float) Load 51(inF1)
-                              Store 49(inF1) 52
-              56:    8(fvec2) Load 55(inF2)
-                              Store 53(inF2) 56
-              60:   10(fvec3) Load 59(inF3)
-                              Store 57(inF3) 60
-              64:   12(fvec4) Load 63(inF4)
-                              Store 61(inF4) 64
-              68:   15(ivec2) Load 67(inI2)
-                              Store 65(inI2) 68
-              70:    6(float) Load 49(inF1)
-                              Store 69(param) 70
-              72:    8(fvec2) Load 53(inF2)
-                              Store 71(param) 72
-              74:   10(fvec3) Load 57(inF3)
-                              Store 73(param) 74
-              76:   12(fvec4) Load 61(inF4)
-                              Store 75(param) 76
-              78:   15(ivec2) Load 65(inI2)
-                              Store 77(param) 78
-              79:           2 FunctionCall 23(@main(f1;vf2;vf3;vf4;vi2;) 69(param) 71(param) 73(param) 75(param) 77(param)
-                              Return
-                              FunctionEnd
-23(@main(f1;vf2;vf3;vf4;vi2;):           2 Function None 17
-        18(inF1):      7(ptr) FunctionParameter
-        19(inF2):      9(ptr) FunctionParameter
-        20(inF3):     11(ptr) FunctionParameter
-        21(inF4):     13(ptr) FunctionParameter
-        22(inI2):     16(ptr) FunctionParameter
-              24:             Label
-              28:    6(float) ExtInst 1(GLSL.std.450) 78(InterpolateAtOffset) 18(inF1) 27
-              32:    8(fvec2) ExtInst 1(GLSL.std.450) 78(InterpolateAtOffset) 19(inF2) 31
-              36:   10(fvec3) ExtInst 1(GLSL.std.450) 78(InterpolateAtOffset) 20(inF3) 35
-              39:   12(fvec4) ExtInst 1(GLSL.std.450) 78(InterpolateAtOffset) 21(inF4) 38
-              40:   15(ivec2) Load 22(inI2)
-              42:   15(ivec2) CompositeConstruct 41 41
-              43:   15(ivec2) ShiftLeftLogical 40 42
-              44:   15(ivec2) CompositeConstruct 41 41
-              45:   15(ivec2) ShiftRightArithmetic 43 44
-              46:    8(fvec2) ConvertSToF 45
-              47:    8(fvec2) VectorTimesScalar 46 30
-              48:    6(float) ExtInst 1(GLSL.std.450) 78(InterpolateAtOffset) 18(inF1) 47
-                              Return
-                              FunctionEnd
index 9638706..7b7509d 100644 (file)
@@ -1,10 +1,33 @@
+struct PS_INPUT
+{
+        float2 vPos: TEXCOORD0;
+};
 
-void main(float inF1, float2 inF2, float3 inF3, float4 inF4, int2 inI2) : COLOR
+float4 main(float inF1, float2 inF2, float3 inF3, float4 inF4, int2 inI2, PS_INPUT i) : COLOR
 {
-    EvaluateAttributeSnapped(inF1, int2(8,15));
-    EvaluateAttributeSnapped(inF2, int2(0,1));
-    EvaluateAttributeSnapped(inF3, int2(3,10));
-    EvaluateAttributeSnapped(inF4, int2(7,8));
+    float  oF1 = EvaluateAttributeSnapped(inF1, int2(8,15));
+    float2 oF2 = EvaluateAttributeSnapped(inF2, int2(0,1));
+    float3 oF3 = EvaluateAttributeSnapped(inF3, int2(3,10));
+    float4 oF4 = EvaluateAttributeSnapped(inF4, int2(7,8));
+
+    oF1 += EvaluateAttributeSnapped(inF1, inI2);
+
+    oF1 += EvaluateAttributeAtSample(inF1, 3);
+    oF2 += EvaluateAttributeAtSample(inF2, 3);
+    oF3 += EvaluateAttributeAtSample(inF3, 3);
+    oF4 += EvaluateAttributeAtSample(inF4, 3);
+
+    oF1 += EvaluateAttributeAtSample(inF1, inI2.x);
+
+    oF1 += EvaluateAttributeAtCentroid(inF1);
+    oF2 += EvaluateAttributeAtCentroid(inF2);
+    oF3 += EvaluateAttributeAtCentroid(inF3);
+    oF4 += EvaluateAttributeAtCentroid(inF4);
+
+    oF2 += EvaluateAttributeSnapped(i.vPos, int2(0,1));
+    oF2 += EvaluateAttributeAtSample(i.vPos, 3);
+    oF2 += EvaluateAttributeAtCentroid(i.vPos);
 
-    EvaluateAttributeSnapped(inF1, inI2);
+    float4 color = float4(oF1, oF2.y, oF3.z, oF4.w);
+    return color;
 }
index 63dd8e3..d62f392 100644 (file)
@@ -6075,8 +6075,12 @@ void HlslParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fn
     case EOpInterpolateAtCentroid:
     case EOpInterpolateAtSample:
     case EOpInterpolateAtOffset:
+        // TODO(greg-lunarg): Re-enable this check. It currently gives false errors for builtins
+        // defined and passed as members of a struct. In this case the storage class is showing to be
+        // Function. See glslang #2584
+
         // Make sure the first argument is an interpolant, or an array element of an interpolant
-        if (arg0->getType().getQualifier().storage != EvqVaryingIn) {
+        // if (arg0->getType().getQualifier().storage != EvqVaryingIn) {
             // It might still be an array element.
             //
             // We could check more, but the semantics of the first argument are already met; the
@@ -6084,11 +6088,11 @@ void HlslParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fn
             //
             // ES and desktop 4.3 and earlier:  swizzles may not be used
             // desktop 4.4 and later: swizzles may be used
-            const TIntermTyped* base = TIntermediate::findLValueBase(arg0, true);
-            if (base == nullptr || base->getType().getQualifier().storage != EvqVaryingIn)
-                error(loc, "first argument must be an interpolant, or interpolant-array element",
-                      fnCandidate.getName().c_str(), "");
-        }
+            // const TIntermTyped* base = TIntermediate::findLValueBase(arg0, true);
+            // if (base == nullptr || base->getType().getQualifier().storage != EvqVaryingIn)
+            //     error(loc, "first argument must be an interpolant, or interpolant-array element",
+            //           fnCandidate.getName().c_str(), "");
+        // }
         break;
 
     default:
index de071b9..33deef5 100644 (file)
@@ -245,7 +245,6 @@ INSTANTIATE_TEST_SUITE_P(
         {"hlsl.isfinite.frag", "main"},
         {"hlsl.intrinsics.barriers.comp", "ComputeShaderFunction"},
         {"hlsl.intrinsics.comp", "ComputeShaderFunction"},
-        {"hlsl.intrinsics.evalfns.frag", "main"},
         {"hlsl.intrinsics.d3dcolortoubyte4.frag", "main"},
         {"hlsl.intrinsics.double.frag", "PixelShaderFunction"},
         {"hlsl.intrinsics.f1632.frag", "main"},
@@ -471,6 +470,7 @@ INSTANTIATE_TEST_SUITE_P(
         {"hlsl.flattenOpaqueInitMix.vert", "main"},
         {"hlsl.flattenSubset.frag", "main"},
         {"hlsl.flattenSubset2.frag", "main"},
+        {"hlsl.intrinsics.evalfns.frag", "main"},
         {"hlsl.partialFlattenLocal.vert", "main"},
         {"hlsl.partialFlattenMixed.vert", "main"}
     }),
index 4442f89..e69a3ae 100644 (file)
@@ -5,14 +5,14 @@
       "site" : "github",
       "subrepo" : "KhronosGroup/SPIRV-Tools",
       "subdir" : "External/spirv-tools",
-      "commit" : "c79edd260c2b503f0eca57310057b4a100999cc5"
+      "commit" : "48007a5c7f7cc671b391bebd46e87fd6edc6c24b"
     },
     {
       "name" : "spirv-tools/external/spirv-headers",
       "site" : "github",
       "subrepo" : "KhronosGroup/SPIRV-Headers",
       "subdir" : "External/spirv-tools/external/spirv-headers",
-      "commit" : "75b30a659c8a4979104986652c54cc421fc51129"
+      "commit" : "f88a1f98fa7a44ccfcf33d810c72b200e7d9a78a"
     }
   ]
 }