Commit fcc0aa3b by John Kessenich

HLSL: Switch to generic selector, but using GLSL #version 400 rules.

Next step is to modify for HLSL rules.
parent ab89bbe7
// function selection under type conversion
void foo1(double a, uint b) {}
void foo1(double a, int b) {}
void foo1(double a, float b) {}
void foo1(double a, double b){}
float4 PixelShaderFunction(float4 input) : COLOR0
{
double d;
uint u;
int i;
float f;
foo1(d, d);
foo1(d, u);
foo1(d, i);
foo1(d, f);
foo1(f, d);
foo1(f, u);
foo1(f, i);
foo1(f, f);
foo1(u, d);
foo1(u, u);
foo1(u, i);
foo1(u, f);
foo1(i, d);
foo1(i, u);
foo1(i, i);
foo1(i, f);
return input;
}
...@@ -3,4 +3,4 @@ ...@@ -3,4 +3,4 @@
// For the date, it uses the current date (when then script is run). // For the date, it uses the current date (when then script is run).
#define GLSLANG_REVISION "Overload400-PrecQual.1433" #define GLSLANG_REVISION "Overload400-PrecQual.1433"
#define GLSLANG_DATE "23-Aug-2016" #define GLSLANG_DATE "24-Aug-2016"
...@@ -121,6 +121,7 @@ INSTANTIATE_TEST_CASE_P( ...@@ -121,6 +121,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.load.offset.dx10.frag", "main"}, {"hlsl.load.offset.dx10.frag", "main"},
{"hlsl.load.offsetarray.dx10.frag", "main"}, {"hlsl.load.offsetarray.dx10.frag", "main"},
{"hlsl.numericsuffixes.frag", "main"}, {"hlsl.numericsuffixes.frag", "main"},
{"hlsl.overload.frag", "PixelShaderFunction"},
{"hlsl.pp.line.frag", "main"}, {"hlsl.pp.line.frag", "main"},
{"hlsl.promotions.frag", "main"}, {"hlsl.promotions.frag", "main"},
{"hlsl.sample.array.dx10.frag", "main"}, {"hlsl.sample.array.dx10.frag", "main"},
......
...@@ -3535,6 +3535,10 @@ void HlslParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQuali ...@@ -3535,6 +3535,10 @@ void HlslParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQuali
// //
// Look up a function name in the symbol table, and make sure it is a function. // Look up a function name in the symbol table, and make sure it is a function.
// //
// First, look for an exact match. If there is none, use the generic selector
// TParseContextBase::selectFunction() to find one, parameterized by the
// convertible() and better() predicates defined below.
//
// Return the function symbol if found, otherwise nullptr. // Return the function symbol if found, otherwise nullptr.
// //
const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn) const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
...@@ -3551,57 +3555,53 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu ...@@ -3551,57 +3555,53 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu
if (symbol) if (symbol)
return symbol->getAsFunction(); return symbol->getAsFunction();
// exact match not found, look through a list of overloaded functions of the same name // no exact match, use the generic selector, parameterized by the GLSL rules
const TFunction* candidate = nullptr; // create list of candidates to send
TVector<const TFunction*> candidateList; TVector<const TFunction*> candidateList;
symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn); symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
for (auto it = candidateList.begin(); it != candidateList.end(); ++it) { // can 'from' convert to 'to'?
const TFunction& function = *(*it); auto convertible = [this](const TType& from, const TType& to) {
if (from == to)
return true;
if (from.isArray() || to.isArray() || ! from.sameElementShape(to))
return false;
return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType());
};
// Is 'to2' a better conversion than 'to1'?
// Ties should not be considered as better.
// Assumes 'convertible' already said true.
auto better = [](const TType& from, const TType& to1, const TType& to2) {
// 1. exact match
if (from == to2)
return from != to1;
if (from == to1)
return false;
// to even be a potential match, number of arguments has to match // 2. float -> double is better
if (call.getParamCount() != function.getParamCount()) if (from.getBasicType() == EbtFloat) {
continue; if (to2.getBasicType() == EbtDouble && to1.getBasicType() != EbtDouble)
return true;
}
bool possibleMatch = true; // 3. -> float is better than -> double
for (int i = 0; i < function.getParamCount(); ++i) { return to2.getBasicType() == EbtFloat && to1.getBasicType() == EbtDouble;
// same types is easy };
if (*function[i].type == *call[i].type)
continue;
// We have a mismatch in type, see if it is implicitly convertible // for ambiguity reporting
bool tie = false;
if (function[i].type->isArray() || call[i].type->isArray() || // send to the generic selector
! function[i].type->sameElementShape(*call[i].type)) const TFunction* bestMatch = selectFunction(candidateList, call, convertible, better, tie);
possibleMatch = false;
else {
// do direction-specific checks for conversion of basic type
if (function[i].type->getQualifier().isParamInput()) {
if (! intermediate.canImplicitlyPromote(call[i].type->getBasicType(), function[i].type->getBasicType()))
possibleMatch = false;
}
if (function[i].type->getQualifier().isParamOutput()) {
if (! intermediate.canImplicitlyPromote(function[i].type->getBasicType(), call[i].type->getBasicType()))
possibleMatch = false;
}
}
if (! possibleMatch)
break;
}
if (possibleMatch) {
if (candidate) {
// our second match, meaning ambiguity
error(loc, "ambiguous function signature match: multiple signatures match under implicit type conversion", call.getName().c_str(), "");
} else
candidate = &function;
}
}
if (candidate == nullptr) if (bestMatch == nullptr)
error(loc, "no matching overloaded function found", call.getName().c_str(), ""); error(loc, "no matching overloaded function found", call.getName().c_str(), "");
else if (tie)
error(loc, "ambiguous best function under implicit type conversion", call.getName().c_str(), "");
return candidate; return bestMatch;
} }
// //
......
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