Optimize remaining simple 1-argument intrinsics.

Aside from sqrt() and normalize(), we now optimize all the intrinsics
which take a single argument as input, and return that argument with
each of its components permuted as output.

This CL also introduces a minor restriction--we no longer optimize
intrinsics which evaluate to inf or nan, such as `inversesqrt(-1)`.
These will be left in the source as-is.

Change-Id: I4919b3c18a2df81accd6daf2f650b9f587ff43fc
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/406577
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
John Stiles 2021-05-11 10:37:56 -04:00 committed by Skia Commit-Bot
parent f3c38a3d0a
commit 33ef30ec68
25 changed files with 1357 additions and 131 deletions

View File

@ -1 +1,14 @@
uniform half a; void main() { sk_FragColor.x = degrees(a); } uniform half4 input, expected;
uniform half4 colorGreen, colorRed;
half4 main(float2 coords) {
const half4 constVal = half4(1.5707963268, 3.1415926536, 4.7123889804, 6.2831853072);
return (degrees(input.x) == expected.x &&
degrees(input.xy) == expected.xy &&
degrees(input.xyz) == expected.xyz &&
degrees(input.xyzw) == expected.xyzw &&
degrees(constVal.x) == expected.x &&
degrees(constVal.xy) == expected.xy &&
degrees(constVal.xyz) == expected.xyz &&
degrees(constVal.xyzw) == expected.xyzw) ? colorGreen : colorRed;
}

View File

@ -1 +1,19 @@
uniform float a; void main() { sk_FragColor.x = half(inversesqrt(a)); } uniform half4 input, expected;
uniform half4 colorGreen, colorRed;
half4 main(float2 coords) {
const half4 constVal = half4(1, 4, 16, 64);
const half4 negativeVal = half4(-1, -4, -16, -64); // should not optimize away
return (inversesqrt(input.x) == expected.x &&
inversesqrt(input.xy) == expected.xy &&
inversesqrt(input.xyz) == expected.xyz &&
inversesqrt(input.xyzw) == expected.xyzw &&
inversesqrt(constVal.x) == expected.x &&
inversesqrt(constVal.xy) == expected.xy &&
inversesqrt(constVal.xyz) == expected.xyz &&
inversesqrt(constVal.xyzw) == expected.xyzw &&
inversesqrt(negativeVal.x) == expected.x &&
inversesqrt(negativeVal.xy) == expected.xy &&
inversesqrt(negativeVal.xyz) == expected.xyz &&
inversesqrt(negativeVal.xyzw) == expected.xyzw) ? colorGreen : colorRed;
}

View File

@ -1 +1,14 @@
uniform half a; void main() { sk_FragColor.x = radians(a); } uniform half4 input, expected;
uniform half4 colorGreen, colorRed;
half4 main(float2 coords) {
const half4 constVal = half4(0);
return (radians(input.x) == expected.x &&
radians(input.xy) == expected.xy &&
radians(input.xyz) == expected.xyz &&
radians(input.xyzw) == expected.xyzw &&
radians(constVal.x) == expected.x &&
radians(constVal.xy) == expected.xy &&
radians(constVal.xyz) == expected.xyz &&
radians(constVal.xyzw) == expected.xyzw) ? colorGreen : colorRed;
}

View File

@ -1 +1,14 @@
uniform half a; void main() { sk_FragColor.x = round(a); } uniform half4 input, expected;
uniform half4 colorGreen, colorRed;
half4 main(float2 coords) {
const half4 constVal = half4(-1.5, -0.5, 0.5, 1.5);
return (round(input.x) == expected.x &&
round(input.xy) == expected.xy &&
round(input.xyz) == expected.xyz &&
round(input.xyzw) == expected.xyzw &&
round(constVal.x) == expected.x &&
round(constVal.xy) == expected.xy &&
round(constVal.xyz) == expected.xyz &&
round(constVal.xyzw) == expected.xyzw) ? colorGreen : colorRed;
}

View File

@ -1 +1,14 @@
uniform half a; void main() { sk_FragColor.x = roundEven(a); } uniform half4 input, expected;
uniform half4 colorGreen, colorRed;
half4 main(float2 coords) {
const half4 constVal = half4(-1.5, -0.5, 0.5, 1.5);
return (roundEven(input.x) == expected.x &&
roundEven(input.xy) == expected.xy &&
roundEven(input.xyz) == expected.xyz &&
roundEven(input.xyzw) == expected.xyzw &&
roundEven(constVal.x) == expected.x &&
roundEven(constVal.xy) == expected.xy &&
roundEven(constVal.xyz) == expected.xyz &&
roundEven(constVal.xyzw) == expected.xyzw) ? colorGreen : colorRed;
}

View File

@ -1 +1,15 @@
uniform half a; void main() { sk_FragColor.x = saturate(a); } uniform half4 testInputs; // equals (-1.25, 0, 0.75, 2.25)
uniform half4 colorGreen, colorRed;
half4 main(float2 coords) {
const half4 constVal = half4(-1.25, 0, 0.75, 2.25);
half4 expected = half4(0, 0, 0.75, 1);
return (saturate(testInputs.x) == expected.x &&
saturate(testInputs.xy) == expected.xy &&
saturate(testInputs.xyz) == expected.xyz &&
saturate(testInputs.xyzw) == expected.xyzw &&
saturate(constVal.x) == expected.x &&
saturate(constVal.xy) == expected.xy &&
saturate(constVal.xyz) == expected.xyz &&
saturate(constVal.xyzw) == expected.xyzw) ? colorGreen : colorRed;
}

View File

@ -108,6 +108,12 @@ static std::unique_ptr<Expression> evaluate_intrinsic_1_of_type(const Context& c
const Expression* subexpr = arg->getConstantSubexpression(index); const Expression* subexpr = arg->getConstantSubexpression(index);
SkASSERT(subexpr); SkASSERT(subexpr);
auto value = evaluate(subexpr->as<LITERAL>().value()); auto value = evaluate(subexpr->as<LITERAL>().value());
if constexpr (std::is_floating_point<decltype(value)>::value) {
// If evaluation of the intrinsic yields a non-finite value, bail on optimization.
if (!isfinite(value)) {
return nullptr;
}
}
result.push_back(LITERAL::Make(subexpr->fOffset, value, &type)); result.push_back(LITERAL::Make(subexpr->fOffset, value, &type));
} }
@ -249,6 +255,22 @@ static std::unique_ptr<Expression> optimize_intrinsic_call(const Context& contex
case k_log2_IntrinsicKind: case k_log2_IntrinsicKind:
return evaluate_intrinsic_float1(context, arguments, [](float a) { return log2(a); }); return evaluate_intrinsic_float1(context, arguments, [](float a) { return log2(a); });
case k_saturate_IntrinsicKind:
return evaluate_intrinsic_float1(context, arguments,
[](float a) { return (a < 0) ? 0 : (a > 1) ? 1 : a; });
case k_round_IntrinsicKind: // GLSL `round` documents its rounding mode as unspecified
case k_roundEven_IntrinsicKind: // and is allowed to behave identically to `roundEven`.
return evaluate_intrinsic_float1(context, arguments,
[](float a) { return round(a / 2) * 2; });
case k_inversesqrt_IntrinsicKind:
return evaluate_intrinsic_float1(context, arguments,
[](float a) { return 1 / sqrt(a); });
case k_radians_IntrinsicKind:
return evaluate_intrinsic_float1(context, arguments,
[](float a) { return a * 0.0174532925; });
case k_degrees_IntrinsicKind:
return evaluate_intrinsic_float1(context, arguments,
[](float a) { return a * 57.2957795; });
default: default:
return nullptr; return nullptr;
} }

View File

