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

@@ -283,10 +283,10 @@ spv::Dim TranslateDimensionality(const glslang::TSampler& sampler)
}
}
// Translate glslang type to SPIR-V precision decorations.
spv::Decoration TranslatePrecisionDecoration(const glslang::TType& type)
// Translate glslang precision to SPIR-V precision decorations.
spv::Decoration TranslatePrecisionDecoration(glslang::TPrecisionQualifier glslangPrecision)
{
switch (type.getQualifier().precision) {
switch (glslangPrecision) {
case glslang::EpqLow: return spv::DecorationRelaxedPrecision;
case glslang::EpqMedium: return spv::DecorationRelaxedPrecision;
default:
@@ -294,6 +294,12 @@ spv::Decoration TranslatePrecisionDecoration(const glslang::TType& type)
}
}
// Translate glslang type to SPIR-V precision decorations.
spv::Decoration TranslatePrecisionDecoration(const glslang::TType& type)
{
return TranslatePrecisionDecoration(type.getQualifier().precision);
}
// Translate glslang type to SPIR-V block decorations.
spv::Decoration TranslateBlockDecoration(const glslang::TType& type)
{
@@ -940,7 +946,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
spv::Id leftRValue = accessChainLoad(node->getLeft()->getType());
// do the operation
rValue = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getType()),
rValue = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getOperationPrecision()),
TranslateNoContractionDecoration(node->getType().getQualifier()),
convertGlslangToSpvType(node->getType()), leftRValue, rValue,
node->getType().getBasicType());
@@ -1065,7 +1071,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
spv::Id right = accessChainLoad(node->getRight()->getType());
// get result
spv::Id result = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getType()),
spv::Id result = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getOperationPrecision()),
TranslateNoContractionDecoration(node->getType().getQualifier()),
convertGlslangToSpvType(node->getType()), left, right,
node->getLeft()->getType().getBasicType());
@@ -1142,7 +1148,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
else
operand = accessChainLoad(node->getOperand()->getType());
spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision());
spv::Decoration noContraction = TranslateNoContractionDecoration(node->getType().getQualifier());
// it could be a conversion
@@ -1187,7 +1193,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
else
op = glslang::EOpSub;
spv::Id result = createBinaryOperation(op, TranslatePrecisionDecoration(node->getType()),
spv::Id result = createBinaryOperation(op, precision,
TranslateNoContractionDecoration(node->getType().getQualifier()),
convertGlslangToSpvType(node->getType()), operand, one,
node->getType().getBasicType());
@@ -1249,7 +1255,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
assert(node->getOp());
spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision());
switch (node->getOp()) {
case glslang::EOpSequence:
@@ -2573,7 +2579,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
translateArguments(*node->getAsAggregate(), arguments);
else
translateArguments(*node->getAsUnaryNode(), arguments);
spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision());
spv::Builder::TextureParameters params = { };
params.sampler = arguments[0];