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
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 9137cc0..81aacd1 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -2301,7 +2301,8 @@
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 @@
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.