@ -1,12 +1,16 @@
OpCapability Shader OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450" %1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise OpEntryPoint Fragment %_entrypoint_v "_entrypoint" %sk_FragColor %sk_Clockwise
OpExecutionMode %main OriginUpperLeft OpExecutionMode %_entrypoint_v OriginUpperLeft
OpName %sk_FragColor "sk_FragColor" OpName %sk_FragColor "sk_FragColor"
OpName %sk_Clockwise "sk_Clockwise" OpName %sk_Clockwise "sk_Clockwise"
OpName %_UniformBuffer "_UniformBuffer" OpName %_UniformBuffer "_UniformBuffer"
OpMemberName %_UniformBuffer 0 "a" OpMemberName %_UniformBuffer 0 "input"
OpMemberName %_UniformBuffer 1 "expected"
OpMemberName %_UniformBuffer 2 "colorGreen"
OpMemberName %_UniformBuffer 3 "colorRed"
OpName %_entrypoint_v "_entrypoint_v"
OpName %main "main" OpName %main "main"
OpDecorate %sk_FragColor RelaxedPrecision OpDecorate %sk_FragColor RelaxedPrecision
OpDecorate %sk_FragColor Location 0 OpDecorate %sk_FragColor Location 0
@ -14,11 +18,46 @@ OpDecorate %sk_FragColor Index 0
OpDecorate %sk_Clockwise BuiltIn FrontFacing OpDecorate %sk_Clockwise BuiltIn FrontFacing
OpMemberDecorate %_UniformBuffer 0 Offset 0 OpMemberDecorate %_UniformBuffer 0 Offset 0
OpMemberDecorate %_UniformBuffer 0 RelaxedPrecision OpMemberDecorate %_UniformBuffer 0 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 1 Offset 16
OpMemberDecorate %_UniformBuffer 1 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 2 Offset 32
OpMemberDecorate %_UniformBuffer 2 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 3 Offset 48
OpMemberDecorate %_UniformBuffer 3 RelaxedPrecision
OpDecorate %_UniformBuffer Block OpDecorate %_UniformBuffer Block
OpDecorate %10 Binding 0 OpDecorate %10 Binding 0
OpDecorate %10 DescriptorSet 0 OpDecorate %10 DescriptorSet 0
OpDecorate %16 RelaxedPrecision OpDecorate %27 RelaxedPrecision
OpDecorate %21 RelaxedPrecision OpDecorate %32 RelaxedPrecision
OpDecorate %33 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %43 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %46 RelaxedPrecision
OpDecorate %47 RelaxedPrecision
OpDecorate %54 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
OpDecorate %57 RelaxedPrecision
OpDecorate %60 RelaxedPrecision
OpDecorate %61 RelaxedPrecision
OpDecorate %68 RelaxedPrecision
OpDecorate %70 RelaxedPrecision
OpDecorate %72 RelaxedPrecision
OpDecorate %81 RelaxedPrecision
OpDecorate %82 RelaxedPrecision
OpDecorate %88 RelaxedPrecision
OpDecorate %90 RelaxedPrecision
OpDecorate %91 RelaxedPrecision
OpDecorate %98 RelaxedPrecision
OpDecorate %100 RelaxedPrecision
OpDecorate %101 RelaxedPrecision
OpDecorate %108 RelaxedPrecision
OpDecorate %110 RelaxedPrecision
OpDecorate %121 RelaxedPrecision
OpDecorate %124 RelaxedPrecision
OpDecorate %125 RelaxedPrecision
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%v4float = OpTypeVector %float 4 %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float %_ptr_Output_v4float = OpTypePointer Output %v4float
@ -26,21 +65,153 @@ OpDecorate %21 RelaxedPrecision
%bool = OpTypeBool %bool = OpTypeBool
%_ptr_Input_bool = OpTypePointer Input %bool %_ptr_Input_bool = OpTypePointer Input %bool
%sk_Clockwise = OpVariable %_ptr_Input_bool Input %sk_Clockwise = OpVariable %_ptr_Input_bool Input
%_UniformBuffer = OpTypeStruct %float %_UniformBuffer = OpTypeStruct %v4float %v4float %v4float %v4float
%_ptr_Uniform__UniformBuffer = OpTypePointer Uniform %_UniformBuffer %_ptr_Uniform__UniformBuffer = OpTypePointer Uniform %_UniformBuffer
%10 = OpVariable %_ptr_Uniform__UniformBuffer Uniform %10 = OpVariable %_ptr_Uniform__UniformBuffer Uniform
%void = OpTypeVoid %void = OpTypeVoid
%14 = OpTypeFunction %void %15 = OpTypeFunction %void
%_ptr_Uniform_float = OpTypePointer Uniform %float %v2float = OpTypeVector %float 2
%float_0 = OpConstant %float 0
%19 = OpConstantComposite %v2float %float_0 %float_0
%_ptr_Function_v2float = OpTypePointer Function %v2float
%23 = OpTypeFunction %v4float %_ptr_Function_v2float
%false = OpConstantFalse %bool
%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%int_0 = OpConstant %int 0 %int_0 = OpConstant %int 0
%_ptr_Output_float = OpTypePointer Output %float %int_1 = OpConstant %int 1
%main = OpFunction %void None %14 %v2bool = OpTypeVector %bool 2
%15 = OpLabel %v3float = OpTypeVector %float 3
%17 = OpAccessChain %_ptr_Uniform_float %10 %int_0 %v3bool = OpTypeVector %bool 3
%21 = OpLoad %float %17 %v4bool = OpTypeVector %bool 4
%16 = OpExtInst %float %1 Degrees %21 %float_90 = OpConstant %float 90
%22 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0 %float_180 = OpConstant %float 180
OpStore %22 %16 %88 = OpConstantComposite %v2float %float_90 %float_180
%float_270 = OpConstant %float 270
%98 = OpConstantComposite %v3float %float_90 %float_180 %float_270
%float_360 = OpConstant %float 360
%108 = OpConstantComposite %v4float %float_90 %float_180 %float_270 %float_360
%_ptr_Function_v4float = OpTypePointer Function %v4float
%int_2 = OpConstant %int 2
%int_3 = OpConstant %int 3
%_entrypoint_v = OpFunction %void None %15
%16 = OpLabel
%20 = OpVariable %_ptr_Function_v2float Function
OpStore %20 %19
%22 = OpFunctionCall %v4float %main %20
OpStore %sk_FragColor %22
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%main = OpFunction %v4float None %23
%24 = OpFunctionParameter %_ptr_Function_v2float
%25 = OpLabel
%114 = OpVariable %_ptr_Function_v4float Function
%28 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%32 = OpLoad %v4float %28
%33 = OpCompositeExtract %float %32 0
%27 = OpExtInst %float %1 Degrees %33
%34 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%36 = OpLoad %v4float %34
%37 = OpCompositeExtract %float %36 0
%38 = OpFOrdEqual %bool %27 %37
OpSelectionMerge %40 None
OpBranchConditional %38 %39 %40
%39 = OpLabel
%42 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%43 = OpLoad %v4float %42
%44 = OpVectorShuffle %v2float %43 %43 0 1
%41 = OpExtInst %v2float %1 Degrees %44
%45 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%46 = OpLoad %v4float %45
%47 = OpVectorShuffle %v2float %46 %46 0 1
%48 = OpFOrdEqual %v2bool %41 %47
%50 = OpAll %bool %48
OpBranch %40
%40 = OpLabel
%51 = OpPhi %bool %false %25 %50 %39
OpSelectionMerge %53 None
OpBranchConditional %51 %52 %53
%52 = OpLabel
%55 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%56 = OpLoad %v4float %55
%57 = OpVectorShuffle %v3float %56 %56 0 1 2
%54 = OpExtInst %v3float %1 Degrees %57
%59 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%60 = OpLoad %v4float %59
%61 = OpVectorShuffle %v3float %60 %60 0 1 2
%62 = OpFOrdEqual %v3bool %54 %61
%64 = OpAll %bool %62
OpBranch %53
%53 = OpLabel
%65 = OpPhi %bool %false %40 %64 %52
OpSelectionMerge %67 None
OpBranchConditional %65 %66 %67
%66 = OpLabel
%69 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%70 = OpLoad %v4float %69
%68 = OpExtInst %v4float %1 Degrees %70
%71 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%72 = OpLoad %v4float %71
%73 = OpFOrdEqual %v4bool %68 %72
%75 = OpAll %bool %73
OpBranch %67
%67 = OpLabel
%76 = OpPhi %bool %false %53 %75 %66
OpSelectionMerge %78 None
OpBranchConditional %76 %77 %78
%77 = OpLabel
%80 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%81 = OpLoad %v4float %80
%82 = OpCompositeExtract %float %81 0
%83 = OpFOrdEqual %bool %float_90 %82
OpBranch %78
%78 = OpLabel
%84 = OpPhi %bool %false %67 %83 %77
OpSelectionMerge %86 None
OpBranchConditional %84 %85 %86
%85 = OpLabel
%89 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%90 = OpLoad %v4float %89
%91 = OpVectorShuffle %v2float %90 %90 0 1
%92 = OpFOrdEqual %v2bool %88 %91
%93 = OpAll %bool %92
OpBranch %86
%86 = OpLabel
%94 = OpPhi %bool %false %78 %93 %85
OpSelectionMerge %96 None
OpBranchConditional %94 %95 %96
%95 = OpLabel
%99 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%100 = OpLoad %v4float %99
%101 = OpVectorShuffle %v3float %100 %100 0 1 2
%102 = OpFOrdEqual %v3bool %98 %101
%103 = OpAll %bool %102
OpBranch %96
%96 = OpLabel
%104 = OpPhi %bool %false %86 %103 %95
OpSelectionMerge %106 None
OpBranchConditional %104 %105 %106
%105 = OpLabel
%109 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%110 = OpLoad %v4float %109
%111 = OpFOrdEqual %v4bool %108 %110
%112 = OpAll %bool %111
OpBranch %106
%106 = OpLabel
%113 = OpPhi %bool %false %96 %112 %105
OpSelectionMerge %118 None
OpBranchConditional %113 %116 %117
%116 = OpLabel
%119 = OpAccessChain %_ptr_Uniform_v4float %10 %int_2
%121 = OpLoad %v4float %119
OpStore %114 %121
OpBranch %118
%117 = OpLabel
%122 = OpAccessChain %_ptr_Uniform_v4float %10 %int_3
%124 = OpLoad %v4float %122
OpStore %114 %124
OpBranch %118
%118 = OpLabel
%125 = OpLoad %v4float %114
OpReturnValue %125
OpFunctionEnd

View File

@ -1,6 +1,9 @@
out vec4 sk_FragColor; out vec4 sk_FragColor;
uniform float a; uniform vec4 input;
void main() { uniform vec4 expected;
sk_FragColor.x = degrees(a); uniform vec4 colorGreen;
uniform vec4 colorRed;
vec4 main() {
return ((((((degrees(input.x) == expected.x && degrees(input.xy) == expected.xy) && degrees(input.xyz) == expected.xyz) && degrees(input) == expected) && 90.0 == expected.x) && vec2(90.0, 180.0) == expected.xy) && vec3(90.0, 180.0, 270.0) == expected.xyz) && vec4(90.0, 180.0, 270.0, 360.0) == expected ? colorGreen : colorRed;
} }

View File

@ -2,7 +2,10 @@
#include <simd/simd.h> #include <simd/simd.h>
using namespace metal; using namespace metal;
struct Uniforms { struct Uniforms {
float a; float4 input;
float4 expected;
float4 colorGreen;
float4 colorRed;
}; };
struct Inputs { struct Inputs {
}; };
@ -13,6 +16,6 @@ struct Outputs {
fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) { fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {
Outputs _out; Outputs _out;
(void)_out; (void)_out;
_out.sk_FragColor.x = ((_uniforms.a) * 57.2957795); _out.sk_FragColor = ((((((((_uniforms.input.x) * 57.2957795) == _uniforms.expected.x && all(((_uniforms.input.xy) * 57.2957795) == _uniforms.expected.xy)) && all(((_uniforms.input.xyz) * 57.2957795) == _uniforms.expected.xyz)) && all(((_uniforms.input) * 57.2957795) == _uniforms.expected)) && 90.0 == _uniforms.expected.x) && all(float2(90.0, 180.0) == _uniforms.expected.xy)) && all(float3(90.0, 180.0, 270.0) == _uniforms.expected.xyz)) && all(float4(90.0, 180.0, 270.0, 360.0) == _uniforms.expected) ? _uniforms.colorGreen : _uniforms.colorRed;
return _out; return _out;
} }

View File

