Implement constant folding for index expressions into matrices.

Indexing into a constant matrix is a constant expression, so we are
obligated to support it for ES2 compatibility.

Change-Id: Ibe1e5bac39d9a88ce0222997a38e8b6952fdb336
Bug: skia:12472
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/469819
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
John Stiles 2021-11-10 14:06:52 -05:00 committed by SkCQ
parent d7936dcda0
commit 6fae052362
4 changed files with 39 additions and 21 deletions

View File

@ -9,7 +9,11 @@ bool test() {
int a[int4(1, 2, 3, 4).y];
int b[int(max(-5.5, 2.0))];
int c[two];
return check_array_is_int_2(a) && check_array_is_int_2(b) && check_array_is_int_2(c);
int d[int2(float2x2(1, 2, 3, 4)[0]).y];
return check_array_is_int_2(a) &&
check_array_is_int_2(b) &&
check_array_is_int_2(c) &&
check_array_is_int_2(d);
}
bool check_array_is_float_3(float[3] x) {

View File

@ -9,6 +9,7 @@
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/ir/SkSLBinaryExpression.h"
#include "src/sksl/ir/SkSLConstructorArray.h"
#include "src/sksl/ir/SkSLConstructorCompound.h"
#include "src/sksl/ir/SkSLIndexExpression.h"
#include "src/sksl/ir/SkSLLiteral.h"
#include "src/sksl/ir/SkSLSwizzle.h"
@ -115,6 +116,37 @@ std::unique_ptr<Expression> IndexExpression::Make(const Context& context,
return arguments[indexValue]->clone();
}
}
if (baseType.isMatrix()) {
// Matrices can be constructed with vectors that don't line up on column boundaries,
// so extracting out the values from the constructor can be tricky. Fortunately, we
// can reconstruct an equivalent vector using `getConstantSubexpression`. If we
// can't extract the data using `getConstantSubexpression`, it wasn't constant and
// we're not obligated to simplify anything.
const Expression* baseExpr = ConstantFolder::GetConstantValueForVariable(*base);
int vecWidth = baseType.rows();
const Type& vecType = baseType.componentType().toCompound(context,
vecWidth,
/*rows=*/1);
indexValue *= vecWidth;
ExpressionArray ctorArgs;
ctorArgs.reserve_back(vecWidth);
for (int slot = 0; slot < vecWidth; ++slot) {
if (const Expression* subexpr = baseExpr->getConstantSubexpression(indexValue +
slot)) {
ctorArgs.push_back(subexpr->clone());
} else {
ctorArgs.reset();
break;
}
}
if (!ctorArgs.empty()) {
int line = ctorArgs.front()->fLine;
return ConstructorCompound::Make(context, line, vecType, std::move(ctorArgs));
}
}
}
}

View File

@ -16,5 +16,6 @@ vec4 main() {
float g[3];
int _2_b[2];
int _3_c[2];
return (check_array_is_int_2_bi(_2_b) && check_array_is_int_2_bi(_3_c)) && test_param_bff(f, g) ? colorGreen : colorRed;
int _4_d[2];
return ((check_array_is_int_2_bi(_2_b) && check_array_is_int_2_bi(_3_c)) && check_array_is_int_2_bi(_4_d)) && test_param_bff(f, g) ? colorGreen : colorRed;
}

View File

@ -9,24 +9,5 @@ vec4 main() {
_0_ok = _0_ok && mat3(unknownInput) == mat3(mat2(1.0));
_0_ok = _0_ok && mat3(9.0, 0.0, 0.0, 0.0, 9.0, 0.0, 0.0, 0.0, unknownInput) == mat3(mat2(9.0));
_0_ok = _0_ok && vec4(testMatrix2x2) == vec4(1.0, 2.0, 3.0, 4.0);
_0_ok = _0_ok && mat2(5.0)[0] == vec2(5.0, 0.0);
_0_ok = _0_ok && mat2(5.0)[1] == vec2(0.0, 5.0);
_0_ok = _0_ok && mat2(5.0)[0].x == 5.0;
_0_ok = _0_ok && mat2(5.0)[0].y == 0.0;
_0_ok = _0_ok && mat2(5.0)[1].x == 0.0;
_0_ok = _0_ok && mat2(5.0)[1].y == 5.0;
const mat3 _1_m = mat3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
_0_ok = _0_ok && _1_m[0] == vec3(1.0, 2.0, 3.0);
_0_ok = _0_ok && _1_m[1] == vec3(4.0, 5.0, 6.0);
_0_ok = _0_ok && _1_m[2] == vec3(7.0, 8.0, 9.0);
_0_ok = _0_ok && _1_m[0].x == 1.0;
_0_ok = _0_ok && _1_m[0].y == 2.0;
_0_ok = _0_ok && _1_m[0].z == 3.0;
_0_ok = _0_ok && _1_m[1].x == 4.0;
_0_ok = _0_ok && _1_m[1].y == 5.0;
_0_ok = _0_ok && _1_m[1].z == 6.0;
_0_ok = _0_ok && _1_m[2].x == 7.0;
_0_ok = _0_ok && _1_m[2].y == 8.0;
_0_ok = _0_ok && _1_m[2].z == 9.0;
return _0_ok ? colorGreen : colorRed;
}