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);
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index 237496e..1594da3 100755
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -192,7 +192,7 @@
// See makeStructResultType() for non-decorated structs
// needed as the result of some instructions, which does
// check for duplicates.
-Id Builder::makeStructType(std::vector<Id>& members, const char* name)
+Id Builder::makeStructType(const std::vector<Id>& members, const char* name)
{
// Don't look for previous one, because in the general case,
// structs can be duplicated except for decorations.
@@ -321,7 +321,7 @@
return type->getResultId();
}
-Id Builder::makeFunctionType(Id returnType, std::vector<Id>& paramTypes)
+Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes)
{
// try to find it
Instruction* type;
@@ -805,19 +805,28 @@
Block* entry;
std::vector<Id> params;
+ std::vector<Decoration> precisions;
- mainFunction = makeFunctionEntry(makeVoidType(), "main", params, &entry);
+ mainFunction = makeFunctionEntry(NoPrecision, makeVoidType(), "main", params, precisions, &entry);
return mainFunction;
}
// Comments in header
-Function* Builder::makeFunctionEntry(Id returnType, const char* name, std::vector<Id>& paramTypes, Block **entry)
+Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name,
+ const std::vector<Id>& paramTypes, const std::vector<Decoration>& precisions, Block **entry)
{
+ // Make the function and initial instructions in it
Id typeId = makeFunctionType(returnType, paramTypes);
Id firstParamId = paramTypes.size() == 0 ? 0 : getUniqueIds((int)paramTypes.size());
Function* function = new Function(getUniqueId(), returnType, typeId, firstParamId, module);
+ // Set up the precisions
+ setPrecision(function->getId(), precision);
+ for (unsigned p = 0; p < (unsigned)precisions.size(); ++p)
+ setPrecision(firstParamId + p, precisions[p]);
+
+ // CFG
if (entry) {
*entry = new Block(getUniqueId(), *function);
function->addBlock(*entry);
@@ -1117,10 +1126,10 @@
}
// Comments in header
-Id Builder::createRvalueSwizzle(Id typeId, Id source, std::vector<unsigned>& channels)
+Id Builder::createRvalueSwizzle(Decoration precision, Id typeId, Id source, std::vector<unsigned>& channels)
{
if (channels.size() == 1)
- return createCompositeExtract(source, typeId, channels.front());
+ return setPrecision(createCompositeExtract(source, typeId, channels.front()), precision);
Instruction* swizzle = new Instruction(getUniqueId(), typeId, OpVectorShuffle);
assert(isVector(source));
@@ -1130,7 +1139,7 @@
swizzle->addImmediateOperand(channels[i]);
buildPoint->addInstruction(std::unique_ptr<Instruction>(swizzle));
- return swizzle->getResultId();
+ return setPrecision(swizzle->getResultId(), precision);
}
// Comments in header
@@ -1178,7 +1187,7 @@
}
// Comments in header
-Id Builder::smearScalar(Decoration /*precision*/, Id scalar, Id vectorType)
+Id Builder::smearScalar(Decoration precision, Id scalar, Id vectorType)
{
assert(getNumComponents(scalar) == 1);
assert(getTypeId(scalar) == getScalarTypeId(vectorType));
@@ -1192,11 +1201,11 @@
smear->addIdOperand(scalar);
buildPoint->addInstruction(std::unique_ptr<Instruction>(smear));
- return smear->getResultId();
+ return setPrecision(smear->getResultId(), precision);
}
// Comments in header
-Id Builder::createBuiltinCall(Decoration /*precision*/, Id resultType, Id builtins, int entryPoint, std::vector<Id>& args)
+Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, std::vector<Id>& args)
{
Instruction* inst = new Instruction(getUniqueId(), resultType, OpExtInst);
inst->addIdOperand(builtins);
@@ -1205,6 +1214,7 @@
inst->addIdOperand(args[arg]);
buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
+
return inst->getResultId();
}
@@ -1386,6 +1396,7 @@
// Decode the return type that was a special structure
createStore(createCompositeExtract(resultId, typeId1, 1), parameters.texelOut);
resultId = createCompositeExtract(resultId, typeId0, 0);
+ setPrecision(resultId, precision);
} else {
// When a smear is needed, do it, as per what was computed
// above when resultType was changed to a scalar type.
@@ -1492,7 +1503,6 @@
if (isScalarType(valueType)) {
// scalar
resultId = createBinOp(op, boolType, value1, value2);
- setPrecision(resultId, precision);
} else {
// vector
resultId = createBinOp(op, makeVectorType(boolType, numConstituents), value1, value2);
@@ -1501,7 +1511,7 @@
resultId = createUnaryOp(equal ? OpAll : OpAny, boolType, resultId);
}
- return resultId;
+ return setPrecision(resultId, precision);
}
// Only structs, arrays, and matrices should be left.
@@ -1521,7 +1531,7 @@
if (constituent == 0)
resultId = subResultId;
else
- resultId = createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId);
+ resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId), precision);
}
return resultId;
@@ -1543,7 +1553,7 @@
// Vector or scalar constructor
Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sources, Id resultTypeId)
{
- Id result = 0;
+ Id result = NoResult;
unsigned int numTargetComponents = getNumTypeComponents(resultTypeId);
unsigned int targetComponent = 0;
@@ -1566,7 +1576,7 @@
if (sourceSize > 1) {
std::vector<unsigned> swiz;
swiz.push_back(s);
- arg = createRvalueSwizzle(scalarTypeId, arg, swiz);
+ arg = createRvalueSwizzle(precision, scalarTypeId, arg, swiz);
}
if (numTargetComponents > 1)
@@ -1583,9 +1593,7 @@
if (constituents.size() > 0)
result = createCompositeConstruct(resultTypeId, constituents);
- setPrecision(result, precision);
-
- return result;
+ return setPrecision(result, precision);
}
// Comments in header
@@ -1666,11 +1674,13 @@
std::vector<Id> vectorComponents;
for (int row = 0; row < numRows; ++row)
vectorComponents.push_back(ids[col][row]);
- matrixColumns.push_back(createCompositeConstruct(columnTypeId, vectorComponents));
+ Id column = createCompositeConstruct(columnTypeId, vectorComponents);
+ setPrecision(column, precision);
+ matrixColumns.push_back(column);
}
// make the matrix
- return createCompositeConstruct(resultTypeId, matrixColumns);
+ return setPrecision(createCompositeConstruct(resultTypeId, matrixColumns), precision);
}
// Comments in header
@@ -1895,7 +1905,7 @@
}
// Comments in header
-Id Builder::accessChainLoad(Id resultType)
+Id Builder::accessChainLoad(Decoration precision, Id resultType)
{
Id id;
@@ -1904,7 +1914,7 @@
transferAccessChainSwizzle(false);
if (accessChain.indexChain.size() > 0) {
Id swizzleBase = accessChain.preSwizzleBaseType != NoType ? accessChain.preSwizzleBaseType : resultType;
-
+
// if all the accesses are constants, we can use OpCompositeExtract
std::vector<unsigned> indexes;
bool constant = true;
@@ -1933,12 +1943,14 @@
// load through the access chain
id = createLoad(collapseAccessChain());
}
+ setPrecision(id, precision);
} else
- id = accessChain.base;
+ id = accessChain.base; // no precision, it was set when this was defined
} else {
transferAccessChainSwizzle(true);
// load through the access chain
id = createLoad(collapseAccessChain());
+ setPrecision(id, precision);
}
// Done, unless there are swizzles to do
@@ -1952,12 +1964,12 @@
Id swizzledType = getScalarTypeId(getTypeId(id));
if (accessChain.swizzle.size() > 1)
swizzledType = makeVectorType(swizzledType, (int)accessChain.swizzle.size());
- id = createRvalueSwizzle(swizzledType, id, accessChain.swizzle);
+ id = createRvalueSwizzle(precision, swizzledType, id, accessChain.swizzle);
}
// dynamic single-component selection
if (accessChain.component != NoResult)
- id = createVectorExtractDynamic(id, resultType, accessChain.component);
+ id = setPrecision(createVectorExtractDynamic(id, resultType, accessChain.component), precision);
return id;
}
diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h
index fbfbfad..00516c8 100755
--- a/SPIRV/SpvBuilder.h
+++ b/SPIRV/SpvBuilder.h
@@ -100,13 +100,13 @@
Id makeIntType(int width) { return makeIntegerType(width, true); }
Id makeUintType(int width) { return makeIntegerType(width, false); }
Id makeFloatType(int width);
- Id makeStructType(std::vector<Id>& members, const char*);
+ Id makeStructType(const std::vector<Id>& members, const char*);
Id makeStructResultType(Id type0, Id type1);
Id makeVectorType(Id component, int size);
Id makeMatrixType(Id component, int cols, int rows);
Id makeArrayType(Id element, unsigned size, int stride); // 0 means no stride decoration
Id makeRuntimeArray(Id element);
- Id makeFunctionType(Id returnType, std::vector<Id>& paramTypes);
+ Id makeFunctionType(Id returnType, const std::vector<Id>& paramTypes);
Id makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format);
Id makeSamplerType();
Id makeSampledImageType(Id imageType);
@@ -210,7 +210,8 @@
// Make a shader-style function, and create its entry block if entry is non-zero.
// Return the function, pass back the entry.
// The returned pointer is only valid for the lifetime of this builder.
- Function* makeFunctionEntry(Id returnType, const char* name, std::vector<Id>& paramTypes, Block **entry = 0);
+ Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, const std::vector<Id>& paramTypes,
+ const std::vector<Decoration>& precisions, Block **entry = 0);
// Create a return. An 'implicit' return is one not appearing in the source
// code. In the case of an implicit return, no post-return block is inserted.
@@ -225,7 +226,7 @@
// Create a global or function local or IO variable.
Id createVariable(StorageClass, Id type, const char* name = 0);
- // Create an imtermediate with an undefined value.
+ // Create an intermediate with an undefined value.
Id createUndefined(Id type);
// Store into an Id and return the l-value
@@ -262,7 +263,7 @@
// Take an rvalue (source) and a set of channels to extract from it to
// make a new rvalue, which is returned.
- Id createRvalueSwizzle(Id typeId, Id source, std::vector<unsigned>& channels);
+ Id createRvalueSwizzle(Decoration precision, Id typeId, Id source, std::vector<unsigned>& channels);
// Take a copy of an lvalue (target) and a source of components, and set the
// source components into the lvalue where the 'channels' say to put them.
@@ -270,13 +271,15 @@
// (No true lvalue or stores are used.)
Id createLvalueSwizzle(Id typeId, Id target, Id source, std::vector<unsigned>& channels);
- // If the value passed in is an instruction and the precision is not NoPrecision,
- // it gets tagged with the requested precision.
- void setPrecision(Id /* value */, Decoration precision)
+ // If both the id and precision are valid, the id
+ // gets tagged with the requested precision.
+ // The passed in id is always the returned id, to simplify use patterns.
+ Id setPrecision(Id id, Decoration precision)
{
- if (precision != NoPrecision) {
- ;// TODO
- }
+ if (precision != NoPrecision && id != NoResult)
+ addDecoration(id, precision);
+
+ return id;
}
// Can smear a scalar to a vector for the following forms:
@@ -299,7 +302,7 @@
Id smearScalar(Decoration precision, Id scalarVal, Id vectorType);
// Create a call to a built-in function.
- Id createBuiltinCall(Decoration precision, Id resultType, Id builtins, int entryPoint, std::vector<Id>& args);
+ Id createBuiltinCall(Id resultType, Id builtins, int entryPoint, std::vector<Id>& args);
// List of parameters used to create a texture operation
struct TextureParameters {
@@ -330,7 +333,7 @@
Id createBitFieldExtractCall(Decoration precision, Id, Id, Id, bool isSigned);
Id createBitFieldInsertCall(Decoration precision, Id, Id, Id, Id);
- // Reduction comparision for composites: For equal and not-equal resulting in a scalar.
+ // Reduction comparison for composites: For equal and not-equal resulting in a scalar.
Id createCompositeCompare(Decoration precision, Id, Id, bool /* true if for equal, false if for not-equal */);
// OpCompositeConstruct
@@ -498,7 +501,7 @@
void accessChainStore(Id rvalue);
// use accessChain and swizzle to load an r-value
- Id accessChainLoad(Id ResultType);
+ Id accessChainLoad(Decoration precision, Id ResultType);
// get the direct pointer for an l-value
Id accessChainGetLValue();