SPV: RelaxedPrecision: Plumb this through the full AST->SPV translator.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index a75c7ca..94e37e8 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -93,6 +93,7 @@
spv::Id getSampledType(const glslang::TSampler&);
spv::Id convertGlslangToSpvType(const glslang::TType& type);
spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&);
+ spv::Id accessChainLoad(const glslang::TType& type);
glslang::TLayoutPacking getExplicitLayout(const glslang::TType& type) const;
int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
int getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
@@ -234,7 +235,6 @@
switch (type.getQualifier().precision) {
case glslang::EpqLow: return spv::DecorationRelaxedPrecision;
case glslang::EpqMedium: return spv::DecorationRelaxedPrecision;
- case glslang::EpqHigh: return spv::NoPrecision;
default:
return spv::NoPrecision;
}
@@ -709,12 +709,12 @@
// evaluate the right
builder.clearAccessChain();
node->getRight()->traverse(this);
- spv::Id rValue = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType()));
+ spv::Id rValue = accessChainLoad(node->getRight()->getType());
if (node->getOp() != glslang::EOpAssign) {
// the left is also an r-value
builder.setAccessChain(lValue);
- spv::Id leftRValue = builder.accessChainLoad(convertGlslangToSpvType(node->getLeft()->getType()));
+ spv::Id leftRValue = accessChainLoad(node->getLeft()->getType());
// do the operation
rValue = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getType()),
@@ -782,7 +782,7 @@
// compute the next index in the chain
builder.clearAccessChain();
node->getRight()->traverse(this);
- spv::Id index = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType()));
+ spv::Id index = accessChainLoad(node->getRight()->getType());
// restore the saved access chain
builder.setAccessChain(partial);
@@ -824,21 +824,20 @@
// Assume generic binary op...
- // Get the operands
+ // get right operand
builder.clearAccessChain();
node->getLeft()->traverse(this);
- spv::Id left = builder.accessChainLoad(convertGlslangToSpvType(node->getLeft()->getType()));
+ spv::Id left = accessChainLoad(node->getLeft()->getType());
+ // get left operand
builder.clearAccessChain();
node->getRight()->traverse(this);
- spv::Id right = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType()));
+ spv::Id right = accessChainLoad(node->getRight()->getType());
- spv::Id result;
- spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
-
- result = createBinaryOperation(node->getOp(), precision,
- convertGlslangToSpvType(node->getType()), left, right,
- node->getLeft()->getType().getBasicType());
+ // get result
+ spv::Id result = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getType()),
+ convertGlslangToSpvType(node->getType()), left, right,
+ node->getLeft()->getType().getBasicType());
builder.clearAccessChain();
if (! result) {
@@ -896,7 +895,7 @@
node->getOp() == glslang::EOpInterpolateAtCentroid)
operand = builder.accessChainGetLValue(); // Special case l-value operands
else
- operand = builder.accessChainLoad(convertGlslangToSpvType(node->getOperand()->getType()));
+ operand = accessChainLoad(node->getOperand()->getType());
spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
@@ -1208,11 +1207,11 @@
builder.clearAccessChain();
left->traverse(this);
- spv::Id leftId = builder.accessChainLoad(convertGlslangToSpvType(left->getType()));
+ spv::Id leftId = accessChainLoad(left->getType());
builder.clearAccessChain();
right->traverse(this);
- spv::Id rightId = builder.accessChainLoad(convertGlslangToSpvType(right->getType()));
+ spv::Id rightId = accessChainLoad(right->getType());
result = createBinaryOperation(binOp, precision,
convertGlslangToSpvType(node->getType()), leftId, rightId,
@@ -1275,7 +1274,7 @@
if (lvalue)
operands.push_back(builder.accessChainGetLValue());
else
- operands.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangOperands[arg]->getAsTyped()->getType())));
+ operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
}
if (atomic) {
@@ -1325,13 +1324,13 @@
node->getCondition()->traverse(this);
// make an "if" based on the value created by the condition
- spv::Builder::If ifBuilder(builder.accessChainLoad(convertGlslangToSpvType(node->getCondition()->getType())), builder);
+ spv::Builder::If ifBuilder(accessChainLoad(node->getCondition()->getType()), builder);
if (node->getTrueBlock()) {
// emit the "then" statement
node->getTrueBlock()->traverse(this);
if (result)
- builder.createStore(builder.accessChainLoad(convertGlslangToSpvType(node->getTrueBlock()->getAsTyped()->getType())), result);
+ builder.createStore(accessChainLoad(node->getTrueBlock()->getAsTyped()->getType()), result);
}
if (node->getFalseBlock()) {
@@ -1339,7 +1338,7 @@
// emit the "else" statement
node->getFalseBlock()->traverse(this);
if (result)
- builder.createStore(builder.accessChainLoad(convertGlslangToSpvType(node->getFalseBlock()->getAsTyped()->getType())), result);
+ builder.createStore(accessChainLoad(node->getFalseBlock()->getAsTyped()->getType()), result);
}
ifBuilder.makeEndIf();
@@ -1360,7 +1359,7 @@
{
// emit and get the condition before doing anything with switch
node->getCondition()->traverse(this);
- spv::Id selector = builder.accessChainLoad(convertGlslangToSpvType(node->getCondition()->getAsTyped()->getType()));
+ spv::Id selector = accessChainLoad(node->getCondition()->getAsTyped()->getType());
// browse the children to sort out code segments
int defaultSegment = -1;
@@ -1433,7 +1432,7 @@
builder.setBuildPoint(&test);
node->getTest()->traverse(this);
spv::Id condition =
- builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType()));
+ accessChainLoad(node->getTest()->getType());
builder.createConditionalBranch(condition, &blocks.body, &blocks.merge);
builder.setBuildPoint(&blocks.body);
@@ -1463,7 +1462,7 @@
if (node->getTest()) {
node->getTest()->traverse(this);
spv::Id condition =
- builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType()));
+ accessChainLoad(node->getTest()->getType());
builder.createConditionalBranch(condition, &blocks.head, &blocks.merge);
} else {
// TODO: unless there was a break/return/discard instruction
@@ -1497,7 +1496,7 @@
break;
case glslang::EOpReturn:
if (node->getExpression())
- builder.makeReturn(false, builder.accessChainLoad(convertGlslangToSpvType(node->getExpression()->getType())));
+ builder.makeReturn(false, accessChainLoad(node->getExpression()->getType()));
else
builder.makeReturn(false);
@@ -1765,6 +1764,11 @@
return spvType;
}
+spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
+{
+ return builder.accessChainLoad(TranslatePrecisionDecoration(type), convertGlslangToSpvType(type));
+}
+
// Decide whether or not this type should be
// decorated with offsets and strides, and if so
// whether std140 or std430 rules should be applied.
@@ -1885,6 +1889,7 @@
// copy-in/copy-out semantics. They can be handled though with a pointer to a copy.
std::vector<spv::Id> paramTypes;
+ std::vector<spv::Decoration> paramPrecisions;
glslang::TIntermSequence& parameters = glslFunction->getSequence()[0]->getAsAggregate()->getSequence();
for (int p = 0; p < (int)parameters.size(); ++p) {
@@ -1894,12 +1899,14 @@
typeId = builder.makePointer(spv::StorageClassFunction, typeId);
else
constReadOnlyParameters.insert(parameters[p]->getAsSymbolNode()->getId());
+ paramPrecisions.push_back(TranslatePrecisionDecoration(paramType));
paramTypes.push_back(typeId);
}
spv::Block* functionBlock;
- spv::Function *function = builder.makeFunctionEntry(convertGlslangToSpvType(glslFunction->getType()), glslFunction->getName().c_str(),
- paramTypes, &functionBlock);
+ spv::Function *function = builder.makeFunctionEntry(TranslatePrecisionDecoration(glslFunction->getType()),
+ convertGlslangToSpvType(glslFunction->getType()),
+ glslFunction->getName().c_str(), paramTypes, paramPrecisions, &functionBlock);
// Track function to emit/call later
functionMap[glslFunction->getName().c_str()] = function;
@@ -2028,7 +2035,7 @@
if (lvalue)
arguments.push_back(builder.accessChainGetLValue());
else
- arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangArguments[i]->getAsTyped()->getType())));
+ arguments.push_back(accessChainLoad(glslangArguments[i]->getAsTyped()->getType()));
}
}
@@ -2036,7 +2043,7 @@
{
builder.clearAccessChain();
node.getOperand()->traverse(this);
- arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(node.getOperand()->getType())));
+ arguments.push_back(accessChainLoad(node.getOperand()->getType()));
}
spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermOperator* node)
@@ -2241,19 +2248,19 @@
// 1. Evaluate the arguments
std::vector<spv::Builder::AccessChain> lValues;
std::vector<spv::Id> rValues;
- std::vector<spv::Id> argTypes;
+ std::vector<const glslang::TType*> argTypes;
for (int a = 0; a < (int)glslangArgs.size(); ++a) {
// build l-value
builder.clearAccessChain();
glslangArgs[a]->traverse(this);
- argTypes.push_back(convertGlslangToSpvType(glslangArgs[a]->getAsTyped()->getType()));
+ argTypes.push_back(&glslangArgs[a]->getAsTyped()->getType());
// keep outputs as l-values, evaluate input-only as r-values
if (qualifiers[a] != glslang::EvqConstReadOnly) {
// save l-value
lValues.push_back(builder.getAccessChain());
} else {
// process r-value
- rValues.push_back(builder.accessChainLoad(argTypes.back()));
+ rValues.push_back(accessChainLoad(*argTypes.back()));
}
}
@@ -2273,7 +2280,7 @@
if (qualifiers[a] == glslang::EvqIn || qualifiers[a] == glslang::EvqInOut) {
// need to copy the input into output space
builder.setAccessChain(lValues[lValueCount]);
- spv::Id copy = builder.accessChainLoad(argTypes[a]);
+ spv::Id copy = accessChainLoad(*argTypes[a]);
builder.createStore(copy, arg);
}
++lValueCount;
@@ -2286,6 +2293,7 @@
// 3. Make the call.
spv::Id result = builder.createFunctionCall(function, spvArgs);
+ builder.setPrecision(result, TranslatePrecisionDecoration(node->getType()));
// 4. Copy back out an "out" arguments.
lValueCount = 0;
@@ -2446,10 +2454,7 @@
if (needMatchingVectors)
builder.promoteScalar(precision, left, right);
- spv::Id id = builder.createBinOp(binOp, typeId, left, right);
- builder.setPrecision(id, precision);
-
- return id;
+ return builder.setPrecision(builder.createBinOp(binOp, typeId, left, right), precision);
}
if (! comparison)
@@ -2514,12 +2519,8 @@
break;
}
- if (binOp != spv::OpNop) {
- spv::Id id = builder.createBinOp(binOp, typeId, left, right);
- builder.setPrecision(id, precision);
-
- return id;
- }
+ if (binOp != spv::OpNop)
+ return builder.setPrecision(builder.createBinOp(binOp, typeId, left, right), precision);
return 0;
}
@@ -2574,12 +2575,8 @@
break;
}
- if (firstClass) {
- spv::Id id = builder.createBinOp(op, typeId, left, right);
- builder.setPrecision(id, precision);
-
- return id;
- }
+ if (firstClass)
+ return builder.setPrecision(builder.createBinOp(op, typeId, left, right), precision);
// Handle component-wise +, -, *, and / for all combinations of type.
// The result type of all of them is the same type as the (a) matrix operand.
@@ -2619,9 +2616,7 @@
}
// put the pieces together
- spv::Id id = builder.createCompositeConstruct(typeId, results);
- builder.setPrecision(id, precision);
- return id;
+ return builder.setPrecision(builder.createCompositeConstruct(typeId, results), precision);
}
default:
assert(0);
@@ -2899,13 +2894,11 @@
if (libCall >= 0) {
std::vector<spv::Id> args;
args.push_back(operand);
- id = builder.createBuiltinCall(precision, typeId, stdBuiltins, libCall, args);
+ id = builder.createBuiltinCall(typeId, stdBuiltins, libCall, args);
} else
id = builder.createUnaryOp(unaryOp, typeId, operand);
- builder.setPrecision(id, precision);
-
- return id;
+ return builder.setPrecision(id, precision);
}
// Create a unary operation on a matrix
@@ -2935,10 +2928,7 @@
}
// put the pieces together
- spv::Id id = builder.createCompositeConstruct(typeId, results);
- builder.setPrecision(id, precision);
-
- return id;
+ return builder.setPrecision(builder.createCompositeConstruct(typeId, results), precision);
}
spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, spv::Decoration precision, spv::Id destType, spv::Id operand)
@@ -3031,9 +3021,7 @@
} else
result = builder.createUnaryOp(convOp, destType, operand);
- builder.setPrecision(result, precision);
-
- return result;
+ return builder.setPrecision(result, precision);
}
spv::Id TGlslangToSpvTraverser::makeSmearedConstant(spv::Id constant, int vectorSize)
@@ -3277,7 +3265,7 @@
// Construct the call arguments, without modifying the original operands vector.
// We might need the remaining arguments, e.g. in the EOpFrexp case.
std::vector<spv::Id> callArguments(operands.begin(), operands.begin() + consumedOperands);
- id = builder.createBuiltinCall(precision, typeId, stdBuiltins, libCall, callArguments);
+ id = builder.createBuiltinCall(typeId, stdBuiltins, libCall, callArguments);
} else {
switch (consumedOperands) {
case 0:
@@ -3320,9 +3308,7 @@
break;
}
- builder.setPrecision(id, precision);
-
- return id;
+ return builder.setPrecision(id, precision);
}
// Intrinsics with no arguments, no return value, and no precision.
@@ -3644,7 +3630,7 @@
// emit left operand
builder.clearAccessChain();
left.traverse(this);
- spv::Id leftId = builder.accessChainLoad(boolTypeId);
+ spv::Id leftId = builder.accessChainLoad(spv::NoPrecision, boolTypeId);
// Operands to accumulate OpPhi operands
std::vector<spv::Id> phiOperands;
@@ -3667,7 +3653,7 @@
// emit right operand as the "then" part of the "if"
builder.clearAccessChain();
right.traverse(this);
- spv::Id rightId = builder.accessChainLoad(boolTypeId);
+ spv::Id rightId = builder.accessChainLoad(spv::NoPrecision, boolTypeId);
// accumulate left operand's phi information
phiOperands.push_back(rightId);