@ -1,21 +1,79 @@
OpCapability Shader OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450" %1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise OpEntryPoint Fragment %_entrypoint_v "_entrypoint" %sk_FragColor %sk_Clockwise
OpExecutionMode %main OriginUpperLeft OpExecutionMode %_entrypoint_v OriginUpperLeft
OpName %sk_FragColor "sk_FragColor" OpName %sk_FragColor "sk_FragColor"
OpName %sk_Clockwise "sk_Clockwise" OpName %sk_Clockwise "sk_Clockwise"
OpName %_UniformBuffer "_UniformBuffer" OpName %_UniformBuffer "_UniformBuffer"
OpMemberName %_UniformBuffer 0 "a" OpMemberName %_UniformBuffer 0 "input"
OpMemberName %_UniformBuffer 1 "expected"
OpMemberName %_UniformBuffer 2 "colorGreen"
OpMemberName %_UniformBuffer 3 "colorRed"
OpName %_entrypoint_v "_entrypoint_v"
OpName %main "main" OpName %main "main"
OpName %negativeVal "negativeVal"
OpDecorate %sk_FragColor RelaxedPrecision OpDecorate %sk_FragColor RelaxedPrecision
OpDecorate %sk_FragColor Location 0 OpDecorate %sk_FragColor Location 0
OpDecorate %sk_FragColor Index 0 OpDecorate %sk_FragColor Index 0
OpDecorate %sk_Clockwise BuiltIn FrontFacing OpDecorate %sk_Clockwise BuiltIn FrontFacing
OpMemberDecorate %_UniformBuffer 0 Offset 0 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 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 3 Offset 48
OpMemberDecorate %_UniformBuffer 3 RelaxedPrecision
OpDecorate %_UniformBuffer Block OpDecorate %_UniformBuffer Block
OpDecorate %10 Binding 0 OpDecorate %10 Binding 0
OpDecorate %10 DescriptorSet 0 OpDecorate %10 DescriptorSet 0
OpDecorate %negativeVal RelaxedPrecision
OpDecorate %32 RelaxedPrecision
OpDecorate %34 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %43 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %48 RelaxedPrecision
OpDecorate %50 RelaxedPrecision
OpDecorate %51 RelaxedPrecision
OpDecorate %53 RelaxedPrecision
OpDecorate %54 RelaxedPrecision
OpDecorate %61 RelaxedPrecision
OpDecorate %63 RelaxedPrecision
OpDecorate %64 RelaxedPrecision
OpDecorate %67 RelaxedPrecision
OpDecorate %68 RelaxedPrecision
OpDecorate %75 RelaxedPrecision
OpDecorate %77 RelaxedPrecision
OpDecorate %79 RelaxedPrecision
OpDecorate %88 RelaxedPrecision
OpDecorate %89 RelaxedPrecision
OpDecorate %95 RelaxedPrecision
OpDecorate %97 RelaxedPrecision
OpDecorate %98 RelaxedPrecision
OpDecorate %105 RelaxedPrecision
OpDecorate %107 RelaxedPrecision
OpDecorate %108 RelaxedPrecision
OpDecorate %115 RelaxedPrecision
OpDecorate %117 RelaxedPrecision
OpDecorate %125 RelaxedPrecision
OpDecorate %126 RelaxedPrecision
OpDecorate %131 RelaxedPrecision
OpDecorate %132 RelaxedPrecision
OpDecorate %134 RelaxedPrecision
OpDecorate %135 RelaxedPrecision
OpDecorate %141 RelaxedPrecision
OpDecorate %142 RelaxedPrecision
OpDecorate %144 RelaxedPrecision
OpDecorate %145 RelaxedPrecision
OpDecorate %151 RelaxedPrecision
OpDecorate %152 RelaxedPrecision
OpDecorate %154 RelaxedPrecision
OpDecorate %164 RelaxedPrecision
OpDecorate %167 RelaxedPrecision
OpDecorate %168 RelaxedPrecision
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%v4float = OpTypeVector %float 4 %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float %_ptr_Output_v4float = OpTypePointer Output %v4float
@ -23,21 +81,209 @@ OpDecorate %10 DescriptorSet 0
%bool = OpTypeBool %bool = OpTypeBool
%_ptr_Input_bool = OpTypePointer Input %bool %_ptr_Input_bool = OpTypePointer Input %bool
%sk_Clockwise = OpVariable %_ptr_Input_bool Input %sk_Clockwise = OpVariable %_ptr_Input_bool Input
%_UniformBuffer = OpTypeStruct %float %_UniformBuffer = OpTypeStruct %v4float %v4float %v4float %v4float
%_ptr_Uniform__UniformBuffer = OpTypePointer Uniform %_UniformBuffer %_ptr_Uniform__UniformBuffer = OpTypePointer Uniform %_UniformBuffer
%10 = OpVariable %_ptr_Uniform__UniformBuffer Uniform %10 = OpVariable %_ptr_Uniform__UniformBuffer Uniform
%void = OpTypeVoid %void = OpTypeVoid
%14 = OpTypeFunction %void %15 = OpTypeFunction %void
%_ptr_Uniform_float = OpTypePointer Uniform %float %v2float = OpTypeVector %float 2
%float_0 = OpConstant %float 0
%19 = OpConstantComposite %v2float %float_0 %float_0
%_ptr_Function_v2float = OpTypePointer Function %v2float
%23 = OpTypeFunction %v4float %_ptr_Function_v2float
%_ptr_Function_v4float = OpTypePointer Function %v4float
%float_n1 = OpConstant %float -1
%float_n4 = OpConstant %float -4
%float_n16 = OpConstant %float -16
%float_n64 = OpConstant %float -64
%32 = OpConstantComposite %v4float %float_n1 %float_n4 %float_n16 %float_n64
%false = OpConstantFalse %bool
%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%int_0 = OpConstant %int 0 %int_0 = OpConstant %int 0
%_ptr_Output_float = OpTypePointer Output %float %int_1 = OpConstant %int 1
%main = OpFunction %void None %14 %v2bool = OpTypeVector %bool 2
%15 = OpLabel %v3float = OpTypeVector %float 3
%17 = OpAccessChain %_ptr_Uniform_float %10 %int_0 %v3bool = OpTypeVector %bool 3
%21 = OpLoad %float %17 %v4bool = OpTypeVector %bool 4
%16 = OpExtInst %float %1 InverseSqrt %21 %float_1 = OpConstant %float 1
%22 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0 %float_0_5 = OpConstant %float 0.5
OpStore %22 %16 %95 = OpConstantComposite %v2float %float_1 %float_0_5
%float_0_25 = OpConstant %float 0.25
%105 = OpConstantComposite %v3float %float_1 %float_0_5 %float_0_25
%float_0_125 = OpConstant %float 0.125
%115 = OpConstantComposite %v4float %float_1 %float_0_5 %float_0_25 %float_0_125
%132 = OpConstantComposite %v2float %float_n1 %float_n4
%142 = OpConstantComposite %v3float %float_n1 %float_n4 %float_n16
%int_2 = OpConstant %int 2
%int_3 = OpConstant %int 3
%_entrypoint_v = OpFunction %void None %15
%16 = OpLabel
%20 = OpVariable %_ptr_Function_v2float Function
OpStore %20 %19
%22 = OpFunctionCall %v4float %main %20
OpStore %sk_FragColor %22
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%main = OpFunction %v4float None %23
%24 = OpFunctionParameter %_ptr_Function_v2float
%25 = OpLabel
%negativeVal = OpVariable %_ptr_Function_v4float Function
%158 = OpVariable %_ptr_Function_v4float Function
OpStore %negativeVal %32
%35 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%39 = OpLoad %v4float %35
%40 = OpCompositeExtract %float %39 0
%34 = OpExtInst %float %1 InverseSqrt %40
%41 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%43 = OpLoad %v4float %41
%44 = OpCompositeExtract %float %43 0
%45 = OpFOrdEqual %bool %34 %44
OpSelectionMerge %47 None
OpBranchConditional %45 %46 %47
%46 = OpLabel
%49 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%50 = OpLoad %v4float %49
%51 = OpVectorShuffle %v2float %50 %50 0 1
%48 = OpExtInst %v2float %1 InverseSqrt %51
%52 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%53 = OpLoad %v4float %52
%54 = OpVectorShuffle %v2float %53 %53 0 1
%55 = OpFOrdEqual %v2bool %48 %54
%57 = OpAll %bool %55
OpBranch %47
%47 = OpLabel
%58 = OpPhi %bool %false %25 %57 %46
OpSelectionMerge %60 None
OpBranchConditional %58 %59 %60
%59 = OpLabel
%62 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%63 = OpLoad %v4float %62
%64 = OpVectorShuffle %v3float %63 %63 0 1 2
%61 = OpExtInst %v3float %1 InverseSqrt %64
%66 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%67 = OpLoad %v4float %66
%68 = OpVectorShuffle %v3float %67 %67 0 1 2
%69 = OpFOrdEqual %v3bool %61 %68
%71 = OpAll %bool %69
OpBranch %60
%60 = OpLabel
%72 = OpPhi %bool %false %47 %71 %59
OpSelectionMerge %74 None
OpBranchConditional %72 %73 %74
%73 = OpLabel
%76 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%77 = OpLoad %v4float %76
%75 = OpExtInst %v4float %1 InverseSqrt %77
%78 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%79 = OpLoad %v4float %78
%80 = OpFOrdEqual %v4bool %75 %79
%82 = OpAll %bool %80
OpBranch %74
%74 = OpLabel
%83 = OpPhi %bool %false %60 %82 %73
OpSelectionMerge %85 None
OpBranchConditional %83 %84 %85
%84 = OpLabel
%87 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%88 = OpLoad %v4float %87
%89 = OpCompositeExtract %float %88 0
%90 = OpFOrdEqual %bool %float_1 %89
OpBranch %85
%85 = OpLabel
%91 = OpPhi %bool %false %74 %90 %84
OpSelectionMerge %93 None
OpBranchConditional %91 %92 %93
%92 = OpLabel
%96 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%97 = OpLoad %v4float %96
%98 = OpVectorShuffle %v2float %97 %97 0 1
%99 = OpFOrdEqual %v2bool %95 %98
%100 = OpAll %bool %99
OpBranch %93
%93 = OpLabel
%101 = OpPhi %bool %false %85 %100 %92
OpSelectionMerge %103 None
OpBranchConditional %101 %102 %103
%102 = OpLabel
%106 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%107 = OpLoad %v4float %106
%108 = OpVectorShuffle %v3float %107 %107 0 1 2
%109 = OpFOrdEqual %v3bool %105 %108
%110 = OpAll %bool %109
OpBranch %103
%103 = OpLabel
%111 = OpPhi %bool %false %93 %110 %102
OpSelectionMerge %113 None
OpBranchConditional %111 %112 %113
%112 = OpLabel
%116 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%117 = OpLoad %v4float %116
%118 = OpFOrdEqual %v4bool %115 %117
%119 = OpAll %bool %118
OpBranch %113
%113 = OpLabel
%120 = OpPhi %bool %false %103 %119 %112
OpSelectionMerge %122 None
OpBranchConditional %120 %121 %122
%121 = OpLabel
%123 = OpExtInst %float %1 InverseSqrt %float_n1
%124 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%125 = OpLoad %v4float %124
%126 = OpCompositeExtract %float %125 0
%127 = OpFOrdEqual %bool %123 %126
OpBranch %122
%122 = OpLabel
%128 = OpPhi %bool %false %113 %127 %121
OpSelectionMerge %130 None
OpBranchConditional %128 %129 %130
%129 = OpLabel
%131 = OpExtInst %v2float %1 InverseSqrt %132
%133 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%134 = OpLoad %v4float %133
%135 = OpVectorShuffle %v2float %134 %134 0 1
%136 = OpFOrdEqual %v2bool %131 %135
%137 = OpAll %bool %136
OpBranch %130
%130 = OpLabel
%138 = OpPhi %bool %false %122 %137 %129
OpSelectionMerge %140 None
OpBranchConditional %138 %139 %140
%139 = OpLabel
%141 = OpExtInst %v3float %1 InverseSqrt %142
%143 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%144 = OpLoad %v4float %143
%145 = OpVectorShuffle %v3float %144 %144 0 1 2
%146 = OpFOrdEqual %v3bool %141 %145
%147 = OpAll %bool %146
OpBranch %140
%140 = OpLabel
%148 = OpPhi %bool %false %130 %147 %139
OpSelectionMerge %150 None
OpBranchConditional %148 %149 %150
%149 = OpLabel
%152 = OpLoad %v4float %negativeVal
%151 = OpExtInst %v4float %1 InverseSqrt %152
%153 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%154 = OpLoad %v4float %153
%155 = OpFOrdEqual %v4bool %151 %154
%156 = OpAll %bool %155
OpBranch %150
%150 = OpLabel
%157 = OpPhi %bool %false %140 %156 %149
OpSelectionMerge %161 None
OpBranchConditional %157 %159 %160
%159 = OpLabel
%162 = OpAccessChain %_ptr_Uniform_v4float %10 %int_2
%164 = OpLoad %v4float %162
OpStore %158 %164
OpBranch %161
%160 = OpLabel
%165 = OpAccessChain %_ptr_Uniform_v4float %10 %int_3
%167 = OpLoad %v4float %165
OpStore %158 %167
OpBranch %161
%161 = OpLabel
%168 = OpLoad %v4float %158
OpReturnValue %168
OpFunctionEnd

