additional skslc vector optimizations
Bug: skia: Change-Id: I845d0952c281835a630882ae4026277c93ccf542 Reviewed-on: https://skia-review.googlesource.com/14406 Commit-Queue: Ethan Nicholas <ethannicholas@google.com> Reviewed-by: Ben Wagner <benjaminwagner@google.com>
This commit is contained in:
parent
93cb252c17
commit
fe53e5828f
@ -396,14 +396,27 @@ bool try_replace_expression(BasicBlock* b,
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the expression is a constant numeric literal with the specified value.
|
||||
* Returns true if the expression is a constant numeric literal with the specified value, or a
|
||||
* constant vector with all elements equal to the specified value.
|
||||
*/
|
||||
bool is_constant(Expression& expr, double value) {
|
||||
bool is_constant(const Expression& expr, double value) {
|
||||
switch (expr.fKind) {
|
||||
case Expression::kIntLiteral_Kind:
|
||||
return ((IntLiteral&) expr).fValue == value;
|
||||
case Expression::kFloatLiteral_Kind:
|
||||
return ((FloatLiteral&) expr).fValue == value;
|
||||
case Expression::kConstructor_Kind: {
|
||||
Constructor& c = (Constructor&) expr;
|
||||
if (c.fType.kind() == Type::kVector_Kind && c.isConstant()) {
|
||||
for (int i = 0; i < c.fType.columns(); ++i) {
|
||||
if (!is_constant(c.getVecComponent(i), value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@ -417,6 +430,7 @@ void delete_left(BasicBlock* b,
|
||||
std::vector<BasicBlock::Node>::iterator* iter,
|
||||
bool* outUpdated,
|
||||
bool* outNeedsRescan) {
|
||||
ASSERT((*(*iter)->expression())->fKind == Expression::kBinary_Kind);
|
||||
*outUpdated = true;
|
||||
if (!try_replace_expression(b, iter, &((BinaryExpression&) **(*iter)->expression()).fRight)) {
|
||||
*outNeedsRescan = true;
|
||||
@ -431,12 +445,95 @@ void delete_right(BasicBlock* b,
|
||||
std::vector<BasicBlock::Node>::iterator* iter,
|
||||
bool* outUpdated,
|
||||
bool* outNeedsRescan) {
|
||||
ASSERT((*(*iter)->expression())->fKind == Expression::kBinary_Kind);
|
||||
*outUpdated = true;
|
||||
if (!try_replace_expression(b, iter, &((BinaryExpression&) **(*iter)->expression()).fLeft)) {
|
||||
*outNeedsRescan = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the specified type using a single argument.
|
||||
*/
|
||||
static std::unique_ptr<Expression> construct(const Type& type, std::unique_ptr<Expression> v) {
|
||||
std::vector<std::unique_ptr<Expression>> args;
|
||||
args.push_back(std::move(v));
|
||||
auto result = std::unique_ptr<Expression>(new Constructor(Position(), type, std::move(args)));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in the implementations of vectorize_left and vectorize_right. Given a vector type and an
|
||||
* expression x, deletes the expression pointed to by iter and replaces it with <type>(x).
|
||||
*/
|
||||
static void vectorize(BasicBlock* b,
|
||||
std::vector<BasicBlock::Node>::iterator* iter,
|
||||
const Type& type,
|
||||
std::unique_ptr<Expression>* otherExpression,
|
||||
bool* outUpdated,
|
||||
bool* outNeedsRescan) {
|
||||
ASSERT((*(*iter)->expression())->fKind == Expression::kBinary_Kind);
|
||||
ASSERT(type.kind() == Type::kVector_Kind);
|
||||
ASSERT((*otherExpression)->fType.kind() == Type::kScalar_Kind);
|
||||
*outUpdated = true;
|
||||
std::unique_ptr<Expression>* target = (*iter)->expression();
|
||||
if (!b->tryRemoveExpression(iter)) {
|
||||
*target = construct(type, std::move(*otherExpression));
|
||||
*outNeedsRescan = true;
|
||||
} else {
|
||||
*target = construct(type, std::move(*otherExpression));
|
||||
if (!b->tryInsertExpression(iter, target)) {
|
||||
*outNeedsRescan = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a binary expression of the form x <op> vec<n>(y), deletes the right side and vectorizes the
|
||||
* left to yield vec<n>(x).
|
||||
*/
|
||||
static void vectorize_left(BasicBlock* b,
|
||||
std::vector<BasicBlock::Node>::iterator* iter,
|
||||
bool* outUpdated,
|
||||
bool* outNeedsRescan) {
|
||||
BinaryExpression& bin = (BinaryExpression&) **(*iter)->expression();
|
||||
vectorize(b, iter, bin.fRight->fType, &bin.fLeft, outUpdated, outNeedsRescan);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a binary expression of the form vec<n>(x) <op> y, deletes the left side and vectorizes the
|
||||
* right to yield vec<n>(y).
|
||||
*/
|
||||
static void vectorize_right(BasicBlock* b,
|
||||
std::vector<BasicBlock::Node>::iterator* iter,
|
||||
bool* outUpdated,
|
||||
bool* outNeedsRescan) {
|
||||
BinaryExpression& bin = (BinaryExpression&) **(*iter)->expression();
|
||||
vectorize(b, iter, bin.fLeft->fType, &bin.fRight, outUpdated, outNeedsRescan);
|
||||
}
|
||||
|
||||
// Mark that an expression which we were writing to is no longer being written to
|
||||
void clear_write(const Expression& expr) {
|
||||
switch (expr.fKind) {
|
||||
case Expression::kVariableReference_Kind: {
|
||||
((VariableReference&) expr).setRefKind(VariableReference::kRead_RefKind);
|
||||
break;
|
||||
}
|
||||
case Expression::kFieldAccess_Kind:
|
||||
clear_write(*((FieldAccess&) expr).fBase);
|
||||
break;
|
||||
case Expression::kSwizzle_Kind:
|
||||
clear_write(*((Swizzle&) expr).fBase);
|
||||
break;
|
||||
case Expression::kIndex_Kind:
|
||||
clear_write(*((IndexExpression&) expr).fBase);
|
||||
break;
|
||||
default:
|
||||
ABORT("shouldn't be writing to this kind of expression\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
BasicBlock& b,
|
||||
std::vector<BasicBlock::Node>::iterator* iter,
|
||||
@ -485,30 +582,148 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
case Expression::kBinary_Kind: {
|
||||
// collapse useless expressions like x * 1 or x + 0
|
||||
BinaryExpression* bin = (BinaryExpression*) expr;
|
||||
if (((bin->fLeft->fType.kind() != Type::kScalar_Kind) &&
|
||||
(bin->fLeft->fType.kind() != Type::kVector_Kind)) ||
|
||||
((bin->fRight->fType.kind() != Type::kScalar_Kind) &&
|
||||
(bin->fRight->fType.kind() != Type::kVector_Kind))) {
|
||||
break;
|
||||
}
|
||||
switch (bin->fOperator) {
|
||||
case Token::STAR:
|
||||
if (is_constant(*bin->fLeft, 1)) {
|
||||
delete_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
if (bin->fLeft->fType.kind() == Type::kVector_Kind &&
|
||||
bin->fRight->fType.kind() == Type::kScalar_Kind) {
|
||||
// vec4(1) * x -> vec4(x)
|
||||
vectorize_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
} else {
|
||||
// 1 * x -> x
|
||||
// 1 * vec4(x) -> vec4(x)
|
||||
// vec4(1) * vec4(x) -> vec4(x)
|
||||
delete_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
}
|
||||
}
|
||||
else if (is_constant(*bin->fLeft, 0)) {
|
||||
if (bin->fLeft->fType.kind() == Type::kScalar_Kind &&
|
||||
bin->fRight->fType.kind() == Type::kVector_Kind) {
|
||||
// 0 * vec4(x) -> vec4(0)
|
||||
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
} else {
|
||||
// 0 * x -> 0
|
||||
// vec4(0) * x -> vec4(0)
|
||||
// vec4(0) * vec4(x) -> vec4(0)
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
}
|
||||
}
|
||||
else if (is_constant(*bin->fRight, 1)) {
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
if (bin->fLeft->fType.kind() == Type::kScalar_Kind &&
|
||||
bin->fRight->fType.kind() == Type::kVector_Kind) {
|
||||
// x * vec4(1) -> vec4(x)
|
||||
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
} else {
|
||||
// x * 1 -> x
|
||||
// vec4(x) * 1 -> vec4(x)
|
||||
// vec4(x) * vec4(1) -> vec4(x)
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
}
|
||||
}
|
||||
else if (is_constant(*bin->fRight, 0)) {
|
||||
if (bin->fLeft->fType.kind() == Type::kVector_Kind &&
|
||||
bin->fRight->fType.kind() == Type::kScalar_Kind) {
|
||||
// vec4(x) * 0 -> vec4(0)
|
||||
vectorize_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
} else {
|
||||
// x * 0 -> 0
|
||||
// x * vec4(0) -> vec4(0)
|
||||
// vec4(x) * vec4(0) -> vec4(0)
|
||||
delete_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Token::PLUS:
|
||||
if (is_constant(*bin->fLeft, 0)) {
|
||||
delete_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
}
|
||||
if (is_constant(*bin->fRight, 0)) {
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
if (bin->fLeft->fType.kind() == Type::kVector_Kind &&
|
||||
bin->fRight->fType.kind() == Type::kScalar_Kind) {
|
||||
// vec4(0) + x -> vec4(x)
|
||||
vectorize_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
} else {
|
||||
// 0 + x -> x
|
||||
// 0 + vec4(x) -> vec4(x)
|
||||
// vec4(0) + vec4(x) -> vec4(x)
|
||||
delete_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
}
|
||||
} else if (is_constant(*bin->fRight, 0)) {
|
||||
if (bin->fLeft->fType.kind() == Type::kScalar_Kind &&
|
||||
bin->fRight->fType.kind() == Type::kVector_Kind) {
|
||||
// x + vec4(0) -> vec4(x)
|
||||
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
} else {
|
||||
// x + 0 -> x
|
||||
// vec4(x) + 0 -> vec4(x)
|
||||
// vec4(x) + vec4(0) -> vec4(x)
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Token::MINUS:
|
||||
if (is_constant(*bin->fRight, 0)) {
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
if (bin->fLeft->fType.kind() == Type::kScalar_Kind &&
|
||||
bin->fRight->fType.kind() == Type::kVector_Kind) {
|
||||
// x - vec4(0) -> vec4(x)
|
||||
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
} else {
|
||||
// x - 0 -> x
|
||||
// vec4(x) - 0 -> vec4(x)
|
||||
// vec4(x) - vec4(0) -> vec4(x)
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Token::SLASH:
|
||||
if (is_constant(*bin->fRight, 1)) {
|
||||
if (bin->fLeft->fType.kind() == Type::kScalar_Kind &&
|
||||
bin->fRight->fType.kind() == Type::kVector_Kind) {
|
||||
// x / vec4(1) -> vec4(x)
|
||||
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
} else {
|
||||
// x / 1 -> x
|
||||
// vec4(x) / 1 -> vec4(x)
|
||||
// vec4(x) / vec4(1) -> vec4(x)
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
}
|
||||
} else if (is_constant(*bin->fLeft, 0)) {
|
||||
if (bin->fLeft->fType.kind() == Type::kScalar_Kind &&
|
||||
bin->fRight->fType.kind() == Type::kVector_Kind) {
|
||||
// 0 / vec4(x) -> vec4(0)
|
||||
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
} else {
|
||||
// 0 / x -> 0
|
||||
// vec4(0) / x -> vec4(0)
|
||||
// vec4(0) / vec4(x) -> vec4(0)
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Token::PLUSEQ:
|
||||
if (is_constant(*bin->fRight, 0)) {
|
||||
clear_write(*bin->fLeft);
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
}
|
||||
break;
|
||||
case Token::MINUSEQ:
|
||||
if (is_constant(*bin->fRight, 0)) {
|
||||
clear_write(*bin->fLeft);
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
}
|
||||
break;
|
||||
case Token::STAREQ:
|
||||
if (is_constant(*bin->fRight, 1)) {
|
||||
clear_write(*bin->fLeft);
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
}
|
||||
break;
|
||||
case Token::SLASHEQ:
|
||||
if (is_constant(*bin->fRight, 1)) {
|
||||
clear_write(*bin->fLeft);
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
}
|
||||
break;
|
||||
|
@ -173,8 +173,8 @@ DEF_TEST(SkSLMatrices, r) {
|
||||
"mat2x4 x = mat2x4(1);"
|
||||
"mat3x2 y = mat3x2(1, 0, 0, 1, vec2(2, 2));"
|
||||
"mat3x4 z = x * y;"
|
||||
"vec3 v1 = mat3(1) * vec3(1);"
|
||||
"vec3 v2 = vec3(1) * mat3(1);"
|
||||
"vec3 v1 = mat3(1) * vec3(2);"
|
||||
"vec3 v2 = vec3(2) * mat3(1);"
|
||||
"sk_FragColor = vec4(z[0].x, v1 + v2);"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
@ -182,8 +182,8 @@ DEF_TEST(SkSLMatrices, r) {
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"void main() {\n"
|
||||
" mat3x4 z = mat2x4(1.0) * mat3x2(1.0, 0.0, 0.0, 1.0, vec2(2.0, 2.0));\n"
|
||||
" vec3 v1 = mat3(1.0) * vec3(1.0);\n"
|
||||
" vec3 v2 = vec3(1.0) * mat3(1.0);\n"
|
||||
" vec3 v1 = mat3(1.0) * vec3(2.0);\n"
|
||||
" vec3 v2 = vec3(2.0) * mat3(1.0);\n"
|
||||
" sk_FragColor = vec4(z[0].x, v1 + v2);\n"
|
||||
"}\n");
|
||||
}
|
||||
@ -523,6 +523,25 @@ DEF_TEST(SkSLIntFolding, r) {
|
||||
"sk_FragColor.r = 6 >= 7 ? 10 : -10;"
|
||||
"sk_FragColor.r = 6 <= 6 ? 11 : -11;"
|
||||
"sk_FragColor.r = 6 <= 5 ? 12 : -12;"
|
||||
"sk_FragColor.r = int(sqrt(1)) + 0;"
|
||||
"sk_FragColor.r = 0 + int(sqrt(2));"
|
||||
"sk_FragColor.r = int(sqrt(3)) - 0;"
|
||||
"sk_FragColor.r = int(sqrt(4)) * 0;"
|
||||
"sk_FragColor.r = int(sqrt(5)) * 1;"
|
||||
"sk_FragColor.r = 1 * int(sqrt(6));"
|
||||
"sk_FragColor.r = 0 * int(sqrt(7));"
|
||||
"sk_FragColor.r = int(sqrt(8)) / 1;"
|
||||
"sk_FragColor.r = 0 / int(sqrt(9));"
|
||||
"int x = int(sqrt(2));"
|
||||
"x += 1;"
|
||||
"x += 0;"
|
||||
"x -= 1;"
|
||||
"x -= 0;"
|
||||
"x *= 1;"
|
||||
"x *= 2;"
|
||||
"x /= 1;"
|
||||
"x /= 2;"
|
||||
"sk_FragColor.r = x;"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
@ -549,6 +568,21 @@ DEF_TEST(SkSLIntFolding, r) {
|
||||
" sk_FragColor.x = -10.0;\n"
|
||||
" sk_FragColor.x = 11.0;\n"
|
||||
" sk_FragColor.x = -12.0;\n"
|
||||
" sk_FragColor.x = float(int(sqrt(1.0)));\n"
|
||||
" sk_FragColor.x = float(int(sqrt(2.0)));\n"
|
||||
" sk_FragColor.x = float(int(sqrt(3.0)));\n"
|
||||
" sk_FragColor.x = 0.0;\n"
|
||||
" sk_FragColor.x = float(int(sqrt(5.0)));\n"
|
||||
" sk_FragColor.x = float(int(sqrt(6.0)));\n"
|
||||
" sk_FragColor.x = 0.0;\n"
|
||||
" sk_FragColor.x = float(int(sqrt(8.0)));\n"
|
||||
" sk_FragColor.x = 0.0;\n"
|
||||
" int x = int(sqrt(2.0));\n"
|
||||
" x += 1;\n"
|
||||
" x -= 1;\n"
|
||||
" x *= 2;\n"
|
||||
" x /= 2;\n"
|
||||
" sk_FragColor.x = float(x);\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
@ -572,6 +606,23 @@ DEF_TEST(SkSLFloatFolding, r) {
|
||||
"sk_FragColor.r = 6.0 < 6.0 ? 10 : -10;"
|
||||
"sk_FragColor.r = 6.0 <= 6.0 ? 11 : -11;"
|
||||
"sk_FragColor.r = 6.0 <= 5.0 ? 12 : -12;"
|
||||
"sk_FragColor.r = sqrt(1) + 0;"
|
||||
"sk_FragColor.r = 0 + sqrt(2);"
|
||||
"sk_FragColor.r = sqrt(3) - 0;"
|
||||
"sk_FragColor.r = sqrt(4) * 0;"
|
||||
"sk_FragColor.r = sqrt(5) * 1;"
|
||||
"sk_FragColor.r = 1 * sqrt(6);"
|
||||
"sk_FragColor.r = 0 * sqrt(7);"
|
||||
"sk_FragColor.r = sqrt(8) / 1;"
|
||||
"sk_FragColor.r = 0 / sqrt(9);"
|
||||
"sk_FragColor.r += 1;"
|
||||
"sk_FragColor.r += 0;"
|
||||
"sk_FragColor.r -= 1;"
|
||||
"sk_FragColor.r -= 0;"
|
||||
"sk_FragColor.r *= 1;"
|
||||
"sk_FragColor.r *= 2;"
|
||||
"sk_FragColor.r /= 1;"
|
||||
"sk_FragColor.r /= 2;"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
@ -594,6 +645,19 @@ DEF_TEST(SkSLFloatFolding, r) {
|
||||
" sk_FragColor.x = -10.0;\n"
|
||||
" sk_FragColor.x = 11.0;\n"
|
||||
" sk_FragColor.x = -12.0;\n"
|
||||
" sk_FragColor.x = sqrt(1.0);\n"
|
||||
" sk_FragColor.x = sqrt(2.0);\n"
|
||||
" sk_FragColor.x = sqrt(3.0);\n"
|
||||
" sk_FragColor.x = 0.0;\n"
|
||||
" sk_FragColor.x = sqrt(5.0);\n"
|
||||
" sk_FragColor.x = sqrt(6.0);\n"
|
||||
" sk_FragColor.x = 0.0;\n"
|
||||
" sk_FragColor.x = sqrt(8.0);\n"
|
||||
" sk_FragColor.x = 0.0;\n"
|
||||
" sk_FragColor.x += 1.0;\n"
|
||||
" sk_FragColor.x -= 1.0;\n"
|
||||
" sk_FragColor.x *= 2.0;\n"
|
||||
" sk_FragColor.x /= 2.0;\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
@ -639,6 +703,39 @@ DEF_TEST(SkSLVecFolding, r) {
|
||||
"sk_FragColor.x = vec4(vec3(1), 1) == vec4(vec2(1), 1, 0) ? 8.0 : -8.0;"
|
||||
"sk_FragColor.x = vec2(1) != vec2(1, 0) ? 9.0 : -9.0;"
|
||||
"sk_FragColor.x = vec4(1) != vec4(vec2(1), vec2(1)) ? 10.0 : -10.0;"
|
||||
"sk_FragColor = vec4(sqrt(1)) * vec4(1);"
|
||||
"sk_FragColor = vec4(1) * vec4(sqrt(2));"
|
||||
"sk_FragColor = vec4(0) * vec4(sqrt(3));"
|
||||
"sk_FragColor = vec4(sqrt(4)) * vec4(0);"
|
||||
"sk_FragColor = vec4(0) / vec4(sqrt(5));"
|
||||
"sk_FragColor = vec4(0) + vec4(sqrt(6));"
|
||||
"sk_FragColor = vec4(sqrt(7)) + vec4(0);"
|
||||
"sk_FragColor = vec4(sqrt(8)) - vec4(0);"
|
||||
"sk_FragColor = vec4(0) + sqrt(9);"
|
||||
"sk_FragColor = vec4(0) * sqrt(10);"
|
||||
"sk_FragColor = vec4(0) / sqrt(11);"
|
||||
"sk_FragColor = vec4(1) * sqrt(12);"
|
||||
"sk_FragColor = 0 + vec4(sqrt(13));"
|
||||
"sk_FragColor = 0 * vec4(sqrt(14));"
|
||||
"sk_FragColor = 0 / vec4(sqrt(15));"
|
||||
"sk_FragColor = 1 * vec4(sqrt(16));"
|
||||
"sk_FragColor = vec4(sqrt(17)) + 0;"
|
||||
"sk_FragColor = vec4(sqrt(18)) * 0;"
|
||||
"sk_FragColor = vec4(sqrt(19)) * 1;"
|
||||
"sk_FragColor = vec4(sqrt(19.5)) - 0;"
|
||||
"sk_FragColor = sqrt(20) * vec4(1);"
|
||||
"sk_FragColor = sqrt(21) + vec4(0);"
|
||||
"sk_FragColor = sqrt(22) - vec4(0);"
|
||||
"sk_FragColor = sqrt(23) / vec4(1);"
|
||||
"sk_FragColor = vec4(sqrt(24)) / 1;"
|
||||
"sk_FragColor += vec4(1);"
|
||||
"sk_FragColor += vec4(0);"
|
||||
"sk_FragColor -= vec4(1);"
|
||||
"sk_FragColor -= vec4(0);"
|
||||
"sk_FragColor *= vec4(1);"
|
||||
"sk_FragColor *= vec4(2);"
|
||||
"sk_FragColor /= vec4(1);"
|
||||
"sk_FragColor /= vec4(2);"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
@ -660,6 +757,35 @@ DEF_TEST(SkSLVecFolding, r) {
|
||||
" sk_FragColor.x = -8.0;\n"
|
||||
" sk_FragColor.x = 9.0;\n"
|
||||
" sk_FragColor.x = -10.0;\n"
|
||||
" sk_FragColor = vec4(sqrt(1.0));\n"
|
||||
" sk_FragColor = vec4(sqrt(2.0));\n"
|
||||
" sk_FragColor = vec4(0.0);\n"
|
||||
" sk_FragColor = vec4(0.0);\n"
|
||||
" sk_FragColor = vec4(0.0);\n"
|
||||
" sk_FragColor = vec4(sqrt(6.0));\n"
|
||||
" sk_FragColor = vec4(sqrt(7.0));\n"
|
||||
" sk_FragColor = vec4(sqrt(8.0));\n"
|
||||
" sk_FragColor = vec4(sqrt(9.0));\n"
|
||||
" sk_FragColor = vec4(0.0);\n"
|
||||
" sk_FragColor = vec4(0.0);\n"
|
||||
" sk_FragColor = vec4(sqrt(12.0));\n"
|
||||
" sk_FragColor = vec4(sqrt(13.0));\n"
|
||||
" sk_FragColor = vec4(0.0);\n"
|
||||
" sk_FragColor = vec4(0.0);\n"
|
||||
" sk_FragColor = vec4(sqrt(16.0));\n"
|
||||
" sk_FragColor = vec4(sqrt(17.0));\n"
|
||||
" sk_FragColor = vec4(0.0);\n"
|
||||
" sk_FragColor = vec4(sqrt(19.0));\n"
|
||||
" sk_FragColor = vec4(sqrt(19.5));\n"
|
||||
" sk_FragColor = vec4(sqrt(20.0));\n"
|
||||
" sk_FragColor = vec4(sqrt(21.0));\n"
|
||||
" sk_FragColor = vec4(sqrt(22.0));\n"
|
||||
" sk_FragColor = vec4(sqrt(23.0));\n"
|
||||
" sk_FragColor = vec4(sqrt(24.0));\n"
|
||||
" sk_FragColor += vec4(1.0);\n"
|
||||
" sk_FragColor -= vec4(1.0);\n"
|
||||
" sk_FragColor *= vec4(2.0);\n"
|
||||
" sk_FragColor /= vec4(2.0);\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
@ -1030,38 +1156,38 @@ DEF_TEST(SkSLRectangleTexture, r) {
|
||||
test(r,
|
||||
"uniform sampler2D test;"
|
||||
"void main() {"
|
||||
" sk_FragColor = texture(test, vec2(1));"
|
||||
" sk_FragColor = texture(test, vec2(0.5));"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"uniform sampler2D test;\n"
|
||||
"void main() {\n"
|
||||
" sk_FragColor = texture(test, vec2(1.0));\n"
|
||||
" sk_FragColor = texture(test, vec2(0.5));\n"
|
||||
"}\n");
|
||||
test(r,
|
||||
"uniform sampler2DRect test;"
|
||||
"void main() {"
|
||||
" sk_FragColor = texture(test, vec2(1));"
|
||||
" sk_FragColor = texture(test, vec2(0.5));"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"uniform sampler2DRect test;\n"
|
||||
"void main() {\n"
|
||||
" sk_FragColor = texture(test, textureSize(test) * vec2(1.0));\n"
|
||||
" sk_FragColor = texture(test, textureSize(test) * vec2(0.5));\n"
|
||||
"}\n");
|
||||
test(r,
|
||||
"uniform sampler2DRect test;"
|
||||
"void main() {"
|
||||
" sk_FragColor = texture(test, vec3(1));"
|
||||
" sk_FragColor = texture(test, vec3(0.5));"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"uniform sampler2DRect test;\n"
|
||||
"void main() {\n"
|
||||
" sk_FragColor = texture(test, vec3(textureSize(test), 1.0) * vec3(1.0));\n"
|
||||
" sk_FragColor = texture(test, vec3(textureSize(test), 1.0) * vec3(0.5));\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user