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:
@@ -2981,7 +2981,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
||||
// receive the result, and must later swizzle that into the original
|
||||
// l-value.
|
||||
complexLvalues.push_back(builder.getAccessChain());
|
||||
temporaryLvalues.push_back(builder.createVariable(spv::StorageClassFunction,
|
||||
temporaryLvalues.push_back(builder.createVariable(
|
||||
spv::NoPrecision, spv::StorageClassFunction,
|
||||
builder.accessChainGetInferredType(), "swizzleTemp"));
|
||||
operands.push_back(temporaryLvalues.back());
|
||||
} else {
|
||||
@@ -3084,7 +3085,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
||||
|
||||
for (unsigned int i = 0; i < temporaryLvalues.size(); ++i) {
|
||||
builder.setAccessChain(complexLvalues[i]);
|
||||
builder.accessChainStore(builder.createLoad(temporaryLvalues[i]));
|
||||
builder.accessChainStore(builder.createLoad(temporaryLvalues[i], spv::NoPrecision));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3201,7 +3202,8 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
||||
} else {
|
||||
// We need control flow to select the result.
|
||||
// TODO: Once SPIR-V OpSelect allows arbitrary types, eliminate this path.
|
||||
result = builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(node->getType()));
|
||||
result = builder.createVariable(TranslatePrecisionDecoration(node->getType()),
|
||||
spv::StorageClassFunction, convertGlslangToSpvType(node->getType()));
|
||||
|
||||
// Selection control:
|
||||
const spv::SelectionControlMask control = TranslateSelectionControl(*node);
|
||||
@@ -3226,8 +3228,10 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
||||
// Execute the one side needed, as per the condition
|
||||
const auto executeOneSide = [&]() {
|
||||
// Always emit control flow.
|
||||
if (node->getBasicType() != glslang::EbtVoid)
|
||||
result = builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(node->getType()));
|
||||
if (node->getBasicType() != glslang::EbtVoid) {
|
||||
result = builder.createVariable(TranslatePrecisionDecoration(node->getType()), spv::StorageClassFunction,
|
||||
convertGlslangToSpvType(node->getType()));
|
||||
}
|
||||
|
||||
// Selection control:
|
||||
const spv::SelectionControlMask control = TranslateSelectionControl(*node);
|
||||
@@ -3424,15 +3428,17 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
|
||||
builder.createLoopContinue();
|
||||
break;
|
||||
case glslang::EOpReturn:
|
||||
if (node->getExpression()) {
|
||||
if (node->getExpression() != nullptr) {
|
||||
const glslang::TType& glslangReturnType = node->getExpression()->getType();
|
||||
spv::Id returnId = accessChainLoad(glslangReturnType);
|
||||
if (builder.getTypeId(returnId) != currentFunction->getReturnType()) {
|
||||
if (builder.getTypeId(returnId) != currentFunction->getReturnType() ||
|
||||
TranslatePrecisionDecoration(glslangReturnType) != currentFunction->getReturnPrecision()) {
|
||||
builder.clearAccessChain();
|
||||
spv::Id copyId = builder.createVariable(spv::StorageClassFunction, currentFunction->getReturnType());
|
||||
spv::Id copyId = builder.createVariable(currentFunction->getReturnPrecision(),
|
||||
spv::StorageClassFunction, currentFunction->getReturnType());
|
||||
builder.setAccessChainLValue(copyId);
|
||||
multiTypeStore(glslangReturnType, returnId);
|
||||
returnId = builder.createLoad(copyId);
|
||||
returnId = builder.createLoad(copyId, currentFunction->getReturnPrecision());
|
||||
}
|
||||
builder.makeReturn(false, returnId);
|
||||
} else
|
||||
@@ -3539,7 +3545,7 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
|
||||
false /* specConst */);
|
||||
}
|
||||
|
||||
return builder.createVariable(storageClass, spvType, name, initializer);
|
||||
return builder.createVariable(spv::NoPrecision, storageClass, spvType, name, initializer);
|
||||
}
|
||||
|
||||
// Return type Id of the sampled type.
|
||||
@@ -5334,10 +5340,8 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
|
||||
++lValueCount;
|
||||
} else if (writableParam(qualifiers[a])) {
|
||||
// need space to hold the copy
|
||||
arg = builder.createVariable(spv::StorageClassFunction,
|
||||
arg = builder.createVariable(function->getParamPrecision(a), spv::StorageClassFunction,
|
||||
builder.getContainedTypeId(function->getParamType(a)), "param");
|
||||
if (function->isReducedPrecisionParam(a))
|
||||
builder.setPrecision(arg, spv::DecorationRelaxedPrecision);
|
||||
if (qualifiers[a] == glslang::EvqIn || qualifiers[a] == glslang::EvqInOut) {
|
||||
// need to copy the input into output space
|
||||
builder.setAccessChain(lValues[lValueCount]);
|
||||
@@ -5348,21 +5352,15 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
|
||||
}
|
||||
++lValueCount;
|
||||
} else {
|
||||
const bool argIsRelaxedPrecision = TranslatePrecisionDecoration(*argTypes[a]) ==
|
||||
spv::DecorationRelaxedPrecision;
|
||||
// process r-value, which involves a copy for a type mismatch
|
||||
if (function->getParamType(a) != convertGlslangToSpvType(*argTypes[a]) ||
|
||||
argIsRelaxedPrecision != function->isReducedPrecisionParam(a))
|
||||
TranslatePrecisionDecoration(*argTypes[a]) != function->getParamPrecision(a))
|
||||
{
|
||||
spv::Id argCopy = builder.createVariable(spv::StorageClassFunction, function->getParamType(a), "arg");
|
||||
if (function->isReducedPrecisionParam(a))
|
||||
builder.setPrecision(argCopy, spv::DecorationRelaxedPrecision);
|
||||
spv::Id argCopy = builder.createVariable(function->getParamPrecision(a), spv::StorageClassFunction, function->getParamType(a), "arg");
|
||||
builder.clearAccessChain();
|
||||
builder.setAccessChainLValue(argCopy);
|
||||
multiTypeStore(*argTypes[a], rValues[rValueCount]);
|
||||
arg = builder.createLoad(argCopy);
|
||||
if (function->isReducedPrecisionParam(a))
|
||||
builder.setPrecision(arg, spv::DecorationRelaxedPrecision);
|
||||
arg = builder.createLoad(argCopy, function->getParamPrecision(a));
|
||||
} else
|
||||
arg = rValues[rValueCount];
|
||||
++rValueCount;
|
||||
@@ -5381,7 +5379,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
|
||||
++lValueCount;
|
||||
else if (writableParam(qualifiers[a])) {
|
||||
if (qualifiers[a] == glslang::EvqOut || qualifiers[a] == glslang::EvqInOut) {
|
||||
spv::Id copy = builder.createLoad(spvArgs[a]);
|
||||
spv::Id copy = builder.createLoad(spvArgs[a], spv::NoPrecision);
|
||||
builder.setAccessChain(lValues[lValueCount]);
|
||||
multiTypeStore(*argTypes[a], copy);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user