SPV: Partially address #2293: correct "const in" precision matching.
Track whether formal parameters declare reduced precision and match
that with arguments, and if they differ, make a copy to promote the
precision.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index b63d901..fb36212 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -5346,13 +5346,21 @@
}
++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])) {
+ if (function->getParamType(a) != convertGlslangToSpvType(*argTypes[a]) ||
+ argIsRelaxedPrecision != function->isReducedPrecisionParam(a))
+ {
spv::Id argCopy = builder.createVariable(spv::StorageClassFunction, function->getParamType(a), "arg");
+ if (function->isReducedPrecisionParam(a))
+ builder.setPrecision(argCopy, spv::DecorationRelaxedPrecision);
builder.clearAccessChain();
builder.setAccessChainLValue(argCopy);
multiTypeStore(*argTypes[a], rValues[rValueCount]);
arg = builder.createLoad(argCopy);
+ if (function->isReducedPrecisionParam(a))
+ builder.setPrecision(arg, spv::DecorationRelaxedPrecision);
} else
arg = rValues[rValueCount];
++rValueCount;
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index 62b7d0e..f884224 100644
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -1298,8 +1298,11 @@
// Set up the precisions
setPrecision(function->getId(), precision);
for (unsigned p = 0; p < (unsigned)decorations.size(); ++p) {
- for (int d = 0; d < (int)decorations[p].size(); ++d)
+ for (int d = 0; d < (int)decorations[p].size(); ++d) {
addDecoration(firstParamId + p, decorations[p][d]);
+ if (decorations[p][d] == DecorationRelaxedPrecision)
+ function->addReducedPrecisionParam(p);
+ }
}
// CFG
diff --git a/SPIRV/spvIR.h b/SPIRV/spvIR.h
index 6523035..6146518 100755
--- a/SPIRV/spvIR.h
+++ b/SPIRV/spvIR.h
@@ -55,6 +55,7 @@
#include <iostream>
#include <memory>
#include <vector>
+#include <set>
namespace spv {
@@ -355,6 +356,10 @@
void setImplicitThis() { implicitThis = true; }
bool hasImplicitThis() const { return implicitThis; }
+ void addReducedPrecisionParam(int p) { reducedPrecisionParams.insert(p); }
+ bool isReducedPrecisionParam(int p) const
+ { return reducedPrecisionParams.find(p) != reducedPrecisionParams.end(); }
+
void dump(std::vector<unsigned int>& out) const
{
// OpFunction
@@ -379,6 +384,7 @@
std::vector<Instruction*> parameterInstructions;
std::vector<Block*> blocks;
bool implicitThis; // true if this is a member function expecting to be passed a 'this' as the first argument
+ std::set<int> reducedPrecisionParams; // list of parameter indexes that need a relaxed precision arg
};
//