View File

@ -1,6 +1,10 @@
out vec4 sk_FragColor; out vec4 sk_FragColor;
uniform float a; uniform vec4 input;
void main() { uniform vec4 expected;
sk_FragColor.x = inversesqrt(a); uniform vec4 colorGreen;
uniform vec4 colorRed;
vec4 main() {
const vec4 negativeVal = vec4(-1.0, -4.0, -16.0, -64.0);
return ((((((((((inversesqrt(input.x) == expected.x && inversesqrt(input.xy) == expected.xy) && inversesqrt(input.xyz) == expected.xyz) && inversesqrt(input) == expected) && 1.0 == expected.x) && vec2(1.0, 0.5) == expected.xy) && vec3(1.0, 0.5, 0.25) == expected.xyz) && vec4(1.0, 0.5, 0.25, 0.125) == expected) && inversesqrt(-1.0) == expected.x) && inversesqrt(vec2(-1.0, -4.0)) == expected.xy) && inversesqrt(vec3(-1.0, -4.0, -16.0)) == expected.xyz) && inversesqrt(negativeVal) == expected ? colorGreen : colorRed;
} }

View File

@ -2,7 +2,10 @@
#include <simd/simd.h> #include <simd/simd.h>
using namespace metal; using namespace metal;
struct Uniforms { struct Uniforms {
float a; float4 input;
float4 expected;
float4 colorGreen;
float4 colorRed;
}; };
struct Inputs { struct Inputs {
}; };
@ -13,6 +16,7 @@ struct Outputs {
fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) { fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {
Outputs _out; Outputs _out;
(void)_out; (void)_out;
_out.sk_FragColor.x = rsqrt(_uniforms.a); const float4 negativeVal = float4(-1.0, -4.0, -16.0, -64.0);
_out.sk_FragColor = ((((((((((rsqrt(_uniforms.input.x) == _uniforms.expected.x && all(rsqrt(_uniforms.input.xy) == _uniforms.expected.xy)) && all(rsqrt(_uniforms.input.xyz) == _uniforms.expected.xyz)) && all(rsqrt(_uniforms.input) == _uniforms.expected)) && 1.0 == _uniforms.expected.x) && all(float2(1.0, 0.5) == _uniforms.expected.xy)) && all(float3(1.0, 0.5, 0.25) == _uniforms.expected.xyz)) && all(float4(1.0, 0.5, 0.25, 0.125) == _uniforms.expected)) && rsqrt(-1.0) == _uniforms.expected.x) && all(rsqrt(float2(-1.0, -4.0)) == _uniforms.expected.xy)) && all(rsqrt(float3(-1.0, -4.0, -16.0)) == _uniforms.expected.xyz)) && all(rsqrt(negativeVal) == _uniforms.expected) ? _uniforms.colorGreen : _uniforms.colorRed;
return _out; return _out;
} }

View File

@ -1,12 +1,16 @@
OpCapability Shader OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450" %1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise OpEntryPoint Fragment %_entrypoint_v "_entrypoint" %sk_FragColor %sk_Clockwise
OpExecutionMode %main OriginUpperLeft OpExecutionMode %_entrypoint_v OriginUpperLeft
OpName %sk_FragColor "sk_FragColor" OpName %sk_FragColor "sk_FragColor"
OpName %sk_Clockwise "sk_Clockwise" OpName %sk_Clockwise "sk_Clockwise"
OpName %_UniformBuffer "_UniformBuffer" OpName %_UniformBuffer "_UniformBuffer"
OpMemberName %_UniformBuffer 0 "a" OpMemberName %_UniformBuffer 0 "input"
OpMemberName %_UniformBuffer 1 "expected"
OpMemberName %_UniformBuffer 2 "colorGreen"
OpMemberName %_UniformBuffer 3 "colorRed"
OpName %_entrypoint_v "_entrypoint_v"
OpName %main "main" OpName %main "main"
OpDecorate %sk_FragColor RelaxedPrecision OpDecorate %sk_FragColor RelaxedPrecision
OpDecorate %sk_FragColor Location 0 OpDecorate %sk_FragColor Location 0
@ -14,11 +18,45 @@ OpDecorate %sk_FragColor Index 0
OpDecorate %sk_Clockwise BuiltIn FrontFacing OpDecorate %sk_Clockwise BuiltIn FrontFacing
OpMemberDecorate %_UniformBuffer 0 Offset 0 OpMemberDecorate %_UniformBuffer 0 Offset 0
OpMemberDecorate %_UniformBuffer 0 RelaxedPrecision OpMemberDecorate %_UniformBuffer 0 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 1 Offset 16
OpMemberDecorate %_UniformBuffer 1 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 2 Offset 32
OpMemberDecorate %_UniformBuffer 2 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 3 Offset 48
OpMemberDecorate %_UniformBuffer 3 RelaxedPrecision
OpDecorate %_UniformBuffer Block OpDecorate %_UniformBuffer Block
OpDecorate %10 Binding 0 OpDecorate %10 Binding 0
OpDecorate %10 DescriptorSet 0 OpDecorate %10 DescriptorSet 0
OpDecorate %16 RelaxedPrecision OpDecorate %27 RelaxedPrecision
OpDecorate %21 RelaxedPrecision OpDecorate %32 RelaxedPrecision
OpDecorate %33 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %43 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %46 RelaxedPrecision
OpDecorate %47 RelaxedPrecision
OpDecorate %54 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
OpDecorate %57 RelaxedPrecision
OpDecorate %60 RelaxedPrecision
OpDecorate %61 RelaxedPrecision
OpDecorate %68 RelaxedPrecision
OpDecorate %70 RelaxedPrecision
OpDecorate %72 RelaxedPrecision
OpDecorate %80 RelaxedPrecision
OpDecorate %81 RelaxedPrecision
OpDecorate %87 RelaxedPrecision
OpDecorate %88 RelaxedPrecision
OpDecorate %94 RelaxedPrecision
OpDecorate %96 RelaxedPrecision
OpDecorate %97 RelaxedPrecision
OpDecorate %103 RelaxedPrecision
OpDecorate %105 RelaxedPrecision
OpDecorate %116 RelaxedPrecision
OpDecorate %119 RelaxedPrecision
OpDecorate %120 RelaxedPrecision
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%v4float = OpTypeVector %float 4 %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float %_ptr_Output_v4float = OpTypePointer Output %v4float
@ -26,21 +64,148 @@ OpDecorate %21 RelaxedPrecision
%bool = OpTypeBool %bool = OpTypeBool
%_ptr_Input_bool = OpTypePointer Input %bool %_ptr_Input_bool = OpTypePointer Input %bool
%sk_Clockwise = OpVariable %_ptr_Input_bool Input %sk_Clockwise = OpVariable %_ptr_Input_bool Input
%_UniformBuffer = OpTypeStruct %float %_UniformBuffer = OpTypeStruct %v4float %v4float %v4float %v4float
%_ptr_Uniform__UniformBuffer = OpTypePointer Uniform %_UniformBuffer %_ptr_Uniform__UniformBuffer = OpTypePointer Uniform %_UniformBuffer
%10 = OpVariable %_ptr_Uniform__UniformBuffer Uniform %10 = OpVariable %_ptr_Uniform__UniformBuffer Uniform
%void = OpTypeVoid %void = OpTypeVoid
%14 = OpTypeFunction %void %15 = OpTypeFunction %void
%_ptr_Uniform_float = OpTypePointer Uniform %float %v2float = OpTypeVector %float 2
%float_0 = OpConstant %float 0
%19 = OpConstantComposite %v2float %float_0 %float_0
%_ptr_Function_v2float = OpTypePointer Function %v2float
%23 = OpTypeFunction %v4float %_ptr_Function_v2float
%false = OpConstantFalse %bool
%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%int_0 = OpConstant %int 0 %int_0 = OpConstant %int 0
%_ptr_Output_float = OpTypePointer Output %float %int_1 = OpConstant %int 1
%main = OpFunction %void None %14 %v2bool = OpTypeVector %bool 2
%15 = OpLabel %v3float = OpTypeVector %float 3
%17 = OpAccessChain %_ptr_Uniform_float %10 %int_0 %v3bool = OpTypeVector %bool 3
%21 = OpLoad %float %17 %v4bool = OpTypeVector %bool 4
%16 = OpExtInst %float %1 Radians %21 %94 = OpConstantComposite %v3float %float_0 %float_0 %float_0
%22 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0 %103 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
OpStore %22 %16 %_ptr_Function_v4float = OpTypePointer Function %v4float
%int_2 = OpConstant %int 2
%int_3 = OpConstant %int 3
%_entrypoint_v = OpFunction %void None %15
%16 = OpLabel
%20 = OpVariable %_ptr_Function_v2float Function
OpStore %20 %19
%22 = OpFunctionCall %v4float %main %20
OpStore %sk_FragColor %22
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%main = OpFunction %v4float None %23
%24 = OpFunctionParameter %_ptr_Function_v2float
%25 = OpLabel
%109 = OpVariable %_ptr_Function_v4float Function
%28 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%32 = OpLoad %v4float %28
%33 = OpCompositeExtract %float %32 0
%27 = OpExtInst %float %1 Radians %33
%34 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%36 = OpLoad %v4float %34
%37 = OpCompositeExtract %float %36 0
%38 = OpFOrdEqual %bool %27 %37
OpSelectionMerge %40 None
OpBranchConditional %38 %39 %40
%39 = OpLabel
%42 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%43 = OpLoad %v4float %42
%44 = OpVectorShuffle %v2float %43 %43 0 1
%41 = OpExtInst %v2float %1 Radians %44
%45 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%46 = OpLoad %v4float %45
%47 = OpVectorShuffle %v2float %46 %46 0 1
%48 = OpFOrdEqual %v2bool %41 %47
%50 = OpAll %bool %48
OpBranch %40
%40 = OpLabel
%51 = OpPhi %bool %false %25 %50 %39
OpSelectionMerge %53 None
OpBranchConditional %51 %52 %53
%52 = OpLabel
%55 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%56 = OpLoad %v4float %55
%57 = OpVectorShuffle %v3float %56 %56 0 1 2
%54 = OpExtInst %v3float %1 Radians %57
%59 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%60 = OpLoad %v4float %59
%61 = OpVectorShuffle %v3float %60 %60 0 1 2
%62 = OpFOrdEqual %v3bool %54 %61
%64 = OpAll %bool %62
OpBranch %53
%53 = OpLabel
%65 = OpPhi %bool %false %40 %64 %52
OpSelectionMerge %67 None
OpBranchConditional %65 %66 %67
%66 = OpLabel
%69 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%70 = OpLoad %v4float %69
%68 = OpExtInst %v4float %1 Radians %70
%71 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%72 = OpLoad %v4float %71
%73 = OpFOrdEqual %v4bool %68 %72
%75 = OpAll %bool %73
OpBranch %67
%67 = OpLabel
%76 = OpPhi %bool %false %53 %75 %66
OpSelectionMerge %78 None
OpBranchConditional %76 %77 %78
%77 = OpLabel
%79 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%80 = OpLoad %v4float %79
%81 = OpCompositeExtract %float %80 0
%82 = OpFOrdEqual %bool %float_0 %81
OpBranch %78
%78 = OpLabel
%83 = OpPhi %bool %false %67 %82 %77
OpSelectionMerge %85 None
OpBranchConditional %83 %84 %85
%84 = OpLabel
%86 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%87 = OpLoad %v4float %86
%88 = OpVectorShuffle %v2float %87 %87 0 1
%89 = OpFOrdEqual %v2bool %19 %88
%90 = OpAll %bool %89
OpBranch %85
%85 = OpLabel
%91 = OpPhi %bool %false %78 %90 %84
OpSelectionMerge %93 None
OpBranchConditional %91 %92 %93
%92 = OpLabel
%95 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%96 = OpLoad %v4float %95
%97 = OpVectorShuffle %v3float %96 %96 0 1 2
%98 = OpFOrdEqual %v3bool %94 %97
%99 = OpAll %bool %98
OpBranch %93
%93 = OpLabel
%100 = OpPhi %bool %false %85 %99 %92
OpSelectionMerge %102 None
OpBranchConditional %100 %101 %102
%101 = OpLabel
%104 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%105 = OpLoad %v4float %104
%106 = OpFOrdEqual %v4bool %103 %105
%107 = OpAll %bool %106
OpBranch %102
%102 = OpLabel
%108 = OpPhi %bool %false %93 %107 %101
OpSelectionMerge %113 None
OpBranchConditional %108 %111 %112
%111 = OpLabel
%114 = OpAccessChain %_ptr_Uniform_v4float %10 %int_2
%116 = OpLoad %v4float %114
OpStore %109 %116
OpBranch %113
%112 = OpLabel
%117 = OpAccessChain %_ptr_Uniform_v4float %10 %int_3
%119 = OpLoad %v4float %117
OpStore %109 %119
OpBranch %113
%113 = OpLabel
%120 = OpLoad %v4float %109
OpReturnValue %120
OpFunctionEnd

View File

@ -1,6 +1,9 @@
out vec4 sk_FragColor; out vec4 sk_FragColor;
uniform float a; uniform vec4 input;
void main() { uniform vec4 expected;
sk_FragColor.x = radians(a); uniform vec4 colorGreen;
uniform vec4 colorRed;
vec4 main() {
return ((((((radians(input.x) == expected.x && radians(input.xy) == expected.xy) && radians(input.xyz) == expected.xyz) && radians(input) == expected) && 0.0 == expected.x) && vec2(0.0, 0.0) == expected.xy) && vec3(0.0, 0.0, 0.0) == expected.xyz) && vec4(0.0, 0.0, 0.0, 0.0) == expected ? colorGreen : colorRed;
} }

View File

@ -2,7 +2,10 @@
#include <simd/simd.h> #include <simd/simd.h>
using namespace metal; using namespace metal;
struct Uniforms { struct Uniforms {
float a; float4 input;
float4 expected;
float4 colorGreen;
float4 colorRed;
}; };
struct Inputs { struct Inputs {
}; };
@ -13,6 +16,6 @@ struct Outputs {
fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) { fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {
Outputs _out; Outputs _out;
(void)_out; (void)_out;
_out.sk_FragColor.x = ((_uniforms.a) * 0.0174532925); _out.sk_FragColor = ((((((((_uniforms.input.x) * 0.0174532925) == _uniforms.expected.x && all(((_uniforms.input.xy) * 0.0174532925) == _uniforms.expected.xy)) && all(((_uniforms.input.xyz) * 0.0174532925) == _uniforms.expected.xyz)) && all(((_uniforms.input) * 0.0174532925) == _uniforms.expected)) && 0.0 == _uniforms.expected.x) && all(float2(0.0, 0.0) == _uniforms.expected.xy)) && all(float3(0.0, 0.0, 0.0) == _uniforms.expected.xyz)) && all(float4(0.0, 0.0, 0.0, 0.0) == _uniforms.expected) ? _uniforms.colorGreen : _uniforms.colorRed;
return _out; return _out;
} }

View File

@ -1,12 +1,16 @@
OpCapability Shader OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450" %1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise OpEntryPoint Fragment %_entrypoint_v "_entrypoint" %sk_FragColor %sk_Clockwise
OpExecutionMode %main OriginUpperLeft OpExecutionMode %_entrypoint_v OriginUpperLeft
OpName %sk_FragColor "sk_FragColor" OpName %sk_FragColor "sk_FragColor"
OpName %sk_Clockwise "sk_Clockwise" OpName %sk_Clockwise "sk_Clockwise"
OpName %_UniformBuffer "_UniformBuffer" OpName %_UniformBuffer "_UniformBuffer"
OpMemberName %_UniformBuffer 0 "a" OpMemberName %_UniformBuffer 0 "input"
OpMemberName %_UniformBuffer 1 "expected"
OpMemberName %_UniformBuffer 2 "colorGreen"
OpMemberName %_UniformBuffer 3 "colorRed"
OpName %_entrypoint_v "_entrypoint_v"
OpName %main "main" OpName %main "main"
OpDecorate %sk_FragColor RelaxedPrecision OpDecorate %sk_FragColor RelaxedPrecision
OpDecorate %sk_FragColor Location 0 OpDecorate %sk_FragColor Location 0
@ -14,11 +18,46 @@ OpDecorate %sk_FragColor Index 0
OpDecorate %sk_Clockwise BuiltIn FrontFacing OpDecorate %sk_Clockwise BuiltIn FrontFacing
OpMemberDecorate %_UniformBuffer 0 Offset 0 OpMemberDecorate %_UniformBuffer 0 Offset 0
OpMemberDecorate %_UniformBuffer 0 RelaxedPrecision OpMemberDecorate %_UniformBuffer 0 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 1 Offset 16
OpMemberDecorate %_UniformBuffer 1 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 2 Offset 32
OpMemberDecorate %_UniformBuffer 2 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 3 Offset 48
OpMemberDecorate %_UniformBuffer 3 RelaxedPrecision
OpDecorate %_UniformBuffer Block OpDecorate %_UniformBuffer Block
OpDecorate %10 Binding 0 OpDecorate %10 Binding 0
OpDecorate %10 DescriptorSet 0 OpDecorate %10 DescriptorSet 0
OpDecorate %16 RelaxedPrecision OpDecorate %27 RelaxedPrecision
OpDecorate %21 RelaxedPrecision OpDecorate %32 RelaxedPrecision
OpDecorate %33 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %43 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %46 RelaxedPrecision
OpDecorate %47 RelaxedPrecision
OpDecorate %54 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
OpDecorate %57 RelaxedPrecision
OpDecorate %60 RelaxedPrecision
OpDecorate %61 RelaxedPrecision
OpDecorate %68 RelaxedPrecision
OpDecorate %70 RelaxedPrecision
OpDecorate %72 RelaxedPrecision
OpDecorate %81 RelaxedPrecision
OpDecorate %82 RelaxedPrecision
OpDecorate %88 RelaxedPrecision
OpDecorate %90 RelaxedPrecision
OpDecorate %91 RelaxedPrecision
OpDecorate %97 RelaxedPrecision
OpDecorate %99 RelaxedPrecision
OpDecorate %100 RelaxedPrecision
OpDecorate %107 RelaxedPrecision
OpDecorate %109 RelaxedPrecision
OpDecorate %120 RelaxedPrecision
OpDecorate %123 RelaxedPrecision
OpDecorate %124 RelaxedPrecision
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%v4float = OpTypeVector %float 4 %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float %_ptr_Output_v4float = OpTypePointer Output %v4float
@ -26,21 +65,152 @@ OpDecorate %21 RelaxedPrecision
%bool = OpTypeBool %bool = OpTypeBool
%_ptr_Input_bool = OpTypePointer Input %bool %_ptr_Input_bool = OpTypePointer Input %bool
%sk_Clockwise = OpVariable %_ptr_Input_bool Input %sk_Clockwise = OpVariable %_ptr_Input_bool Input
%_UniformBuffer = OpTypeStruct %float %_UniformBuffer = OpTypeStruct %v4float %v4float %v4float %v4float
%_ptr_Uniform__UniformBuffer = OpTypePointer Uniform %_UniformBuffer %_ptr_Uniform__UniformBuffer = OpTypePointer Uniform %_UniformBuffer
%10 = OpVariable %_ptr_Uniform__UniformBuffer Uniform %10 = OpVariable %_ptr_Uniform__UniformBuffer Uniform
%void = OpTypeVoid %void = OpTypeVoid
%14 = OpTypeFunction %void %15 = OpTypeFunction %void
%_ptr_Uniform_float = OpTypePointer Uniform %float %v2float = OpTypeVector %float 2
%float_0 = OpConstant %float 0
%19 = OpConstantComposite %v2float %float_0 %float_0
%_ptr_Function_v2float = OpTypePointer Function %v2float
%23 = OpTypeFunction %v4float %_ptr_Function_v2float
%false = OpConstantFalse %bool
%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%int_0 = OpConstant %int 0 %int_0 = OpConstant %int 0
%_ptr_Output_float = OpTypePointer Output %float %int_1 = OpConstant %int 1
%main = OpFunction %void None %14 %v2bool = OpTypeVector %bool 2
%15 = OpLabel %v3float = OpTypeVector %float 3
%17 = OpAccessChain %_ptr_Uniform_float %10 %int_0 %v3bool = OpTypeVector %bool 3
%21 = OpLoad %float %17 %v4bool = OpTypeVector %bool 4
%16 = OpExtInst %float %1 Round %21 %float_n2 = OpConstant %float -2
%22 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0 %float_n0 = OpConstant %float -0
OpStore %22 %16 %88 = OpConstantComposite %v2float %float_n2 %float_n0
%97 = OpConstantComposite %v3float %float_n2 %float_n0 %float_0
%float_2 = OpConstant %float 2
%107 = OpConstantComposite %v4float %float_n2 %float_n0 %float_0 %float_2
%_ptr_Function_v4float = OpTypePointer Function %v4float
%int_2 = OpConstant %int 2
%int_3 = OpConstant %int 3
%_entrypoint_v = OpFunction %void None %15
%16 = OpLabel
%20 = OpVariable %_ptr_Function_v2float Function
OpStore %20 %19
%22 = OpFunctionCall %v4float %main %20
OpStore %sk_FragColor %22
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%main = OpFunction %v4float None %23
%24 = OpFunctionParameter %_ptr_Function_v2float
%25 = OpLabel
%113 = OpVariable %_ptr_Function_v4float Function
%28 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%32 = OpLoad %v4float %28
%33 = OpCompositeExtract %float %32 0
%27 = OpExtInst %float %1 Round %33
%34 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%36 = OpLoad %v4float %34
%37 = OpCompositeExtract %float %36 0
%38 = OpFOrdEqual %bool %27 %37
OpSelectionMerge %40 None
OpBranchConditional %38 %39 %40
%39 = OpLabel
%42 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%43 = OpLoad %v4float %42
%44 = OpVectorShuffle %v2float %43 %43 0 1
%41 = OpExtInst %v2float %1 Round %44
%45 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%46 = OpLoad %v4float %45
%47 = OpVectorShuffle %v2float %46 %46 0 1
%48 = OpFOrdEqual %v2bool %41 %47
%50 = OpAll %bool %48
OpBranch %40
%40 = OpLabel
%51 = OpPhi %bool %false %25 %50 %39
OpSelectionMerge %53 None
OpBranchConditional %51 %52 %53
%52 = OpLabel
%55 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%56 = OpLoad %v4float %55
%57 = OpVectorShuffle %v3float %56 %56 0 1 2
%54 = OpExtInst %v3float %1 Round %57
%59 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%60 = OpLoad %v4float %59
%61 = OpVectorShuffle %v3float %60 %60 0 1 2
%62 = OpFOrdEqual %v3bool %54 %61
%64 = OpAll %bool %62
OpBranch %53
%53 = OpLabel
%65 = OpPhi %bool %false %40 %64 %52
OpSelectionMerge %67 None
OpBranchConditional %65 %66 %67
%66 = OpLabel
%69 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%70 = OpLoad %v4float %69
%68 = OpExtInst %v4float %1 Round %70
%71 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%72 = OpLoad %v4float %71
%73 = OpFOrdEqual %v4bool %68 %72
%75 = OpAll %bool %73
OpBranch %67
%67 = OpLabel
%76 = OpPhi %bool %false %53 %75 %66
OpSelectionMerge %78 None
OpBranchConditional %76 %77 %78
%77 = OpLabel
%80 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%81 = OpLoad %v4float %80
%82 = OpCompositeExtract %float %81 0
%83 = OpFOrdEqual %bool %float_n2 %82
OpBranch %78
%78 = OpLabel
%84 = OpPhi %bool %false %67 %83 %77
OpSelectionMerge %86 None
OpBranchConditional %84 %85 %86
%85 = OpLabel
%89 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%90 = OpLoad %v4float %89
%91 = OpVectorShuffle %v2float %90 %90 0 1
%92 = OpFOrdEqual %v2bool %88 %91
%93 = OpAll %bool %92
OpBranch %86
%86 = OpLabel
%94 = OpPhi %bool %false %78 %93 %85
OpSelectionMerge %96 None
OpBranchConditional %94 %95 %96
%95 = OpLabel
%98 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%99 = OpLoad %v4float %98
%100 = OpVectorShuffle %v3float %99 %99 0 1 2
%101 = OpFOrdEqual %v3bool %97 %100
%102 = OpAll %bool %101
OpBranch %96
%96 = OpLabel
%103 = OpPhi %bool %false %86 %102 %95
OpSelectionMerge %105 None
OpBranchConditional %103 %104 %105
%104 = OpLabel
%108 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%109 = OpLoad %v4float %108
%110 = OpFOrdEqual %v4bool %107 %109
%111 = OpAll %bool %110
OpBranch %105
%105 = OpLabel
%112 = OpPhi %bool %false %96 %111 %104
OpSelectionMerge %117 None
OpBranchConditional %112 %115 %116
%115 = OpLabel
%118 = OpAccessChain %_ptr_Uniform_v4float %10 %int_2
%120 = OpLoad %v4float %118
OpStore %113 %120
OpBranch %117
%116 = OpLabel
%121 = OpAccessChain %_ptr_Uniform_v4float %10 %int_3
%123 = OpLoad %v4float %121
OpStore %113 %123
OpBranch %117
%117 = OpLabel
%124 = OpLoad %v4float %113
OpReturnValue %124
OpFunctionEnd

View File

@ -1,6 +1,9 @@
out vec4 sk_FragColor; out vec4 sk_FragColor;
uniform float a; uniform vec4 input;
void main() { uniform vec4 expected;
sk_FragColor.x = round(a); uniform vec4 colorGreen;
uniform vec4 colorRed;
vec4 main() {
return ((((((round(input.x) == expected.x && round(input.xy) == expected.xy) && round(input.xyz) == expected.xyz) && round(input) == expected) && -2.0 == expected.x) && vec2(-2.0, -0.0) == expected.xy) && vec3(-2.0, -0.0, 0.0) == expected.xyz) && vec4(-2.0, -0.0, 0.0, 2.0) == expected ? colorGreen : colorRed;
} }

View File

@ -2,7 +2,10 @@
#include <simd/simd.h> #include <simd/simd.h>
using namespace metal; using namespace metal;
struct Uniforms { struct Uniforms {
float a; float4 input;
float4 expected;
float4 colorGreen;
float4 colorRed;
}; };
struct Inputs { struct Inputs {
}; };
@ -13,6 +16,6 @@ struct Outputs {
fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) { fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {
Outputs _out; Outputs _out;
(void)_out; (void)_out;
_out.sk_FragColor.x = round(_uniforms.a); _out.sk_FragColor = ((((((round(_uniforms.input.x) == _uniforms.expected.x && all(round(_uniforms.input.xy) == _uniforms.expected.xy)) && all(round(_uniforms.input.xyz) == _uniforms.expected.xyz)) && all(round(_uniforms.input) == _uniforms.expected)) && -2.0 == _uniforms.expected.x) && all(float2(-2.0, -0.0) == _uniforms.expected.xy)) && all(float3(-2.0, -0.0, 0.0) == _uniforms.expected.xyz)) && all(float4(-2.0, -0.0, 0.0, 2.0) == _uniforms.expected) ? _uniforms.colorGreen : _uniforms.colorRed;
return _out; return _out;
} }

View File

@ -1,12 +1,16 @@
OpCapability Shader OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450" %1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise OpEntryPoint Fragment %_entrypoint_v "_entrypoint" %sk_FragColor %sk_Clockwise
OpExecutionMode %main OriginUpperLeft OpExecutionMode %_entrypoint_v OriginUpperLeft
OpName %sk_FragColor "sk_FragColor" OpName %sk_FragColor "sk_FragColor"
OpName %sk_Clockwise "sk_Clockwise" OpName %sk_Clockwise "sk_Clockwise"
OpName %_UniformBuffer "_UniformBuffer" OpName %_UniformBuffer "_UniformBuffer"
OpMemberName %_UniformBuffer 0 "a" OpMemberName %_UniformBuffer 0 "input"
OpMemberName %_UniformBuffer 1 "expected"
OpMemberName %_UniformBuffer 2 "colorGreen"
OpMemberName %_UniformBuffer 3 "colorRed"
OpName %_entrypoint_v "_entrypoint_v"
OpName %main "main" OpName %main "main"
OpDecorate %sk_FragColor RelaxedPrecision OpDecorate %sk_FragColor RelaxedPrecision
OpDecorate %sk_FragColor Location 0 OpDecorate %sk_FragColor Location 0
@ -14,11 +18,46 @@ OpDecorate %sk_FragColor Index 0
OpDecorate %sk_Clockwise BuiltIn FrontFacing OpDecorate %sk_Clockwise BuiltIn FrontFacing
OpMemberDecorate %_UniformBuffer 0 Offset 0 OpMemberDecorate %_UniformBuffer 0 Offset 0
OpMemberDecorate %_UniformBuffer 0 RelaxedPrecision OpMemberDecorate %_UniformBuffer 0 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 1 Offset 16
OpMemberDecorate %_UniformBuffer 1 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 2 Offset 32
OpMemberDecorate %_UniformBuffer 2 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 3 Offset 48
OpMemberDecorate %_UniformBuffer 3 RelaxedPrecision
OpDecorate %_UniformBuffer Block OpDecorate %_UniformBuffer Block
OpDecorate %10 Binding 0 OpDecorate %10 Binding 0
OpDecorate %10 DescriptorSet 0 OpDecorate %10 DescriptorSet 0
OpDecorate %16 RelaxedPrecision OpDecorate %27 RelaxedPrecision
OpDecorate %21 RelaxedPrecision OpDecorate %32 RelaxedPrecision
OpDecorate %33 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %41 RelaxedPrecision
OpDecorate %43 RelaxedPrecision
OpDecorate %44 RelaxedPrecision
OpDecorate %46 RelaxedPrecision
OpDecorate %47 RelaxedPrecision
OpDecorate %54 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
OpDecorate %57 RelaxedPrecision
OpDecorate %60 RelaxedPrecision
OpDecorate %61 RelaxedPrecision
OpDecorate %68 RelaxedPrecision
OpDecorate %70 RelaxedPrecision
OpDecorate %72 RelaxedPrecision
OpDecorate %81 RelaxedPrecision
OpDecorate %82 RelaxedPrecision
OpDecorate %88 RelaxedPrecision
OpDecorate %90 RelaxedPrecision
OpDecorate %91 RelaxedPrecision
OpDecorate %97 RelaxedPrecision
OpDecorate %99 RelaxedPrecision
OpDecorate %100 RelaxedPrecision
OpDecorate %107 RelaxedPrecision
OpDecorate %109 RelaxedPrecision
OpDecorate %120 RelaxedPrecision
OpDecorate %123 RelaxedPrecision
OpDecorate %124 RelaxedPrecision
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%v4float = OpTypeVector %float 4 %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float %_ptr_Output_v4float = OpTypePointer Output %v4float
@ -26,21 +65,152 @@ OpDecorate %21 RelaxedPrecision
%bool = OpTypeBool %bool = OpTypeBool
%_ptr_Input_bool = OpTypePointer Input %bool %_ptr_Input_bool = OpTypePointer Input %bool
%sk_Clockwise = OpVariable %_ptr_Input_bool Input %sk_Clockwise = OpVariable %_ptr_Input_bool Input
%_UniformBuffer = OpTypeStruct %float %_UniformBuffer = OpTypeStruct %v4float %v4float %v4float %v4float
%_ptr_Uniform__UniformBuffer = OpTypePointer Uniform %_UniformBuffer %_ptr_Uniform__UniformBuffer = OpTypePointer Uniform %_UniformBuffer
%10 = OpVariable %_ptr_Uniform__UniformBuffer Uniform %10 = OpVariable %_ptr_Uniform__UniformBuffer Uniform
%void = OpTypeVoid %void = OpTypeVoid
%14 = OpTypeFunction %void %15 = OpTypeFunction %void
%_ptr_Uniform_float = OpTypePointer Uniform %float %v2float = OpTypeVector %float 2
%float_0 = OpConstant %float 0
%19 = OpConstantComposite %v2float %float_0 %float_0
%_ptr_Function_v2float = OpTypePointer Function %v2float
%23 = OpTypeFunction %v4float %_ptr_Function_v2float
%false = OpConstantFalse %bool
%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%int_0 = OpConstant %int 0 %int_0 = OpConstant %int 0
%_ptr_Output_float = OpTypePointer Output %float %int_1 = OpConstant %int 1
%main = OpFunction %void None %14 %v2bool = OpTypeVector %bool 2
%15 = OpLabel %v3float = OpTypeVector %float 3
%17 = OpAccessChain %_ptr_Uniform_float %10 %int_0 %v3bool = OpTypeVector %bool 3
%21 = OpLoad %float %17 %v4bool = OpTypeVector %bool 4
%16 = OpExtInst %float %1 RoundEven %21 %float_n2 = OpConstant %float -2
%22 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0 %float_n0 = OpConstant %float -0
OpStore %22 %16 %88 = OpConstantComposite %v2float %float_n2 %float_n0
%97 = OpConstantComposite %v3float %float_n2 %float_n0 %float_0
%float_2 = OpConstant %float 2
%107 = OpConstantComposite %v4float %float_n2 %float_n0 %float_0 %float_2
%_ptr_Function_v4float = OpTypePointer Function %v4float
%int_2 = OpConstant %int 2
%int_3 = OpConstant %int 3
%_entrypoint_v = OpFunction %void None %15
%16 = OpLabel
%20 = OpVariable %_ptr_Function_v2float Function
OpStore %20 %19
%22 = OpFunctionCall %v4float %main %20
OpStore %sk_FragColor %22
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%main = OpFunction %v4float None %23
%24 = OpFunctionParameter %_ptr_Function_v2float
%25 = OpLabel
%113 = OpVariable %_ptr_Function_v4float Function
%28 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%32 = OpLoad %v4float %28
%33 = OpCompositeExtract %float %32 0
%27 = OpExtInst %float %1 RoundEven %33
%34 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%36 = OpLoad %v4float %34
%37 = OpCompositeExtract %float %36 0
%38 = OpFOrdEqual %bool %27 %37
OpSelectionMerge %40 None
OpBranchConditional %38 %39 %40
%39 = OpLabel
%42 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%43 = OpLoad %v4float %42
%44 = OpVectorShuffle %v2float %43 %43 0 1
%41 = OpExtInst %v2float %1 RoundEven %44
%45 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%46 = OpLoad %v4float %45
%47 = OpVectorShuffle %v2float %46 %46 0 1
%48 = OpFOrdEqual %v2bool %41 %47
%50 = OpAll %bool %48
OpBranch %40
%40 = OpLabel
%51 = OpPhi %bool %false %25 %50 %39
OpSelectionMerge %53 None
OpBranchConditional %51 %52 %53
%52 = OpLabel
%55 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%56 = OpLoad %v4float %55
%57 = OpVectorShuffle %v3float %56 %56 0 1 2
%54 = OpExtInst %v3float %1 RoundEven %57
%59 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%60 = OpLoad %v4float %59
%61 = OpVectorShuffle %v3float %60 %60 0 1 2
%62 = OpFOrdEqual %v3bool %54 %61
%64 = OpAll %bool %62
OpBranch %53
%53 = OpLabel
%65 = OpPhi %bool %false %40 %64 %52
OpSelectionMerge %67 None
OpBranchConditional %65 %66 %67
%66 = OpLabel
%69 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%70 = OpLoad %v4float %69
%68 = OpExtInst %v4float %1 RoundEven %70
%71 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%72 = OpLoad %v4float %71
%73 = OpFOrdEqual %v4bool %68 %72
%75 = OpAll %bool %73
OpBranch %67
%67 = OpLabel
%76 = OpPhi %bool %false %53 %75 %66
OpSelectionMerge %78 None
OpBranchConditional %76 %77 %78
%77 = OpLabel
%80 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%81 = OpLoad %v4float %80
%82 = OpCompositeExtract %float %81 0
%83 = OpFOrdEqual %bool %float_n2 %82
OpBranch %78
%78 = OpLabel
%84 = OpPhi %bool %false %67 %83 %77
OpSelectionMerge %86 None
OpBranchConditional %84 %85 %86
%85 = OpLabel
%89 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%90 = OpLoad %v4float %89
%91 = OpVectorShuffle %v2float %90 %90 0 1
%92 = OpFOrdEqual %v2bool %88 %91
%93 = OpAll %bool %92
OpBranch %86
%86 = OpLabel
%94 = OpPhi %bool %false %78 %93 %85
OpSelectionMerge %96 None
OpBranchConditional %94 %95 %96
%95 = OpLabel
%98 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%99 = OpLoad %v4float %98
%100 = OpVectorShuffle %v3float %99 %99 0 1 2
%101 = OpFOrdEqual %v3bool %97 %100
%102 = OpAll %bool %101
OpBranch %96
%96 = OpLabel
%103 = OpPhi %bool %false %86 %102 %95
OpSelectionMerge %105 None
OpBranchConditional %103 %104 %105
%104 = OpLabel
%108 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%109 = OpLoad %v4float %108
%110 = OpFOrdEqual %v4bool %107 %109
%111 = OpAll %bool %110
OpBranch %105
%105 = OpLabel
%112 = OpPhi %bool %false %96 %111 %104
OpSelectionMerge %117 None
OpBranchConditional %112 %115 %116
%115 = OpLabel
%118 = OpAccessChain %_ptr_Uniform_v4float %10 %int_2
%120 = OpLoad %v4float %118
OpStore %113 %120
OpBranch %117
%116 = OpLabel
%121 = OpAccessChain %_ptr_Uniform_v4float %10 %int_3
%123 = OpLoad %v4float %121
OpStore %113 %123
OpBranch %117
%117 = OpLabel
%124 = OpLoad %v4float %113
OpReturnValue %124
OpFunctionEnd

View File

@ -1,6 +1,9 @@
out vec4 sk_FragColor; out vec4 sk_FragColor;
uniform float a; uniform vec4 input;
void main() { uniform vec4 expected;
sk_FragColor.x = roundEven(a); uniform vec4 colorGreen;
uniform vec4 colorRed;
vec4 main() {
return ((((((roundEven(input.x) == expected.x && roundEven(input.xy) == expected.xy) && roundEven(input.xyz) == expected.xyz) && roundEven(input) == expected) && -2.0 == expected.x) && vec2(-2.0, -0.0) == expected.xy) && vec3(-2.0, -0.0, 0.0) == expected.xyz) && vec4(-2.0, -0.0, 0.0, 2.0) == expected ? colorGreen : colorRed;
} }

View File

@ -2,7 +2,10 @@
#include <simd/simd.h> #include <simd/simd.h>
using namespace metal; using namespace metal;
struct Uniforms { struct Uniforms {
float a; float4 input;
float4 expected;
float4 colorGreen;
float4 colorRed;
}; };
struct Inputs { struct Inputs {
}; };
@ -13,6 +16,6 @@ struct Outputs {
fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) { fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {
Outputs _out; Outputs _out;
(void)_out; (void)_out;
_out.sk_FragColor.x = rint(_uniforms.a); _out.sk_FragColor = ((((((rint(_uniforms.input.x) == _uniforms.expected.x && all(rint(_uniforms.input.xy) == _uniforms.expected.xy)) && all(rint(_uniforms.input.xyz) == _uniforms.expected.xyz)) && all(rint(_uniforms.input) == _uniforms.expected)) && -2.0 == _uniforms.expected.x) && all(float2(-2.0, -0.0) == _uniforms.expected.xy)) && all(float3(-2.0, -0.0, 0.0) == _uniforms.expected.xyz)) && all(float4(-2.0, -0.0, 0.0, 2.0) == _uniforms.expected) ? _uniforms.colorGreen : _uniforms.colorRed;
return _out; return _out;
} }

View File

