Commit 90dd70f7 by John Kessenich

HLSL: Allow arbitrary baseType -> baseType conversion of calling arguments.

This also puts a stake in the ground as to which is better when selection from multiple signatures.
parent 4c3a7fd1
// function selection under type conversion // function selection under type conversion
void foo1(double a, bool b) {}
void foo1(double a, uint b) {} void foo1(double a, uint b) {}
void foo1(double a, int b) {} void foo1(double a, int b) {}
void foo1(double a, float b) {} void foo1(double a, float b) {}
void foo1(double a, double b){} void foo1(double a, double b){}
// uint -> int
void foo2(int a, bool b) {}
void foo2(int a, uint b) {}
void foo2(int a, int b) {}
void foo2(int a, float b) {}
void foo2(int a, double b){}
// everything can promote
void foo3(bool b) {}
void foo4(uint b) {}
void foo5(int b) {}
void foo6(float b) {}
void foo7(double b){}
// shorter forward chain better than longer or backward chain
void foo8(float);
void foo8(double);
void foo9(int);
void foo9(uint);
void foo10(bool);
void foo10(int);
float4 PixelShaderFunction(float4 input) : COLOR0 float4 PixelShaderFunction(float4 input) : COLOR0
{ {
bool b;
double d; double d;
uint u; uint u;
int i; int i;
float f; float f;
foo1(d, b);
foo1(d, d); foo1(d, d);
foo1(d, u); foo1(d, u);
foo1(d, i); foo1(d, i);
foo1(d, f); foo1(d, f);
foo1(f, b);
foo1(f, d); foo1(f, d);
foo1(f, u); foo1(f, u);
foo1(f, i); foo1(f, i);
foo1(f, f); foo1(f, f);
foo1(u, b);
foo1(u, d); foo1(u, d);
foo1(u, u); foo1(u, u);
foo1(u, i); foo1(u, i);
foo1(u, f); foo1(u, f);
foo1(i, b);
foo1(i, d); foo1(i, d);
foo1(i, u); foo1(i, u);
foo1(i, i); foo1(i, i);
foo1(i, f); foo1(i, f);
foo2(u, b);
foo2(u, d);
foo2(u, u);
foo2(u, i);
foo2(u, f);
foo2(i, b);
foo2(i, d);
foo2(i, u);
foo2(i, i);
foo2(i, f);
foo3(b);
foo3(d);
foo3(u);
foo3(i);
foo3(f);
foo4(b);
foo4(d);
foo4(u);
foo4(i);
foo4(f);
foo5(b);
foo5(d);
foo5(u);
foo5(i);
foo5(f);
foo6(b);
foo6(d);
foo6(u);
foo6(i);
foo6(f);
foo7(b);
foo7(d);
foo7(u);
foo7(i);
foo7(f);
foo8(b);
foo8(u);
foo8(i);
foo9(b);
foo9(f);
foo9(d);
foo10(u);
foo10(f);
foo10(d);
return input; return input;
} }
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
// For the version, it uses the latest git tag followed by the number of commits. // For the version, it uses the latest git tag followed by the number of commits.
// 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.1434"
#define GLSLANG_DATE "24-Aug-2016" #define GLSLANG_DATE "25-Aug-2016"
...@@ -750,6 +750,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat ...@@ -750,6 +750,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
case EOpDivAssign: // ... case EOpDivAssign: // ...
case EOpModAssign: // ... case EOpModAssign: // ...
case EOpReturn: // function returns can also perform arbitrary conversions case EOpReturn: // function returns can also perform arbitrary conversions
case EOpFunctionCall: // conversion of a calling parameter
return true; return true;
default: default:
break; break;
......
...@@ -3567,27 +3567,46 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu ...@@ -3567,27 +3567,46 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu
return true; return true;
if (from.isArray() || to.isArray() || ! from.sameElementShape(to)) if (from.isArray() || to.isArray() || ! from.sameElementShape(to))
return false; return false;
return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType()); return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType(), EOpFunctionCall);
}; };
// Is 'to2' a better conversion than 'to1'? // Is 'to2' a better conversion than 'to1'?
// Ties should not be considered as better. // Ties should not be considered as better.
// Assumes 'convertible' already said true. // Assumes 'convertible' already said true.
auto better = [](const TType& from, const TType& to1, const TType& to2) { auto better = [](const TType& from, const TType& to1, const TType& to2) {
// 1. exact match // exact match is always better than mismatch
if (from == to2) if (from == to2)
return from != to1; return from != to1;
if (from == to1) if (from == to1)
return false; return false;
// 2. float -> double is better // float -> double is better than any other float conversion
if (from.getBasicType() == EbtFloat) { if (from.getBasicType() == EbtFloat) {
if (to2.getBasicType() == EbtDouble && to1.getBasicType() != EbtDouble) if (to2.getBasicType() == EbtDouble && to1.getBasicType() != EbtDouble)
return true; return true;
} }
// 3. -> float is better than -> double // int -> uint is better than any other int conversion
return to2.getBasicType() == EbtFloat && to1.getBasicType() == EbtDouble; if (from.getBasicType() == EbtInt) {
if (to2.getBasicType() == EbtUint && to1.getBasicType() != EbtUint)
return true;
}
// TODO: these should be replaced by a more generic "shorter chain is better than longer chain" rule
// -> float is better than -> double
if (to2.getBasicType() == EbtFloat && to1.getBasicType() == EbtDouble)
return true;
// -> int is better than -> bool
if ((to2.getBasicType() == EbtInt || to2.getBasicType() == EbtUint) && to1.getBasicType() == EbtBool)
return true;
// -> uint is better than -> int
if (to2.getBasicType() == EbtUint && to1.getBasicType() == EbtInt)
return true;
return false;
}; };
// for ambiguity reporting // for ambiguity reporting
......
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