SkSL Metal backend can now handle CCPR
Bug: skia: Change-Id: I796a40db46174b405495af8234c5b8d7920a46d6 Reviewed-on: https://skia-review.googlesource.com/c/189985 Reviewed-by: Jim Van Verth <jvanverth@google.com> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
402bf74ea8
commit
0dc8087e91
@ -1301,6 +1301,26 @@ bool Compiler::optimize(Program& program) {
|
||||
this->scanCFG((FunctionDefinition&) element);
|
||||
}
|
||||
}
|
||||
if (program.fKind != Program::kFragmentProcessor_Kind) {
|
||||
for (auto iter = program.fElements.begin(); iter != program.fElements.end();) {
|
||||
if ((*iter)->fKind == ProgramElement::kVar_Kind) {
|
||||
VarDeclarations& vars = (VarDeclarations&) **iter;
|
||||
for (auto varIter = vars.fVars.begin(); varIter != vars.fVars.end();) {
|
||||
const Variable& var = *((VarDeclaration&) **varIter).fVar;
|
||||
if (var.dead()) {
|
||||
varIter = vars.fVars.erase(varIter);
|
||||
} else {
|
||||
++varIter;
|
||||
}
|
||||
}
|
||||
if (vars.fVars.size() == 0) {
|
||||
iter = program.fElements.erase(iter);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
fSource = nullptr;
|
||||
}
|
||||
return fErrorCount == 0;
|
||||
|
@ -26,6 +26,8 @@ void MetalCodeGenerator::setupIntrinsics() {
|
||||
#define SPECIAL(x) std::make_pair(kSpecial_IntrinsicKind, k ## x ## _SpecialIntrinsic)
|
||||
fIntrinsicMap[String("texture")] = SPECIAL(Texture);
|
||||
fIntrinsicMap[String("mod")] = SPECIAL(Mod);
|
||||
fIntrinsicMap[String("equal")] = METAL(Equal);
|
||||
fIntrinsicMap[String("notEqual")] = METAL(NotEqual);
|
||||
fIntrinsicMap[String("lessThan")] = METAL(LessThan);
|
||||
fIntrinsicMap[String("lessThanEqual")] = METAL(LessThanEqual);
|
||||
fIntrinsicMap[String("greaterThan")] = METAL(GreaterThan);
|
||||
@ -172,6 +174,12 @@ void MetalCodeGenerator::writeIntrinsicCall(const FunctionCall& c) {
|
||||
case kMetal_IntrinsicKind:
|
||||
this->writeExpression(*c.fArguments[0], kSequence_Precedence);
|
||||
switch ((MetalIntrinsic) intrinsicId) {
|
||||
case kEqual_MetalIntrinsic:
|
||||
this->write(" == ");
|
||||
break;
|
||||
case kNotEqual_MetalIntrinsic:
|
||||
this->write(" != ");
|
||||
break;
|
||||
case kLessThan_MetalIntrinsic:
|
||||
this->write(" < ");
|
||||
break;
|
||||
@ -248,18 +256,82 @@ void MetalCodeGenerator::writeFunctionCall(const FunctionCall& c) {
|
||||
}
|
||||
|
||||
void MetalCodeGenerator::writeInverseHack(const Expression& mat) {
|
||||
String name = "ERROR_MatrixInverseNotImplementedFor_" + mat.fType.name();
|
||||
if (mat.fType == *fContext.fFloat2x2_Type) {
|
||||
name = "_inverse2";
|
||||
String typeName = mat.fType.name();
|
||||
String name = typeName + "_inverse";
|
||||
if (mat.fType == *fContext.fFloat2x2_Type || mat.fType == *fContext.fHalf2x2_Type) {
|
||||
if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
|
||||
fWrittenIntrinsics.insert(name);
|
||||
fExtraFunctions.writeText((
|
||||
"float2x2 " + name + "(float2x2 m) {"
|
||||
typeName + " " + name + "(" + typeName + " m) {"
|
||||
" return float2x2(m[1][1], -m[0][1], -m[1][0], m[0][0]) * (1/determinant(m));"
|
||||
"}"
|
||||
).c_str());
|
||||
}
|
||||
}
|
||||
else if (mat.fType == *fContext.fFloat3x3_Type || mat.fType == *fContext.fHalf3x3_Type) {
|
||||
if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
|
||||
fWrittenIntrinsics.insert(name);
|
||||
fExtraFunctions.writeText((
|
||||
typeName + " " + name + "(" + typeName + " m) {"
|
||||
" float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];"
|
||||
" float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];"
|
||||
" float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];"
|
||||
" float b01 = a22 * a11 - a12 * a21;"
|
||||
" float b11 = -a22 * a10 + a12 * a20;"
|
||||
" float b21 = a21 * a10 - a11 * a20;"
|
||||
" float det = a00 * b01 + a01 * b11 + a02 * b21;"
|
||||
" return " + typeName +
|
||||
" (b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11),"
|
||||
" b11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10),"
|
||||
" b21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) * "
|
||||
" (1/det);"
|
||||
"}"
|
||||
).c_str());
|
||||
}
|
||||
}
|
||||
else if (mat.fType == *fContext.fFloat4x4_Type || mat.fType == *fContext.fHalf4x4_Type) {
|
||||
if (fWrittenIntrinsics.find(name) == fWrittenIntrinsics.end()) {
|
||||
fWrittenIntrinsics.insert(name);
|
||||
fExtraFunctions.writeText((
|
||||
typeName + " " + name + "(" + typeName + " m) {"
|
||||
" float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3];"
|
||||
" float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3];"
|
||||
" float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3];"
|
||||
" float a30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3];"
|
||||
" float b00 = a00 * a11 - a01 * a10;"
|
||||
" float b01 = a00 * a12 - a02 * a10;"
|
||||
" float b02 = a00 * a13 - a03 * a10;"
|
||||
" float b03 = a01 * a12 - a02 * a11;"
|
||||
" float b04 = a01 * a13 - a03 * a11;"
|
||||
" float b05 = a02 * a13 - a03 * a12;"
|
||||
" float b06 = a20 * a31 - a21 * a30;"
|
||||
" float b07 = a20 * a32 - a22 * a30;"
|
||||
" float b08 = a20 * a33 - a23 * a30;"
|
||||
" float b09 = a21 * a32 - a22 * a31;"
|
||||
" float b10 = a21 * a33 - a23 * a31;"
|
||||
" float b11 = a22 * a33 - a23 * a32;"
|
||||
" float det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - "
|
||||
" b04 * b07 + b05 * b06;"
|
||||
" return " + typeName + "(a11 * b11 - a12 * b10 + a13 * b09,"
|
||||
" a02 * b10 - a01 * b11 - a03 * b09,"
|
||||
" a31 * b05 - a32 * b04 + a33 * b03,"
|
||||
" a22 * b04 - a21 * b05 - a23 * b03,"
|
||||
" a12 * b08 - a10 * b11 - a13 * b07,"
|
||||
" a00 * b11 - a02 * b08 + a03 * b07,"
|
||||
" a32 * b02 - a30 * b05 - a33 * b01,"
|
||||
" a20 * b05 - a22 * b02 + a23 * b01,"
|
||||
" a10 * b10 - a11 * b08 + a13 * b06,"
|
||||
" a01 * b08 - a00 * b10 - a03 * b06,"
|
||||
" a30 * b04 - a31 * b02 + a33 * b00,"
|
||||
" a21 * b02 - a20 * b04 - a23 * b00,"
|
||||
" a11 * b07 - a10 * b09 - a12 * b06,"
|
||||
" a00 * b09 - a01 * b07 + a02 * b06,"
|
||||
" a31 * b01 - a30 * b03 - a32 * b00,"
|
||||
" a20 * b03 - a21 * b01 + a22 * b00) / det;"
|
||||
"}"
|
||||
).c_str());
|
||||
}
|
||||
}
|
||||
this->write(name);
|
||||
}
|
||||
|
||||
@ -300,8 +372,8 @@ void MetalCodeGenerator::writeSpecialIntrinsic(const FunctionCall & c, SpecialIn
|
||||
// of type 'arg'.
|
||||
String MetalCodeGenerator::getMatrixConstructHelper(const Type& matrix, const Type& arg) {
|
||||
String key = matrix.name() + arg.name();
|
||||
auto found = fMatrixConstructHelpers.find(key);
|
||||
if (found != fMatrixConstructHelpers.end()) {
|
||||
auto found = fHelpers.find(key);
|
||||
if (found != fHelpers.end()) {
|
||||
return found->second;
|
||||
}
|
||||
String name;
|
||||
@ -331,8 +403,34 @@ String MetalCodeGenerator::getMatrixConstructHelper(const Type& matrix, const Ty
|
||||
fExtraFunctions.writeText(")");
|
||||
}
|
||||
fExtraFunctions.writeText(");\n}\n");
|
||||
}
|
||||
else if (matrix.rows() == 2 && matrix.columns() == 2) {
|
||||
} else if (arg.kind() == Type::kMatrix_Kind) {
|
||||
// creating a matrix from another matrix
|
||||
int argColumns = arg.columns();
|
||||
int argRows = arg.rows();
|
||||
name = "float" + to_string(columns) + "x" + to_string(rows) + "_from_float" +
|
||||
to_string(argColumns) + "x" + to_string(argRows);
|
||||
fExtraFunctions.printf("float%dx%d %s(float%dx%d m) {\n",
|
||||
columns, rows, name.c_str(), argColumns, argRows);
|
||||
fExtraFunctions.printf(" return float%dx%d(", columns, rows);
|
||||
for (int i = 0; i < columns; ++i) {
|
||||
if (i > 0) {
|
||||
fExtraFunctions.writeText(", ");
|
||||
}
|
||||
fExtraFunctions.printf("float%d(", rows);
|
||||
for (int j = 0; j < rows; ++j) {
|
||||
if (j > 0) {
|
||||
fExtraFunctions.writeText(", ");
|
||||
}
|
||||
if (i < argColumns && j < argRows) {
|
||||
fExtraFunctions.printf("m[%d][%d]", i, j);
|
||||
} else {
|
||||
fExtraFunctions.writeText("0");
|
||||
}
|
||||
}
|
||||
fExtraFunctions.writeText(")");
|
||||
}
|
||||
fExtraFunctions.writeText(");\n}\n");
|
||||
} else if (matrix.rows() == 2 && matrix.columns() == 2 && arg == *fContext.fFloat4_Type) {
|
||||
// float2x2(float4) doesn't work, need to split it into float2x2(float2, float2)
|
||||
name = "float2x2_from_float4";
|
||||
fExtraFunctions.printf(
|
||||
@ -341,12 +439,11 @@ String MetalCodeGenerator::getMatrixConstructHelper(const Type& matrix, const Ty
|
||||
"}\n",
|
||||
name.c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
SkASSERT(false);
|
||||
name = "<error>";
|
||||
}
|
||||
fMatrixConstructHelpers[key] = name;
|
||||
fHelpers[key] = name;
|
||||
return name;
|
||||
}
|
||||
|
||||
@ -380,15 +477,14 @@ void MetalCodeGenerator::writeConstructor(const Constructor& c, Precedence paren
|
||||
for (const auto& arg : c.fArguments) {
|
||||
this->write(separator);
|
||||
separator = ", ";
|
||||
if (Type::kMatrix_Kind == c.fType.kind() && Type::kScalar_Kind == arg->fType.kind()) {
|
||||
// float2x2(float, float, float, float) doesn't work in Metal 1, so we need to merge
|
||||
// to float2x2(float2, float2).
|
||||
if (Type::kMatrix_Kind == c.fType.kind() && arg->fType.columns() != c.fType.rows()) {
|
||||
// merge scalars and smaller vectors together
|
||||
if (!scalarCount) {
|
||||
this->writeType(c.fType.componentType());
|
||||
this->write(to_string(c.fType.rows()));
|
||||
this->write("(");
|
||||
}
|
||||
++scalarCount;
|
||||
scalarCount += arg->fType.columns();
|
||||
}
|
||||
this->writeExpression(*arg, kSequence_Precedence);
|
||||
if (scalarCount && scalarCount == c.fType.rows()) {
|
||||
@ -527,10 +623,39 @@ MetalCodeGenerator::Precedence MetalCodeGenerator::GetBinaryPrecedence(Token::Ki
|
||||
}
|
||||
}
|
||||
|
||||
void MetalCodeGenerator::writeMatrixTimesEqualHelper(const Type& left, const Type& right,
|
||||
const Type& result) {
|
||||
String key = "TimesEqual" + left.name() + right.name();
|
||||
if (fHelpers.find(key) == fHelpers.end()) {
|
||||
fExtraFunctions.printf("%s operator*=(thread %s& left, thread const %s& right) {\n"
|
||||
" left = left * right;\n"
|
||||
" return left;\n"
|
||||
"}", result.name().c_str(), left.name().c_str(),
|
||||
right.name().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void MetalCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
|
||||
Precedence parentPrecedence) {
|
||||
Precedence precedence = GetBinaryPrecedence(b.fOperator);
|
||||
if (precedence >= parentPrecedence) {
|
||||
bool needParens = precedence >= parentPrecedence;
|
||||
switch (b.fOperator) {
|
||||
case Token::EQEQ:
|
||||
if (b.fLeft->fType.kind() == Type::kVector_Kind) {
|
||||
this->write("all");
|
||||
needParens = true;
|
||||
}
|
||||
break;
|
||||
case Token::NEQ:
|
||||
if (b.fLeft->fType.kind() == Type::kVector_Kind) {
|
||||
this->write("!all");
|
||||
needParens = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (needParens) {
|
||||
this->write("(");
|
||||
}
|
||||
if (Compiler::IsAssignment(b.fOperator) &&
|
||||
@ -541,6 +666,10 @@ void MetalCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
|
||||
// dereference it here.
|
||||
this->write("*");
|
||||
}
|
||||
if (b.fOperator == Token::STAREQ && b.fLeft->fType.kind() == Type::kMatrix_Kind &&
|
||||
b.fRight->fType.kind() == Type::kMatrix_Kind) {
|
||||
this->writeMatrixTimesEqualHelper(b.fLeft->fType, b.fRight->fType, b.fType);
|
||||
}
|
||||
this->writeExpression(*b.fLeft, precedence);
|
||||
if (b.fOperator != Token::EQ && Compiler::IsAssignment(b.fOperator) &&
|
||||
Expression::kSwizzle_Kind == b.fLeft->fKind && !b.fLeft->hasSideEffects()) {
|
||||
@ -561,7 +690,7 @@ void MetalCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
|
||||
this->write(String(" ") + Compiler::OperatorName(b.fOperator) + " ");
|
||||
}
|
||||
this->writeExpression(*b.fRight, precedence);
|
||||
if (precedence >= parentPrecedence) {
|
||||
if (needParens) {
|
||||
this->write(")");
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +107,8 @@ protected:
|
||||
};
|
||||
|
||||
enum MetalIntrinsic {
|
||||
kEqual_MetalIntrinsic,
|
||||
kNotEqual_MetalIntrinsic,
|
||||
kLessThan_MetalIntrinsic,
|
||||
kLessThanEqual_MetalIntrinsic,
|
||||
kGreaterThan_MetalIntrinsic,
|
||||
@ -186,6 +188,8 @@ protected:
|
||||
|
||||
String getMatrixConstructHelper(const Type& matrix, const Type& arg);
|
||||
|
||||
void writeMatrixTimesEqualHelper(const Type& left, const Type& right, const Type& result);
|
||||
|
||||
void writeSpecialIntrinsic(const FunctionCall& c, SpecialIntrinsic kind);
|
||||
|
||||
bool canCoerce(const Type& t1, const Type& t2);
|
||||
@ -272,7 +276,7 @@ protected:
|
||||
std::unordered_map<const FunctionDeclaration*, Requirements> fRequirements;
|
||||
bool fSetupFragPositionGlobal = false;
|
||||
bool fSetupFragPositionLocal = false;
|
||||
std::unordered_map<String, String> fMatrixConstructHelpers;
|
||||
std::unordered_map<String, String> fHelpers;
|
||||
int fUniformBuffer = -1;
|
||||
|
||||
typedef CodeGenerator INHERITED;
|
||||
|
@ -53,9 +53,11 @@ struct Variable : public Symbol {
|
||||
}
|
||||
|
||||
bool dead() const {
|
||||
return !fWriteCount || (!fReadCount && !(fModifiers.fFlags & (Modifiers::kOut_Flag |
|
||||
Modifiers::kPLS_Flag |
|
||||
Modifiers::kPLSOut_Flag)));
|
||||
return (!fWriteCount && !(fModifiers.fFlags & (Modifiers::kIn_Flag |
|
||||
Modifiers::kUniform_Flag))) ||
|
||||
(!fReadCount && !(fModifiers.fFlags & (Modifiers::kOut_Flag |
|
||||
Modifiers::kPLS_Flag |
|
||||
Modifiers::kPLSOut_Flag)));
|
||||
}
|
||||
|
||||
mutable Modifiers fModifiers;
|
||||
|
@ -261,40 +261,46 @@ DEF_TEST(SkSLStructs, r) {
|
||||
"};"
|
||||
"B b1, b2, b3;"
|
||||
"void main() {"
|
||||
" a1.x = 0;"
|
||||
" b1.x = 0;"
|
||||
" sk_FragColor.r = half(a1.x + b1.x);"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"struct A {\n"
|
||||
" int x;\n"
|
||||
" int y;\n"
|
||||
"} a1, a2;\n"
|
||||
"A a3;\n"
|
||||
"} a1;\n"
|
||||
"struct B {\n"
|
||||
" float x;\n"
|
||||
" float[2] y;\n"
|
||||
" layout (binding = 1) A z;\n"
|
||||
"} b1, b2, b3;\n"
|
||||
"} b1;\n"
|
||||
"void main() {\n"
|
||||
" a1.x = 0;\n"
|
||||
" b1.x = 0.0;\n"
|
||||
" sk_FragColor.x = float(a1.x) + b1.x;\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLVersion, r) {
|
||||
test(r,
|
||||
"in float test; void main() { sk_FragColor = half4(0.75); }",
|
||||
"in float test; void main() { sk_FragColor.r = half(test); }",
|
||||
*SkSL::ShaderCapsFactory::Version450Core(),
|
||||
"#version 450 core\n"
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"in float test;\n"
|
||||
"void main() {\n"
|
||||
" sk_FragColor = vec4(0.75);\n"
|
||||
" sk_FragColor.x = test;\n"
|
||||
"}\n");
|
||||
test(r,
|
||||
"in float test; void main() { sk_FragColor = half4(0.75); }",
|
||||
"in float test; void main() { sk_FragColor.r = half(test); }",
|
||||
*SkSL::ShaderCapsFactory::Version110(),
|
||||
"#version 110\n"
|
||||
"varying float test;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = vec4(0.75);\n"
|
||||
" gl_FragColor.x = test;\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
@ -502,28 +508,43 @@ DEF_TEST(SkSLVectorConstructors, r) {
|
||||
"float3 v4 = float3(float2(1), 1.0);"
|
||||
"int2 v5 = int2(1);"
|
||||
"int2 v6 = int2(float2(1, 2));"
|
||||
"float2 v7 = float2(int2(1, 2));",
|
||||
"float2 v7 = float2(int2(1, 2));"
|
||||
"void main() {"
|
||||
"sk_FragColor.r = half(v1.x + v2.x + v3.x + v4.x + v5.x + v6.x + v7.x);"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"vec2 v1 = vec2(1.0);\n"
|
||||
"vec2 v2 = vec2(1.0, 2.0);\n"
|
||||
"vec2 v3 = vec2(1.0);\n"
|
||||
"vec3 v4 = vec3(vec2(1.0), 1.0);\n"
|
||||
"ivec2 v5 = ivec2(1);\n"
|
||||
"ivec2 v6 = ivec2(vec2(1.0, 2.0));\n"
|
||||
"vec2 v7 = vec2(ivec2(1, 2));\n");
|
||||
"vec2 v7 = vec2(ivec2(1, 2));\n"
|
||||
"void main() {\n"
|
||||
" sk_FragColor.x = (((((v1.x + v2.x) + v3.x) + v4.x) + float(v5.x)) + float(v6.x)) + "
|
||||
"v7.x;\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLArrayConstructors, r) {
|
||||
test(r,
|
||||
"float test1[] = float[](1, 2, 3, 4);"
|
||||
"float2 test2[] = float2[](float2(1, 2), float2(3, 4));"
|
||||
"float4x4 test3[] = float4x4[]();",
|
||||
"float4x4 test3[] = float4x4[]();"
|
||||
"void main() {"
|
||||
"sk_FragColor.r = half(test1[0] + test2[0].x + test3[0][0][0]);"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"float test1[] = float[](1.0, 2.0, 3.0, 4.0);\n"
|
||||
"vec2 test2[] = vec2[](vec2(1.0, 2.0), vec2(3.0, 4.0));\n"
|
||||
"mat4 test3[] = mat4[]();\n");
|
||||
"mat4 test3[] = mat4[]();\n"
|
||||
"void main() {\n"
|
||||
" sk_FragColor.x = (test1[0] + test2[0].x) + test3[0][0][0];\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLDerivatives, r) {
|
||||
@ -1089,14 +1110,24 @@ DEF_TEST(SkSLOffset, r) {
|
||||
"layout(offset = 0) int x;"
|
||||
"layout(offset = 4) int y;"
|
||||
"int z;"
|
||||
"} test;",
|
||||
"} test;"
|
||||
"void main() {"
|
||||
"Test t;"
|
||||
"t.x = 0;"
|
||||
"sk_FragColor.r = half(t.x);"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
"struct Test {\n"
|
||||
" layout (offset = 0) int x;\n"
|
||||
" layout (offset = 4) int y;\n"
|
||||
" int z;\n"
|
||||
"} test;\n");
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"void main() {\n"
|
||||
" struct Test {\n"
|
||||
" layout (offset = 0) int x;\n"
|
||||
" layout (offset = 4) int y;\n"
|
||||
" int z;\n"
|
||||
" } t;\n"
|
||||
" t.x = 0;\n"
|
||||
" sk_FragColor.x = float(t.x);\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLFragCoord, r) {
|
||||
@ -1752,9 +1783,14 @@ DEF_TEST(SkSLTypePrecision, r) {
|
||||
"double4 d4 = double4(1, 2, 3, 4);"
|
||||
"float2x2 f22 = float2x2(1, 2, 3, 4);"
|
||||
"half2x4 h24 = half2x4(1, 2, 3, 4, 5, 6, 7, 8);"
|
||||
"double4x2 d42 = double4x2(1, 2, 3, 4, 5, 6, 7, 8);",
|
||||
"double4x2 d42 = double4x2(1, 2, 3, 4, 5, 6, 7, 8);"
|
||||
"void main() {"
|
||||
"sk_FragColor.r = half(f + h + d + f2.x + h3.x + d4.x + f22[0][0] + h24[0][0] + "
|
||||
"d42[0][0]);"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"float f = 1.0;\n"
|
||||
"float h = 2.0;\n"
|
||||
"double d = 3.0;\n"
|
||||
@ -1763,23 +1799,34 @@ DEF_TEST(SkSLTypePrecision, r) {
|
||||
"dvec4 d4 = dvec4(1.0, 2.0, 3.0, 4.0);\n"
|
||||
"mat2 f22 = mat2(1.0, 2.0, 3.0, 4.0);\n"
|
||||
"mat2x4 h24 = mat2x4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);\n"
|
||||
"dmat4x2 d42 = dmat4x2(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);\n");
|
||||
"dmat4x2 d42 = dmat4x2(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);\n"
|
||||
"void main() {\n"
|
||||
" sk_FragColor.x = float(((((((double(f + h) + d) + double(f2.x)) + double(h3.x)) + "
|
||||
"d4.x) + double(f22[0][0])) + double(h24[0][0])) + d42[0][0]);\n"
|
||||
"}\n");
|
||||
test(r,
|
||||
"float f = 1;"
|
||||
"half h = 2;"
|
||||
"float2 f2 = float2(1, 2);"
|
||||
"half3 h3 = half3(1, 2, 3);"
|
||||
"float2x2 f22 = float2x2(1, 2, 3, 4);"
|
||||
"half2x4 h24 = half2x4(1, 2, 3, 4, 5, 6, 7, 8);",
|
||||
"half2x4 h24 = half2x4(1, 2, 3, 4, 5, 6, 7, 8);"
|
||||
"void main() {"
|
||||
"sk_FragColor.r = half(f + h + f2.x + h3.x + f22[0][0] + h24[0][0]);"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::UsesPrecisionModifiers(),
|
||||
"#version 400\n"
|
||||
"precision mediump float;\n"
|
||||
"out mediump vec4 sk_FragColor;\n"
|
||||
"highp float f = 1.0;\n"
|
||||
"mediump float h = 2.0;\n"
|
||||
"highp vec2 f2 = vec2(1.0, 2.0);\n"
|
||||
"mediump vec3 h3 = vec3(1.0, 2.0, 3.0);\n"
|
||||
"highp mat2 f22 = mat2(1.0, 2.0, 3.0, 4.0);\n"
|
||||
"mediump mat2x4 h24 = mat2x4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);\n");
|
||||
"mediump mat2x4 h24 = mat2x4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);\n"
|
||||
"void main() {\n"
|
||||
" sk_FragColor.x = ((((f + h) + f2.x) + h3.x) + f22[0][0]) + h24[0][0];\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLNumberConversions, r) {
|
||||
@ -1819,9 +1866,17 @@ DEF_TEST(SkSLNumberConversions, r) {
|
||||
"float us2f = us;"
|
||||
"float ui2f = ui;"
|
||||
"float h2f = h;"
|
||||
"float f2f = f;",
|
||||
"float f2f = f;"
|
||||
"void main() {"
|
||||
"sk_FragColor.r = half(s + i + us + half(ui) + h + f + s2s + i2s + us2s + ui2s + h2s + "
|
||||
"f2s + s2i + i2i + us2i + ui2i + h2i + f2i + s2us + i2us + us2us + "
|
||||
"ui2us + h2us + f2us + half(s2ui) + half(i2ui) + half(us2ui) + "
|
||||
"half(ui2ui) + half(h2ui) + half(f2ui) + s2f + i2f + us2f + ui2f + "
|
||||
"h2f + f2f);"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"int s = int(sqrt(1.0));\n"
|
||||
"int i = int(sqrt(1.0));\n"
|
||||
"uint us = uint(sqrt(1.0));\n"
|
||||
@ -1857,7 +1912,16 @@ DEF_TEST(SkSLNumberConversions, r) {
|
||||
"float us2f = float(us);\n"
|
||||
"float ui2f = float(ui);\n"
|
||||
"float h2f = h;\n"
|
||||
"float f2f = f;\n");
|
||||
"float f2f = f;\n"
|
||||
"void main() {\n"
|
||||
" sk_FragColor.x = ((((((((((((((((((((((((((((((((float((s + i) + int(us)) + "
|
||||
"float(ui)) + h) + f) + float(s2s)) + float(i2s)) + float(us2s)) + float(ui2s)) + "
|
||||
"float(h2s)) + float(f2s)) + float(s2i)) + float(i2i)) + float(us2i)) + float(ui2i)) + "
|
||||
"float(h2i)) + float(f2i)) + float(s2us)) + float(i2us)) + float(us2us)) + "
|
||||
"float(ui2us)) + float(h2us)) + float(f2us)) + float(s2ui)) + float(i2ui)) + "
|
||||
"float(us2ui)) + float(ui2ui)) + float(h2ui)) + float(f2ui)) + s2f) + i2f) + us2f) + "
|
||||
"ui2f) + h2f) + f2f;\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLForceHighPrecision, r) {
|
||||
|
Loading…
Reference in New Issue
Block a user