Front-end: Implement 2nd task of issue #400; precision of result and operation.

From the ES spec + Bugzilla 15931 and GL_KHR_vulkan_glsl:
- Update precision qualifiers for all built-in function prototypes.
- Implement the new algorithm used to distinguish built-in function
  operation precisions from result precisions.
Also add tracking of separate result and operation precisions, and
use that in generating SPIR-V.
(SPIR-V cares about precision of operation, while the front-end
cares about precision of result, for propagation.)
This commit is contained in:
John Kessenich 2016-08-01 19:44:00 -06:00
parent 6c136223ed
commit f6640761c4
18 changed files with 408 additions and 308 deletions

View file

@ -634,7 +634,7 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt
if (fields.num == 1) {
TIntermTyped* index = intermediate.addConstantUnion(fields.offsets[0], loc);
result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision));
result->setType(TType(base->getBasicType(), EvqTemporary));
} else {
TString vectorString = field;
TIntermTyped* index = intermediate.addSwizzle(fields, loc);
@ -1953,11 +1953,6 @@ void HlslParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fn
}
const TIntermSequence& aggArgs = *argp; // only valid when unaryArg is nullptr
// built-in texturing functions get their return value precision from the precision of the sampler
if (fnCandidate.getType().getQualifier().precision == EpqNone &&
fnCandidate.getParamCount() > 0 && fnCandidate[0].type->getBasicType() == EbtSampler)
callNode.getQualifier().precision = arg0->getQualifier().precision;
switch (callNode.getOp()) {
case EOpTextureGather:
case EOpTextureGatherOffset:
@ -2060,11 +2055,6 @@ void HlslParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fn
case EOpInterpolateAtCentroid:
case EOpInterpolateAtSample:
case EOpInterpolateAtOffset:
// "For the interpolateAt* functions, the call will return a precision
// qualification matching the precision of the 'interpolant' argument to
// the function call."
callNode.getQualifier().precision = arg0->getQualifier().precision;
// Make sure the first argument is an interpolant, or an array element of an interpolant
if (arg0->getType().getQualifier().storage != EvqVaryingIn) {
// It might still be an array element.
@ -2580,10 +2570,6 @@ void HlslParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, c
else if (src.storage != EvqTemporary && src.storage != EvqGlobal)
error(loc, "too many storage qualifiers", GetStorageQualifierString(src.storage), "");
// Precision qualifiers
if (dst.precision == EpqNone || (force && src.precision != EpqNone))
dst.precision = src.precision;
// Layout qualifiers
mergeObjectLayoutQualifiers(dst, src, false);