Add support for matrix == and != in Metal shaders.

We need to polyfill an operator== and != when these are first
encountered in the code.

Change-Id: I539c838ee1871bcb0c4b66abb8a4a0f91146cd4f
Bug: skia:11306
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/368496
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
John Stiles 2021-02-09 17:22:44 -05:00
parent 2271b54c1e
commit c501857188
8 changed files with 434 additions and 166 deletions

View File

@ -1,4 +1,6 @@
uniform half4 colorGreen, colorRed;
uniform half2x2 testMatrix2x2;
uniform half3x3 testMatrix3x3;
bool test_float() {
float3 v1 = float3x3(1) * float3(2);
@ -42,6 +44,15 @@ bool test_half() {
return true;
}
half4 main() {
return test_float() && test_half() ? colorGreen : colorRed;
bool test_equality() {
bool ok = true;
ok = ok && testMatrix2x2 == half2x2(1,2,3,4);
ok = ok && testMatrix3x3 == half3x3(1,2,3,4,5,6,7,8,9);
ok = ok && testMatrix2x2 != half2x2(100);
ok = ok && testMatrix3x3 != half3x3(9,8,7,6,5,4,3,2,1);
return ok;
}
half4 main() {
return test_float() && test_half() && test_equality() ? colorGreen : colorRed;
}

View File

@ -1186,7 +1186,7 @@ void MetalCodeGenerator::writeSwizzle(const Swizzle& swizzle) {
void MetalCodeGenerator::writeMatrixTimesEqualHelper(const Type& left, const Type& right,
const Type& result) {
String key = "TimesEqual" + this->typeName(left) + this->typeName(right);
String key = "TimesEqual" + this->typeName(left) + ":" + this->typeName(right);
auto [iter, wasInserted] = fHelpers.insert(key);
if (wasInserted) {
@ -1199,6 +1199,50 @@ void MetalCodeGenerator::writeMatrixTimesEqualHelper(const Type& left, const Typ
}
}
void MetalCodeGenerator::writeMatrixEqualityHelper(const Type& left, const Type& right) {
SkASSERTF(left.rows() == right.rows() && left.columns() == right.columns(), "left=%s, right=%s",
left.description().c_str(), right.description().c_str());
String key = "Equality" + this->typeName(left) + ":" + this->typeName(right);
auto [iter, wasInserted] = fHelpers.insert(key);
if (wasInserted) {
fExtraFunctions.printf(
"thread bool operator==(const %s left, const %s right) {\n"
" return",
this->typeName(left).c_str(), this->typeName(right).c_str());
for (int index=0; index<left.columns(); ++index) {
fExtraFunctions.printf("%s all(left[%d] == right[%d])",
index == 0 ? "" : " &&", index, index);
}
fExtraFunctions.printf(";\n"
"}\n");
}
}
void MetalCodeGenerator::writeMatrixInequalityHelper(const Type& left, const Type& right) {
SkASSERTF(left.rows() == right.rows() && left.columns() == right.columns(), "left=%s, right=%s",
left.description().c_str(), right.description().c_str());
String key = "Inequality" + this->typeName(left) + ":" + this->typeName(right);
auto [iter, wasInserted] = fHelpers.insert(key);
if (wasInserted) {
fExtraFunctions.printf(
"thread bool operator!=(const %s left, const %s right) {\n"
" return",
this->typeName(left).c_str(), this->typeName(right).c_str());
for (int index=0; index<left.columns(); ++index) {
fExtraFunctions.printf("%s any(left[%d] != right[%d])",
index == 0 ? "" : " ||", index, index);
}
fExtraFunctions.printf(";\n"
"}\n");
}
}
void MetalCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
Precedence parentPrecedence) {
const Expression& left = *b.left();
@ -1227,8 +1271,14 @@ void MetalCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
if (needParens) {
this->write("(");
}
if (op == Token::Kind::TK_STAREQ && leftType.isMatrix() && rightType.isMatrix()) {
this->writeMatrixTimesEqualHelper(leftType, rightType, b.type());
if (leftType.isMatrix() && rightType.isMatrix()) {
if (op == Token::Kind::TK_STAREQ) {
this->writeMatrixTimesEqualHelper(leftType, rightType, b.type());
} else if (op == Token::Kind::TK_EQEQ) {
this->writeMatrixEqualityHelper(leftType, rightType);
} else if (op == Token::Kind::TK_NEQ) {
this->writeMatrixInequalityHelper(leftType, rightType);
}
}
this->writeExpression(left, precedence);
if (op != Token::Kind::TK_EQ && Operators::IsAssignment(op) &&

View File

@ -210,8 +210,13 @@ protected:
void assembleMatrixFromExpressions(const ExpressionArray& args, int rows, int columns);
void writeMatrixCompMult();
void writeMatrixTimesEqualHelper(const Type& left, const Type& right, const Type& result);
void writeMatrixEqualityHelper(const Type& left, const Type& right);
void writeMatrixInequalityHelper(const Type& left, const Type& right);
void writeArgumentList(const ExpressionArray& arguments);
void writeSimpleIntrinsic(const FunctionCall& c);

View File

@ -59,6 +59,11 @@ static void test_one_permutation(skiatest::Reporter* r,
set_uniform(&builder, "colorBlue", SkV4{0, 0, 1, 1});
set_uniform(&builder, "colorWhite", SkV4{1, 1, 1, 1});
set_uniform(&builder, "testInputs", SkV4{-1.25, 0, 0.75, 2.25});
set_uniform(&builder, "testMatrix2x2", std::array<float,4>{1, 2,
3, 4});
set_uniform(&builder, "testMatrix3x3", std::array<float,9>{1, 2, 3,
4, 5, 6,
7, 8, 9});
set_uniform(&builder, "unknownInput", 1.0f);
sk_sp<SkShader> shader = builder.makeShader(/*localMatrix=*/nullptr, /*isOpaque=*/true);

View File

@ -13,6 +13,9 @@ struct Globals {
texture2d<float> s;
sampler sSmplr;
};
thread bool operator!=(const float4x4 left, const float4x4 right) {
return any(left[0] != right[0]) || any(left[1] != right[1]) || any(left[2] != right[2]) || any(left[3] != right[3]);
}
fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], texture2d<float> s[[texture(0)]], sampler sSmplr[[sampler(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {

View File

@ -8,6 +8,8 @@ OpName %sk_Clockwise "sk_Clockwise"
OpName %_UniformBuffer "_UniformBuffer"
OpMemberName %_UniformBuffer 0 "colorGreen"
OpMemberName %_UniformBuffer 1 "colorRed"
OpMemberName %_UniformBuffer 2 "testMatrix2x2"
OpMemberName %_UniformBuffer 3 "testMatrix3x3"
OpName %_entrypoint "_entrypoint"
OpName %main "main"
OpName %_1_m3 "_1_m3"
@ -18,6 +20,7 @@ OpName %_6_m3 "_6_m3"
OpName %_7_m5 "_7_m5"
OpName %_8_m6 "_8_m6"
OpName %_9_m11 "_9_m11"
OpName %_11_ok "_11_ok"
OpDecorate %sk_FragColor RelaxedPrecision
OpDecorate %sk_FragColor Location 0
OpDecorate %sk_FragColor Index 0
@ -27,44 +30,77 @@ OpMemberDecorate %_UniformBuffer 0 Offset 0
OpMemberDecorate %_UniformBuffer 0 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 1 Offset 16
OpMemberDecorate %_UniformBuffer 1 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 2 Offset 32
OpMemberDecorate %_UniformBuffer 2 ColMajor
OpMemberDecorate %_UniformBuffer 2 MatrixStride 16
OpMemberDecorate %_UniformBuffer 2 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 3 Offset 64
OpMemberDecorate %_UniformBuffer 3 ColMajor
OpMemberDecorate %_UniformBuffer 3 MatrixStride 16
OpMemberDecorate %_UniformBuffer 3 RelaxedPrecision
OpDecorate %_UniformBuffer Block
OpDecorate %10 Binding 0
OpDecorate %10 DescriptorSet 0
OpDecorate %93 RelaxedPrecision
OpDecorate %94 RelaxedPrecision
OpDecorate %92 RelaxedPrecision
OpDecorate %95 RelaxedPrecision
OpDecorate %96 RelaxedPrecision
OpDecorate %94 RelaxedPrecision
OpDecorate %97 RelaxedPrecision
OpDecorate %99 RelaxedPrecision
OpDecorate %100 RelaxedPrecision
OpDecorate %98 RelaxedPrecision
OpDecorate %96 RelaxedPrecision
OpDecorate %96 RelaxedPrecision
OpDecorate %103 RelaxedPrecision
OpDecorate %104 RelaxedPrecision
OpDecorate %102 RelaxedPrecision
OpDecorate %98 RelaxedPrecision
OpDecorate %105 RelaxedPrecision
OpDecorate %106 RelaxedPrecision
OpDecorate %109 RelaxedPrecision
OpDecorate %110 RelaxedPrecision
OpDecorate %104 RelaxedPrecision
OpDecorate %108 RelaxedPrecision
OpDecorate %108 RelaxedPrecision
OpDecorate %113 RelaxedPrecision
OpDecorate %114 RelaxedPrecision
OpDecorate %111 RelaxedPrecision
OpDecorate %112 RelaxedPrecision
OpDecorate %110 RelaxedPrecision
OpDecorate %110 RelaxedPrecision
OpDecorate %115 RelaxedPrecision
OpDecorate %116 RelaxedPrecision
OpDecorate %126 RelaxedPrecision
OpDecorate %127 RelaxedPrecision
OpDecorate %114 RelaxedPrecision
OpDecorate %117 RelaxedPrecision
OpDecorate %118 RelaxedPrecision
OpDecorate %128 RelaxedPrecision
OpDecorate %129 RelaxedPrecision
OpDecorate %125 RelaxedPrecision
OpDecorate %125 RelaxedPrecision
OpDecorate %130 RelaxedPrecision
OpDecorate %131 RelaxedPrecision
OpDecorate %127 RelaxedPrecision
OpDecorate %127 RelaxedPrecision
OpDecorate %132 RelaxedPrecision
OpDecorate %133 RelaxedPrecision
OpDecorate %134 RelaxedPrecision
OpDecorate %135 RelaxedPrecision
OpDecorate %131 RelaxedPrecision
OpDecorate %131 RelaxedPrecision
OpDecorate %151 RelaxedPrecision
OpDecorate %136 RelaxedPrecision
OpDecorate %137 RelaxedPrecision
OpDecorate %133 RelaxedPrecision
OpDecorate %133 RelaxedPrecision
OpDecorate %157 RelaxedPrecision
OpDecorate %159 RelaxedPrecision
OpDecorate %160 RelaxedPrecision
OpDecorate %158 RelaxedPrecision
OpDecorate %172 RelaxedPrecision
OpDecorate %178 RelaxedPrecision
OpDecorate %185 RelaxedPrecision
OpDecorate %186 RelaxedPrecision
OpDecorate %187 RelaxedPrecision
OpDecorate %184 RelaxedPrecision
OpDecorate %204 RelaxedPrecision
OpDecorate %208 RelaxedPrecision
OpDecorate %211 RelaxedPrecision
OpDecorate %212 RelaxedPrecision
OpDecorate %210 RelaxedPrecision
OpDecorate %210 RelaxedPrecision
OpDecorate %223 RelaxedPrecision
OpDecorate %227 RelaxedPrecision
OpDecorate %229 RelaxedPrecision
OpDecorate %230 RelaxedPrecision
OpDecorate %231 RelaxedPrecision
OpDecorate %228 RelaxedPrecision
OpDecorate %247 RelaxedPrecision
OpDecorate %255 RelaxedPrecision
OpDecorate %258 RelaxedPrecision
OpDecorate %259 RelaxedPrecision
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
@ -72,14 +108,16 @@ OpDecorate %151 RelaxedPrecision
%bool = OpTypeBool
%_ptr_Input_bool = OpTypePointer Input %bool
%sk_Clockwise = OpVariable %_ptr_Input_bool Input
%_UniformBuffer = OpTypeStruct %v4float %v4float
%v2float = OpTypeVector %float 2
%mat2v2float = OpTypeMatrix %v2float 2
%v3float = OpTypeVector %float 3
%mat3v3float = OpTypeMatrix %v3float 3
%_UniformBuffer = OpTypeStruct %v4float %v4float %mat2v2float %mat3v3float
%_ptr_Uniform__UniformBuffer = OpTypePointer Uniform %_UniformBuffer
%10 = OpVariable %_ptr_Uniform__UniformBuffer Uniform
%void = OpTypeVoid
%15 = OpTypeFunction %void
%18 = OpTypeFunction %v4float
%v2float = OpTypeVector %float 2
%mat2v2float = OpTypeMatrix %v2float 2
%19 = OpTypeFunction %void
%22 = OpTypeFunction %v4float
%_ptr_Function_mat2v2float = OpTypePointer Function %mat2v2float
%float_1 = OpConstant %float 1
%float_2 = OpConstant %float 2
@ -91,148 +129,274 @@ OpDecorate %151 RelaxedPrecision
%_ptr_Function_v2float = OpTypePointer Function %v2float
%mat4v4float = OpTypeMatrix %v4float 4
%_ptr_Function_mat4v4float = OpTypePointer Function %mat4v4float
%_ptr_Function_bool = OpTypePointer Function %bool
%true = OpConstantTrue %bool
%_ptr_Uniform_mat2v2float = OpTypePointer Uniform %mat2v2float
%int_2 = OpConstant %int 2
%v2bool = OpTypeVector %bool 2
%false = OpConstantFalse %bool
%_ptr_Uniform_mat3v3float = OpTypePointer Uniform %mat3v3float
%int_3 = OpConstant %int 3
%float_5 = OpConstant %float 5
%float_6 = OpConstant %float 6
%float_7 = OpConstant %float 7
%float_8 = OpConstant %float 8
%float_9 = OpConstant %float 9
%v3bool = OpTypeVector %bool 3
%float_100 = OpConstant %float 100
%_ptr_Function_v4float = OpTypePointer Function %v4float
%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
%_entrypoint = OpFunction %void None %15
%16 = OpLabel
%17 = OpFunctionCall %v4float %main
OpStore %sk_FragColor %17
%int_1 = OpConstant %int 1
%_entrypoint = OpFunction %void None %19
%20 = OpLabel
%21 = OpFunctionCall %v4float %main
OpStore %sk_FragColor %21
OpReturn
OpFunctionEnd
%main = OpFunction %v4float None %18
%19 = OpLabel
%main = OpFunction %v4float None %22
%23 = OpLabel
%_1_m3 = OpVariable %_ptr_Function_mat2v2float Function
%_2_m5 = OpVariable %_ptr_Function_mat2v2float Function
%38 = OpVariable %_ptr_Function_mat2v2float Function
%40 = OpVariable %_ptr_Function_mat2v2float Function
%_3_m6 = OpVariable %_ptr_Function_mat2v2float Function
%_4_m11 = OpVariable %_ptr_Function_mat4v4float Function
%_6_m3 = OpVariable %_ptr_Function_mat2v2float Function
%_7_m5 = OpVariable %_ptr_Function_mat2v2float Function
%101 = OpVariable %_ptr_Function_mat2v2float Function
%103 = OpVariable %_ptr_Function_mat2v2float Function
%_8_m6 = OpVariable %_ptr_Function_mat2v2float Function
%_9_m11 = OpVariable %_ptr_Function_mat4v4float Function
%29 = OpCompositeConstruct %v2float %float_1 %float_2
%30 = OpCompositeConstruct %v2float %float_3 %float_4
%28 = OpCompositeConstruct %mat2v2float %29 %30
OpStore %_1_m3 %28
%31 = OpLoad %mat2v2float %_1_m3
%34 = OpCompositeConstruct %v2float %float_1 %float_0
%35 = OpCompositeConstruct %v2float %float_0 %float_1
%32 = OpCompositeConstruct %mat2v2float %34 %35
%36 = OpMatrixTimesMatrix %mat2v2float %31 %32
OpStore %_1_m3 %36
%40 = OpCompositeConstruct %v2float %float_1 %float_2
%41 = OpCompositeConstruct %v2float %float_3 %float_4
%39 = OpCompositeConstruct %mat2v2float %40 %41
OpStore %38 %39
%44 = OpAccessChain %_ptr_Function_v2float %38 %int_0
%46 = OpLoad %v2float %44
%47 = OpCompositeExtract %float %46 0
%49 = OpCompositeConstruct %v2float %47 %float_0
%50 = OpCompositeConstruct %v2float %float_0 %47
%48 = OpCompositeConstruct %mat2v2float %49 %50
OpStore %_2_m5 %48
%53 = OpCompositeConstruct %v2float %float_1 %float_2
%54 = OpCompositeConstruct %v2float %float_3 %float_4
%52 = OpCompositeConstruct %mat2v2float %53 %54
OpStore %_3_m6 %52
%55 = OpLoad %mat2v2float %_3_m6
%56 = OpLoad %mat2v2float %_2_m5
%57 = OpCompositeExtract %v2float %55 0
%58 = OpCompositeExtract %v2float %56 0
%59 = OpFAdd %v2float %57 %58
%60 = OpCompositeExtract %v2float %55 1
%61 = OpCompositeExtract %v2float %56 1
%62 = OpFAdd %v2float %60 %61
%63 = OpCompositeConstruct %mat2v2float %59 %62
OpStore %_3_m6 %63
%68 = OpCompositeConstruct %v4float %float_2 %float_0 %float_0 %float_0
%69 = OpCompositeConstruct %v4float %float_0 %float_2 %float_0 %float_0
%70 = OpCompositeConstruct %v4float %float_0 %float_0 %float_2 %float_0
%71 = OpCompositeConstruct %v4float %float_0 %float_0 %float_0 %float_2
%67 = OpCompositeConstruct %mat4v4float %68 %69 %70 %71
OpStore %_4_m11 %67
%72 = OpLoad %mat4v4float %_4_m11
%74 = OpCompositeConstruct %v4float %float_1 %float_0 %float_0 %float_0
%75 = OpCompositeConstruct %v4float %float_0 %float_1 %float_0 %float_0
%76 = OpCompositeConstruct %v4float %float_0 %float_0 %float_1 %float_0
%77 = OpCompositeConstruct %v4float %float_0 %float_0 %float_0 %float_1
%73 = OpCompositeConstruct %mat4v4float %74 %75 %76 %77
%78 = OpCompositeExtract %v4float %72 0
%79 = OpCompositeExtract %v4float %73 0
%80 = OpFSub %v4float %78 %79
%81 = OpCompositeExtract %v4float %72 1
%82 = OpCompositeExtract %v4float %73 1
%83 = OpFSub %v4float %81 %82
%84 = OpCompositeExtract %v4float %72 2
%85 = OpCompositeExtract %v4float %73 2
%86 = OpFSub %v4float %84 %85
%87 = OpCompositeExtract %v4float %72 3
%88 = OpCompositeExtract %v4float %73 3
%89 = OpFSub %v4float %87 %88
%90 = OpCompositeConstruct %mat4v4float %80 %83 %86 %89
OpStore %_4_m11 %90
%93 = OpCompositeConstruct %v2float %float_1 %float_2
%94 = OpCompositeConstruct %v2float %float_3 %float_4
%92 = OpCompositeConstruct %mat2v2float %93 %94
OpStore %_6_m3 %92
%95 = OpLoad %mat2v2float %_6_m3
%97 = OpCompositeConstruct %v2float %float_1 %float_0
%98 = OpCompositeConstruct %v2float %float_0 %float_1
%96 = OpCompositeConstruct %mat2v2float %97 %98
%99 = OpMatrixTimesMatrix %mat2v2float %95 %96
OpStore %_6_m3 %99
%103 = OpCompositeConstruct %v2float %float_1 %float_2
%104 = OpCompositeConstruct %v2float %float_3 %float_4
%102 = OpCompositeConstruct %mat2v2float %103 %104
OpStore %101 %102
%105 = OpAccessChain %_ptr_Function_v2float %101 %int_0
%106 = OpLoad %v2float %105
%107 = OpCompositeExtract %float %106 0
%109 = OpCompositeConstruct %v2float %107 %float_0
%110 = OpCompositeConstruct %v2float %float_0 %107
%108 = OpCompositeConstruct %mat2v2float %109 %110
OpStore %_7_m5 %108
%113 = OpCompositeConstruct %v2float %float_1 %float_2
%114 = OpCompositeConstruct %v2float %float_3 %float_4
%112 = OpCompositeConstruct %mat2v2float %113 %114
OpStore %_8_m6 %112
%115 = OpLoad %mat2v2float %_8_m6
%116 = OpLoad %mat2v2float %_7_m5
%117 = OpCompositeExtract %v2float %115 0
%118 = OpCompositeExtract %v2float %116 0
%119 = OpFAdd %v2float %117 %118
%120 = OpCompositeExtract %v2float %115 1
%121 = OpCompositeExtract %v2float %116 1
%122 = OpFAdd %v2float %120 %121
%123 = OpCompositeConstruct %mat2v2float %119 %122
OpStore %_8_m6 %123
%126 = OpCompositeConstruct %v4float %float_2 %float_0 %float_0 %float_0
%127 = OpCompositeConstruct %v4float %float_0 %float_2 %float_0 %float_0
%128 = OpCompositeConstruct %v4float %float_0 %float_0 %float_2 %float_0
%129 = OpCompositeConstruct %v4float %float_0 %float_0 %float_0 %float_2
%125 = OpCompositeConstruct %mat4v4float %126 %127 %128 %129
OpStore %_9_m11 %125
%130 = OpLoad %mat4v4float %_9_m11
%132 = OpCompositeConstruct %v4float %float_1 %float_0 %float_0 %float_0
%133 = OpCompositeConstruct %v4float %float_0 %float_1 %float_0 %float_0
%134 = OpCompositeConstruct %v4float %float_0 %float_0 %float_1 %float_0
%135 = OpCompositeConstruct %v4float %float_0 %float_0 %float_0 %float_1
%131 = OpCompositeConstruct %mat4v4float %132 %133 %134 %135
%136 = OpCompositeExtract %v4float %130 0
%137 = OpCompositeExtract %v4float %131 0
%138 = OpFSub %v4float %136 %137
%139 = OpCompositeExtract %v4float %130 1
%140 = OpCompositeExtract %v4float %131 1
%141 = OpFSub %v4float %139 %140
%142 = OpCompositeExtract %v4float %130 2
%143 = OpCompositeExtract %v4float %131 2
%144 = OpFSub %v4float %142 %143
%145 = OpCompositeExtract %v4float %130 3
%146 = OpCompositeExtract %v4float %131 3
%147 = OpFSub %v4float %145 %146
%148 = OpCompositeConstruct %mat4v4float %138 %141 %144 %147
OpStore %_9_m11 %148
%149 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%151 = OpLoad %v4float %149
OpReturnValue %151
%_11_ok = OpVariable %_ptr_Function_bool Function
%248 = OpVariable %_ptr_Function_v4float Function
%31 = OpCompositeConstruct %v2float %float_1 %float_2
%32 = OpCompositeConstruct %v2float %float_3 %float_4
%30 = OpCompositeConstruct %mat2v2float %31 %32
OpStore %_1_m3 %30
%33 = OpLoad %mat2v2float %_1_m3
%36 = OpCompositeConstruct %v2float %float_1 %float_0
%37 = OpCompositeConstruct %v2float %float_0 %float_1
%34 = OpCompositeConstruct %mat2v2float %36 %37
%38 = OpMatrixTimesMatrix %mat2v2float %33 %34
OpStore %_1_m3 %38
%42 = OpCompositeConstruct %v2float %float_1 %float_2
%43 = OpCompositeConstruct %v2float %float_3 %float_4
%41 = OpCompositeConstruct %mat2v2float %42 %43
OpStore %40 %41
%46 = OpAccessChain %_ptr_Function_v2float %40 %int_0
%48 = OpLoad %v2float %46
%49 = OpCompositeExtract %float %48 0
%51 = OpCompositeConstruct %v2float %49 %float_0
%52 = OpCompositeConstruct %v2float %float_0 %49
%50 = OpCompositeConstruct %mat2v2float %51 %52
OpStore %_2_m5 %50
%55 = OpCompositeConstruct %v2float %float_1 %float_2
%56 = OpCompositeConstruct %v2float %float_3 %float_4
%54 = OpCompositeConstruct %mat2v2float %55 %56
OpStore %_3_m6 %54
%57 = OpLoad %mat2v2float %_3_m6
%58 = OpLoad %mat2v2float %_2_m5
%59 = OpCompositeExtract %v2float %57 0
%60 = OpCompositeExtract %v2float %58 0
%61 = OpFAdd %v2float %59 %60
%62 = OpCompositeExtract %v2float %57 1
%63 = OpCompositeExtract %v2float %58 1
%64 = OpFAdd %v2float %62 %63
%65 = OpCompositeConstruct %mat2v2float %61 %64
OpStore %_3_m6 %65
%70 = OpCompositeConstruct %v4float %float_2 %float_0 %float_0 %float_0
%71 = OpCompositeConstruct %v4float %float_0 %float_2 %float_0 %float_0
%72 = OpCompositeConstruct %v4float %float_0 %float_0 %float_2 %float_0
%73 = OpCompositeConstruct %v4float %float_0 %float_0 %float_0 %float_2
%69 = OpCompositeConstruct %mat4v4float %70 %71 %72 %73
OpStore %_4_m11 %69
%74 = OpLoad %mat4v4float %_4_m11
%76 = OpCompositeConstruct %v4float %float_1 %float_0 %float_0 %float_0
%77 = OpCompositeConstruct %v4float %float_0 %float_1 %float_0 %float_0
%78 = OpCompositeConstruct %v4float %float_0 %float_0 %float_1 %float_0
%79 = OpCompositeConstruct %v4float %float_0 %float_0 %float_0 %float_1
%75 = OpCompositeConstruct %mat4v4float %76 %77 %78 %79
%80 = OpCompositeExtract %v4float %74 0
%81 = OpCompositeExtract %v4float %75 0
%82 = OpFSub %v4float %80 %81
%83 = OpCompositeExtract %v4float %74 1
%84 = OpCompositeExtract %v4float %75 1
%85 = OpFSub %v4float %83 %84
%86 = OpCompositeExtract %v4float %74 2
%87 = OpCompositeExtract %v4float %75 2
%88 = OpFSub %v4float %86 %87
%89 = OpCompositeExtract %v4float %74 3
%90 = OpCompositeExtract %v4float %75 3
%91 = OpFSub %v4float %89 %90
%92 = OpCompositeConstruct %mat4v4float %82 %85 %88 %91
OpStore %_4_m11 %92
%95 = OpCompositeConstruct %v2float %float_1 %float_2
%96 = OpCompositeConstruct %v2float %float_3 %float_4
%94 = OpCompositeConstruct %mat2v2float %95 %96
OpStore %_6_m3 %94
%97 = OpLoad %mat2v2float %_6_m3
%99 = OpCompositeConstruct %v2float %float_1 %float_0
%100 = OpCompositeConstruct %v2float %float_0 %float_1
%98 = OpCompositeConstruct %mat2v2float %99 %100
%101 = OpMatrixTimesMatrix %mat2v2float %97 %98
OpStore %_6_m3 %101
%105 = OpCompositeConstruct %v2float %float_1 %float_2
%106 = OpCompositeConstruct %v2float %float_3 %float_4
%104 = OpCompositeConstruct %mat2v2float %105 %106
OpStore %103 %104
%107 = OpAccessChain %_ptr_Function_v2float %103 %int_0
%108 = OpLoad %v2float %107
%109 = OpCompositeExtract %float %108 0
%111 = OpCompositeConstruct %v2float %109 %float_0
%112 = OpCompositeConstruct %v2float %float_0 %109
%110 = OpCompositeConstruct %mat2v2float %111 %112
OpStore %_7_m5 %110
%115 = OpCompositeConstruct %v2float %float_1 %float_2
%116 = OpCompositeConstruct %v2float %float_3 %float_4
%114 = OpCompositeConstruct %mat2v2float %115 %116
OpStore %_8_m6 %114
%117 = OpLoad %mat2v2float %_8_m6
%118 = OpLoad %mat2v2float %_7_m5
%119 = OpCompositeExtract %v2float %117 0
%120 = OpCompositeExtract %v2float %118 0
%121 = OpFAdd %v2float %119 %120
%122 = OpCompositeExtract %v2float %117 1
%123 = OpCompositeExtract %v2float %118 1
%124 = OpFAdd %v2float %122 %123
%125 = OpCompositeConstruct %mat2v2float %121 %124
OpStore %_8_m6 %125
%128 = OpCompositeConstruct %v4float %float_2 %float_0 %float_0 %float_0
%129 = OpCompositeConstruct %v4float %float_0 %float_2 %float_0 %float_0
%130 = OpCompositeConstruct %v4float %float_0 %float_0 %float_2 %float_0
%131 = OpCompositeConstruct %v4float %float_0 %float_0 %float_0 %float_2
%127 = OpCompositeConstruct %mat4v4float %128 %129 %130 %131
OpStore %_9_m11 %127
%132 = OpLoad %mat4v4float %_9_m11
%134 = OpCompositeConstruct %v4float %float_1 %float_0 %float_0 %float_0
%135 = OpCompositeConstruct %v4float %float_0 %float_1 %float_0 %float_0
%136 = OpCompositeConstruct %v4float %float_0 %float_0 %float_1 %float_0
%137 = OpCompositeConstruct %v4float %float_0 %float_0 %float_0 %float_1
%133 = OpCompositeConstruct %mat4v4float %134 %135 %136 %137
%138 = OpCompositeExtract %v4float %132 0
%139 = OpCompositeExtract %v4float %133 0
%140 = OpFSub %v4float %138 %139
%141 = OpCompositeExtract %v4float %132 1
%142 = OpCompositeExtract %v4float %133 1
%143 = OpFSub %v4float %141 %142
%144 = OpCompositeExtract %v4float %132 2
%145 = OpCompositeExtract %v4float %133 2
%146 = OpFSub %v4float %144 %145
%147 = OpCompositeExtract %v4float %132 3
%148 = OpCompositeExtract %v4float %133 3
%149 = OpFSub %v4float %147 %148
%150 = OpCompositeConstruct %mat4v4float %140 %143 %146 %149
OpStore %_9_m11 %150
OpStore %_11_ok %true
%154 = OpAccessChain %_ptr_Uniform_mat2v2float %10 %int_2
%157 = OpLoad %mat2v2float %154
%159 = OpCompositeConstruct %v2float %float_1 %float_2
%160 = OpCompositeConstruct %v2float %float_3 %float_4
%158 = OpCompositeConstruct %mat2v2float %159 %160
%162 = OpCompositeExtract %v2float %157 0
%163 = OpCompositeExtract %v2float %158 0
%164 = OpFOrdEqual %v2bool %162 %163
%165 = OpAll %bool %164
%166 = OpCompositeExtract %v2float %157 1
%167 = OpCompositeExtract %v2float %158 1
%168 = OpFOrdEqual %v2bool %166 %167
%169 = OpAll %bool %168
%170 = OpLogicalAnd %bool %165 %169
OpStore %_11_ok %170
%172 = OpLoad %bool %_11_ok
OpSelectionMerge %174 None
OpBranchConditional %172 %173 %174
%173 = OpLabel
%175 = OpAccessChain %_ptr_Uniform_mat3v3float %10 %int_3
%178 = OpLoad %mat3v3float %175
%185 = OpCompositeConstruct %v3float %float_1 %float_2 %float_3
%186 = OpCompositeConstruct %v3float %float_4 %float_5 %float_6
%187 = OpCompositeConstruct %v3float %float_7 %float_8 %float_9
%184 = OpCompositeConstruct %mat3v3float %185 %186 %187
%189 = OpCompositeExtract %v3float %178 0
%190 = OpCompositeExtract %v3float %184 0
%191 = OpFOrdEqual %v3bool %189 %190
%192 = OpAll %bool %191
%193 = OpCompositeExtract %v3float %178 1
%194 = OpCompositeExtract %v3float %184 1
%195 = OpFOrdEqual %v3bool %193 %194
%196 = OpAll %bool %195
%197 = OpLogicalAnd %bool %192 %196
%198 = OpCompositeExtract %v3float %178 2
%199 = OpCompositeExtract %v3float %184 2
%200 = OpFOrdEqual %v3bool %198 %199
%201 = OpAll %bool %200
%202 = OpLogicalAnd %bool %197 %201
OpBranch %174
%174 = OpLabel
%203 = OpPhi %bool %false %23 %202 %173
OpStore %_11_ok %203
%204 = OpLoad %bool %_11_ok
OpSelectionMerge %206 None
OpBranchConditional %204 %205 %206
%205 = OpLabel
%207 = OpAccessChain %_ptr_Uniform_mat2v2float %10 %int_2
%208 = OpLoad %mat2v2float %207
%211 = OpCompositeConstruct %v2float %float_100 %float_0
%212 = OpCompositeConstruct %v2float %float_0 %float_100
%210 = OpCompositeConstruct %mat2v2float %211 %212
%213 = OpCompositeExtract %v2float %208 0
%214 = OpCompositeExtract %v2float %210 0
%215 = OpFOrdNotEqual %v2bool %213 %214
%216 = OpAny %bool %215
%217 = OpCompositeExtract %v2float %208 1
%218 = OpCompositeExtract %v2float %210 1
%219 = OpFOrdNotEqual %v2bool %217 %218
%220 = OpAny %bool %219
%221 = OpLogicalOr %bool %216 %220
OpBranch %206
%206 = OpLabel
%222 = OpPhi %bool %false %174 %221 %205
OpStore %_11_ok %222
%223 = OpLoad %bool %_11_ok
OpSelectionMerge %225 None
OpBranchConditional %223 %224 %225
%224 = OpLabel
%226 = OpAccessChain %_ptr_Uniform_mat3v3float %10 %int_3
%227 = OpLoad %mat3v3float %226
%229 = OpCompositeConstruct %v3float %float_9 %float_8 %float_7
%230 = OpCompositeConstruct %v3float %float_6 %float_5 %float_4
%231 = OpCompositeConstruct %v3float %float_3 %float_2 %float_1
%228 = OpCompositeConstruct %mat3v3float %229 %230 %231
%232 = OpCompositeExtract %v3float %227 0
%233 = OpCompositeExtract %v3float %228 0
%234 = OpFOrdNotEqual %v3bool %232 %233
%235 = OpAny %bool %234
%236 = OpCompositeExtract %v3float %227 1
%237 = OpCompositeExtract %v3float %228 1
%238 = OpFOrdNotEqual %v3bool %236 %237
%239 = OpAny %bool %238
%240 = OpLogicalOr %bool %235 %239
%241 = OpCompositeExtract %v3float %227 2
%242 = OpCompositeExtract %v3float %228 2
%243 = OpFOrdNotEqual %v3bool %241 %242
%244 = OpAny %bool %243
%245 = OpLogicalOr %bool %240 %244
OpBranch %225
%225 = OpLabel
%246 = OpPhi %bool %false %206 %245 %224
OpStore %_11_ok %246
%247 = OpLoad %bool %_11_ok
OpSelectionMerge %252 None
OpBranchConditional %247 %250 %251
%250 = OpLabel
%253 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%255 = OpLoad %v4float %253
OpStore %248 %255
OpBranch %252
%251 = OpLabel
%256 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%258 = OpLoad %v4float %256
OpStore %248 %258
OpBranch %252
%252 = OpLabel
%259 = OpLoad %v4float %248
OpReturnValue %259
OpFunctionEnd

View File

@ -2,6 +2,8 @@
out vec4 sk_FragColor;
uniform vec4 colorGreen;
uniform vec4 colorRed;
uniform mat2 testMatrix2x2;
uniform mat3 testMatrix3x3;
vec4 main() {
mat2 _1_m3 = mat2(1.0, 2.0, 3.0, 4.0);
_1_m3 *= mat2(1.0);
@ -17,7 +19,13 @@ vec4 main() {
_8_m6 += _7_m5;
mat4 _9_m11 = mat4(2.0);
_9_m11 -= mat4(1.0);
return colorGreen;
bool _11_ok = true;
_11_ok = testMatrix2x2 == mat2(1.0, 2.0, 3.0, 4.0);
_11_ok = _11_ok && testMatrix3x3 == mat3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
_11_ok = _11_ok && testMatrix2x2 != mat2(100.0);
_11_ok = _11_ok && testMatrix3x3 != mat3(9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0);
return _11_ok ? colorGreen : colorRed;
}

View File

@ -4,6 +4,8 @@ using namespace metal;
struct Uniforms {
float4 colorGreen;
float4 colorRed;
float2x2 testMatrix2x2;
float3x3 testMatrix3x3;
};
struct Inputs {
};
@ -14,6 +16,20 @@ thread float2x2& operator*=(thread float2x2& left, thread const float2x2& right)
left = left * right;
return left;
}
thread bool operator==(const float2x2 left, const float2x2 right) {
return all(left[0] == right[0]) && all(left[1] == right[1]);
}
thread bool operator==(const float3x3 left, const float3x3 right) {
return all(left[0] == right[0]) && all(left[1] == right[1]) && all(left[2] == right[2]);
}
thread bool operator!=(const float2x2 left, const float2x2 right) {
return any(left[0] != right[0]) || any(left[1] != right[1]);
}
thread bool operator!=(const float3x3 left, const float3x3 right) {
return any(left[0] != right[0]) || any(left[1] != right[1]) || any(left[2] != right[2]);
}
fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {
@ -33,8 +49,14 @@ fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _unifo
_8_m6 += _7_m5;
float4x4 _9_m11 = float4x4(2.0);
_9_m11 -= float4x4(1.0);
_out.sk_FragColor = _uniforms.colorGreen;
bool _11_ok = true;
_11_ok = _uniforms.testMatrix2x2 == float2x2(float2(1.0, 2.0), float2(3.0, 4.0));
_11_ok = _11_ok && _uniforms.testMatrix3x3 == float3x3(float3(1.0, 2.0, 3.0), float3(4.0, 5.0, 6.0), float3(7.0, 8.0, 9.0));
_11_ok = _11_ok && _uniforms.testMatrix2x2 != float2x2(100.0);
_11_ok = _11_ok && _uniforms.testMatrix3x3 != float3x3(float3(9.0, 8.0, 7.0), float3(6.0, 5.0, 4.0), float3(3.0, 2.0, 1.0));
_out.sk_FragColor = _11_ok ? _uniforms.colorGreen : _uniforms.colorRed;
return _out;
}