Commit 4df10335 by John Kessenich

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.
parent fbb9dc2c
...@@ -5346,13 +5346,21 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg ...@@ -5346,13 +5346,21 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
} }
++lValueCount; ++lValueCount;
} else { } else {
const bool argIsRelaxedPrecision = TranslatePrecisionDecoration(*argTypes[a]) ==
spv::DecorationRelaxedPrecision;
// process r-value, which involves a copy for a type mismatch // 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"); spv::Id argCopy = builder.createVariable(spv::StorageClassFunction, function->getParamType(a), "arg");
if (function->isReducedPrecisionParam(a))
builder.setPrecision(argCopy, spv::DecorationRelaxedPrecision);
builder.clearAccessChain(); builder.clearAccessChain();
builder.setAccessChainLValue(argCopy); builder.setAccessChainLValue(argCopy);
multiTypeStore(*argTypes[a], rValues[rValueCount]); multiTypeStore(*argTypes[a], rValues[rValueCount]);
arg = builder.createLoad(argCopy); arg = builder.createLoad(argCopy);
if (function->isReducedPrecisionParam(a))
builder.setPrecision(arg, spv::DecorationRelaxedPrecision);
} else } else
arg = rValues[rValueCount]; arg = rValues[rValueCount];
++rValueCount; ++rValueCount;
......
...@@ -1298,8 +1298,11 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const ...@@ -1298,8 +1298,11 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
// Set up the precisions // Set up the precisions
setPrecision(function->getId(), precision); setPrecision(function->getId(), precision);
for (unsigned p = 0; p < (unsigned)decorations.size(); ++p) { 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]); addDecoration(firstParamId + p, decorations[p][d]);
if (decorations[p][d] == DecorationRelaxedPrecision)
function->addReducedPrecisionParam(p);
}
} }
// CFG // CFG
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#include <iostream> #include <iostream>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <set>
namespace spv { namespace spv {
...@@ -355,6 +356,10 @@ public: ...@@ -355,6 +356,10 @@ public:
void setImplicitThis() { implicitThis = true; } void setImplicitThis() { implicitThis = true; }
bool hasImplicitThis() const { return implicitThis; } 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 void dump(std::vector<unsigned int>& out) const
{ {
// OpFunction // OpFunction
...@@ -379,6 +384,7 @@ protected: ...@@ -379,6 +384,7 @@ protected:
std::vector<Instruction*> parameterInstructions; std::vector<Instruction*> parameterInstructions;
std::vector<Block*> blocks; std::vector<Block*> blocks;
bool implicitThis; // true if this is a member function expecting to be passed a 'this' as the first argument 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
}; };
// //
......
spv.precisionArgs.frag
// Module Version 10000
// Generated by (magic number): 8000a
// Id's are bound by 27
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginUpperLeft
Source ESSL 310
Name 4 "main"
Name 10 "fooConst(f1;f1;"
Name 8 "f"
Name 9 "g"
Name 13 "aM"
Name 15 "bM"
Name 17 "arg"
Name 20 "aH"
Name 22 "bH"
Name 24 "arg"
Decorate 8(f) RelaxedPrecision
Decorate 13(aM) RelaxedPrecision
Decorate 14 RelaxedPrecision
Decorate 15(bM) RelaxedPrecision
Decorate 16 RelaxedPrecision
Decorate 24(arg) RelaxedPrecision
Decorate 25 RelaxedPrecision
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeFunction 2 6(float) 6(float)
12: TypePointer Function 6(float)
4(main): 2 Function None 3
5: Label
13(aM): 12(ptr) Variable Function
15(bM): 12(ptr) Variable Function
17(arg): 12(ptr) Variable Function
20(aH): 12(ptr) Variable Function
22(bH): 12(ptr) Variable Function
24(arg): 12(ptr) Variable Function
14: 6(float) Load 13(aM)
16: 6(float) Load 15(bM)
Store 17(arg) 16
18: 6(float) Load 17(arg)
19: 2 FunctionCall 10(fooConst(f1;f1;) 14 18
21: 6(float) Load 20(aH)
23: 6(float) Load 22(bH)
Store 24(arg) 21
25: 6(float) Load 24(arg)
26: 2 FunctionCall 10(fooConst(f1;f1;) 25 23
Return
FunctionEnd
10(fooConst(f1;f1;): 2 Function None 7
8(f): 6(float) FunctionParameter
9(g): 6(float) FunctionParameter
11: Label
Return
FunctionEnd
#version 310 es
precision mediump float;
void fooConst(const in float f, const in highp float g)
{
}
void main()
{
float aM, bM;
highp float aH, bH;
fooConst(aM, bM); // must copy bM
fooConst(aH, bH); // must copy aH
}
...@@ -375,6 +375,7 @@ INSTANTIATE_TEST_CASE_P( ...@@ -375,6 +375,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.Operations.frag", "spv.Operations.frag",
"spv.paramMemory.frag", "spv.paramMemory.frag",
"spv.precision.frag", "spv.precision.frag",
"spv.precisionArgs.frag",
"spv.precisionNonESSamp.frag", "spv.precisionNonESSamp.frag",
"spv.prepost.frag", "spv.prepost.frag",
"spv.privateVariableTypes.frag", "spv.privateVariableTypes.frag",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment