60 {
61 #define M(stage) stage,
62
64
65
67 #undef M
68};
69
70
71
72
73
74
75
77 #define M(stage) stage,
78
80
81
83 #undef M
84
85
86
122};
123
124
125static_assert((
int)ProgramOp::label == (
int)BuilderOp::label);
126
127
128struct Instruction {
132 int fImmA = 0;
133 int fImmB = 0;
134 int fImmC = 0;
135 int fImmD = 0;
136 int fStackID = 0;
137};
138
139class Callbacks {
140public:
141 virtual ~Callbacks() = default;
142
143 virtual bool appendShader(int index) = 0;
144 virtual bool appendColorFilter(int index) = 0;
145 virtual bool appendBlender(int index) = 0;
146
147 virtual void toLinearSrgb(
const void*
color) = 0;
148 virtual void fromLinearSrgb(
const void*
color) = 0;
149};
150
151class Program {
152public:
154 int numValueSlots,
155 int numUniformSlots,
156 int numImmutableSlots,
157 int numLabels,
158 DebugTracePriv* debugTrace);
159 ~Program();
160
163 Callbacks* callbacks,
165
166 void dump(
SkWStream* out,
bool writeInstructionCount =
false)
const;
167
168 int numUniforms() const { return fNumUniformSlots; }
169
170private:
172
173 struct SlotData {
177 };
179
182 void* ctx;
183 };
187 const SlotData& slots) const;
189 StackDepths tempStackMaxDepths() const;
190
191
194 std::byte* basePtr,
195 ProgramOp baseStage,
198 int numSlots) const;
201 std::byte* basePtr,
204 int numSlots) const;
209 int numSlots) const;
214 int numSlots) const;
215
216
217
218
220 float* dst, int numSlots) const;
221
222
223
224
225
226
228 float* dst, int numSlots) const;
229
230
231
232
233
234
235
236
238 ProgramOp baseStage,
239 SkRPOffset dst, int32_t value,
int numSlots)
const;
240
241
242
243
244
246 ProgramOp stage,
248
249
250
251
252
253
254
256 ProgramOp baseStage, std::byte* basePtr,
258
259
260
261
262
267
268
269
270
271
273 ProgramOp stage, std::byte* basePtr,
SkRPOffset dst,
275
276
278
281
283 int fNumValueSlots = 0;
284 int fNumUniformSlots = 0;
285 int fNumImmutableSlots = 0;
286 int fNumTempStackSlots = 0;
287 int fNumLabels = 0;
288 StackDepths fTempStackMaxDepths;
289 DebugTracePriv* fDebugTrace = nullptr;
290 std::unique_ptr<SkSL::TraceHook> fTraceHook;
291};
292
294public:
295
296 std::unique_ptr<Program> finish(int numValueSlots,
297 int numUniformSlots,
298 int numImmutableSlots,
299 DebugTracePriv* debugTrace = nullptr);
300
301
302
303
304
305 int nextLabelID() {
306 return fNumLabels++;
307 }
308
309
310
311
312
313
314 void enableExecutionMaskWrites() {
315 ++fExecutionMaskWritesEnabled;
316 }
317
318 void disableExecutionMaskWrites() {
319 SkASSERT(this->executionMaskWritesAreEnabled());
320 --fExecutionMaskWritesEnabled;
321 }
322
323 bool executionMaskWritesAreEnabled() {
324 return fExecutionMaskWritesEnabled > 0;
325 }
326
327
328 void init_lane_masks() {
329 this->appendInstruction(BuilderOp::init_lane_masks, {});
330 }
331
332 void store_src_rg(SlotRange slots) {
334 this->appendInstruction(BuilderOp::store_src_rg, {slots.index});
335 }
336
337 void store_src(SlotRange slots) {
339 this->appendInstruction(BuilderOp::store_src, {slots.index});
340 }
341
342 void store_dst(SlotRange slots) {
344 this->appendInstruction(BuilderOp::store_dst, {slots.index});
345 }
346
347 void store_device_xy01(SlotRange slots) {
349 this->appendInstruction(BuilderOp::store_device_xy01, {slots.index});
350 }
351
352 void load_src(SlotRange slots) {
354 this->appendInstruction(BuilderOp::load_src, {slots.index});
355 }
356
357 void load_dst(SlotRange slots) {
359 this->appendInstruction(BuilderOp::load_dst, {slots.index});
360 }
361
362 void set_current_stack(int stackID) {
363 fCurrentStackID = stackID;
364 }
365
366
367 void label(int labelID);
368
369
370 void jump(int labelID);
371
372
373 void branch_if_all_lanes_active(int labelID);
374
375
376 void branch_if_any_lanes_active(int labelID);
377
378
379 void branch_if_no_lanes_active(int labelID);
380
381
383
384
385 void push_constant_i(int32_t val,
int count = 1);
386
387 void push_zeros(
int count) {
388 this->push_constant_i(0,
count);
389 }
390
391 void push_constant_f(float val) {
392 this->push_constant_i(sk_bit_cast<int32_t>(val), 1);
393 }
394
395 void push_constant_u(uint32_t val,
int count = 1) {
396 this->push_constant_i(sk_bit_cast<int32_t>(val),
count);
397 }
398
399
401
402
403
404 void store_immutable_value_i(Slot slot, int32_t val) {
405 this->appendInstruction(BuilderOp::store_immutable_value, {slot}, val);
406 }
407
408
410
411
412
413
414
416
417
418
420 this->push_slots_or_immutable(src, BuilderOp::push_slots);
421 }
422
423
425 this->push_slots_or_immutable(src, BuilderOp::push_immutable);
426 }
427
428 void push_slots_or_immutable(SlotRange src, BuilderOp op);
429
430
431
432
433
435 this->push_slots_or_immutable_indirect(fixedRange, dynamicStack, limitRange,
436 BuilderOp::push_slots_indirect);
437 }
438
440 this->push_slots_or_immutable_indirect(fixedRange, dynamicStack, limitRange,
441 BuilderOp::push_immutable_indirect);
442 }
443
444 void push_slots_or_immutable_indirect(SlotRange fixedRange, int dynamicStack,
445 SlotRange limitRange, BuilderOp op);
446
447
448
451 }
452
454
455
456
459 int offsetFromStackTop);
460
461
462
464 int dynamicStackID,
465 SlotRange limitRange,
467 int offsetFromStackTop);
468
469
470
473 }
474
476
477
478
479
480
482 int dynamicStackID,
483 SlotRange limitRange);
484
485
486 void pop_slots_indirect(SlotRange fixedRange, int dynamicStackID, SlotRange limitRange) {
489 }
490
491
492
493 void unary_op(BuilderOp op, int32_t slots);
494
495
496
497 void binary_op(BuilderOp op, int32_t slots);
498
499
500
501 void ternary_op(BuilderOp op, int32_t slots);
502
503
504
505 void dot_floats(int32_t slots);
506
507
508
509 void refract_floats();
510
511
512 void inverse_matrix(int32_t n);
513
514
516
519 }
520
521
523
524
525 void pop_slots(SlotRange dst);
526
527
528 void push_duplicates(
int count);
529
530
531
532 void push_clone(
int numSlots,
int offsetFromStackTop = 0);
533
534
536
537
538
539
541 int dynamicStackID,
542 int otherStackID,
543 int offsetFromStackTop);
544
545
546 void case_op(int value) {
547 this->appendInstruction(BuilderOp::case_op, {},
value);
548 }
549
550
551 void continue_op(int continueMaskStackID) {
552 this->appendInstruction(BuilderOp::continue_op, {}, continueMaskStackID);
553 }
554
556
557
559 this->appendInstruction(BuilderOp::select, {}, slots);
560 }
561
562
563
564 void pop_slots_unmasked(SlotRange dst);
565
566 void copy_slots_masked(SlotRange dst, SlotRange src) {
568 this->appendInstruction(BuilderOp::copy_slot_masked, {
dst.index,
src.index},
dst.count);
569 }
570
571 void copy_slots_unmasked(SlotRange dst, SlotRange src);
572
573 void copy_immutable_unmasked(SlotRange dst, SlotRange src);
574
575
576 void copy_constant(Slot slot, int constantValue);
577
578
579 void zero_slots_unmasked(SlotRange dst);
580
581
583
584
585 void transpose(int columns, int rows);
586
587
588
589 void diagonal_matrix(int columns, int rows);
590
591
592 void matrix_resize(int origColumns, int origRows, int newColumns, int newRows);
593
594
595 void matrix_multiply(
int leftColumns,
int leftRows,
int rightColumns,
int rightRows);
596
598
600 SkASSERT(this->executionMaskWritesAreEnabled());
601 this->appendInstruction(BuilderOp::pop_condition_mask, {});
602 }
603
604 void merge_condition_mask();
605
606 void merge_inv_condition_mask() {
607 SkASSERT(this->executionMaskWritesAreEnabled());
608 this->appendInstruction(BuilderOp::merge_inv_condition_mask, {});
609 }
610
612 SkASSERT(this->executionMaskWritesAreEnabled());
613 this->appendInstruction(BuilderOp::push_loop_mask, {});
614 }
615
617 SkASSERT(this->executionMaskWritesAreEnabled());
618 this->appendInstruction(BuilderOp::pop_loop_mask, {});
619 }
620
621
622 void exchange_src();
623
625 this->appendInstruction(BuilderOp::push_src_rgba, {});
626 }
627
629 this->appendInstruction(BuilderOp::push_dst_rgba, {});
630 }
631
633 this->appendInstruction(BuilderOp::push_device_xy01, {});
634 }
635
637
639 this->appendInstruction(BuilderOp::pop_dst_rgba, {});
640 }
641
642 void mask_off_loop_mask() {
643 SkASSERT(this->executionMaskWritesAreEnabled());
644 this->appendInstruction(BuilderOp::mask_off_loop_mask, {});
645 }
646
647 void reenable_loop_mask(SlotRange src) {
648 SkASSERT(this->executionMaskWritesAreEnabled());
650 this->appendInstruction(BuilderOp::reenable_loop_mask, {
src.index});
651 }
652
654 SkASSERT(this->executionMaskWritesAreEnabled());
655 this->appendInstruction(BuilderOp::pop_and_reenable_loop_mask, {});
656 }
657
658 void merge_loop_mask() {
659 SkASSERT(this->executionMaskWritesAreEnabled());
660 this->appendInstruction(BuilderOp::merge_loop_mask, {});
661 }
662
664 SkASSERT(this->executionMaskWritesAreEnabled());
665 this->appendInstruction(BuilderOp::push_return_mask, {});
666 }
667
669
670 void mask_off_return_mask() {
671 SkASSERT(this->executionMaskWritesAreEnabled());
672 this->appendInstruction(BuilderOp::mask_off_return_mask, {});
673 }
674
675 void invoke_shader(int childIdx) {
676 this->appendInstruction(BuilderOp::invoke_shader, {}, childIdx);
677 }
678
679 void invoke_color_filter(int childIdx) {
680 this->appendInstruction(BuilderOp::invoke_color_filter, {}, childIdx);
681 }
682
683 void invoke_blender(int childIdx) {
684 this->appendInstruction(BuilderOp::invoke_blender, {}, childIdx);
685 }
686
687 void invoke_to_linear_srgb() {
688
689
691 this->appendInstruction(BuilderOp::invoke_to_linear_srgb, {});
693 }
694
695 void invoke_from_linear_srgb() {
696
697
699 this->appendInstruction(BuilderOp::invoke_from_linear_srgb, {});
701 }
702
703
704 void trace_line(int traceMaskStackID, int line) {
705 this->appendInstruction(BuilderOp::trace_line, {}, traceMaskStackID,
line);
706 }
707
708
709 void trace_var(int traceMaskStackID, SlotRange r) {
710 this->appendInstruction(BuilderOp::trace_var, {r.index}, traceMaskStackID, r.count);
711 }
712
713
715 int dynamicStackID, SlotRange limitRange);
716
717
718 void trace_enter(int traceMaskStackID, int funcID) {
719 this->appendInstruction(BuilderOp::trace_enter, {}, traceMaskStackID, funcID);
720 }
721
722
723 void trace_exit(int traceMaskStackID, int funcID) {
724 this->appendInstruction(BuilderOp::trace_exit, {}, traceMaskStackID, funcID);
725 }
726
727
728 void trace_scope(int traceMaskStackID, int delta) {
729 this->appendInstruction(BuilderOp::trace_scope, {}, traceMaskStackID,
delta);
730 }
731
732private:
733 struct SlotList {
734 SlotList(Slot
a = NA, Slot
b = NA) : fSlotA(
a), fSlotB(
b) {}
737 };
738 void appendInstruction(BuilderOp op, SlotList slots,
739 int a = 0,
int b = 0,
int c = 0,
int d = 0);
740 Instruction* lastInstruction(int fromBack = 0);
741 Instruction* lastInstructionOnAnyStack(int fromBack = 0);
742 void simplifyPopSlotsUnmasked(SlotRange* dst);
743 bool simplifyImmediateUnmaskedOp();
744
746 int fNumLabels = 0;
747 int fExecutionMaskWritesEnabled = 0;
748 int fCurrentStackID = 0;
749};
750
751}
752}
753
754#endif
static SkTileMode optimize(SkTileMode tm, int dimension)
#define SK_RASTER_PIPELINE_OPS_ALL(M)
#define SKRP_EXTENDED_OPS(M)
static void dump(const float m[20], SkYUVColorSpace cs, bool rgb2yuv)
Type::kYUV Type::kRGBA() int(0.7 *637)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
SI void matrix_multiply(SkRasterPipeline_MatrixMultiplyCtx *packed, std::byte *base)
@ copy_uniform_to_slots_unmasked
@ push_immutable_indirect
@ copy_stack_to_slots_indirect
@ copy_stack_to_slots_unmasked
@ swizzle_copy_stack_to_slots_indirect
@ push_clone_indirect_from_stack
@ swizzle_copy_stack_to_slots
@ branch_if_no_active_lanes_on_stack_top_equal
@ pop_and_reenable_loop_mask
DlVertices::Builder Builder