Commit 7fbaca0d by Greg Fischer

Fix SPIR-V for HLSL EvaluateAttribute* of interpolants in structs

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
parent 6dc24ffa
......@@ -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.
......
......@@ -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());
}
......
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
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;
}
......@@ -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:
......
......@@ -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"}
}),
......
......@@ -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"
}
]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment