Implement constant folding for vector*scalar ops.

Change-Id: I96b547de4fe4b73096fb26d0ef21a4e7555ca06a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/352238
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-01-11 13:07:47 -05:00 committed by Skia Commit-Bot
parent c39a143632
commit 508eba7578
2 changed files with 61 additions and 24 deletions

View File

@ -53,6 +53,7 @@ static std::unique_ptr<Expression> simplify_vector(const Context& context,
const Expression& left, const Expression& left,
Token::Kind op, Token::Kind op,
const Expression& right) { const Expression& right) {
SkASSERT(left.type().isVector());
SkASSERT(left.type() == right.type()); SkASSERT(left.type() == right.type());
const Type& type = left.type(); const Type& type = left.type();
@ -110,6 +111,16 @@ static std::unique_ptr<Expression> simplify_vector(const Context& context,
} }
} }
static Constructor splat_scalar(const Expression& scalar, const Type& type) {
SkASSERT(type.isVector());
SkASSERT(type.componentType() == scalar.type());
// Use a Constructor to splat the scalar expression across a vector.
ExpressionArray arg;
arg.push_back(scalar.clone());
return Constructor{scalar.fOffset, &type, std::move(arg)};
}
std::unique_ptr<Expression> ConstantFolder::Simplify(const Context& context, std::unique_ptr<Expression> ConstantFolder::Simplify(const Context& context,
ErrorReporter& errors, ErrorReporter& errors,
const Expression& left, const Expression& left,
@ -246,6 +257,32 @@ std::unique_ptr<Expression> ConstantFolder::Simplify(const Context& context,
return nullptr; return nullptr;
} }
// Perform constant folding on vectors against scalars, e.g.: half4(2) + 2
if (leftType.isVector() && leftType.componentType() == rightType) {
if (rightType.isFloat()) {
return simplify_vector<SKSL_FLOAT>(context, errors,
left, op, splat_scalar(right, left.type()));
}
if (rightType.isInteger()) {
return simplify_vector<SKSL_INT>(context, errors,
left, op, splat_scalar(right, left.type()));
}
return nullptr;
}
// Perform constant folding on scalars against vectors, e.g.: 2 + half4(2)
if (rightType.isVector() && rightType.componentType() == leftType) {
if (leftType.isFloat()) {
return simplify_vector<SKSL_FLOAT>(context, errors,
splat_scalar(left, right.type()), op, right);
}
if (leftType.isInteger()) {
return simplify_vector<SKSL_INT>(context, errors,
splat_scalar(left, right.type()), op, right);
}
return nullptr;
}
// Perform constant folding on pairs of matrices. // Perform constant folding on pairs of matrices.
if (leftType.isMatrix() && rightType.isMatrix()) { if (leftType.isMatrix() && rightType.isMatrix()) {
bool equality; bool equality;

View File

@ -1,32 +1,32 @@
out vec4 sk_FragColor; out vec4 sk_FragColor;
void main() { void main() {
sk_FragColor = vec4(vec2(1.0), 2.0, 3.0) + 5.0; sk_FragColor = vec4(6.0, 6.0, 7.0, 8.0);
sk_FragColor = vec4(8.0, vec3(10.0)) - 1.0; sk_FragColor = vec4(7.0, 9.0, 9.0, 9.0);
sk_FragColor = vec4(vec2(8.0), vec2(9.0)) + 1.0; sk_FragColor = vec4(9.0, 9.0, 10.0, 10.0);
sk_FragColor.xyz = vec3(2.0) * 3.0; sk_FragColor.xyz = vec3(6.0, 6.0, 6.0);
sk_FragColor.xy = vec2(12.0) / 4.0; sk_FragColor.xy = vec2(3.0, 3.0);
sk_FragColor.x = (vec4(12.0) / 2.0).y; sk_FragColor.x = 6.0;
sk_FragColor = 5.0 + vec4(vec2(1.0), 2.0, 3.0); sk_FragColor = vec4(6.0, 6.0, 7.0, 8.0);
sk_FragColor = 1.0 - vec4(8.0, vec3(10.0)); sk_FragColor = vec4(-7.0, -9.0, -9.0, -9.0);
sk_FragColor = 1.0 + vec4(vec2(8.0), vec2(9.0)); sk_FragColor = vec4(9.0, 9.0, 10.0, 10.0);
sk_FragColor.xyz = 3.0 * vec3(2.0); sk_FragColor.xyz = vec3(6.0, 6.0, 6.0);
sk_FragColor.xy = 4.0 / vec2(0.5); sk_FragColor.xy = vec2(8.0, 8.0);
sk_FragColor = 20.0 / vec4(10.0, 20.0, 40.0, 80.0); sk_FragColor = vec4(2.0, 1.0, 0.5, 0.25);
ivec4 _0_result; ivec4 _0_result;
_0_result = ivec4(ivec2(1), 2, 3) + 5; _0_result = ivec4(6, 6, 7, 8);
_0_result = ivec4(8, ivec3(10)) - 1; _0_result = ivec4(7, 9, 9, 9);
_0_result = ivec4(ivec2(8), ivec2(9)) + 1; _0_result = ivec4(9, 9, 10, 10);
_0_result.xyz = ivec3(2) * 3; _0_result.xyz = ivec3(6, 6, 6);
_0_result.xy = ivec2(12) / 4; _0_result.xy = ivec2(3, 3);
_0_result.x = (ivec4(12) / 2).y; _0_result.x = 6;
_0_result = 5 + ivec4(ivec2(1), 2, 3); _0_result = ivec4(6, 6, 7, 8);
_0_result = 1 - ivec4(8, ivec3(10)); _0_result = ivec4(-7, -9, -9, -9);
_0_result = 1 + ivec4(ivec2(8), ivec2(9)); _0_result = ivec4(9, 9, 10, 10);
_0_result.xyz = 3 * ivec3(2); _0_result.xyz = ivec3(6, 6, 6);
_0_result.xy = 4 / ivec2(4); _0_result.xy = ivec2(1, 1);
_0_result.xyz = 20 / ivec3(10, 20, 40); _0_result.xyz = ivec3(2, 1, 0);
sk_FragColor = vec4(_0_result); sk_FragColor = vec4(_0_result);
} }