1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2022 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStream.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkArenaAlloc.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkStringView.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkRasterPipeline.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/codegen/SkSLRasterPipelineBuilder.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/tracing/SkSLDebugTracePriv.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
15*c8dee2aaSAndroid Build Coastguard Worker
get_program_dump(SkSL::RP::Program & program)16*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkData> get_program_dump(SkSL::RP::Program& program) {
17*c8dee2aaSAndroid Build Coastguard Worker SkDynamicMemoryWStream stream;
18*c8dee2aaSAndroid Build Coastguard Worker program.dump(&stream);
19*c8dee2aaSAndroid Build Coastguard Worker return stream.detachAsData();
20*c8dee2aaSAndroid Build Coastguard Worker }
21*c8dee2aaSAndroid Build Coastguard Worker
as_string_view(const sk_sp<SkData> & dump)22*c8dee2aaSAndroid Build Coastguard Worker static std::string_view as_string_view(const sk_sp<SkData>& dump) {
23*c8dee2aaSAndroid Build Coastguard Worker return std::string_view(static_cast<const char*>(dump->data()), dump->size());
24*c8dee2aaSAndroid Build Coastguard Worker }
25*c8dee2aaSAndroid Build Coastguard Worker
check(skiatest::Reporter * r,SkSL::RP::Program & program,std::string_view expected)26*c8dee2aaSAndroid Build Coastguard Worker static void check(skiatest::Reporter* r, SkSL::RP::Program& program, std::string_view expected) {
27*c8dee2aaSAndroid Build Coastguard Worker // Verify that the program matches expectations.
28*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> dump = get_program_dump(program);
29*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, as_string_view(dump) == expected,
30*c8dee2aaSAndroid Build Coastguard Worker "Output did not match expectation:\n%.*s",
31*c8dee2aaSAndroid Build Coastguard Worker (int)dump->size(), static_cast<const char*>(dump->data()));
32*c8dee2aaSAndroid Build Coastguard Worker }
33*c8dee2aaSAndroid Build Coastguard Worker
one_slot_at(SkSL::RP::Slot index)34*c8dee2aaSAndroid Build Coastguard Worker static SkSL::RP::SlotRange one_slot_at(SkSL::RP::Slot index) {
35*c8dee2aaSAndroid Build Coastguard Worker return SkSL::RP::SlotRange{index, 1};
36*c8dee2aaSAndroid Build Coastguard Worker }
37*c8dee2aaSAndroid Build Coastguard Worker
two_slots_at(SkSL::RP::Slot index)38*c8dee2aaSAndroid Build Coastguard Worker static SkSL::RP::SlotRange two_slots_at(SkSL::RP::Slot index) {
39*c8dee2aaSAndroid Build Coastguard Worker return SkSL::RP::SlotRange{index, 2};
40*c8dee2aaSAndroid Build Coastguard Worker }
41*c8dee2aaSAndroid Build Coastguard Worker
three_slots_at(SkSL::RP::Slot index)42*c8dee2aaSAndroid Build Coastguard Worker static SkSL::RP::SlotRange three_slots_at(SkSL::RP::Slot index) {
43*c8dee2aaSAndroid Build Coastguard Worker return SkSL::RP::SlotRange{index, 3};
44*c8dee2aaSAndroid Build Coastguard Worker }
45*c8dee2aaSAndroid Build Coastguard Worker
four_slots_at(SkSL::RP::Slot index)46*c8dee2aaSAndroid Build Coastguard Worker static SkSL::RP::SlotRange four_slots_at(SkSL::RP::Slot index) {
47*c8dee2aaSAndroid Build Coastguard Worker return SkSL::RP::SlotRange{index, 4};
48*c8dee2aaSAndroid Build Coastguard Worker }
49*c8dee2aaSAndroid Build Coastguard Worker
five_slots_at(SkSL::RP::Slot index)50*c8dee2aaSAndroid Build Coastguard Worker static SkSL::RP::SlotRange five_slots_at(SkSL::RP::Slot index) {
51*c8dee2aaSAndroid Build Coastguard Worker return SkSL::RP::SlotRange{index, 5};
52*c8dee2aaSAndroid Build Coastguard Worker }
53*c8dee2aaSAndroid Build Coastguard Worker
ten_slots_at(SkSL::RP::Slot index)54*c8dee2aaSAndroid Build Coastguard Worker static SkSL::RP::SlotRange ten_slots_at(SkSL::RP::Slot index) {
55*c8dee2aaSAndroid Build Coastguard Worker return SkSL::RP::SlotRange{index, 10};
56*c8dee2aaSAndroid Build Coastguard Worker }
57*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilder,r)58*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilder, r) {
59*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
60*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
61*c8dee2aaSAndroid Build Coastguard Worker builder.store_src_rg(two_slots_at(0));
62*c8dee2aaSAndroid Build Coastguard Worker builder.store_src(four_slots_at(2));
63*c8dee2aaSAndroid Build Coastguard Worker builder.store_dst(four_slots_at(4));
64*c8dee2aaSAndroid Build Coastguard Worker builder.store_device_xy01(four_slots_at(6));
65*c8dee2aaSAndroid Build Coastguard Worker builder.init_lane_masks();
66*c8dee2aaSAndroid Build Coastguard Worker builder.enableExecutionMaskWrites();
67*c8dee2aaSAndroid Build Coastguard Worker builder.mask_off_return_mask();
68*c8dee2aaSAndroid Build Coastguard Worker builder.mask_off_loop_mask();
69*c8dee2aaSAndroid Build Coastguard Worker builder.reenable_loop_mask(one_slot_at(4));
70*c8dee2aaSAndroid Build Coastguard Worker builder.disableExecutionMaskWrites();
71*c8dee2aaSAndroid Build Coastguard Worker builder.load_src(four_slots_at(1));
72*c8dee2aaSAndroid Build Coastguard Worker builder.load_dst(four_slots_at(3));
73*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/10,
74*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
75*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
76*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
77*c8dee2aaSAndroid Build Coastguard Worker R"(store_src_rg v0..1 = src.rg
78*c8dee2aaSAndroid Build Coastguard Worker store_src v2..5 = src.rgba
79*c8dee2aaSAndroid Build Coastguard Worker store_dst v4..7 = dst.rgba
80*c8dee2aaSAndroid Build Coastguard Worker store_device_xy01 v6..9 = DeviceCoords.xy01
81*c8dee2aaSAndroid Build Coastguard Worker init_lane_masks CondMask = LoopMask = RetMask = true
82*c8dee2aaSAndroid Build Coastguard Worker mask_off_return_mask RetMask &= ~(CondMask & LoopMask & RetMask)
83*c8dee2aaSAndroid Build Coastguard Worker mask_off_loop_mask LoopMask &= ~(CondMask & LoopMask & RetMask)
84*c8dee2aaSAndroid Build Coastguard Worker reenable_loop_mask LoopMask |= v4
85*c8dee2aaSAndroid Build Coastguard Worker load_src src.rgba = v1..4
86*c8dee2aaSAndroid Build Coastguard Worker load_dst dst.rgba = v3..6
87*c8dee2aaSAndroid Build Coastguard Worker )");
88*c8dee2aaSAndroid Build Coastguard Worker }
89*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderPushPopMaskRegisters,r)90*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderPushPopMaskRegisters, r) {
91*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
92*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
93*c8dee2aaSAndroid Build Coastguard Worker
94*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, !builder.executionMaskWritesAreEnabled());
95*c8dee2aaSAndroid Build Coastguard Worker builder.enableExecutionMaskWrites();
96*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, builder.executionMaskWritesAreEnabled());
97*c8dee2aaSAndroid Build Coastguard Worker
98*c8dee2aaSAndroid Build Coastguard Worker builder.push_condition_mask(); // push into 0
99*c8dee2aaSAndroid Build Coastguard Worker builder.push_loop_mask(); // push into 1
100*c8dee2aaSAndroid Build Coastguard Worker builder.push_return_mask(); // push into 2
101*c8dee2aaSAndroid Build Coastguard Worker builder.merge_condition_mask(); // set the condition-mask to 1 & 2
102*c8dee2aaSAndroid Build Coastguard Worker builder.merge_inv_condition_mask(); // set the condition-mask to 1 & ~2
103*c8dee2aaSAndroid Build Coastguard Worker builder.pop_condition_mask(); // pop from 2
104*c8dee2aaSAndroid Build Coastguard Worker builder.merge_loop_mask(); // mask off the loop-mask against 1
105*c8dee2aaSAndroid Build Coastguard Worker builder.push_condition_mask(); // push into 2
106*c8dee2aaSAndroid Build Coastguard Worker builder.pop_condition_mask(); // pop from 2
107*c8dee2aaSAndroid Build Coastguard Worker builder.pop_loop_mask(); // pop from 1
108*c8dee2aaSAndroid Build Coastguard Worker builder.pop_return_mask(); // pop from 0
109*c8dee2aaSAndroid Build Coastguard Worker builder.push_condition_mask(); // push into 0
110*c8dee2aaSAndroid Build Coastguard Worker builder.pop_and_reenable_loop_mask(); // pop from 0
111*c8dee2aaSAndroid Build Coastguard Worker
112*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, builder.executionMaskWritesAreEnabled());
113*c8dee2aaSAndroid Build Coastguard Worker builder.disableExecutionMaskWrites();
114*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, !builder.executionMaskWritesAreEnabled());
115*c8dee2aaSAndroid Build Coastguard Worker
116*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/0,
117*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
118*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
119*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
120*c8dee2aaSAndroid Build Coastguard Worker R"(store_condition_mask $0 = CondMask
121*c8dee2aaSAndroid Build Coastguard Worker store_loop_mask $1 = LoopMask
122*c8dee2aaSAndroid Build Coastguard Worker store_return_mask $2 = RetMask
123*c8dee2aaSAndroid Build Coastguard Worker merge_condition_mask CondMask = $1 & $2
124*c8dee2aaSAndroid Build Coastguard Worker merge_inv_condition_mask CondMask = $1 & ~$2
125*c8dee2aaSAndroid Build Coastguard Worker load_condition_mask CondMask = $2
126*c8dee2aaSAndroid Build Coastguard Worker merge_loop_mask LoopMask &= $1
127*c8dee2aaSAndroid Build Coastguard Worker store_condition_mask $2 = CondMask
128*c8dee2aaSAndroid Build Coastguard Worker load_condition_mask CondMask = $2
129*c8dee2aaSAndroid Build Coastguard Worker load_loop_mask LoopMask = $1
130*c8dee2aaSAndroid Build Coastguard Worker load_return_mask RetMask = $0
131*c8dee2aaSAndroid Build Coastguard Worker store_condition_mask $0 = CondMask
132*c8dee2aaSAndroid Build Coastguard Worker reenable_loop_mask LoopMask |= $0
133*c8dee2aaSAndroid Build Coastguard Worker )");
134*c8dee2aaSAndroid Build Coastguard Worker }
135*c8dee2aaSAndroid Build Coastguard Worker
136*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderCaseOp,r)137*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderCaseOp, r) {
138*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
139*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
140*c8dee2aaSAndroid Build Coastguard Worker
141*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_i(123); // push a test value
142*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_i(~0); // push an all-on default mask
143*c8dee2aaSAndroid Build Coastguard Worker builder.case_op(123); // do `case 123:`
144*c8dee2aaSAndroid Build Coastguard Worker builder.case_op(124); // do `case 124:`
145*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(2);
146*c8dee2aaSAndroid Build Coastguard Worker
147*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/0,
148*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
149*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
150*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
151*c8dee2aaSAndroid Build Coastguard Worker R"(copy_constant $0 = 0x0000007B (1.723597e-43)
152*c8dee2aaSAndroid Build Coastguard Worker copy_constant $1 = 0xFFFFFFFF
153*c8dee2aaSAndroid Build Coastguard Worker case_op if ($0 == 0x0000007B) { LoopMask = true; $1 = false; }
154*c8dee2aaSAndroid Build Coastguard Worker case_op if ($0 == 0x0000007C) { LoopMask = true; $1 = false; }
155*c8dee2aaSAndroid Build Coastguard Worker )");
156*c8dee2aaSAndroid Build Coastguard Worker }
157*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderPushPopSrcDst,r)158*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderPushPopSrcDst, r) {
159*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
160*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
161*c8dee2aaSAndroid Build Coastguard Worker
162*c8dee2aaSAndroid Build Coastguard Worker builder.push_src_rgba();
163*c8dee2aaSAndroid Build Coastguard Worker builder.push_dst_rgba();
164*c8dee2aaSAndroid Build Coastguard Worker builder.pop_src_rgba();
165*c8dee2aaSAndroid Build Coastguard Worker builder.exchange_src();
166*c8dee2aaSAndroid Build Coastguard Worker builder.exchange_src();
167*c8dee2aaSAndroid Build Coastguard Worker builder.exchange_src();
168*c8dee2aaSAndroid Build Coastguard Worker builder.pop_dst_rgba();
169*c8dee2aaSAndroid Build Coastguard Worker
170*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/0,
171*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
172*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
173*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
174*c8dee2aaSAndroid Build Coastguard Worker R"(store_src $0..3 = src.rgba
175*c8dee2aaSAndroid Build Coastguard Worker store_dst $4..7 = dst.rgba
176*c8dee2aaSAndroid Build Coastguard Worker load_src src.rgba = $4..7
177*c8dee2aaSAndroid Build Coastguard Worker exchange_src swap(src.rgba, $0..3)
178*c8dee2aaSAndroid Build Coastguard Worker load_dst dst.rgba = $0..3
179*c8dee2aaSAndroid Build Coastguard Worker )");
180*c8dee2aaSAndroid Build Coastguard Worker }
181*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderInvokeChild,r)182*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderInvokeChild, r) {
183*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
184*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
185*c8dee2aaSAndroid Build Coastguard Worker
186*c8dee2aaSAndroid Build Coastguard Worker builder.invoke_shader(1);
187*c8dee2aaSAndroid Build Coastguard Worker builder.invoke_color_filter(2);
188*c8dee2aaSAndroid Build Coastguard Worker builder.invoke_blender(3);
189*c8dee2aaSAndroid Build Coastguard Worker
190*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/0,
191*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
192*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
193*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
194*c8dee2aaSAndroid Build Coastguard Worker R"(invoke_shader invoke_shader 0x00000001
195*c8dee2aaSAndroid Build Coastguard Worker invoke_color_filter invoke_color_filter 0x00000002
196*c8dee2aaSAndroid Build Coastguard Worker invoke_blender invoke_blender 0x00000003
197*c8dee2aaSAndroid Build Coastguard Worker )");
198*c8dee2aaSAndroid Build Coastguard Worker }
199*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderPushPopTempImmediates,r)200*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderPushPopTempImmediates, r) {
201*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
202*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
203*c8dee2aaSAndroid Build Coastguard Worker builder.set_current_stack(1);
204*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_i(999); // push into 2
205*c8dee2aaSAndroid Build Coastguard Worker builder.set_current_stack(0);
206*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(13.5f); // push into 0
207*c8dee2aaSAndroid Build Coastguard Worker builder.push_clone_from_stack(one_slot_at(0), /*otherStackID=*/1, /*offsetFromStackTop=*/1);
208*c8dee2aaSAndroid Build Coastguard Worker // push into 1 from 2
209*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(1); // discard 2
210*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_u(357); // push into 2
211*c8dee2aaSAndroid Build Coastguard Worker builder.set_current_stack(1);
212*c8dee2aaSAndroid Build Coastguard Worker builder.push_clone_from_stack(one_slot_at(0), /*otherStackID=*/0, /*offsetFromStackTop=*/1);
213*c8dee2aaSAndroid Build Coastguard Worker // push into 3 from 0
214*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(2); // discard 2 and 3
215*c8dee2aaSAndroid Build Coastguard Worker builder.set_current_stack(0);
216*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(1.2f); // push into 2
217*c8dee2aaSAndroid Build Coastguard Worker builder.pad_stack(3); // pad slots 3,4,5
218*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(3.4f); // push into 6
219*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(7); // discard 0 through 6
220*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/1,
221*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
222*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
223*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
224*c8dee2aaSAndroid Build Coastguard Worker R"(copy_constant $2 = 0x000003E7 (1.399897e-42)
225*c8dee2aaSAndroid Build Coastguard Worker copy_constant $0 = 0x41580000 (13.5)
226*c8dee2aaSAndroid Build Coastguard Worker copy_constant $1 = 0x00000165 (5.002636e-43)
227*c8dee2aaSAndroid Build Coastguard Worker )");
228*c8dee2aaSAndroid Build Coastguard Worker }
229*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderPushPopIndirect,r)230*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderPushPopIndirect, r) {
231*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
232*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
233*c8dee2aaSAndroid Build Coastguard Worker builder.set_current_stack(1);
234*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_i(3);
235*c8dee2aaSAndroid Build Coastguard Worker builder.set_current_stack(0);
236*c8dee2aaSAndroid Build Coastguard Worker builder.push_slots_indirect(two_slots_at(0), /*dynamicStack=*/1, ten_slots_at(0));
237*c8dee2aaSAndroid Build Coastguard Worker builder.push_slots_indirect(four_slots_at(10), /*dynamicStack=*/1, ten_slots_at(10));
238*c8dee2aaSAndroid Build Coastguard Worker builder.push_uniform_indirect(one_slot_at(0), /*dynamicStack=*/1, five_slots_at(0));
239*c8dee2aaSAndroid Build Coastguard Worker builder.push_uniform_indirect(three_slots_at(5), /*dynamicStack=*/1, five_slots_at(5));
240*c8dee2aaSAndroid Build Coastguard Worker builder.swizzle_copy_stack_to_slots_indirect(three_slots_at(6), /*dynamicStackID=*/1,
241*c8dee2aaSAndroid Build Coastguard Worker ten_slots_at(0), {2, 1, 0},
242*c8dee2aaSAndroid Build Coastguard Worker /*offsetFromStackTop=*/3);
243*c8dee2aaSAndroid Build Coastguard Worker builder.copy_stack_to_slots_indirect(three_slots_at(4), /*dynamicStackID=*/1, ten_slots_at(0));
244*c8dee2aaSAndroid Build Coastguard Worker builder.pop_slots_indirect(five_slots_at(0), /*dynamicStackID=*/1, ten_slots_at(0));
245*c8dee2aaSAndroid Build Coastguard Worker builder.pop_slots_indirect(five_slots_at(10), /*dynamicStackID=*/1, ten_slots_at(10));
246*c8dee2aaSAndroid Build Coastguard Worker builder.set_current_stack(1);
247*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(1);
248*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/20,
249*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/10,
250*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
251*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
252*c8dee2aaSAndroid Build Coastguard Worker R"(copy_constant $10 = 0x00000003 (4.203895e-45)
253*c8dee2aaSAndroid Build Coastguard Worker copy_from_indirect_unmasked $0..1 = Indirect(v0..1 + $10)
254*c8dee2aaSAndroid Build Coastguard Worker copy_from_indirect_unmasked $2..5 = Indirect(v10..13 + $10)
255*c8dee2aaSAndroid Build Coastguard Worker copy_from_indirect_uniform_unm $6 = Indirect(u0 + $10)
256*c8dee2aaSAndroid Build Coastguard Worker copy_from_indirect_uniform_unm $7..9 = Indirect(u5..7 + $10)
257*c8dee2aaSAndroid Build Coastguard Worker swizzle_copy_to_indirect_maske Indirect(v6..8 + $10).zyx = Mask($7..9)
258*c8dee2aaSAndroid Build Coastguard Worker copy_to_indirect_masked Indirect(v4..6 + $10) = Mask($7..9)
259*c8dee2aaSAndroid Build Coastguard Worker copy_to_indirect_masked Indirect(v0..4 + $10) = Mask($5..9)
260*c8dee2aaSAndroid Build Coastguard Worker copy_to_indirect_masked Indirect(v10..14 + $10) = Mask($0..4)
261*c8dee2aaSAndroid Build Coastguard Worker )");
262*c8dee2aaSAndroid Build Coastguard Worker }
263*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderCopySlotsMasked,r)264*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderCopySlotsMasked, r) {
265*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
266*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
267*c8dee2aaSAndroid Build Coastguard Worker builder.copy_slots_masked(two_slots_at(0), two_slots_at(2));
268*c8dee2aaSAndroid Build Coastguard Worker builder.copy_slots_masked(four_slots_at(1), four_slots_at(5));
269*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/9,
270*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
271*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
272*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
273*c8dee2aaSAndroid Build Coastguard Worker R"(copy_2_slots_masked v0..1 = Mask(v2..3)
274*c8dee2aaSAndroid Build Coastguard Worker copy_4_slots_masked v1..4 = Mask(v5..8)
275*c8dee2aaSAndroid Build Coastguard Worker )");
276*c8dee2aaSAndroid Build Coastguard Worker }
277*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderCopySlotsUnmasked,r)278*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderCopySlotsUnmasked, r) {
279*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
280*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
281*c8dee2aaSAndroid Build Coastguard Worker builder.copy_slots_unmasked(three_slots_at(0), three_slots_at(2));
282*c8dee2aaSAndroid Build Coastguard Worker builder.copy_slots_unmasked(five_slots_at(1), five_slots_at(5));
283*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/10,
284*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
285*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
286*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
287*c8dee2aaSAndroid Build Coastguard Worker R"(copy_3_slots_unmasked v0..2 = v2..4
288*c8dee2aaSAndroid Build Coastguard Worker copy_4_slots_unmasked v1..4 = v5..8
289*c8dee2aaSAndroid Build Coastguard Worker copy_slot_unmasked v5 = v9
290*c8dee2aaSAndroid Build Coastguard Worker )");
291*c8dee2aaSAndroid Build Coastguard Worker }
292*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderPushPopSlots,r)293*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderPushPopSlots, r) {
294*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
295*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
296*c8dee2aaSAndroid Build Coastguard Worker builder.push_slots(four_slots_at(10)); // push from 10~13 into $0~$3
297*c8dee2aaSAndroid Build Coastguard Worker builder.copy_stack_to_slots(one_slot_at(5), 3); // copy from $1 into 5
298*c8dee2aaSAndroid Build Coastguard Worker builder.pop_slots_unmasked(two_slots_at(20)); // pop from $2~$3 into 20~21 (unmasked)
299*c8dee2aaSAndroid Build Coastguard Worker builder.enableExecutionMaskWrites();
300*c8dee2aaSAndroid Build Coastguard Worker builder.copy_stack_to_slots_unmasked(one_slot_at(4), 2); // copy from $0 into 4
301*c8dee2aaSAndroid Build Coastguard Worker builder.push_slots(three_slots_at(30)); // push from 30~32 into $2~$4
302*c8dee2aaSAndroid Build Coastguard Worker builder.pop_slots(five_slots_at(0)); // pop from $0~$4 into 0~4 (masked)
303*c8dee2aaSAndroid Build Coastguard Worker builder.disableExecutionMaskWrites();
304*c8dee2aaSAndroid Build Coastguard Worker
305*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/50,
306*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
307*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
308*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
309*c8dee2aaSAndroid Build Coastguard Worker R"(copy_4_slots_unmasked $0..3 = v10..13
310*c8dee2aaSAndroid Build Coastguard Worker copy_slot_unmasked v5 = $1
311*c8dee2aaSAndroid Build Coastguard Worker copy_2_slots_unmasked v20..21 = $2..3
312*c8dee2aaSAndroid Build Coastguard Worker copy_slot_unmasked v4 = $0
313*c8dee2aaSAndroid Build Coastguard Worker copy_3_slots_unmasked $2..4 = v30..32
314*c8dee2aaSAndroid Build Coastguard Worker copy_4_slots_masked v0..3 = Mask($0..3)
315*c8dee2aaSAndroid Build Coastguard Worker copy_slot_masked v4 = Mask($4)
316*c8dee2aaSAndroid Build Coastguard Worker )");
317*c8dee2aaSAndroid Build Coastguard Worker }
318*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderDuplicateSelectAndSwizzleSlots,r)319*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderDuplicateSelectAndSwizzleSlots, r) {
320*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
321*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
322*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(1.0f); // push into 0
323*c8dee2aaSAndroid Build Coastguard Worker builder.push_duplicates(1); // duplicate into 1
324*c8dee2aaSAndroid Build Coastguard Worker builder.push_duplicates(2); // duplicate into 2~3
325*c8dee2aaSAndroid Build Coastguard Worker builder.push_duplicates(3); // duplicate into 4~6
326*c8dee2aaSAndroid Build Coastguard Worker builder.push_duplicates(5); // duplicate into 7~11
327*c8dee2aaSAndroid Build Coastguard Worker builder.select(4); // select from 4~7 and 8~11 into 4~7
328*c8dee2aaSAndroid Build Coastguard Worker builder.select(3); // select from 2~4 and 5~7 into 2~4
329*c8dee2aaSAndroid Build Coastguard Worker builder.select(1); // select from 3 and 4 into 3
330*c8dee2aaSAndroid Build Coastguard Worker builder.swizzle_copy_stack_to_slots(four_slots_at(1), {3, 2, 1, 0}, 4);
331*c8dee2aaSAndroid Build Coastguard Worker builder.swizzle_copy_stack_to_slots(four_slots_at(0), {0, 1, 3}, 3);
332*c8dee2aaSAndroid Build Coastguard Worker builder.swizzle(4, {3, 2, 1, 0}); // reverse the order of 0~3 (value.wzyx)
333*c8dee2aaSAndroid Build Coastguard Worker builder.swizzle(4, {1, 2}); // eliminate elements 0 and 3 (value.yz)
334*c8dee2aaSAndroid Build Coastguard Worker builder.swizzle(2, {0}); // eliminate element 1 (value.x)
335*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(1); // balance stack
336*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/6,
337*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
338*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
339*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
340*c8dee2aaSAndroid Build Coastguard Worker R"(splat_4_constants $0..3 = 0x3F800000 (1.0)
341*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $4..7 = 0x3F800000 (1.0)
342*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $8..11 = 0x3F800000 (1.0)
343*c8dee2aaSAndroid Build Coastguard Worker copy_4_slots_masked $4..7 = Mask($8..11)
344*c8dee2aaSAndroid Build Coastguard Worker copy_3_slots_masked $2..4 = Mask($5..7)
345*c8dee2aaSAndroid Build Coastguard Worker copy_slot_masked $3 = Mask($4)
346*c8dee2aaSAndroid Build Coastguard Worker swizzle_copy_4_slots_masked (v1..4).wzyx = Mask($0..3)
347*c8dee2aaSAndroid Build Coastguard Worker swizzle_copy_3_slots_masked (v0..3).xyw = Mask($1..3)
348*c8dee2aaSAndroid Build Coastguard Worker swizzle_4 $0..3 = ($0..3).wzyx
349*c8dee2aaSAndroid Build Coastguard Worker swizzle_2 $0..1 = ($0..2).yz
350*c8dee2aaSAndroid Build Coastguard Worker )");
351*c8dee2aaSAndroid Build Coastguard Worker }
352*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderTransposeMatrix,r)353*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderTransposeMatrix, r) {
354*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
355*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
356*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(1.0f); // push into 0
357*c8dee2aaSAndroid Build Coastguard Worker builder.push_duplicates(15); // duplicate into 1~15
358*c8dee2aaSAndroid Build Coastguard Worker builder.transpose(2, 2); // transpose a 2x2 matrix
359*c8dee2aaSAndroid Build Coastguard Worker builder.transpose(3, 3); // transpose a 3x3 matrix
360*c8dee2aaSAndroid Build Coastguard Worker builder.transpose(4, 4); // transpose a 4x4 matrix
361*c8dee2aaSAndroid Build Coastguard Worker builder.transpose(2, 4); // transpose a 2x4 matrix
362*c8dee2aaSAndroid Build Coastguard Worker builder.transpose(4, 3); // transpose a 4x3 matrix
363*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(16); // balance stack
364*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/0,
365*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
366*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
367*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
368*c8dee2aaSAndroid Build Coastguard Worker R"(splat_4_constants $0..3 = 0x3F800000 (1.0)
369*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $4..7 = 0x3F800000 (1.0)
370*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $8..11 = 0x3F800000 (1.0)
371*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $12..15 = 0x3F800000 (1.0)
372*c8dee2aaSAndroid Build Coastguard Worker swizzle_3 $13..15 = ($13..15).yxz
373*c8dee2aaSAndroid Build Coastguard Worker shuffle $8..15 = ($8..15)[2 5 0 3 6 1 4 7]
374*c8dee2aaSAndroid Build Coastguard Worker shuffle $1..15 = ($1..15)[3 7 11 0 4 8 12 1 5 9 13 2 6 10 14]
375*c8dee2aaSAndroid Build Coastguard Worker shuffle $9..15 = ($9..15)[3 0 4 1 5 2 6]
376*c8dee2aaSAndroid Build Coastguard Worker shuffle $5..15 = ($5..15)[2 5 8 0 3 6 9 1 4 7 10]
377*c8dee2aaSAndroid Build Coastguard Worker )");
378*c8dee2aaSAndroid Build Coastguard Worker }
379*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderDiagonalMatrix,r)380*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderDiagonalMatrix, r) {
381*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
382*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
383*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(0.0f); // push into 0
384*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(1.0f); // push into 1
385*c8dee2aaSAndroid Build Coastguard Worker builder.diagonal_matrix(2, 2); // generate a 2x2 diagonal matrix
386*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(4); // balance stack
387*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(0.0f); // push into 0
388*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(2.0f); // push into 1
389*c8dee2aaSAndroid Build Coastguard Worker builder.diagonal_matrix(4, 4); // generate a 4x4 diagonal matrix
390*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(16); // balance stack
391*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(0.0f); // push into 0
392*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(3.0f); // push into 1
393*c8dee2aaSAndroid Build Coastguard Worker builder.diagonal_matrix(2, 3); // generate a 2x3 diagonal matrix
394*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(6); // balance stack
395*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/0,
396*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
397*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
398*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
399*c8dee2aaSAndroid Build Coastguard Worker R"(copy_constant $0 = 0
400*c8dee2aaSAndroid Build Coastguard Worker copy_constant $1 = 0x3F800000 (1.0)
401*c8dee2aaSAndroid Build Coastguard Worker swizzle_4 $0..3 = ($0..3).yxxy
402*c8dee2aaSAndroid Build Coastguard Worker copy_constant $0 = 0
403*c8dee2aaSAndroid Build Coastguard Worker copy_constant $1 = 0x40000000 (2.0)
404*c8dee2aaSAndroid Build Coastguard Worker shuffle $0..15 = ($0..15)[1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1]
405*c8dee2aaSAndroid Build Coastguard Worker copy_constant $0 = 0
406*c8dee2aaSAndroid Build Coastguard Worker copy_constant $1 = 0x40400000 (3.0)
407*c8dee2aaSAndroid Build Coastguard Worker shuffle $0..5 = ($0..5)[1 0 0 0 1 0]
408*c8dee2aaSAndroid Build Coastguard Worker )");
409*c8dee2aaSAndroid Build Coastguard Worker }
410*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderMatrixResize,r)411*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderMatrixResize, r) {
412*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
413*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
414*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(1.0f); // synthesize a 2x2 matrix
415*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(2.0f);
416*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(3.0f);
417*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(4.0f);
418*c8dee2aaSAndroid Build Coastguard Worker builder.matrix_resize(2, 2, 4, 4); // resize 2x2 matrix into 4x4
419*c8dee2aaSAndroid Build Coastguard Worker builder.matrix_resize(4, 4, 2, 2); // resize 4x4 matrix back into 2x2
420*c8dee2aaSAndroid Build Coastguard Worker builder.matrix_resize(2, 2, 2, 4); // resize 2x2 matrix into 2x4
421*c8dee2aaSAndroid Build Coastguard Worker builder.matrix_resize(2, 4, 4, 2); // resize 2x4 matrix into 4x2
422*c8dee2aaSAndroid Build Coastguard Worker builder.matrix_resize(4, 2, 3, 3); // resize 4x2 matrix into 3x3
423*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(9); // balance stack
424*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/0,
425*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
426*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
427*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
428*c8dee2aaSAndroid Build Coastguard Worker R"(copy_constant $0 = 0x3F800000 (1.0)
429*c8dee2aaSAndroid Build Coastguard Worker copy_constant $1 = 0x40000000 (2.0)
430*c8dee2aaSAndroid Build Coastguard Worker copy_constant $2 = 0x40400000 (3.0)
431*c8dee2aaSAndroid Build Coastguard Worker copy_constant $3 = 0x40800000 (4.0)
432*c8dee2aaSAndroid Build Coastguard Worker copy_constant $4 = 0
433*c8dee2aaSAndroid Build Coastguard Worker copy_constant $5 = 0x3F800000 (1.0)
434*c8dee2aaSAndroid Build Coastguard Worker shuffle $2..15 = ($2..15)[2 2 0 1 2 2 2 2 3 2 2 2 2 3]
435*c8dee2aaSAndroid Build Coastguard Worker shuffle $2..3 = ($2..3)[2 3]
436*c8dee2aaSAndroid Build Coastguard Worker copy_constant $4 = 0
437*c8dee2aaSAndroid Build Coastguard Worker shuffle $2..7 = ($2..7)[2 2 0 1 2 2]
438*c8dee2aaSAndroid Build Coastguard Worker copy_constant $8 = 0
439*c8dee2aaSAndroid Build Coastguard Worker shuffle $2..7 = ($2..7)[2 3 6 6 6 6]
440*c8dee2aaSAndroid Build Coastguard Worker copy_constant $8 = 0
441*c8dee2aaSAndroid Build Coastguard Worker copy_constant $9 = 0x3F800000 (1.0)
442*c8dee2aaSAndroid Build Coastguard Worker shuffle $2..8 = ($2..8)[6 0 1 6 2 3 7]
443*c8dee2aaSAndroid Build Coastguard Worker )");
444*c8dee2aaSAndroid Build Coastguard Worker }
445*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderBranches,r)446*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderBranches, r) {
447*c8dee2aaSAndroid Build Coastguard Worker #if SK_HAS_MUSTTAIL
448*c8dee2aaSAndroid Build Coastguard Worker // We have guaranteed tail-calling, and don't need to rewind the stack.
449*c8dee2aaSAndroid Build Coastguard Worker static constexpr char kExpectationWithKnownExecutionMask[] =
450*c8dee2aaSAndroid Build Coastguard Worker R"(jump jump +9 (label 3 at #10)
451*c8dee2aaSAndroid Build Coastguard Worker label label 0
452*c8dee2aaSAndroid Build Coastguard Worker copy_constant v0 = 0
453*c8dee2aaSAndroid Build Coastguard Worker label label 0x00000001
454*c8dee2aaSAndroid Build Coastguard Worker copy_constant v1 = 0
455*c8dee2aaSAndroid Build Coastguard Worker jump jump -4 (label 0 at #2)
456*c8dee2aaSAndroid Build Coastguard Worker label label 0x00000002
457*c8dee2aaSAndroid Build Coastguard Worker copy_constant v2 = 0
458*c8dee2aaSAndroid Build Coastguard Worker jump jump -7 (label 0 at #2)
459*c8dee2aaSAndroid Build Coastguard Worker label label 0x00000003
460*c8dee2aaSAndroid Build Coastguard Worker branch_if_no_active_lanes_eq branch -4 (label 2 at #7) if no lanes of v2 == 0
461*c8dee2aaSAndroid Build Coastguard Worker branch_if_no_active_lanes_eq branch -10 (label 0 at #2) if no lanes of v2 == 0x00000001 (1.401298e-45)
462*c8dee2aaSAndroid Build Coastguard Worker )";
463*c8dee2aaSAndroid Build Coastguard Worker static constexpr char kExpectationWithExecutionMaskWrites[] =
464*c8dee2aaSAndroid Build Coastguard Worker R"(jump jump +10 (label 3 at #11)
465*c8dee2aaSAndroid Build Coastguard Worker label label 0
466*c8dee2aaSAndroid Build Coastguard Worker copy_constant v0 = 0
467*c8dee2aaSAndroid Build Coastguard Worker label label 0x00000001
468*c8dee2aaSAndroid Build Coastguard Worker copy_constant v1 = 0
469*c8dee2aaSAndroid Build Coastguard Worker branch_if_no_lanes_active branch_if_no_lanes_active -2 (label 1 at #4)
470*c8dee2aaSAndroid Build Coastguard Worker branch_if_all_lanes_active branch_if_all_lanes_active -5 (label 0 at #2)
471*c8dee2aaSAndroid Build Coastguard Worker label label 0x00000002
472*c8dee2aaSAndroid Build Coastguard Worker copy_constant v2 = 0
473*c8dee2aaSAndroid Build Coastguard Worker branch_if_any_lanes_active branch_if_any_lanes_active -8 (label 0 at #2)
474*c8dee2aaSAndroid Build Coastguard Worker label label 0x00000003
475*c8dee2aaSAndroid Build Coastguard Worker branch_if_no_active_lanes_eq branch -4 (label 2 at #8) if no lanes of v2 == 0
476*c8dee2aaSAndroid Build Coastguard Worker branch_if_no_active_lanes_eq branch -11 (label 0 at #2) if no lanes of v2 == 0x00000001 (1.401298e-45)
477*c8dee2aaSAndroid Build Coastguard Worker )";
478*c8dee2aaSAndroid Build Coastguard Worker #else
479*c8dee2aaSAndroid Build Coastguard Worker // We don't have guaranteed tail-calling, so we rewind the stack immediately before any backward
480*c8dee2aaSAndroid Build Coastguard Worker // branches.
481*c8dee2aaSAndroid Build Coastguard Worker static constexpr char kExpectationWithKnownExecutionMask[] =
482*c8dee2aaSAndroid Build Coastguard Worker R"(jump jump +11 (label 3 at #12)
483*c8dee2aaSAndroid Build Coastguard Worker label label 0
484*c8dee2aaSAndroid Build Coastguard Worker copy_constant v0 = 0
485*c8dee2aaSAndroid Build Coastguard Worker label label 0x00000001
486*c8dee2aaSAndroid Build Coastguard Worker copy_constant v1 = 0
487*c8dee2aaSAndroid Build Coastguard Worker stack_rewind
488*c8dee2aaSAndroid Build Coastguard Worker jump jump -5 (label 0 at #2)
489*c8dee2aaSAndroid Build Coastguard Worker label label 0x00000002
490*c8dee2aaSAndroid Build Coastguard Worker copy_constant v2 = 0
491*c8dee2aaSAndroid Build Coastguard Worker stack_rewind
492*c8dee2aaSAndroid Build Coastguard Worker jump jump -9 (label 0 at #2)
493*c8dee2aaSAndroid Build Coastguard Worker label label 0x00000003
494*c8dee2aaSAndroid Build Coastguard Worker stack_rewind
495*c8dee2aaSAndroid Build Coastguard Worker branch_if_no_active_lanes_eq branch -6 (label 2 at #8) if no lanes of v2 == 0
496*c8dee2aaSAndroid Build Coastguard Worker stack_rewind
497*c8dee2aaSAndroid Build Coastguard Worker branch_if_no_active_lanes_eq branch -14 (label 0 at #2) if no lanes of v2 == 0x00000001 (1.401298e-45)
498*c8dee2aaSAndroid Build Coastguard Worker )";
499*c8dee2aaSAndroid Build Coastguard Worker static constexpr char kExpectationWithExecutionMaskWrites[] =
500*c8dee2aaSAndroid Build Coastguard Worker R"(jump jump +13 (label 3 at #14)
501*c8dee2aaSAndroid Build Coastguard Worker label label 0
502*c8dee2aaSAndroid Build Coastguard Worker copy_constant v0 = 0
503*c8dee2aaSAndroid Build Coastguard Worker label label 0x00000001
504*c8dee2aaSAndroid Build Coastguard Worker copy_constant v1 = 0
505*c8dee2aaSAndroid Build Coastguard Worker stack_rewind
506*c8dee2aaSAndroid Build Coastguard Worker branch_if_no_lanes_active branch_if_no_lanes_active -3 (label 1 at #4)
507*c8dee2aaSAndroid Build Coastguard Worker stack_rewind
508*c8dee2aaSAndroid Build Coastguard Worker branch_if_all_lanes_active branch_if_all_lanes_active -7 (label 0 at #2)
509*c8dee2aaSAndroid Build Coastguard Worker label label 0x00000002
510*c8dee2aaSAndroid Build Coastguard Worker copy_constant v2 = 0
511*c8dee2aaSAndroid Build Coastguard Worker stack_rewind
512*c8dee2aaSAndroid Build Coastguard Worker branch_if_any_lanes_active branch_if_any_lanes_active -11 (label 0 at #2)
513*c8dee2aaSAndroid Build Coastguard Worker label label 0x00000003
514*c8dee2aaSAndroid Build Coastguard Worker stack_rewind
515*c8dee2aaSAndroid Build Coastguard Worker branch_if_no_active_lanes_eq branch -6 (label 2 at #10) if no lanes of v2 == 0
516*c8dee2aaSAndroid Build Coastguard Worker stack_rewind
517*c8dee2aaSAndroid Build Coastguard Worker branch_if_no_active_lanes_eq branch -16 (label 0 at #2) if no lanes of v2 == 0x00000001 (1.401298e-45)
518*c8dee2aaSAndroid Build Coastguard Worker )";
519*c8dee2aaSAndroid Build Coastguard Worker #endif
520*c8dee2aaSAndroid Build Coastguard Worker
521*c8dee2aaSAndroid Build Coastguard Worker for (bool enableExecutionMaskWrites : {false, true}) {
522*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
523*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
524*c8dee2aaSAndroid Build Coastguard Worker int label1 = builder.nextLabelID();
525*c8dee2aaSAndroid Build Coastguard Worker int label2 = builder.nextLabelID();
526*c8dee2aaSAndroid Build Coastguard Worker int label3 = builder.nextLabelID();
527*c8dee2aaSAndroid Build Coastguard Worker int label4 = builder.nextLabelID();
528*c8dee2aaSAndroid Build Coastguard Worker
529*c8dee2aaSAndroid Build Coastguard Worker if (enableExecutionMaskWrites) {
530*c8dee2aaSAndroid Build Coastguard Worker builder.enableExecutionMaskWrites();
531*c8dee2aaSAndroid Build Coastguard Worker }
532*c8dee2aaSAndroid Build Coastguard Worker
533*c8dee2aaSAndroid Build Coastguard Worker builder.jump(label4);
534*c8dee2aaSAndroid Build Coastguard Worker builder.label(label1);
535*c8dee2aaSAndroid Build Coastguard Worker builder.zero_slots_unmasked(one_slot_at(0));
536*c8dee2aaSAndroid Build Coastguard Worker builder.label(label2);
537*c8dee2aaSAndroid Build Coastguard Worker builder.zero_slots_unmasked(one_slot_at(1));
538*c8dee2aaSAndroid Build Coastguard Worker builder.branch_if_no_lanes_active(label2);
539*c8dee2aaSAndroid Build Coastguard Worker builder.branch_if_no_lanes_active(label3);
540*c8dee2aaSAndroid Build Coastguard Worker builder.branch_if_all_lanes_active(label1);
541*c8dee2aaSAndroid Build Coastguard Worker builder.label(label3);
542*c8dee2aaSAndroid Build Coastguard Worker builder.zero_slots_unmasked(one_slot_at(2));
543*c8dee2aaSAndroid Build Coastguard Worker builder.branch_if_any_lanes_active(label1);
544*c8dee2aaSAndroid Build Coastguard Worker builder.branch_if_any_lanes_active(label1);
545*c8dee2aaSAndroid Build Coastguard Worker builder.label(label4);
546*c8dee2aaSAndroid Build Coastguard Worker builder.branch_if_no_active_lanes_on_stack_top_equal(0, label3);
547*c8dee2aaSAndroid Build Coastguard Worker builder.branch_if_no_active_lanes_on_stack_top_equal(0, label2);
548*c8dee2aaSAndroid Build Coastguard Worker builder.branch_if_no_active_lanes_on_stack_top_equal(1, label1);
549*c8dee2aaSAndroid Build Coastguard Worker builder.branch_if_no_active_lanes_on_stack_top_equal(1, label4);
550*c8dee2aaSAndroid Build Coastguard Worker
551*c8dee2aaSAndroid Build Coastguard Worker if (enableExecutionMaskWrites) {
552*c8dee2aaSAndroid Build Coastguard Worker builder.disableExecutionMaskWrites();
553*c8dee2aaSAndroid Build Coastguard Worker }
554*c8dee2aaSAndroid Build Coastguard Worker
555*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/3,
556*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
557*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
558*c8dee2aaSAndroid Build Coastguard Worker
559*c8dee2aaSAndroid Build Coastguard Worker check(r, *program, enableExecutionMaskWrites ? kExpectationWithExecutionMaskWrites
560*c8dee2aaSAndroid Build Coastguard Worker : kExpectationWithKnownExecutionMask);
561*c8dee2aaSAndroid Build Coastguard Worker }
562*c8dee2aaSAndroid Build Coastguard Worker }
563*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderBackwardsBranchOverInvocationShouldRewind,r)564*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderBackwardsBranchOverInvocationShouldRewind, r) {
565*c8dee2aaSAndroid Build Coastguard Worker // Branching backward over a call to invoke_shader should always emit a stack_rewind op.
566*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
567*c8dee2aaSAndroid Build Coastguard Worker int label1 = builder.nextLabelID();
568*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(10.0f);
569*c8dee2aaSAndroid Build Coastguard Worker builder.label(label1);
570*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(20.0f);
571*c8dee2aaSAndroid Build Coastguard Worker builder.invoke_shader(9);
572*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(30.0f);
573*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(3);
574*c8dee2aaSAndroid Build Coastguard Worker builder.branch_if_any_lanes_active(label1);
575*c8dee2aaSAndroid Build Coastguard Worker
576*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/3,
577*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
578*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
579*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
580*c8dee2aaSAndroid Build Coastguard Worker R"(copy_constant $0 = 0x41200000 (10.0)
581*c8dee2aaSAndroid Build Coastguard Worker label label 0
582*c8dee2aaSAndroid Build Coastguard Worker copy_constant $1 = 0x41A00000 (20.0)
583*c8dee2aaSAndroid Build Coastguard Worker invoke_shader invoke_shader 0x00000009
584*c8dee2aaSAndroid Build Coastguard Worker stack_rewind
585*c8dee2aaSAndroid Build Coastguard Worker jump jump -4 (label 0 at #2)
586*c8dee2aaSAndroid Build Coastguard Worker )");
587*c8dee2aaSAndroid Build Coastguard Worker }
588*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderBackwardsBranchWithoutInvocationMightNotRewind,r)589*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderBackwardsBranchWithoutInvocationMightNotRewind, r) {
590*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
591*c8dee2aaSAndroid Build Coastguard Worker int label1 = builder.nextLabelID();
592*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(10.0f);
593*c8dee2aaSAndroid Build Coastguard Worker builder.invoke_shader(9);
594*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(20.0f);
595*c8dee2aaSAndroid Build Coastguard Worker builder.label(label1);
596*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(30.0f);
597*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(3);
598*c8dee2aaSAndroid Build Coastguard Worker builder.branch_if_any_lanes_active(label1);
599*c8dee2aaSAndroid Build Coastguard Worker
600*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/3,
601*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
602*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
603*c8dee2aaSAndroid Build Coastguard Worker #if SK_HAS_MUSTTAIL
604*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
605*c8dee2aaSAndroid Build Coastguard Worker R"(copy_constant $0 = 0x41200000 (10.0)
606*c8dee2aaSAndroid Build Coastguard Worker invoke_shader invoke_shader 0x00000009
607*c8dee2aaSAndroid Build Coastguard Worker copy_constant $1 = 0x41A00000 (20.0)
608*c8dee2aaSAndroid Build Coastguard Worker label label 0
609*c8dee2aaSAndroid Build Coastguard Worker jump jump -1 (label 0 at #4)
610*c8dee2aaSAndroid Build Coastguard Worker )");
611*c8dee2aaSAndroid Build Coastguard Worker #else
612*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
613*c8dee2aaSAndroid Build Coastguard Worker R"(copy_constant $0 = 0x41200000 (10.0)
614*c8dee2aaSAndroid Build Coastguard Worker invoke_shader invoke_shader 0x00000009
615*c8dee2aaSAndroid Build Coastguard Worker copy_constant $1 = 0x41A00000 (20.0)
616*c8dee2aaSAndroid Build Coastguard Worker label label 0
617*c8dee2aaSAndroid Build Coastguard Worker stack_rewind
618*c8dee2aaSAndroid Build Coastguard Worker jump jump -2 (label 0 at #4)
619*c8dee2aaSAndroid Build Coastguard Worker )");
620*c8dee2aaSAndroid Build Coastguard Worker #endif
621*c8dee2aaSAndroid Build Coastguard Worker }
622*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderBinaryFloatOps,r)623*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderBinaryFloatOps, r) {
624*c8dee2aaSAndroid Build Coastguard Worker using BuilderOp = SkSL::RP::BuilderOp;
625*c8dee2aaSAndroid Build Coastguard Worker
626*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
627*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(10.0f);
628*c8dee2aaSAndroid Build Coastguard Worker builder.push_duplicates(30);
629*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::add_n_floats, 1);
630*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::sub_n_floats, 2);
631*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::mul_n_floats, 3);
632*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::div_n_floats, 4);
633*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::max_n_floats, 3);
634*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::min_n_floats, 2);
635*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::cmplt_n_floats, 5);
636*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::cmple_n_floats, 4);
637*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::cmpeq_n_floats, 3);
638*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::cmpne_n_floats, 2);
639*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(2);
640*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/0,
641*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
642*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
643*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
644*c8dee2aaSAndroid Build Coastguard Worker R"(splat_4_constants $0..3 = 0x41200000 (10.0)
645*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $4..7 = 0x41200000 (10.0)
646*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $8..11 = 0x41200000 (10.0)
647*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $12..15 = 0x41200000 (10.0)
648*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $16..19 = 0x41200000 (10.0)
649*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $20..23 = 0x41200000 (10.0)
650*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $24..27 = 0x41200000 (10.0)
651*c8dee2aaSAndroid Build Coastguard Worker splat_2_constants $28..29 = 0x41200000 (10.0)
652*c8dee2aaSAndroid Build Coastguard Worker add_imm_float $29 += 0x41200000 (10.0)
653*c8dee2aaSAndroid Build Coastguard Worker sub_2_floats $26..27 -= $28..29
654*c8dee2aaSAndroid Build Coastguard Worker mul_3_floats $22..24 *= $25..27
655*c8dee2aaSAndroid Build Coastguard Worker div_4_floats $17..20 /= $21..24
656*c8dee2aaSAndroid Build Coastguard Worker max_3_floats $15..17 = max($15..17, $18..20)
657*c8dee2aaSAndroid Build Coastguard Worker min_2_floats $14..15 = min($14..15, $16..17)
658*c8dee2aaSAndroid Build Coastguard Worker cmplt_n_floats $6..10 = lessThan($6..10, $11..15)
659*c8dee2aaSAndroid Build Coastguard Worker cmple_4_floats $3..6 = lessThanEqual($3..6, $7..10)
660*c8dee2aaSAndroid Build Coastguard Worker cmpeq_3_floats $1..3 = equal($1..3, $4..6)
661*c8dee2aaSAndroid Build Coastguard Worker cmpne_2_floats $0..1 = notEqual($0..1, $2..3)
662*c8dee2aaSAndroid Build Coastguard Worker )");
663*c8dee2aaSAndroid Build Coastguard Worker }
664*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderBinaryIntOps,r)665*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderBinaryIntOps, r) {
666*c8dee2aaSAndroid Build Coastguard Worker using BuilderOp = SkSL::RP::BuilderOp;
667*c8dee2aaSAndroid Build Coastguard Worker
668*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
669*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_i(123);
670*c8dee2aaSAndroid Build Coastguard Worker builder.push_duplicates(40);
671*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::bitwise_and_n_ints, 1);
672*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::bitwise_xor_n_ints, 2);
673*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::bitwise_or_n_ints, 3);
674*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::add_n_ints, 2);
675*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::sub_n_ints, 3);
676*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::mul_n_ints, 4);
677*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::div_n_ints, 5);
678*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::max_n_ints, 4);
679*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::min_n_ints, 3);
680*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::cmplt_n_ints, 1);
681*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::cmple_n_ints, 2);
682*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::cmpeq_n_ints, 3);
683*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::cmpne_n_ints, 4);
684*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(4);
685*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/0,
686*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
687*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
688*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
689*c8dee2aaSAndroid Build Coastguard Worker R"(splat_4_constants $0..3 = 0x0000007B (1.723597e-43)
690*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $4..7 = 0x0000007B (1.723597e-43)
691*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $8..11 = 0x0000007B (1.723597e-43)
692*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $12..15 = 0x0000007B (1.723597e-43)
693*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $16..19 = 0x0000007B (1.723597e-43)
694*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $20..23 = 0x0000007B (1.723597e-43)
695*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $24..27 = 0x0000007B (1.723597e-43)
696*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $28..31 = 0x0000007B (1.723597e-43)
697*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $32..35 = 0x0000007B (1.723597e-43)
698*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $36..39 = 0x0000007B (1.723597e-43)
699*c8dee2aaSAndroid Build Coastguard Worker bitwise_and_imm_int $39 &= 0x0000007B
700*c8dee2aaSAndroid Build Coastguard Worker bitwise_xor_2_ints $36..37 ^= $38..39
701*c8dee2aaSAndroid Build Coastguard Worker bitwise_or_3_ints $32..34 |= $35..37
702*c8dee2aaSAndroid Build Coastguard Worker add_2_ints $31..32 += $33..34
703*c8dee2aaSAndroid Build Coastguard Worker sub_3_ints $27..29 -= $30..32
704*c8dee2aaSAndroid Build Coastguard Worker mul_4_ints $22..25 *= $26..29
705*c8dee2aaSAndroid Build Coastguard Worker div_n_ints $16..20 /= $21..25
706*c8dee2aaSAndroid Build Coastguard Worker max_4_ints $13..16 = max($13..16, $17..20)
707*c8dee2aaSAndroid Build Coastguard Worker min_3_ints $11..13 = min($11..13, $14..16)
708*c8dee2aaSAndroid Build Coastguard Worker cmplt_int $12 = lessThan($12, $13)
709*c8dee2aaSAndroid Build Coastguard Worker cmple_2_ints $9..10 = lessThanEqual($9..10, $11..12)
710*c8dee2aaSAndroid Build Coastguard Worker cmpeq_3_ints $5..7 = equal($5..7, $8..10)
711*c8dee2aaSAndroid Build Coastguard Worker cmpne_4_ints $0..3 = notEqual($0..3, $4..7)
712*c8dee2aaSAndroid Build Coastguard Worker )");
713*c8dee2aaSAndroid Build Coastguard Worker }
714*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderBinaryUIntOps,r)715*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderBinaryUIntOps, r) {
716*c8dee2aaSAndroid Build Coastguard Worker using BuilderOp = SkSL::RP::BuilderOp;
717*c8dee2aaSAndroid Build Coastguard Worker
718*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
719*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_u(456);
720*c8dee2aaSAndroid Build Coastguard Worker builder.push_duplicates(21);
721*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::div_n_uints, 6);
722*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::cmplt_n_uints, 5);
723*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::cmple_n_uints, 4);
724*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::max_n_uints, 3);
725*c8dee2aaSAndroid Build Coastguard Worker builder.binary_op(BuilderOp::min_n_uints, 2);
726*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(2);
727*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/0,
728*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
729*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
730*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
731*c8dee2aaSAndroid Build Coastguard Worker R"(splat_4_constants $0..3 = 0x000001C8 (6.389921e-43)
732*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $4..7 = 0x000001C8 (6.389921e-43)
733*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $8..11 = 0x000001C8 (6.389921e-43)
734*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $12..15 = 0x000001C8 (6.389921e-43)
735*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $16..19 = 0x000001C8 (6.389921e-43)
736*c8dee2aaSAndroid Build Coastguard Worker splat_2_constants $20..21 = 0x000001C8 (6.389921e-43)
737*c8dee2aaSAndroid Build Coastguard Worker div_n_uints $10..15 /= $16..21
738*c8dee2aaSAndroid Build Coastguard Worker cmplt_n_uints $6..10 = lessThan($6..10, $11..15)
739*c8dee2aaSAndroid Build Coastguard Worker cmple_4_uints $3..6 = lessThanEqual($3..6, $7..10)
740*c8dee2aaSAndroid Build Coastguard Worker max_3_uints $1..3 = max($1..3, $4..6)
741*c8dee2aaSAndroid Build Coastguard Worker min_2_uints $0..1 = min($0..1, $2..3)
742*c8dee2aaSAndroid Build Coastguard Worker )");
743*c8dee2aaSAndroid Build Coastguard Worker }
744*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderUnaryOps,r)745*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderUnaryOps, r) {
746*c8dee2aaSAndroid Build Coastguard Worker using BuilderOp = SkSL::RP::BuilderOp;
747*c8dee2aaSAndroid Build Coastguard Worker
748*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
749*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_i(456);
750*c8dee2aaSAndroid Build Coastguard Worker builder.push_duplicates(4);
751*c8dee2aaSAndroid Build Coastguard Worker builder.unary_op(BuilderOp::cast_to_float_from_int, 1);
752*c8dee2aaSAndroid Build Coastguard Worker builder.unary_op(BuilderOp::cast_to_float_from_uint, 2);
753*c8dee2aaSAndroid Build Coastguard Worker builder.unary_op(BuilderOp::cast_to_int_from_float, 3);
754*c8dee2aaSAndroid Build Coastguard Worker builder.unary_op(BuilderOp::cast_to_uint_from_float, 4);
755*c8dee2aaSAndroid Build Coastguard Worker builder.unary_op(BuilderOp::cos_float, 4);
756*c8dee2aaSAndroid Build Coastguard Worker builder.unary_op(BuilderOp::tan_float, 3);
757*c8dee2aaSAndroid Build Coastguard Worker builder.unary_op(BuilderOp::sin_float, 2);
758*c8dee2aaSAndroid Build Coastguard Worker builder.unary_op(BuilderOp::sqrt_float, 1);
759*c8dee2aaSAndroid Build Coastguard Worker builder.unary_op(BuilderOp::abs_int, 2);
760*c8dee2aaSAndroid Build Coastguard Worker builder.unary_op(BuilderOp::floor_float, 3);
761*c8dee2aaSAndroid Build Coastguard Worker builder.unary_op(BuilderOp::ceil_float, 4);
762*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(5);
763*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/0,
764*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
765*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
766*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
767*c8dee2aaSAndroid Build Coastguard Worker R"(splat_4_constants $0..3 = 0x000001C8 (6.389921e-43)
768*c8dee2aaSAndroid Build Coastguard Worker copy_constant $4 = 0x000001C8 (6.389921e-43)
769*c8dee2aaSAndroid Build Coastguard Worker cast_to_float_from_int $4 = IntToFloat($4)
770*c8dee2aaSAndroid Build Coastguard Worker cast_to_float_from_2_uints $3..4 = UintToFloat($3..4)
771*c8dee2aaSAndroid Build Coastguard Worker cast_to_int_from_3_floats $2..4 = FloatToInt($2..4)
772*c8dee2aaSAndroid Build Coastguard Worker cast_to_uint_from_4_floats $1..4 = FloatToUint($1..4)
773*c8dee2aaSAndroid Build Coastguard Worker cos_float $1 = cos($1)
774*c8dee2aaSAndroid Build Coastguard Worker cos_float $2 = cos($2)
775*c8dee2aaSAndroid Build Coastguard Worker cos_float $3 = cos($3)
776*c8dee2aaSAndroid Build Coastguard Worker cos_float $4 = cos($4)
777*c8dee2aaSAndroid Build Coastguard Worker tan_float $2 = tan($2)
778*c8dee2aaSAndroid Build Coastguard Worker tan_float $3 = tan($3)
779*c8dee2aaSAndroid Build Coastguard Worker tan_float $4 = tan($4)
780*c8dee2aaSAndroid Build Coastguard Worker sin_float $3 = sin($3)
781*c8dee2aaSAndroid Build Coastguard Worker sin_float $4 = sin($4)
782*c8dee2aaSAndroid Build Coastguard Worker sqrt_float $4 = sqrt($4)
783*c8dee2aaSAndroid Build Coastguard Worker abs_2_ints $3..4 = abs($3..4)
784*c8dee2aaSAndroid Build Coastguard Worker floor_3_floats $2..4 = floor($2..4)
785*c8dee2aaSAndroid Build Coastguard Worker ceil_4_floats $1..4 = ceil($1..4)
786*c8dee2aaSAndroid Build Coastguard Worker )");
787*c8dee2aaSAndroid Build Coastguard Worker }
788*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderUniforms,r)789*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderUniforms, r) {
790*c8dee2aaSAndroid Build Coastguard Worker using BuilderOp = SkSL::RP::BuilderOp;
791*c8dee2aaSAndroid Build Coastguard Worker
792*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
793*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
794*c8dee2aaSAndroid Build Coastguard Worker builder.push_uniform(one_slot_at(0)); // push into 0
795*c8dee2aaSAndroid Build Coastguard Worker builder.push_uniform(two_slots_at(1)); // push into 1~2
796*c8dee2aaSAndroid Build Coastguard Worker builder.push_uniform(three_slots_at(3)); // push into 3~5
797*c8dee2aaSAndroid Build Coastguard Worker builder.push_uniform(four_slots_at(6)); // push into 6~9
798*c8dee2aaSAndroid Build Coastguard Worker builder.push_uniform(five_slots_at(0)); // push into 10~14
799*c8dee2aaSAndroid Build Coastguard Worker builder.unary_op(BuilderOp::abs_int, 1); // perform work so the program isn't eliminated
800*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(15); // balance stack
801*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/0,
802*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/10,
803*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
804*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
805*c8dee2aaSAndroid Build Coastguard Worker R"(copy_4_uniforms $0..3 = u0..3
806*c8dee2aaSAndroid Build Coastguard Worker copy_4_uniforms $4..7 = u4..7
807*c8dee2aaSAndroid Build Coastguard Worker copy_2_uniforms $8..9 = u8..9
808*c8dee2aaSAndroid Build Coastguard Worker copy_4_uniforms $10..13 = u0..3
809*c8dee2aaSAndroid Build Coastguard Worker copy_uniform $14 = u4
810*c8dee2aaSAndroid Build Coastguard Worker abs_int $14 = abs($14)
811*c8dee2aaSAndroid Build Coastguard Worker )");
812*c8dee2aaSAndroid Build Coastguard Worker }
813*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderPushZeros,r)814*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderPushZeros, r) {
815*c8dee2aaSAndroid Build Coastguard Worker using BuilderOp = SkSL::RP::BuilderOp;
816*c8dee2aaSAndroid Build Coastguard Worker
817*c8dee2aaSAndroid Build Coastguard Worker // Create a very simple nonsense program.
818*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
819*c8dee2aaSAndroid Build Coastguard Worker builder.push_zeros(1); // push into 0
820*c8dee2aaSAndroid Build Coastguard Worker builder.push_zeros(2); // push into 1~2
821*c8dee2aaSAndroid Build Coastguard Worker builder.push_zeros(3); // push into 3~5
822*c8dee2aaSAndroid Build Coastguard Worker builder.push_zeros(4); // push into 6~9
823*c8dee2aaSAndroid Build Coastguard Worker builder.push_zeros(5); // push into 10~14
824*c8dee2aaSAndroid Build Coastguard Worker builder.unary_op(BuilderOp::abs_int, 1); // perform work so the program isn't eliminated
825*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(15); // balance stack
826*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/0,
827*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/10,
828*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
829*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
830*c8dee2aaSAndroid Build Coastguard Worker R"(splat_4_constants $0..3 = 0
831*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $4..7 = 0
832*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $8..11 = 0
833*c8dee2aaSAndroid Build Coastguard Worker splat_3_constants $12..14 = 0
834*c8dee2aaSAndroid Build Coastguard Worker abs_int $14 = abs($14)
835*c8dee2aaSAndroid Build Coastguard Worker )");
836*c8dee2aaSAndroid Build Coastguard Worker }
837*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderTernaryFloatOps,r)838*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderTernaryFloatOps, r) {
839*c8dee2aaSAndroid Build Coastguard Worker using BuilderOp = SkSL::RP::BuilderOp;
840*c8dee2aaSAndroid Build Coastguard Worker
841*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
842*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_f(0.75f);
843*c8dee2aaSAndroid Build Coastguard Worker builder.push_duplicates(8);
844*c8dee2aaSAndroid Build Coastguard Worker builder.ternary_op(BuilderOp::mix_n_floats, 3);
845*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(3);
846*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/0,
847*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
848*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
849*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
850*c8dee2aaSAndroid Build Coastguard Worker R"(splat_4_constants $0..3 = 0x3F400000 (0.75)
851*c8dee2aaSAndroid Build Coastguard Worker splat_4_constants $4..7 = 0x3F400000 (0.75)
852*c8dee2aaSAndroid Build Coastguard Worker copy_constant $8 = 0x3F400000 (0.75)
853*c8dee2aaSAndroid Build Coastguard Worker mix_3_floats $0..2 = mix($3..5, $6..8, $0..2)
854*c8dee2aaSAndroid Build Coastguard Worker )");
855*c8dee2aaSAndroid Build Coastguard Worker }
856*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderAutomaticStackRewinding,r)857*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderAutomaticStackRewinding, r) {
858*c8dee2aaSAndroid Build Coastguard Worker using BuilderOp = SkSL::RP::BuilderOp;
859*c8dee2aaSAndroid Build Coastguard Worker
860*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
861*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_i(1);
862*c8dee2aaSAndroid Build Coastguard Worker builder.push_duplicates(2000);
863*c8dee2aaSAndroid Build Coastguard Worker builder.unary_op(BuilderOp::abs_int, 1); // perform work so the program isn't eliminated
864*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(2001);
865*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/0,
866*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
867*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
868*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> dump = get_program_dump(*program);
869*c8dee2aaSAndroid Build Coastguard Worker
870*c8dee2aaSAndroid Build Coastguard Worker #if SK_HAS_MUSTTAIL
871*c8dee2aaSAndroid Build Coastguard Worker // We have guaranteed tail-calling, so we never use `stack_rewind`.
872*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, !skstd::contains(as_string_view(dump), "stack_rewind"));
873*c8dee2aaSAndroid Build Coastguard Worker #else
874*c8dee2aaSAndroid Build Coastguard Worker // We can't guarantee tail-calling, so we should automatically insert `stack_rewind` stages into
875*c8dee2aaSAndroid Build Coastguard Worker // long programs.
876*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, skstd::contains(as_string_view(dump), "stack_rewind"));
877*c8dee2aaSAndroid Build Coastguard Worker #endif
878*c8dee2aaSAndroid Build Coastguard Worker }
879*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(RasterPipelineBuilderTraceOps,r)880*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(RasterPipelineBuilderTraceOps, r) {
881*c8dee2aaSAndroid Build Coastguard Worker for (bool provideDebugTrace : {false, true}) {
882*c8dee2aaSAndroid Build Coastguard Worker SkSL::RP::Builder builder;
883*c8dee2aaSAndroid Build Coastguard Worker // Create a trace mask stack on stack-ID 123.
884*c8dee2aaSAndroid Build Coastguard Worker builder.set_current_stack(123);
885*c8dee2aaSAndroid Build Coastguard Worker builder.push_constant_i(~0);
886*c8dee2aaSAndroid Build Coastguard Worker // Emit trace ops.
887*c8dee2aaSAndroid Build Coastguard Worker builder.trace_enter(123, 2);
888*c8dee2aaSAndroid Build Coastguard Worker builder.trace_scope(123, +1);
889*c8dee2aaSAndroid Build Coastguard Worker builder.trace_line(123, 456);
890*c8dee2aaSAndroid Build Coastguard Worker builder.trace_var(123, two_slots_at(3));
891*c8dee2aaSAndroid Build Coastguard Worker builder.trace_scope(123, -1);
892*c8dee2aaSAndroid Build Coastguard Worker builder.trace_exit(123, 2);
893*c8dee2aaSAndroid Build Coastguard Worker // Discard the trace mask.
894*c8dee2aaSAndroid Build Coastguard Worker builder.discard_stack(1);
895*c8dee2aaSAndroid Build Coastguard Worker
896*c8dee2aaSAndroid Build Coastguard Worker if (!provideDebugTrace) {
897*c8dee2aaSAndroid Build Coastguard Worker // Test the output when no DebugTrace info is provided.
898*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/20,
899*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
900*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0);
901*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
902*c8dee2aaSAndroid Build Coastguard Worker R"(copy_constant $0 = 0xFFFFFFFF
903*c8dee2aaSAndroid Build Coastguard Worker trace_enter TraceEnter(???) when $0 is true
904*c8dee2aaSAndroid Build Coastguard Worker trace_scope TraceScope(+1) when $0 is true
905*c8dee2aaSAndroid Build Coastguard Worker trace_line TraceLine(456) when $0 is true
906*c8dee2aaSAndroid Build Coastguard Worker trace_var TraceVar(v3..4) when $0 is true
907*c8dee2aaSAndroid Build Coastguard Worker trace_scope TraceScope(-1) when $0 is true
908*c8dee2aaSAndroid Build Coastguard Worker trace_exit TraceExit(???) when $0 is true
909*c8dee2aaSAndroid Build Coastguard Worker )");
910*c8dee2aaSAndroid Build Coastguard Worker } else {
911*c8dee2aaSAndroid Build Coastguard Worker // Test the output when we supply a populated DebugTrace.
912*c8dee2aaSAndroid Build Coastguard Worker SkSL::DebugTracePriv trace;
913*c8dee2aaSAndroid Build Coastguard Worker trace.fFuncInfo = {{"FunctionA"}, {"FunctionB"}, {"FunctionC"}, {"FunctionD"}};
914*c8dee2aaSAndroid Build Coastguard Worker
915*c8dee2aaSAndroid Build Coastguard Worker SkSL::SlotDebugInfo slot;
916*c8dee2aaSAndroid Build Coastguard Worker slot.name = "Var0";
917*c8dee2aaSAndroid Build Coastguard Worker trace.fSlotInfo.push_back(slot);
918*c8dee2aaSAndroid Build Coastguard Worker slot.name = "Var1";
919*c8dee2aaSAndroid Build Coastguard Worker trace.fSlotInfo.push_back(slot);
920*c8dee2aaSAndroid Build Coastguard Worker slot.name = "Var2";
921*c8dee2aaSAndroid Build Coastguard Worker trace.fSlotInfo.push_back(slot);
922*c8dee2aaSAndroid Build Coastguard Worker slot.name = "Var3";
923*c8dee2aaSAndroid Build Coastguard Worker trace.fSlotInfo.push_back(slot);
924*c8dee2aaSAndroid Build Coastguard Worker slot.name = "Var4";
925*c8dee2aaSAndroid Build Coastguard Worker trace.fSlotInfo.push_back(slot);
926*c8dee2aaSAndroid Build Coastguard Worker
927*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/20,
928*c8dee2aaSAndroid Build Coastguard Worker /*numUniformSlots=*/0,
929*c8dee2aaSAndroid Build Coastguard Worker /*numImmutableSlots=*/0,
930*c8dee2aaSAndroid Build Coastguard Worker &trace);
931*c8dee2aaSAndroid Build Coastguard Worker check(r, *program,
932*c8dee2aaSAndroid Build Coastguard Worker R"(copy_constant $0 = 0xFFFFFFFF
933*c8dee2aaSAndroid Build Coastguard Worker trace_enter TraceEnter(FunctionC) when $0 is true
934*c8dee2aaSAndroid Build Coastguard Worker trace_scope TraceScope(+1) when $0 is true
935*c8dee2aaSAndroid Build Coastguard Worker trace_line TraceLine(456) when $0 is true
936*c8dee2aaSAndroid Build Coastguard Worker trace_var TraceVar(Var3, Var4) when $0 is true
937*c8dee2aaSAndroid Build Coastguard Worker trace_scope TraceScope(-1) when $0 is true
938*c8dee2aaSAndroid Build Coastguard Worker trace_exit TraceExit(FunctionC) when $0 is true
939*c8dee2aaSAndroid Build Coastguard Worker )");
940*c8dee2aaSAndroid Build Coastguard Worker }
941*c8dee2aaSAndroid Build Coastguard Worker }
942*c8dee2aaSAndroid Build Coastguard Worker }
943