SPV: RelaxedPrecision: Generalize fix #2293 to cover more operations.
This simplifies and enforces use of precision in many more places, to help avoid accidental loss of RelaxedPrecision through intermediate operations. Known fixes are: - ?: - function return values with mis-matched precision - precision of function return values when a copy was needed to fix types
This commit is contained in:
@@ -1297,11 +1297,11 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
|
||||
|
||||
// Set up the precisions
|
||||
setPrecision(function->getId(), precision);
|
||||
function->setReturnPrecision(precision);
|
||||
for (unsigned p = 0; p < (unsigned)decorations.size(); ++p) {
|
||||
for (int d = 0; d < (int)decorations[p].size(); ++d) {
|
||||
addDecoration(firstParamId + p, decorations[p][d]);
|
||||
if (decorations[p][d] == DecorationRelaxedPrecision)
|
||||
function->addReducedPrecisionParam(p);
|
||||
function->addParamPrecision(p, decorations[p][d]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1359,7 +1359,7 @@ void Builder::makeDiscard()
|
||||
}
|
||||
|
||||
// Comments in header
|
||||
Id Builder::createVariable(StorageClass storageClass, Id type, const char* name, Id initializer)
|
||||
Id Builder::createVariable(Decoration precision, StorageClass storageClass, Id type, const char* name, Id initializer)
|
||||
{
|
||||
Id pointerType = makePointer(storageClass, type);
|
||||
Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable);
|
||||
@@ -1381,6 +1381,7 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name,
|
||||
|
||||
if (name)
|
||||
addName(inst->getResultId(), name);
|
||||
setPrecision(inst->getResultId(), precision);
|
||||
|
||||
return inst->getResultId();
|
||||
}
|
||||
@@ -1437,7 +1438,8 @@ void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAcce
|
||||
}
|
||||
|
||||
// Comments in header
|
||||
Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
|
||||
Id Builder::createLoad(Id lValue, spv::Decoration precision, spv::MemoryAccessMask memoryAccess,
|
||||
spv::Scope scope, unsigned int alignment)
|
||||
{
|
||||
Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad);
|
||||
load->addIdOperand(lValue);
|
||||
@@ -1455,6 +1457,7 @@ Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope
|
||||
}
|
||||
|
||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(load));
|
||||
setPrecision(load->getResultId(), precision);
|
||||
|
||||
return load->getResultId();
|
||||
}
|
||||
@@ -2677,7 +2680,7 @@ void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, sp
|
||||
// If swizzle still exists, it is out-of-order or not full, we must load the target vector,
|
||||
// extract and insert elements to perform writeMask and/or swizzle.
|
||||
if (accessChain.swizzle.size() > 0) {
|
||||
Id tempBaseId = createLoad(base);
|
||||
Id tempBaseId = createLoad(base, spv::NoPrecision);
|
||||
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
|
||||
}
|
||||
|
||||
@@ -2716,17 +2719,17 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
|
||||
|
||||
if (constant) {
|
||||
id = createCompositeExtract(accessChain.base, swizzleBase, indexes);
|
||||
setPrecision(id, precision);
|
||||
} else {
|
||||
Id lValue = NoResult;
|
||||
if (spvVersion >= Spv_1_4) {
|
||||
// make a new function variable for this r-value, using an initializer,
|
||||
// and mark it as NonWritable so that downstream it can be detected as a lookup
|
||||
// table
|
||||
lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable",
|
||||
accessChain.base);
|
||||
lValue = createVariable(NoPrecision, StorageClassFunction, getTypeId(accessChain.base), "indexable", accessChain.base);
|
||||
addDecoration(lValue, DecorationNonWritable);
|
||||
} else {
|
||||
lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable");
|
||||
lValue = createVariable(NoPrecision, StorageClassFunction, getTypeId(accessChain.base), "indexable");
|
||||
// store into it
|
||||
createStore(accessChain.base, lValue);
|
||||
}
|
||||
@@ -2735,9 +2738,8 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
|
||||
accessChain.isRValue = false;
|
||||
|
||||
// load through the access chain
|
||||
id = createLoad(collapseAccessChain());
|
||||
id = createLoad(collapseAccessChain(), precision);
|
||||
}
|
||||
setPrecision(id, precision);
|
||||
} else
|
||||
id = accessChain.base; // no precision, it was set when this was defined
|
||||
} else {
|
||||
@@ -2756,8 +2758,7 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
|
||||
// loaded image types get decorated. TODO: This should maybe move to
|
||||
// createImageTextureFunctionCall.
|
||||
addDecoration(id, nonUniform);
|
||||
id = createLoad(id, memoryAccess, scope, alignment);
|
||||
setPrecision(id, precision);
|
||||
id = createLoad(id, precision, memoryAccess, scope, alignment);
|
||||
addDecoration(id, nonUniform);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user