diff --git a/gn/sksl_tests.gni b/gn/sksl_tests.gni index a0d66f07c5..0fefc5e1d0 100644 --- a/gn/sksl_tests.gni +++ b/gn/sksl_tests.gni @@ -384,6 +384,7 @@ sksl_shared_tests = [ "/sksl/shared/VectorConstructors.sksl", "/sksl/shared/VertexEarlyReturn.vert", "/sksl/shared/VertexID.vert", + "/sksl/shared/WhileLoopControlFlow.sksl", "/sksl/shared/Width.sksl", ] diff --git a/resources/sksl/shared/WhileLoopControlFlow.sksl b/resources/sksl/shared/WhileLoopControlFlow.sksl new file mode 100644 index 0000000000..6bdb88a95c --- /dev/null +++ b/resources/sksl/shared/WhileLoopControlFlow.sksl @@ -0,0 +1,19 @@ +half4 main() { + half4 x = half4(1, 1, 1, 1); + + // Verify that break is allowed in a while loop. + while (x.a == 1) { + x.r -= 0.25; + if (x.r <= 0) break; + } + + // Verify that continue is allowed in a while loop. + while (x.b > 0) { + x.b -= 0.25; + if (x.a == 1) continue; // should always happen + x.g = 0; + } + + // x contains green. + return x; +} diff --git a/tests/sksl/shared/WhileLoopControlFlow.asm.frag b/tests/sksl/shared/WhileLoopControlFlow.asm.frag new file mode 100644 index 0000000000..41cf70d356 --- /dev/null +++ b/tests/sksl/shared/WhileLoopControlFlow.asm.frag @@ -0,0 +1,103 @@ +### Compilation failed: + +error: SPIR-V validation error: OpEntryPoint Entry Point '2[%main]'s function return type is not void. + OpEntryPoint Fragment %main "main" %sk_Clockwise + +OpCapability Shader +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %main "main" %sk_Clockwise +OpExecutionMode %main OriginUpperLeft +OpName %sk_Clockwise "sk_Clockwise" +OpName %main "main" +OpName %x "x" +OpDecorate %sk_Clockwise RelaxedPrecision +OpDecorate %sk_Clockwise BuiltIn FrontFacing +OpDecorate %19 RelaxedPrecision +OpDecorate %26 RelaxedPrecision +OpDecorate %28 RelaxedPrecision +OpDecorate %29 RelaxedPrecision +OpDecorate %40 RelaxedPrecision +OpDecorate %45 RelaxedPrecision +OpDecorate %46 RelaxedPrecision +OpDecorate %47 RelaxedPrecision +OpDecorate %54 RelaxedPrecision +%bool = OpTypeBool +%_ptr_Input_bool = OpTypePointer Input %bool +%sk_Clockwise = OpVariable %_ptr_Input_bool Input +%float = OpTypeFloat 32 +%v4float = OpTypeVector %float 4 +%8 = OpTypeFunction %v4float +%_ptr_Function_v4float = OpTypePointer Function %v4float +%float_1 = OpConstant %float 1 +%13 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 +%_ptr_Function_float = OpTypePointer Function %float +%int = OpTypeInt 32 1 +%int_0 = OpConstant %int 0 +%float_0_25 = OpConstant %float 0.25 +%float_0 = OpConstant %float 0 +%int_2 = OpConstant %int 2 +%int_1 = OpConstant %int 1 +%main = OpFunction %v4float None %8 +%9 = OpLabel +%x = OpVariable %_ptr_Function_v4float Function +OpStore %x %13 +OpBranch %14 +%14 = OpLabel +OpLoopMerge %18 %17 None +OpBranch %15 +%15 = OpLabel +%19 = OpLoad %v4float %x +%20 = OpCompositeExtract %float %19 3 +%21 = OpFOrdEqual %bool %20 %float_1 +OpBranchConditional %21 %16 %18 +%16 = OpLabel +%22 = OpAccessChain %_ptr_Function_float %x %int_0 +%26 = OpLoad %float %22 +%28 = OpFSub %float %26 %float_0_25 +OpStore %22 %28 +%29 = OpLoad %v4float %x +%30 = OpCompositeExtract %float %29 0 +%32 = OpFOrdLessThanEqual %bool %30 %float_0 +OpSelectionMerge %34 None +OpBranchConditional %32 %33 %34 +%33 = OpLabel +OpBranch %18 +%34 = OpLabel +OpBranch %17 +%17 = OpLabel +OpBranch %14 +%18 = OpLabel +OpBranch %35 +%35 = OpLabel +OpLoopMerge %39 %38 None +OpBranch %36 +%36 = OpLabel +%40 = OpLoad %v4float %x +%41 = OpCompositeExtract %float %40 2 +%42 = OpFOrdGreaterThan %bool %41 %float_0 +OpBranchConditional %42 %37 %39 +%37 = OpLabel +%43 = OpAccessChain %_ptr_Function_float %x %int_2 +%45 = OpLoad %float %43 +%46 = OpFSub %float %45 %float_0_25 +OpStore %43 %46 +%47 = OpLoad %v4float %x +%48 = OpCompositeExtract %float %47 3 +%49 = OpFOrdEqual %bool %48 %float_1 +OpSelectionMerge %51 None +OpBranchConditional %49 %50 %51 +%50 = OpLabel +OpBranch %38 +%51 = OpLabel +%52 = OpAccessChain %_ptr_Function_float %x %int_1 +OpStore %52 %float_0 +OpBranch %38 +%38 = OpLabel +OpBranch %35 +%39 = OpLabel +%54 = OpLoad %v4float %x +OpReturnValue %54 +OpFunctionEnd + +1 error diff --git a/tests/sksl/shared/WhileLoopControlFlow.glsl b/tests/sksl/shared/WhileLoopControlFlow.glsl new file mode 100644 index 0000000000..de1cd98992 --- /dev/null +++ b/tests/sksl/shared/WhileLoopControlFlow.glsl @@ -0,0 +1,14 @@ + +vec4 main() { + vec4 x = vec4(1.0, 1.0, 1.0, 1.0); + while (x.w == 1.0) { + x.x -= 0.25; + if (x.x <= 0.0) break; + } + while (x.z > 0.0) { + x.z -= 0.25; + if (x.w == 1.0) continue; + x.y = 0.0; + } + return x; +} diff --git a/tests/sksl/shared/WhileLoopControlFlow.metal b/tests/sksl/shared/WhileLoopControlFlow.metal new file mode 100644 index 0000000000..f5f3045c68 --- /dev/null +++ b/tests/sksl/shared/WhileLoopControlFlow.metal @@ -0,0 +1,24 @@ +#include +#include +using namespace metal; +struct Inputs { +}; +struct Outputs { + float4 sk_FragColor [[color(0)]]; +}; +fragment Outputs fragmentMain(Inputs _in [[stage_in]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) { + Outputs _out; + (void)_out; + float4 x = float4(1.0, 1.0, 1.0, 1.0); + while (x.w == 1.0) { + x.x = x.x - 0.25; + if (x.x <= 0.0) break; + } + while (x.z > 0.0) { + x.z = x.z - 0.25; + if (x.w == 1.0) continue; + x.y = 0.0; + } + _out.sk_FragColor = x; + return _out; +}