diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 62e0674f..c3d0acb5 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -508,6 +508,12 @@ public: return flat || smooth || nopersp; #endif } +#ifdef AMD_EXTENSIONS + bool isExplicitInterpolation() const + { + return explicitInterp; + } +#endif bool isAuxiliary() const { return centroid || patch || sample; diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index fc653f4c..0d9cea7b 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -1608,6 +1608,23 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan if (base == nullptr || base->getType().getQualifier().storage != EvqVaryingIn) error(loc, "first argument must be an interpolant, or interpolant-array element", fnCandidate.getName().c_str(), ""); } + +#ifdef AMD_EXTENSIONS + if (callNode.getOp() == EOpInterpolateAtVertex) { + if (!arg0->getType().getQualifier().isExplicitInterpolation()) + error(loc, "argument must be qualified as __explicitInterpAMD in", "interpolant", ""); + else { + if (! (*argp)[1]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "vertex index", ""); + else { + unsigned vertexIdx = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getUConst(); + if (vertexIdx > 2) + error(loc, "must be in the range [0, 2]", "vertex index", ""); + } + } + } +#endif + break; case EOpEmitStreamVertex: