From 010c0ec06152d1283364c41a958731512672acca Mon Sep 17 00:00:00 2001 From: John Stiles Date: Mon, 12 Jul 2021 15:05:54 -0400 Subject: [PATCH] Allow swizzles on Boolean scalar expressions. Boolean vector expressions already allowed swizzles (see the SwizzleBoolConstants.sksl test), but scalars had been inadvertently disallowed. Change-Id: I89e7139db50981f0ee1a9a5086b02603e57f967d Bug: skia:12195 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/427196 Commit-Queue: Ethan Nicholas Auto-Submit: John Stiles Reviewed-by: Ethan Nicholas --- src/sksl/ir/SkSLSwizzle.cpp | 10 +- tests/SkSLTest.cpp | 2 +- tests/sksl/shared/SwizzleScalarBool.asm.frag | 110 ++++++++++++++++++- tests/sksl/shared/SwizzleScalarBool.glsl | 13 ++- tests/sksl/shared/SwizzleScalarBool.metal | 26 ++++- 5 files changed, 144 insertions(+), 17 deletions(-) diff --git a/src/sksl/ir/SkSLSwizzle.cpp b/src/sksl/ir/SkSLSwizzle.cpp index 7b70c90a76..70135cdc72 100644 --- a/src/sksl/ir/SkSLSwizzle.cpp +++ b/src/sksl/ir/SkSLSwizzle.cpp @@ -138,7 +138,7 @@ std::unique_ptr Swizzle::Convert(const Context& context, const int offset = base->fOffset; const Type& baseType = base->type(); - if (!baseType.isVector() && !baseType.isNumber()) { + if (!baseType.isVector() && !baseType.isScalar()) { context.fErrors.error( offset, "cannot swizzle value of type '" + baseType.displayName() + "'"); return nullptr; @@ -229,7 +229,7 @@ std::unique_ptr Swizzle::Convert(const Context& context, // scalar.x0x0 -> type4(type2(x), 0).xyxy // vector.y111 -> type4(vector.y, 1).xyyy // vector.z10x -> type4(vector.zx, 1, 0).xzwy - const Type* numberType = &baseType.componentType(); + const Type* scalarType = &baseType.componentType(); ComponentArray swizzleComponents; int maskFieldIdx = 0; int constantFieldIdx = maskComponents.size(); @@ -241,7 +241,7 @@ std::unique_ptr Swizzle::Convert(const Context& context, if (constantZeroIdx == -1) { // Synthesize a 'type(0)' argument at the end of the constructor. constructorArgs.push_back(ConstructorScalarCast::Make( - context, offset, *numberType, + context, offset, *scalarType, IntLiteral::Make(context, offset, /*value=*/0))); constantZeroIdx = constantFieldIdx++; } @@ -251,7 +251,7 @@ std::unique_ptr Swizzle::Convert(const Context& context, if (constantOneIdx == -1) { // Synthesize a 'type(1)' argument at the end of the constructor. constructorArgs.push_back(ConstructorScalarCast::Make( - context, offset, *numberType, + context, offset, *scalarType, IntLiteral::Make(context, offset, /*value=*/1))); constantOneIdx = constantFieldIdx++; } @@ -265,7 +265,7 @@ std::unique_ptr Swizzle::Convert(const Context& context, } expr = Constructor::Convert(context, offset, - numberType->toCompound(context, constantFieldIdx, /*rows=*/1), + scalarType->toCompound(context, constantFieldIdx, /*rows=*/1), std::move(constructorArgs)); if (!expr) { return nullptr; diff --git a/tests/SkSLTest.cpp b/tests/SkSLTest.cpp index 9d95a85a8f..74f58ff166 100644 --- a/tests/SkSLTest.cpp +++ b/tests/SkSLTest.cpp @@ -278,7 +278,7 @@ SKSL_TEST(SkSLSwizzleConstants, "shared/SwizzleConstants.sksl") SKSL_TEST(SkSLSwizzleLTRB, "shared/SwizzleLTRB.sksl") SKSL_TEST(SkSLSwizzleOpt, "shared/SwizzleOpt.sksl") SKSL_TEST(SkSLSwizzleScalar, "shared/SwizzleScalar.sksl") -//SKSL_TEST(SkSLSwizzleScalarBool, "shared/SwizzleScalarBool.sksl") +SKSL_TEST(SkSLSwizzleScalarBool, "shared/SwizzleScalarBool.sksl") SKSL_TEST(SkSLSwizzleScalarInt, "shared/SwizzleScalarInt.sksl") SKSL_TEST(SkSLTernaryAsLValueEntirelyFoldable, "shared/TernaryAsLValueEntirelyFoldable.sksl") SKSL_TEST(SkSLTernaryAsLValueFoldableTest, "shared/TernaryAsLValueFoldableTest.sksl") diff --git a/tests/sksl/shared/SwizzleScalarBool.asm.frag b/tests/sksl/shared/SwizzleScalarBool.asm.frag index 106011eafe..c6c9653960 100644 --- a/tests/sksl/shared/SwizzleScalarBool.asm.frag +++ b/tests/sksl/shared/SwizzleScalarBool.asm.frag @@ -1,4 +1,106 @@ -### Compilation failed: - -error: 5: cannot swizzle value of type 'bool' -1 error +OpCapability Shader +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %_entrypoint_v "_entrypoint" %sk_FragColor %sk_Clockwise +OpExecutionMode %_entrypoint_v OriginUpperLeft +OpName %sk_FragColor "sk_FragColor" +OpName %sk_Clockwise "sk_Clockwise" +OpName %_UniformBuffer "_UniformBuffer" +OpMemberName %_UniformBuffer 0 "unknownInput" +OpName %_entrypoint_v "_entrypoint_v" +OpName %main "main" +OpName %b "b" +OpName %b4 "b4" +OpDecorate %sk_FragColor RelaxedPrecision +OpDecorate %sk_FragColor Location 0 +OpDecorate %sk_FragColor Index 0 +OpDecorate %sk_Clockwise BuiltIn FrontFacing +OpMemberDecorate %_UniformBuffer 0 Offset 0 +OpMemberDecorate %_UniformBuffer 0 RelaxedPrecision +OpDecorate %_UniformBuffer Block +OpDecorate %10 Binding 0 +OpDecorate %10 DescriptorSet 0 +OpDecorate %32 RelaxedPrecision +OpDecorate %37 RelaxedPrecision +OpDecorate %39 RelaxedPrecision +OpDecorate %47 RelaxedPrecision +OpDecorate %49 RelaxedPrecision +OpDecorate %50 RelaxedPrecision +OpDecorate %52 RelaxedPrecision +OpDecorate %54 RelaxedPrecision +OpDecorate %57 RelaxedPrecision +OpDecorate %59 RelaxedPrecision +OpDecorate %61 RelaxedPrecision +OpDecorate %62 RelaxedPrecision +%float = OpTypeFloat 32 +%v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float +%sk_FragColor = OpVariable %_ptr_Output_v4float Output +%bool = OpTypeBool +%_ptr_Input_bool = OpTypePointer Input %bool +%sk_Clockwise = OpVariable %_ptr_Input_bool Input +%_UniformBuffer = OpTypeStruct %float +%_ptr_Uniform__UniformBuffer = OpTypePointer Uniform %_UniformBuffer +%10 = OpVariable %_ptr_Uniform__UniformBuffer Uniform +%void = OpTypeVoid +%15 = OpTypeFunction %void +%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_bool = OpTypePointer Function %bool +%_ptr_Uniform_float = OpTypePointer Uniform %float +%int = OpTypeInt 32 1 +%int_0 = OpConstant %int 0 +%v4bool = OpTypeVector %bool 4 +%_ptr_Function_v4bool = OpTypePointer Function %v4bool +%v2bool = OpTypeVector %bool 2 +%false = OpConstantFalse %bool +%true = OpConstantTrue %bool +%float_1 = OpConstant %float 1 +%_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 +OpFunctionEnd +%main = OpFunction %v4float None %23 +%24 = OpFunctionParameter %_ptr_Function_v2float +%25 = OpLabel +%b = OpVariable %_ptr_Function_bool Function +%b4 = OpVariable %_ptr_Function_v4bool Function +%28 = OpAccessChain %_ptr_Uniform_float %10 %int_0 +%32 = OpLoad %float %28 +%33 = OpFUnordNotEqual %bool %32 %float_0 +OpStore %b %33 +%37 = OpLoad %bool %b +%38 = OpCompositeConstruct %v4bool %37 %37 %37 %37 +OpStore %b4 %38 +%39 = OpLoad %bool %b +%40 = OpCompositeConstruct %v2bool %39 %39 +%42 = OpCompositeExtract %bool %40 0 +%43 = OpCompositeExtract %bool %40 1 +%46 = OpCompositeConstruct %v4bool %42 %43 %false %true +OpStore %b4 %46 +%47 = OpLoad %bool %b +%48 = OpCompositeConstruct %v4bool %false %47 %true %false +OpStore %b4 %48 +%49 = OpLoad %bool %b +%50 = OpLoad %bool %b +%51 = OpCompositeConstruct %v4bool %false %49 %false %50 +OpStore %b4 %51 +%52 = OpLoad %v4bool %b4 +%53 = OpCompositeExtract %bool %52 0 +%54 = OpSelect %float %53 %float_1 %float_0 +%56 = OpCompositeExtract %bool %52 1 +%57 = OpSelect %float %56 %float_1 %float_0 +%58 = OpCompositeExtract %bool %52 2 +%59 = OpSelect %float %58 %float_1 %float_0 +%60 = OpCompositeExtract %bool %52 3 +%61 = OpSelect %float %60 %float_1 %float_0 +%62 = OpCompositeConstruct %v4float %54 %57 %59 %61 +OpReturnValue %62 +OpFunctionEnd diff --git a/tests/sksl/shared/SwizzleScalarBool.glsl b/tests/sksl/shared/SwizzleScalarBool.glsl index 106011eafe..230d552278 100644 --- a/tests/sksl/shared/SwizzleScalarBool.glsl +++ b/tests/sksl/shared/SwizzleScalarBool.glsl @@ -1,4 +1,11 @@ -### Compilation failed: -error: 5: cannot swizzle value of type 'bool' -1 error +out vec4 sk_FragColor; +uniform float unknownInput; +vec4 main() { + bool b = bool(unknownInput); + bvec4 b4 = bvec4(b); + b4 = bvec4(bvec2(b), false, true); + b4 = bvec4(false, b, true, false); + b4 = bvec4(false, b, false, b); + return vec4(b4); +} diff --git a/tests/sksl/shared/SwizzleScalarBool.metal b/tests/sksl/shared/SwizzleScalarBool.metal index 106011eafe..62188bc65a 100644 --- a/tests/sksl/shared/SwizzleScalarBool.metal +++ b/tests/sksl/shared/SwizzleScalarBool.metal @@ -1,4 +1,22 @@ -### Compilation failed: - -error: 5: cannot swizzle value of type 'bool' -1 error +#include +#include +using namespace metal; +struct Uniforms { + float unknownInput; +}; +struct Inputs { +}; +struct Outputs { + float4 sk_FragColor [[color(0)]]; +}; +fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _uniforms [[buffer(0)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) { + Outputs _out; + (void)_out; + bool b = bool(_uniforms.unknownInput); + bool4 b4 = bool4(b); + b4 = bool4(bool2(b), false, true); + b4 = bool4(false, b, true, false); + b4 = bool4(false, b, false, b); + _out.sk_FragColor = float4(b4); + return _out; +}