@ -1,23 +1,57 @@
OpCapability Shader OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450" %1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise OpEntryPoint Fragment %_entrypoint_v "_entrypoint" %sk_FragColor %sk_Clockwise
OpExecutionMode %main OriginUpperLeft OpExecutionMode %_entrypoint_v OriginUpperLeft
OpName %sk_FragColor "sk_FragColor" OpName %sk_FragColor "sk_FragColor"
OpName %sk_Clockwise "sk_Clockwise" OpName %sk_Clockwise "sk_Clockwise"
OpName %_UniformBuffer "_UniformBuffer" OpName %_UniformBuffer "_UniformBuffer"
OpMemberName %_UniformBuffer 0 "a" OpMemberName %_UniformBuffer 0 "testInputs"
OpMemberName %_UniformBuffer 1 "colorGreen"
OpMemberName %_UniformBuffer 2 "colorRed"
OpName %_entrypoint_v "_entrypoint_v"
OpName %main "main" OpName %main "main"
OpName %expected "expected"
OpDecorate %sk_FragColor RelaxedPrecision OpDecorate %sk_FragColor RelaxedPrecision
OpDecorate %sk_FragColor Location 0 OpDecorate %sk_FragColor Location 0
OpDecorate %sk_FragColor Index 0 OpDecorate %sk_FragColor Index 0
OpDecorate %sk_Clockwise BuiltIn FrontFacing OpDecorate %sk_Clockwise BuiltIn FrontFacing
OpMemberDecorate %_UniformBuffer 0 Offset 0 OpMemberDecorate %_UniformBuffer 0 Offset 0
OpMemberDecorate %_UniformBuffer 0 RelaxedPrecision OpMemberDecorate %_UniformBuffer 0 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 1 Offset 16
OpMemberDecorate %_UniformBuffer 1 RelaxedPrecision
OpMemberDecorate %_UniformBuffer 2 Offset 32
OpMemberDecorate %_UniformBuffer 2 RelaxedPrecision
OpDecorate %_UniformBuffer Block OpDecorate %_UniformBuffer Block
OpDecorate %10 Binding 0 OpDecorate %10 Binding 0
OpDecorate %10 DescriptorSet 0 OpDecorate %10 DescriptorSet 0
OpDecorate %21 RelaxedPrecision OpDecorate %expected RelaxedPrecision
OpDecorate %30 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %38 RelaxedPrecision
OpDecorate %39 RelaxedPrecision
OpDecorate %40 RelaxedPrecision
OpDecorate %46 RelaxedPrecision
OpDecorate %47 RelaxedPrecision
OpDecorate %50 RelaxedPrecision
OpDecorate %51 RelaxedPrecision
OpDecorate %60 RelaxedPrecision
OpDecorate %61 RelaxedPrecision
OpDecorate %65 RelaxedPrecision
OpDecorate %66 RelaxedPrecision
OpDecorate %75 RelaxedPrecision
OpDecorate %78 RelaxedPrecision
OpDecorate %85 RelaxedPrecision
OpDecorate %86 RelaxedPrecision
OpDecorate %91 RelaxedPrecision
OpDecorate %92 RelaxedPrecision
OpDecorate %98 RelaxedPrecision
OpDecorate %99 RelaxedPrecision
OpDecorate %100 RelaxedPrecision
OpDecorate %106 RelaxedPrecision
OpDecorate %116 RelaxedPrecision
OpDecorate %119 RelaxedPrecision
OpDecorate %120 RelaxedPrecision
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%v4float = OpTypeVector %float 4 %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float %_ptr_Output_v4float = OpTypePointer Output %v4float
@ -25,23 +59,149 @@ OpDecorate %21 RelaxedPrecision
%bool = OpTypeBool %bool = OpTypeBool
%_ptr_Input_bool = OpTypePointer Input %bool %_ptr_Input_bool = OpTypePointer Input %bool
%sk_Clockwise = OpVariable %_ptr_Input_bool Input %sk_Clockwise = OpVariable %_ptr_Input_bool Input
%_UniformBuffer = OpTypeStruct %float %_UniformBuffer = OpTypeStruct %v4float %v4float %v4float
%_ptr_Uniform__UniformBuffer = OpTypePointer Uniform %_UniformBuffer %_ptr_Uniform__UniformBuffer = OpTypePointer Uniform %_UniformBuffer
%10 = OpVariable %_ptr_Uniform__UniformBuffer Uniform %10 = OpVariable %_ptr_Uniform__UniformBuffer Uniform
%void = OpTypeVoid %void = OpTypeVoid
%14 = OpTypeFunction %void %15 = OpTypeFunction %void
%_ptr_Uniform_float = OpTypePointer Uniform %float %v2float = OpTypeVector %float 2
%float_0 = OpConstant %float 0
%19 = OpConstantComposite %v2float %float_0 %float_0
%_ptr_Function_v2float = OpTypePointer Function %v2float
%23 = OpTypeFunction %v4float %_ptr_Function_v2float
%_ptr_Function_v4float = OpTypePointer Function %v4float
%float_0_75 = OpConstant %float 0.75
%float_1 = OpConstant %float 1
%30 = OpConstantComposite %v4float %float_0 %float_0 %float_0_75 %float_1
%false = OpConstantFalse %bool
%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%int_0 = OpConstant %int 0 %int_0 = OpConstant %int 0
%float_0 = OpConstant %float 0 %v2bool = OpTypeVector %bool 2
%float_1 = OpConstant %float 1 %v3float = OpTypeVector %float 3
%_ptr_Output_float = OpTypePointer Output %float %v3bool = OpTypeVector %bool 3
%main = OpFunction %void None %14 %v4bool = OpTypeVector %bool 4
%15 = OpLabel %98 = OpConstantComposite %v3float %float_0 %float_0 %float_0_75
%17 = OpAccessChain %_ptr_Uniform_float %10 %int_0 %int_1 = OpConstant %int 1
%21 = OpLoad %float %17 %int_2 = OpConstant %int 2
%16 = OpExtInst %float %1 FClamp %21 %float_0 %float_1 %_entrypoint_v = OpFunction %void None %15
%24 = OpAccessChain %_ptr_Output_float %sk_FragColor %int_0 %16 = OpLabel
OpStore %24 %16 %20 = OpVariable %_ptr_Function_v2float Function
OpStore %20 %19
%22 = OpFunctionCall %v4float %main %20
OpStore %sk_FragColor %22
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
%main = OpFunction %v4float None %23
%24 = OpFunctionParameter %_ptr_Function_v2float
%25 = OpLabel
%expected = OpVariable %_ptr_Function_v4float Function
%110 = OpVariable %_ptr_Function_v4float Function
OpStore %expected %30
%33 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%37 = OpLoad %v4float %33
%38 = OpCompositeExtract %float %37 0
%32 = OpExtInst %float %1 FClamp %38 %float_0 %float_1
%39 = OpLoad %v4float %expected
%40 = OpCompositeExtract %float %39 0
%41 = OpFOrdEqual %bool %32 %40
OpSelectionMerge %43 None
OpBranchConditional %41 %42 %43
%42 = OpLabel
%45 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%46 = OpLoad %v4float %45
%47 = OpVectorShuffle %v2float %46 %46 0 1
%48 = OpCompositeConstruct %v2float %float_0 %float_0
%49 = OpCompositeConstruct %v2float %float_1 %float_1
%44 = OpExtInst %v2float %1 FClamp %47 %48 %49
%50 = OpLoad %v4float %expected
%51 = OpVectorShuffle %v2float %50 %50 0 1
%52 = OpFOrdEqual %v2bool %44 %51
%54 = OpAll %bool %52
OpBranch %43
%43 = OpLabel
%55 = OpPhi %bool %false %25 %54 %42
OpSelectionMerge %57 None
OpBranchConditional %55 %56 %57
%56 = OpLabel
%59 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%60 = OpLoad %v4float %59
%61 = OpVectorShuffle %v3float %60 %60 0 1 2
%63 = OpCompositeConstruct %v3float %float_0 %float_0 %float_0
%64 = OpCompositeConstruct %v3float %float_1 %float_1 %float_1
%58 = OpExtInst %v3float %1 FClamp %61 %63 %64
%65 = OpLoad %v4float %expected
%66 = OpVectorShuffle %v3float %65 %65 0 1 2
%67 = OpFOrdEqual %v3bool %58 %66
%69 = OpAll %bool %67
OpBranch %57
%57 = OpLabel
%70 = OpPhi %bool %false %43 %69 %56
OpSelectionMerge %72 None
OpBranchConditional %70 %71 %72
%71 = OpLabel
%74 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%75 = OpLoad %v4float %74
%76 = OpCompositeConstruct %v4float %float_0 %float_0 %float_0 %float_0
%77 = OpCompositeConstruct %v4float %float_1 %float_1 %float_1 %float_1
%73 = OpExtInst %v4float %1 FClamp %75 %76 %77
%78 = OpLoad %v4float %expected
%79 = OpFOrdEqual %v4bool %73 %78
%81 = OpAll %bool %79
OpBranch %72
%72 = OpLabel
%82 = OpPhi %bool %false %57 %81 %71
OpSelectionMerge %84 None
OpBranchConditional %82 %83 %84
%83 = OpLabel
%85 = OpLoad %v4float %expected
%86 = OpCompositeExtract %float %85 0
%87 = OpFOrdEqual %bool %float_0 %86
OpBranch %84
%84 = OpLabel
%88 = OpPhi %bool %false %72 %87 %83
OpSelectionMerge %90 None
OpBranchConditional %88 %89 %90
%89 = OpLabel
%91 = OpLoad %v4float %expected
%92 = OpVectorShuffle %v2float %91 %91 0 1
%93 = OpFOrdEqual %v2bool %19 %92
%94 = OpAll %bool %93
OpBranch %90
%90 = OpLabel
%95 = OpPhi %bool %false %84 %94 %89
OpSelectionMerge %97 None
OpBranchConditional %95 %96 %97
%96 = OpLabel
%99 = OpLoad %v4float %expected
%100 = OpVectorShuffle %v3float %99 %99 0 1 2
%101 = OpFOrdEqual %v3bool %98 %100
%102 = OpAll %bool %101
OpBranch %97
%97 = OpLabel
%103 = OpPhi %bool %false %90 %102 %96
OpSelectionMerge %105 None
OpBranchConditional %103 %104 %105
%104 = OpLabel
%106 = OpLoad %v4float %expected
%107 = OpFOrdEqual %v4bool %30 %106
%108 = OpAll %bool %107
OpBranch %105
%105 = OpLabel
%109 = OpPhi %bool %false %97 %108 %104
OpSelectionMerge %113 None
OpBranchConditional %109 %111 %112
%111 = OpLabel
%114 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%116 = OpLoad %v4float %114
OpStore %110 %116
OpBranch %113
%112 = OpLabel
%117 = OpAccessChain %_ptr_Uniform_v4float %10 %int_2
%119 = OpLoad %v4float %117
OpStore %110 %119
OpBranch %113
%113 = OpLabel
%120 = OpLoad %v4float %110
OpReturnValue %120
OpFunctionEnd

View File

@ -1,6 +1,9 @@
out vec4 sk_FragColor; out vec4 sk_FragColor;
uniform float a; uniform vec4 testInputs;
void main() { uniform vec4 colorGreen;
sk_FragColor.x = clamp(a, 0.0, 1.0); uniform vec4 colorRed;
vec4 main() {
vec4 expected = vec4(0.0, 0.0, 0.75, 1.0);
return ((((((clamp(testInputs.x, 0.0, 1.0) == expected.x && clamp(testInputs.xy, 0.0, 1.0) == expected.xy) && clamp(testInputs.xyz, 0.0, 1.0) == expected.xyz) && clamp(testInputs, 0.0, 1.0) == expected) && 0.0 == expected.x) && vec2(0.0, 0.0) == expected.xy) && vec3(0.0, 0.0, 0.75) == expected.xyz) && vec4(0.0, 0.0, 0.75, 1.0) == expected ? colorGreen : colorRed;
} }

View File

@ -2,7 +2,9 @@
#include <simd/simd.h> #include <simd/simd.h>
using namespace metal; using namespace metal;
struct Uniforms { struct Uniforms {
float a; float4 testInputs;
float4 colorGreen;
float4 colorRed;
}; };
struct Inputs { struct Inputs {
}; };
@ -13,6 +15,7 @@ struct Outputs {
fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) { fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {
Outputs _out; Outputs _out;
(void)_out; (void)_out;
_out.sk_FragColor.x = saturate(_uniforms.a); float4 expected = float4(0.0, 0.0, 0.75, 1.0);
_out.sk_FragColor = ((((((saturate(_uniforms.testInputs.x) == expected.x && all(saturate(_uniforms.testInputs.xy) == expected.xy)) && all(saturate(_uniforms.testInputs.xyz) == expected.xyz)) && all(saturate(_uniforms.testInputs) == expected)) && 0.0 == expected.x) && all(float2(0.0, 0.0) == expected.xy)) && all(float3(0.0, 0.0, 0.75) == expected.xyz)) && all(float4(0.0, 0.0, 0.75, 1.0) == expected) ? _uniforms.colorGreen : _uniforms.colorRed;
return _out; return _out;
} }