14a487fd54
The only type of expressions that getConstantSubexpression could ever return are Literal and nullptr. getConstantValue now returns an optional<double>; nullopt indicates a non-constant value in the slot. This simplifies most use cases, and allows us to get rid of some extra "zero" and "one" Literal objects in some of our Constructor classes. This change fixes a recent fuzzer issue. The fuzzer had discovered that calling `getConstantSubexpression` on a ConstructorCompoundCast that contained a compile-time-constant value would return literals of the wrong type (the cast was not applied). By nesting repeated matrix casts, this type confusion could be turned into an assertion. Change-Id: Icee69219e6db2822ffdfab4e5ccdaff54584a4b6 Bug: oss-fuzz:41000 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/471376 Auto-Submit: John Stiles <johnstiles@google.com> Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: John Stiles <johnstiles@google.com>
107 lines
4.6 KiB
Plaintext
107 lines
4.6 KiB
Plaintext
uniform float2x2 testMatrix2x2;
|
|
uniform half4 colorRed, colorGreen;
|
|
uniform half unknownInput;
|
|
|
|
bool test() {
|
|
bool ok = true;
|
|
ok = ok && (float2x2(float2(1.0, 0.0), float2(0.0, 1.0)) ==
|
|
float2x2(float2(1.0, 0.0), float2(0.0, 1.0)));
|
|
ok = ok && !(float2x2(float2(1.0, 0.0), float2(1.0, 1.0)) ==
|
|
float2x2(float2(1.0, 0.0), float2(0.0, 1.0)));
|
|
|
|
ok = ok && ( float2x2(1) == float2x2(1));
|
|
ok = ok && !( float2x2(1) == float2x2(0));
|
|
ok = ok && ( float2x2(-1) == -float2x2(1));
|
|
ok = ok && ( float2x2(0) == -float2x2(0));
|
|
ok = ok && (-float2x2(-1) == float2x2(1));
|
|
ok = ok && (-float2x2(0) == -float2x2(-0));
|
|
|
|
ok = ok && (float2x2(1) == float2x2(float2(1.0, 0.0), float2(0.0, 1.0)));
|
|
ok = ok && !(float2x2(2) == float2x2(float2(1.0, 0.0), float2(0.0, 1.0)));
|
|
|
|
ok = ok && !(float2x2(1) != float2x2(1));
|
|
ok = ok && (float2x2(1) != float2x2(0));
|
|
ok = ok && (float3x3(float3(1.0, 0.0, 0.0), float3(0.0, 1.0, 0.0), float3(0.0, 0.0, 1.0)) ==
|
|
float3x3(float2x2(1.0)));
|
|
ok = ok && (float3x3(float3(9.0, 0.0, 0.0), float3(0.0, 9.0, 0.0), float3(0.0, 0.0, 1.0)) ==
|
|
float3x3(float2x2(9.0)));
|
|
ok = ok && (float3x3(unknownInput) == float3x3(float2x2(1.0)));
|
|
ok = ok && (float3x3(float3(9).x00, float3(9).0x0, float3(unknownInput).00x) ==
|
|
float3x3(float2x2(9.0)));
|
|
ok = ok && (float2x2(float3x3(1.0)) == float2x2(1.0));
|
|
ok = ok && (float2x2(float3x3(1.0)) == float2x2(1.0));
|
|
ok = ok && (float2x2(float4(1.0, 0.0, 0.0, 1.0)) == float2x2(1.0));
|
|
ok = ok && (float2x2(1.0, 0.0, float2(0.0, 1.0)) == float2x2(1.0));
|
|
ok = ok && (float2x2(float2(1.0, 0.0), 0.0, 1.0) == float2x2(1.0));
|
|
|
|
ok = ok && (float4(testMatrix2x2) * float4(1)) == float4(1, 2, 3, 4);
|
|
ok = ok && (float4(testMatrix2x2) * float4(1)) == float4(testMatrix2x2);
|
|
ok = ok && (float4(testMatrix2x2) * float4(0)) == float4(0);
|
|
|
|
ok = ok && (float2x2(5.0)[0] == float2(5.0, 0.0));
|
|
ok = ok && (float2x2(5.0)[1] == float2(0.0, 5.0));
|
|
|
|
ok = ok && (float2x2(5.0)[0][0] == 5.0);
|
|
ok = ok && (float2x2(5.0)[0][1] == 0.0);
|
|
ok = ok && (float2x2(5.0)[1][0] == 0.0);
|
|
ok = ok && (float2x2(5.0)[1][1] == 5.0);
|
|
|
|
const float3x3 m = float3x3(1, 2, 3, 4, 5, 6, 7, 8, 9);
|
|
ok = ok && (m[0] == float3(1, 2, 3));
|
|
ok = ok && (m[1] == float3(4, 5, 6));
|
|
ok = ok && (m[2] == float3(7, 8, 9));
|
|
|
|
ok = ok && (m[0][0] == 1);
|
|
ok = ok && (m[0][1] == 2);
|
|
ok = ok && (m[0][2] == 3);
|
|
ok = ok && (m[1][0] == 4);
|
|
ok = ok && (m[1][1] == 5);
|
|
ok = ok && (m[1][2] == 6);
|
|
ok = ok && (m[2][0] == 7);
|
|
ok = ok && (m[2][1] == 8);
|
|
ok = ok && (m[2][2] == 9);
|
|
|
|
{
|
|
// This `five` is constant and should always fold.
|
|
const float five = 5.0;
|
|
ok = ok && (float2x2(five)[0] == float2(five, 0.0));
|
|
ok = ok && (float2x2(five)[1] == float2(0.0, five));
|
|
|
|
ok = ok && (float2x2(five)[0][0] == five);
|
|
ok = ok && (float2x2(five)[0][1] == 0.0);
|
|
ok = ok && (float2x2(five)[1][0] == 0.0);
|
|
ok = ok && (float2x2(five)[1][1] == five);
|
|
|
|
ok = ok && (float3x3(1, 2, 3, 4, five, 6, 7, 8, 9)[0] == float3(1, 2, 3));
|
|
ok = ok && (float3x3(1, 2, 3, 4, five, 6, 7, 8, 9)[1] == float3(4, five, 6));
|
|
ok = ok && (float3x3(1, 2, 3, 4, five, 6, 7, 8, 9)[2] == float3(7, 8, 9));
|
|
}
|
|
{
|
|
// This `five` cannot be folded, but the first and third columns should still be foldable.
|
|
float five = 5.0;
|
|
ok = ok && (float3x3(1, 2, 3, 4, five, 6, 7, 8, 9)[0] == float3(1, 2, 3));
|
|
ok = ok && (float3x3(1, 2, 3, 4, five, 6, 7, 8, 9)[1] == float3(4, five, 6));
|
|
ok = ok && (float3x3(1, 2, 3, 4, five, 6, 7, 8, 9)[2] == float3(7, 8, 9));
|
|
}
|
|
{
|
|
// Side-effecting expressions should never be folded away.
|
|
float num = 6.0;
|
|
ok = ok && (float3x3(1, 2, 3, 4, 5, num++, 7, 8, 9)[0] == float3(1, 2, 3));
|
|
ok = ok && (float3x3(1, 2, 3, 4, 5, 6, num++, 8, 9)[1] == float3(4, 5, 6));
|
|
ok = ok && (float3x3(1, 2, 3, 4, 5, 6, 7, num++, 9)[2] == float3(7, 8, 9));
|
|
}
|
|
{
|
|
// The upper-left 2x2 of the matrix is unknown, but the bottom two rows are still foldable.
|
|
ok = ok && float4x4(half3x3(testMatrix2x2))[0] == float4(1, 2, 0, 0);
|
|
ok = ok && float4x4(half3x3(testMatrix2x2))[1] == float4(3, 4, 0, 0);
|
|
ok = ok && float4x4(half3x3(testMatrix2x2))[2] == float4(0, 0, 1, 0);
|
|
ok = ok && float4x4(half3x3(testMatrix2x2))[3] == float4(0, 0, 0, 1);
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
half4 main(float2 coords) {
|
|
return test() ? colorGreen : colorRed;
|
|
}
|