in gfx/skia/skia/src/sksl/codegen/SkSLRasterPipelineBuilder.cpp [2897:3830]
void Program::Dumper::dump(SkWStream* out, bool writeInstructionCount) {
using POp = ProgramOp;
// Allocate memory for the slot and uniform data, even though the program won't ever be
// executed. The program requires pointer ranges for managing its data, and ASAN will report
// errors if those pointers are pointing at unallocated memory.
SkArenaAlloc alloc(/*firstHeapAllocation=*/1000);
fSlots = fProgram.allocateSlotData(&alloc).value();
float* uniformPtr = alloc.makeArray<float>(fProgram.fNumUniformSlots);
fUniforms = SkSpan(uniformPtr, fProgram.fNumUniformSlots);
// Turn this program into an array of Raster Pipeline stages.
fProgram.makeStages(&fStages, &alloc, fUniforms, fSlots);
// Assemble lookup tables for program labels and slot names.
this->buildLabelToStageMap();
this->buildUniqueSlotNameList();
// Emit the program's instruction count.
if (writeInstructionCount) {
int invocationCount = 0, instructionCount = 0;
for (const Stage& stage : fStages) {
switch (stage.op) {
case POp::label:
// consumes zero instructions
break;
case POp::invoke_shader:
case POp::invoke_color_filter:
case POp::invoke_blender:
case POp::invoke_to_linear_srgb:
case POp::invoke_from_linear_srgb:
++invocationCount;
break;
default:
++instructionCount;
break;
}
}
out->writeText(std::to_string(instructionCount).c_str());
out->writeText(" instructions");
if (invocationCount > 0) {
out->writeText(", ");
out->writeText(std::to_string(invocationCount).c_str());
out->writeText(" invocations");
}
out->writeText("\n\n");
}
// Emit all of the program's immutable data.
const char* header = "[immutable slots]\n";
const char* footer = "";
for (const Instruction& inst : fProgram.fInstructions) {
if (inst.fOp == BuilderOp::store_immutable_value) {
out->writeText(header);
out->writeText("i");
out->writeText(std::to_string(inst.fSlotA).c_str());
out->writeText(" = ");
out->writeText(this->imm(sk_bit_cast<float>(inst.fImmA)).c_str());
out->writeText("\n");
header = "";
footer = "\n";
}
}
out->writeText(footer);
// Emit the program's instruction list.
for (int index = 0; index < fStages.size(); ++index) {
const Stage& stage = fStages[index];
std::string opArg1, opArg2, opArg3, opSwizzle;
switch (stage.op) {
case POp::label:
case POp::invoke_shader:
case POp::invoke_color_filter:
case POp::invoke_blender:
opArg1 = this->immCtx(stage.ctx, /*showAsFloat=*/false);
break;
case POp::case_op: {
auto ctx =
SkRPCtxUtils::Unpack((const SkRasterPipelineContexts::CaseOpCtx*)stage.ctx);
opArg1 = this->offsetCtx(ctx.offset, 1);
opArg2 = this->offsetCtx(ctx.offset + sizeof(int32_t) * N, 1);
opArg3 = this->imm(sk_bit_cast<float>(ctx.expectedValue), /*showAsFloat=*/false);
break;
}
case POp::swizzle_1:
case POp::swizzle_2:
case POp::swizzle_3:
case POp::swizzle_4:
std::tie(opArg1, opArg2) = this->swizzleCtx(stage.op, stage.ctx);
break;
case POp::swizzle_copy_slot_masked:
case POp::swizzle_copy_2_slots_masked:
case POp::swizzle_copy_3_slots_masked:
case POp::swizzle_copy_4_slots_masked:
std::tie(opArg1, opArg2) = this->swizzleCopyCtx(stage.op, stage.ctx);
break;
case POp::refract_4_floats:
std::tie(opArg1, opArg2) = this->adjacentPtrCtx(stage.ctx, 4);
opArg3 = this->ptrCtx((const float*)(stage.ctx) + (8 * N), 1);
break;
case POp::dot_2_floats:
opArg1 = this->ptrCtx(stage.ctx, 1);
std::tie(opArg2, opArg3) = this->adjacentPtrCtx(stage.ctx, 2);
break;
case POp::dot_3_floats:
opArg1 = this->ptrCtx(stage.ctx, 1);
std::tie(opArg2, opArg3) = this->adjacentPtrCtx(stage.ctx, 3);
break;
case POp::dot_4_floats:
opArg1 = this->ptrCtx(stage.ctx, 1);
std::tie(opArg2, opArg3) = this->adjacentPtrCtx(stage.ctx, 4);
break;
case POp::shuffle:
std::tie(opArg1, opArg2) = this->shuffleCtx(stage.ctx);
break;
case POp::matrix_multiply_2:
case POp::matrix_multiply_3:
case POp::matrix_multiply_4:
std::tie(opArg1, opArg2, opArg3) = this->matrixMultiply(stage.ctx);
break;
case POp::load_condition_mask:
case POp::store_condition_mask:
case POp::load_loop_mask:
case POp::store_loop_mask:
case POp::merge_loop_mask:
case POp::reenable_loop_mask:
case POp::load_return_mask:
case POp::store_return_mask:
case POp::continue_op:
case POp::cast_to_float_from_int: case POp::cast_to_float_from_uint:
case POp::cast_to_int_from_float: case POp::cast_to_uint_from_float:
case POp::abs_int:
case POp::acos_float:
case POp::asin_float:
case POp::atan_float:
case POp::ceil_float:
case POp::cos_float:
case POp::exp_float:
case POp::exp2_float:
case POp::log_float:
case POp::log2_float:
case POp::floor_float:
case POp::invsqrt_float:
case POp::sin_float:
case POp::sqrt_float:
case POp::tan_float:
opArg1 = this->ptrCtx(stage.ctx, 1);
break;
case POp::store_src_rg:
case POp::cast_to_float_from_2_ints: case POp::cast_to_float_from_2_uints:
case POp::cast_to_int_from_2_floats: case POp::cast_to_uint_from_2_floats:
case POp::abs_2_ints:
case POp::ceil_2_floats:
case POp::floor_2_floats:
case POp::invsqrt_2_floats:
opArg1 = this->ptrCtx(stage.ctx, 2);
break;
case POp::cast_to_float_from_3_ints: case POp::cast_to_float_from_3_uints:
case POp::cast_to_int_from_3_floats: case POp::cast_to_uint_from_3_floats:
case POp::abs_3_ints:
case POp::ceil_3_floats:
case POp::floor_3_floats:
case POp::invsqrt_3_floats:
opArg1 = this->ptrCtx(stage.ctx, 3);
break;
case POp::load_src:
case POp::load_dst:
case POp::exchange_src:
case POp::store_src:
case POp::store_dst:
case POp::store_device_xy01:
case POp::invoke_to_linear_srgb:
case POp::invoke_from_linear_srgb:
case POp::cast_to_float_from_4_ints: case POp::cast_to_float_from_4_uints:
case POp::cast_to_int_from_4_floats: case POp::cast_to_uint_from_4_floats:
case POp::abs_4_ints:
case POp::ceil_4_floats:
case POp::floor_4_floats:
case POp::invsqrt_4_floats:
case POp::inverse_mat2:
opArg1 = this->ptrCtx(stage.ctx, 4);
break;
case POp::inverse_mat3:
opArg1 = this->ptrCtx(stage.ctx, 9);
break;
case POp::inverse_mat4:
opArg1 = this->ptrCtx(stage.ctx, 16);
break;
case POp::copy_constant:
case POp::add_imm_float:
case POp::mul_imm_float:
case POp::cmple_imm_float:
case POp::cmplt_imm_float:
case POp::cmpeq_imm_float:
case POp::cmpne_imm_float:
case POp::min_imm_float:
case POp::max_imm_float:
std::tie(opArg1, opArg2) = this->constantCtx(stage.ctx, 1);
break;
case POp::add_imm_int:
case POp::mul_imm_int:
case POp::bitwise_and_imm_int:
case POp::bitwise_xor_imm_int:
case POp::cmple_imm_int:
case POp::cmple_imm_uint:
case POp::cmplt_imm_int:
case POp::cmplt_imm_uint:
case POp::cmpeq_imm_int:
case POp::cmpne_imm_int:
std::tie(opArg1, opArg2) = this->constantCtx(stage.ctx, 1, /*showAsFloat=*/false);
break;
case POp::splat_2_constants:
case POp::bitwise_and_imm_2_ints:
std::tie(opArg1, opArg2) = this->constantCtx(stage.ctx, 2);
break;
case POp::splat_3_constants:
case POp::bitwise_and_imm_3_ints:
std::tie(opArg1, opArg2) = this->constantCtx(stage.ctx, 3);
break;
case POp::splat_4_constants:
case POp::bitwise_and_imm_4_ints:
std::tie(opArg1, opArg2) = this->constantCtx(stage.ctx, 4);
break;
case POp::copy_uniform:
std::tie(opArg1, opArg2) = this->copyUniformCtx(stage.ctx, 1);
break;
case POp::copy_2_uniforms:
std::tie(opArg1, opArg2) = this->copyUniformCtx(stage.ctx, 2);
break;
case POp::copy_3_uniforms:
std::tie(opArg1, opArg2) = this->copyUniformCtx(stage.ctx, 3);
break;
case POp::copy_4_uniforms:
std::tie(opArg1, opArg2) = this->copyUniformCtx(stage.ctx, 4);
break;
case POp::copy_slot_masked:
case POp::copy_slot_unmasked:
case POp::copy_immutable_unmasked:
std::tie(opArg1, opArg2) = this->binaryOpCtx(stage.ctx, 1);
break;
case POp::copy_2_slots_masked:
case POp::copy_2_slots_unmasked:
case POp::copy_2_immutables_unmasked:
std::tie(opArg1, opArg2) = this->binaryOpCtx(stage.ctx, 2);
break;
case POp::copy_3_slots_masked:
case POp::copy_3_slots_unmasked:
case POp::copy_3_immutables_unmasked:
std::tie(opArg1, opArg2) = this->binaryOpCtx(stage.ctx, 3);
break;
case POp::copy_4_slots_masked:
case POp::copy_4_slots_unmasked:
case POp::copy_4_immutables_unmasked:
std::tie(opArg1, opArg2) = this->binaryOpCtx(stage.ctx, 4);
break;
case POp::copy_from_indirect_uniform_unmasked:
case POp::copy_from_indirect_unmasked:
case POp::copy_to_indirect_masked: {
const auto* ctx =
static_cast<SkRasterPipelineContexts::CopyIndirectCtx*>(stage.ctx);
// We don't incorporate the indirect-limit in the output
opArg1 = this->ptrCtx(ctx->dst, ctx->slots);
opArg2 = this->ptrCtx(ctx->src, ctx->slots);
opArg3 = this->ptrCtx(ctx->indirectOffset, 1);
break;
}
case POp::swizzle_copy_to_indirect_masked: {
const auto* ctx =
static_cast<SkRasterPipelineContexts::SwizzleCopyIndirectCtx*>(stage.ctx);
opArg1 = this->ptrCtx(ctx->dst, this->swizzleWidth(SkSpan(ctx->offsets,
ctx->slots)));
opArg2 = this->ptrCtx(ctx->src, ctx->slots);
opArg3 = this->ptrCtx(ctx->indirectOffset, 1);
opSwizzle = this->swizzleOffsetSpan(SkSpan(ctx->offsets, ctx->slots));
break;
}
case POp::merge_condition_mask:
case POp::merge_inv_condition_mask:
case POp::add_float: case POp::add_int:
case POp::sub_float: case POp::sub_int:
case POp::mul_float: case POp::mul_int:
case POp::div_float: case POp::div_int: case POp::div_uint:
case POp::bitwise_and_int:
case POp::bitwise_or_int:
case POp::bitwise_xor_int:
case POp::mod_float:
case POp::min_float: case POp::min_int: case POp::min_uint:
case POp::max_float: case POp::max_int: case POp::max_uint:
case POp::cmplt_float: case POp::cmplt_int: case POp::cmplt_uint:
case POp::cmple_float: case POp::cmple_int: case POp::cmple_uint:
case POp::cmpeq_float: case POp::cmpeq_int:
case POp::cmpne_float: case POp::cmpne_int:
std::tie(opArg1, opArg2) = this->adjacentPtrCtx(stage.ctx, 1);
break;
case POp::mix_float: case POp::mix_int:
std::tie(opArg1, opArg2, opArg3) = this->adjacent3PtrCtx(stage.ctx, 1);
break;
case POp::add_2_floats: case POp::add_2_ints:
case POp::sub_2_floats: case POp::sub_2_ints:
case POp::mul_2_floats: case POp::mul_2_ints:
case POp::div_2_floats: case POp::div_2_ints: case POp::div_2_uints:
case POp::bitwise_and_2_ints:
case POp::bitwise_or_2_ints:
case POp::bitwise_xor_2_ints:
case POp::mod_2_floats:
case POp::min_2_floats: case POp::min_2_ints: case POp::min_2_uints:
case POp::max_2_floats: case POp::max_2_ints: case POp::max_2_uints:
case POp::cmplt_2_floats: case POp::cmplt_2_ints: case POp::cmplt_2_uints:
case POp::cmple_2_floats: case POp::cmple_2_ints: case POp::cmple_2_uints:
case POp::cmpeq_2_floats: case POp::cmpeq_2_ints:
case POp::cmpne_2_floats: case POp::cmpne_2_ints:
std::tie(opArg1, opArg2) = this->adjacentPtrCtx(stage.ctx, 2);
break;
case POp::mix_2_floats: case POp::mix_2_ints:
std::tie(opArg1, opArg2, opArg3) = this->adjacent3PtrCtx(stage.ctx, 2);
break;
case POp::add_3_floats: case POp::add_3_ints:
case POp::sub_3_floats: case POp::sub_3_ints:
case POp::mul_3_floats: case POp::mul_3_ints:
case POp::div_3_floats: case POp::div_3_ints: case POp::div_3_uints:
case POp::bitwise_and_3_ints:
case POp::bitwise_or_3_ints:
case POp::bitwise_xor_3_ints:
case POp::mod_3_floats:
case POp::min_3_floats: case POp::min_3_ints: case POp::min_3_uints:
case POp::max_3_floats: case POp::max_3_ints: case POp::max_3_uints:
case POp::cmplt_3_floats: case POp::cmplt_3_ints: case POp::cmplt_3_uints:
case POp::cmple_3_floats: case POp::cmple_3_ints: case POp::cmple_3_uints:
case POp::cmpeq_3_floats: case POp::cmpeq_3_ints:
case POp::cmpne_3_floats: case POp::cmpne_3_ints:
std::tie(opArg1, opArg2) = this->adjacentPtrCtx(stage.ctx, 3);
break;
case POp::mix_3_floats: case POp::mix_3_ints:
std::tie(opArg1, opArg2, opArg3) = this->adjacent3PtrCtx(stage.ctx, 3);
break;
case POp::add_4_floats: case POp::add_4_ints:
case POp::sub_4_floats: case POp::sub_4_ints:
case POp::mul_4_floats: case POp::mul_4_ints:
case POp::div_4_floats: case POp::div_4_ints: case POp::div_4_uints:
case POp::bitwise_and_4_ints:
case POp::bitwise_or_4_ints:
case POp::bitwise_xor_4_ints:
case POp::mod_4_floats:
case POp::min_4_floats: case POp::min_4_ints: case POp::min_4_uints:
case POp::max_4_floats: case POp::max_4_ints: case POp::max_4_uints:
case POp::cmplt_4_floats: case POp::cmplt_4_ints: case POp::cmplt_4_uints:
case POp::cmple_4_floats: case POp::cmple_4_ints: case POp::cmple_4_uints:
case POp::cmpeq_4_floats: case POp::cmpeq_4_ints:
case POp::cmpne_4_floats: case POp::cmpne_4_ints:
std::tie(opArg1, opArg2) = this->adjacentPtrCtx(stage.ctx, 4);
break;
case POp::mix_4_floats: case POp::mix_4_ints:
std::tie(opArg1, opArg2, opArg3) = this->adjacent3PtrCtx(stage.ctx, 4);
break;
case POp::add_n_floats: case POp::add_n_ints:
case POp::sub_n_floats: case POp::sub_n_ints:
case POp::mul_n_floats: case POp::mul_n_ints:
case POp::div_n_floats: case POp::div_n_ints: case POp::div_n_uints:
case POp::bitwise_and_n_ints:
case POp::bitwise_or_n_ints:
case POp::bitwise_xor_n_ints:
case POp::mod_n_floats:
case POp::min_n_floats: case POp::min_n_ints: case POp::min_n_uints:
case POp::max_n_floats: case POp::max_n_ints: case POp::max_n_uints:
case POp::cmplt_n_floats: case POp::cmplt_n_ints: case POp::cmplt_n_uints:
case POp::cmple_n_floats: case POp::cmple_n_ints: case POp::cmple_n_uints:
case POp::cmpeq_n_floats: case POp::cmpeq_n_ints:
case POp::cmpne_n_floats: case POp::cmpne_n_ints:
case POp::atan2_n_floats:
case POp::pow_n_floats:
std::tie(opArg1, opArg2) = this->adjacentBinaryOpCtx(stage.ctx);
break;
case POp::mix_n_floats: case POp::mix_n_ints:
case POp::smoothstep_n_floats:
std::tie(opArg1, opArg2, opArg3) = this->adjacentTernaryOpCtx(stage.ctx);
break;
case POp::jump:
case POp::branch_if_all_lanes_active:
case POp::branch_if_any_lanes_active:
case POp::branch_if_no_lanes_active:
opArg1 = this->branchOffset(
static_cast<SkRasterPipelineContexts::BranchCtx*>(stage.ctx), index);
break;
case POp::branch_if_no_active_lanes_eq: {
const auto* ctx =
static_cast<SkRasterPipelineContexts::BranchIfEqualCtx*>(stage.ctx);
opArg1 = this->branchOffset(ctx, index);
opArg2 = this->ptrCtx(ctx->ptr, 1);
opArg3 = this->imm(sk_bit_cast<float>(ctx->value));
break;
}
case POp::trace_var: {
const auto* ctx = static_cast<SkRasterPipelineContexts::TraceVarCtx*>(stage.ctx);
opArg1 = this->ptrCtx(ctx->traceMask, 1);
opArg2 = this->ptrCtx(ctx->data, ctx->numSlots);
if (ctx->indirectOffset != nullptr) {
opArg3 = " + " + this->ptrCtx(ctx->indirectOffset, 1);
}
break;
}
case POp::trace_line: {
const auto* ctx = static_cast<SkRasterPipelineContexts::TraceLineCtx*>(stage.ctx);
opArg1 = this->ptrCtx(ctx->traceMask, 1);
opArg2 = std::to_string(ctx->lineNumber);
break;
}
case POp::trace_enter:
case POp::trace_exit: {
const auto* ctx = static_cast<SkRasterPipelineContexts::TraceFuncCtx*>(stage.ctx);
opArg1 = this->ptrCtx(ctx->traceMask, 1);
opArg2 = (fProgram.fDebugTrace &&
ctx->funcIdx >= 0 &&
ctx->funcIdx < (int)fProgram.fDebugTrace->fFuncInfo.size())
? fProgram.fDebugTrace->fFuncInfo[ctx->funcIdx].name
: "???";
break;
}
case POp::trace_scope: {
const auto* ctx = static_cast<SkRasterPipelineContexts::TraceScopeCtx*>(stage.ctx);
opArg1 = this->ptrCtx(ctx->traceMask, 1);
opArg2 = SkSL::String::printf("%+d", ctx->delta);
break;
}
default:
break;
}
std::string_view opName;
switch (stage.op) {
#define M(x) case POp::x: opName = #x; break;
SK_RASTER_PIPELINE_OPS_ALL(M)
SKRP_EXTENDED_OPS(M)
#undef M
}
std::string opText;
switch (stage.op) {
case POp::trace_var:
opText = "TraceVar(" + opArg2 + opArg3 + ") when " + opArg1 + " is true";
break;
case POp::trace_line:
opText = "TraceLine(" + opArg2 + ") when " + opArg1 + " is true";
break;
case POp::trace_enter:
opText = "TraceEnter(" + opArg2 + ") when " + opArg1 + " is true";
break;
case POp::trace_exit:
opText = "TraceExit(" + opArg2 + ") when " + opArg1 + " is true";
break;
case POp::trace_scope:
opText = "TraceScope(" + opArg2 + ") when " + opArg1 + " is true";
break;
case POp::init_lane_masks:
opText = "CondMask = LoopMask = RetMask = true";
break;
case POp::load_condition_mask:
opText = "CondMask = " + opArg1;
break;
case POp::store_condition_mask:
opText = opArg1 + " = CondMask";
break;
case POp::merge_condition_mask:
opText = "CondMask = " + opArg1 + " & " + opArg2;
break;
case POp::merge_inv_condition_mask:
opText = "CondMask = " + opArg1 + " & ~" + opArg2;
break;
case POp::load_loop_mask:
opText = "LoopMask = " + opArg1;
break;
case POp::store_loop_mask:
opText = opArg1 + " = LoopMask";
break;
case POp::mask_off_loop_mask:
opText = "LoopMask &= ~(CondMask & LoopMask & RetMask)";
break;
case POp::reenable_loop_mask:
opText = "LoopMask |= " + opArg1;
break;
case POp::merge_loop_mask:
opText = "LoopMask &= " + opArg1;
break;
case POp::load_return_mask:
opText = "RetMask = " + opArg1;
break;
case POp::store_return_mask:
opText = opArg1 + " = RetMask";
break;
case POp::mask_off_return_mask:
opText = "RetMask &= ~(CondMask & LoopMask & RetMask)";
break;
case POp::store_src_rg:
opText = opArg1 + " = src.rg";
break;
case POp::exchange_src:
opText = "swap(src.rgba, " + opArg1 + ")";
break;
case POp::store_src:
opText = opArg1 + " = src.rgba";
break;
case POp::store_dst:
opText = opArg1 + " = dst.rgba";
break;
case POp::store_device_xy01:
opText = opArg1 + " = DeviceCoords.xy01";
break;
case POp::load_src:
opText = "src.rgba = " + opArg1;
break;
case POp::load_dst:
opText = "dst.rgba = " + opArg1;
break;
case POp::bitwise_and_int:
case POp::bitwise_and_2_ints:
case POp::bitwise_and_3_ints:
case POp::bitwise_and_4_ints:
case POp::bitwise_and_n_ints:
case POp::bitwise_and_imm_int:
case POp::bitwise_and_imm_2_ints:
case POp::bitwise_and_imm_3_ints:
case POp::bitwise_and_imm_4_ints:
opText = opArg1 + " &= " + opArg2;
break;
case POp::bitwise_or_int:
case POp::bitwise_or_2_ints:
case POp::bitwise_or_3_ints:
case POp::bitwise_or_4_ints:
case POp::bitwise_or_n_ints:
opText = opArg1 + " |= " + opArg2;
break;
case POp::bitwise_xor_int:
case POp::bitwise_xor_2_ints:
case POp::bitwise_xor_3_ints:
case POp::bitwise_xor_4_ints:
case POp::bitwise_xor_n_ints:
case POp::bitwise_xor_imm_int:
opText = opArg1 + " ^= " + opArg2;
break;
case POp::cast_to_float_from_int:
case POp::cast_to_float_from_2_ints:
case POp::cast_to_float_from_3_ints:
case POp::cast_to_float_from_4_ints:
opText = opArg1 + " = IntToFloat(" + opArg1 + ")";
break;
case POp::cast_to_float_from_uint:
case POp::cast_to_float_from_2_uints:
case POp::cast_to_float_from_3_uints:
case POp::cast_to_float_from_4_uints:
opText = opArg1 + " = UintToFloat(" + opArg1 + ")";
break;
case POp::cast_to_int_from_float:
case POp::cast_to_int_from_2_floats:
case POp::cast_to_int_from_3_floats:
case POp::cast_to_int_from_4_floats:
opText = opArg1 + " = FloatToInt(" + opArg1 + ")";
break;
case POp::cast_to_uint_from_float:
case POp::cast_to_uint_from_2_floats:
case POp::cast_to_uint_from_3_floats:
case POp::cast_to_uint_from_4_floats:
opText = opArg1 + " = FloatToUint(" + opArg1 + ")";
break;
case POp::copy_slot_masked: case POp::copy_2_slots_masked:
case POp::copy_3_slots_masked: case POp::copy_4_slots_masked:
case POp::swizzle_copy_slot_masked: case POp::swizzle_copy_2_slots_masked:
case POp::swizzle_copy_3_slots_masked: case POp::swizzle_copy_4_slots_masked:
opText = opArg1 + " = Mask(" + opArg2 + ")";
break;
case POp::copy_uniform: case POp::copy_2_uniforms:
case POp::copy_3_uniforms: case POp::copy_4_uniforms:
case POp::copy_slot_unmasked: case POp::copy_2_slots_unmasked:
case POp::copy_3_slots_unmasked: case POp::copy_4_slots_unmasked:
case POp::copy_immutable_unmasked: case POp::copy_2_immutables_unmasked:
case POp::copy_3_immutables_unmasked: case POp::copy_4_immutables_unmasked:
case POp::copy_constant: case POp::splat_2_constants:
case POp::splat_3_constants: case POp::splat_4_constants:
case POp::swizzle_1: case POp::swizzle_2:
case POp::swizzle_3: case POp::swizzle_4:
case POp::shuffle:
opText = opArg1 + " = " + opArg2;
break;
case POp::copy_from_indirect_unmasked:
case POp::copy_from_indirect_uniform_unmasked:
opText = opArg1 + " = Indirect(" + opArg2 + " + " + opArg3 + ")";
break;
case POp::copy_to_indirect_masked:
opText = "Indirect(" + opArg1 + " + " + opArg3 + ") = Mask(" + opArg2 + ")";
break;
case POp::swizzle_copy_to_indirect_masked:
opText = "Indirect(" + opArg1 + " + " + opArg3 + ")." + opSwizzle + " = Mask(" +
opArg2 + ")";
break;
case POp::abs_int:
case POp::abs_2_ints:
case POp::abs_3_ints:
case POp::abs_4_ints:
opText = opArg1 + " = abs(" + opArg1 + ")";
break;
case POp::acos_float:
opText = opArg1 + " = acos(" + opArg1 + ")";
break;
case POp::asin_float:
opText = opArg1 + " = asin(" + opArg1 + ")";
break;
case POp::atan_float:
opText = opArg1 + " = atan(" + opArg1 + ")";
break;
case POp::atan2_n_floats:
opText = opArg1 + " = atan2(" + opArg1 + ", " + opArg2 + ")";
break;
case POp::ceil_float:
case POp::ceil_2_floats:
case POp::ceil_3_floats:
case POp::ceil_4_floats:
opText = opArg1 + " = ceil(" + opArg1 + ")";
break;
case POp::cos_float:
opText = opArg1 + " = cos(" + opArg1 + ")";
break;
case POp::refract_4_floats:
opText = opArg1 + " = refract(" + opArg1 + ", " + opArg2 + ", " + opArg3 + ")";
break;
case POp::dot_2_floats:
case POp::dot_3_floats:
case POp::dot_4_floats:
opText = opArg1 + " = dot(" + opArg2 + ", " + opArg3 + ")";
break;
case POp::exp_float:
opText = opArg1 + " = exp(" + opArg1 + ")";
break;
case POp::exp2_float:
opText = opArg1 + " = exp2(" + opArg1 + ")";
break;
case POp::log_float:
opText = opArg1 + " = log(" + opArg1 + ")";
break;
case POp::log2_float:
opText = opArg1 + " = log2(" + opArg1 + ")";
break;
case POp::pow_n_floats:
opText = opArg1 + " = pow(" + opArg1 + ", " + opArg2 + ")";
break;
case POp::sin_float:
opText = opArg1 + " = sin(" + opArg1 + ")";
break;
case POp::sqrt_float:
opText = opArg1 + " = sqrt(" + opArg1 + ")";
break;
case POp::tan_float:
opText = opArg1 + " = tan(" + opArg1 + ")";
break;
case POp::floor_float:
case POp::floor_2_floats:
case POp::floor_3_floats:
case POp::floor_4_floats:
opText = opArg1 + " = floor(" + opArg1 + ")";
break;
case POp::invsqrt_float:
case POp::invsqrt_2_floats:
case POp::invsqrt_3_floats:
case POp::invsqrt_4_floats:
opText = opArg1 + " = inversesqrt(" + opArg1 + ")";
break;
case POp::inverse_mat2:
case POp::inverse_mat3:
case POp::inverse_mat4:
opText = opArg1 + " = inverse(" + opArg1 + ")";
break;
case POp::add_float: case POp::add_int:
case POp::add_2_floats: case POp::add_2_ints:
case POp::add_3_floats: case POp::add_3_ints:
case POp::add_4_floats: case POp::add_4_ints:
case POp::add_n_floats: case POp::add_n_ints:
case POp::add_imm_float: case POp::add_imm_int:
opText = opArg1 + " += " + opArg2;
break;
case POp::sub_float: case POp::sub_int:
case POp::sub_2_floats: case POp::sub_2_ints:
case POp::sub_3_floats: case POp::sub_3_ints:
case POp::sub_4_floats: case POp::sub_4_ints:
case POp::sub_n_floats: case POp::sub_n_ints:
opText = opArg1 + " -= " + opArg2;
break;
case POp::mul_float: case POp::mul_int:
case POp::mul_2_floats: case POp::mul_2_ints:
case POp::mul_3_floats: case POp::mul_3_ints:
case POp::mul_4_floats: case POp::mul_4_ints:
case POp::mul_n_floats: case POp::mul_n_ints:
case POp::mul_imm_float: case POp::mul_imm_int:
opText = opArg1 + " *= " + opArg2;
break;
case POp::div_float: case POp::div_int: case POp::div_uint:
case POp::div_2_floats: case POp::div_2_ints: case POp::div_2_uints:
case POp::div_3_floats: case POp::div_3_ints: case POp::div_3_uints:
case POp::div_4_floats: case POp::div_4_ints: case POp::div_4_uints:
case POp::div_n_floats: case POp::div_n_ints: case POp::div_n_uints:
opText = opArg1 + " /= " + opArg2;
break;
case POp::matrix_multiply_2:
case POp::matrix_multiply_3:
case POp::matrix_multiply_4:
opText = opArg1 + " = " + opArg2 + " * " + opArg3;
break;
case POp::mod_float:
case POp::mod_2_floats:
case POp::mod_3_floats:
case POp::mod_4_floats:
case POp::mod_n_floats:
opText = opArg1 + " = mod(" + opArg1 + ", " + opArg2 + ")";
break;
case POp::min_float: case POp::min_int: case POp::min_uint:
case POp::min_2_floats: case POp::min_2_ints: case POp::min_2_uints:
case POp::min_3_floats: case POp::min_3_ints: case POp::min_3_uints:
case POp::min_4_floats: case POp::min_4_ints: case POp::min_4_uints:
case POp::min_n_floats: case POp::min_n_ints: case POp::min_n_uints:
case POp::min_imm_float:
opText = opArg1 + " = min(" + opArg1 + ", " + opArg2 + ")";
break;
case POp::max_float: case POp::max_int: case POp::max_uint:
case POp::max_2_floats: case POp::max_2_ints: case POp::max_2_uints:
case POp::max_3_floats: case POp::max_3_ints: case POp::max_3_uints:
case POp::max_4_floats: case POp::max_4_ints: case POp::max_4_uints:
case POp::max_n_floats: case POp::max_n_ints: case POp::max_n_uints:
case POp::max_imm_float:
opText = opArg1 + " = max(" + opArg1 + ", " + opArg2 + ")";
break;
case POp::cmplt_float: case POp::cmplt_int: case POp::cmplt_uint:
case POp::cmplt_2_floats: case POp::cmplt_2_ints: case POp::cmplt_2_uints:
case POp::cmplt_3_floats: case POp::cmplt_3_ints: case POp::cmplt_3_uints:
case POp::cmplt_4_floats: case POp::cmplt_4_ints: case POp::cmplt_4_uints:
case POp::cmplt_n_floats: case POp::cmplt_n_ints: case POp::cmplt_n_uints:
case POp::cmplt_imm_float: case POp::cmplt_imm_int: case POp::cmplt_imm_uint:
opText = opArg1 + " = lessThan(" + opArg1 + ", " + opArg2 + ")";
break;
case POp::cmple_float: case POp::cmple_int: case POp::cmple_uint:
case POp::cmple_2_floats: case POp::cmple_2_ints: case POp::cmple_2_uints:
case POp::cmple_3_floats: case POp::cmple_3_ints: case POp::cmple_3_uints:
case POp::cmple_4_floats: case POp::cmple_4_ints: case POp::cmple_4_uints:
case POp::cmple_n_floats: case POp::cmple_n_ints: case POp::cmple_n_uints:
case POp::cmple_imm_float: case POp::cmple_imm_int: case POp::cmple_imm_uint:
opText = opArg1 + " = lessThanEqual(" + opArg1 + ", " + opArg2 + ")";
break;
case POp::cmpeq_float: case POp::cmpeq_int:
case POp::cmpeq_2_floats: case POp::cmpeq_2_ints:
case POp::cmpeq_3_floats: case POp::cmpeq_3_ints:
case POp::cmpeq_4_floats: case POp::cmpeq_4_ints:
case POp::cmpeq_n_floats: case POp::cmpeq_n_ints:
case POp::cmpeq_imm_float: case POp::cmpeq_imm_int:
opText = opArg1 + " = equal(" + opArg1 + ", " + opArg2 + ")";
break;
case POp::cmpne_float: case POp::cmpne_int:
case POp::cmpne_2_floats: case POp::cmpne_2_ints:
case POp::cmpne_3_floats: case POp::cmpne_3_ints:
case POp::cmpne_4_floats: case POp::cmpne_4_ints:
case POp::cmpne_n_floats: case POp::cmpne_n_ints:
case POp::cmpne_imm_float: case POp::cmpne_imm_int:
opText = opArg1 + " = notEqual(" + opArg1 + ", " + opArg2 + ")";
break;
case POp::mix_float: case POp::mix_int:
case POp::mix_2_floats: case POp::mix_2_ints:
case POp::mix_3_floats: case POp::mix_3_ints:
case POp::mix_4_floats: case POp::mix_4_ints:
case POp::mix_n_floats: case POp::mix_n_ints:
opText = opArg1 + " = mix(" + opArg2 + ", " + opArg3 + ", " + opArg1 + ")";
break;
case POp::smoothstep_n_floats:
opText = opArg1 + " = smoothstep(" + opArg1 + ", " + opArg2 + ", " + opArg3 + ")";
break;
case POp::jump:
case POp::branch_if_all_lanes_active:
case POp::branch_if_any_lanes_active:
case POp::branch_if_no_lanes_active:
case POp::invoke_shader:
case POp::invoke_color_filter:
case POp::invoke_blender:
opText = std::string(opName) + " " + opArg1;
break;
case POp::invoke_to_linear_srgb:
opText = opArg1 + " = toLinearSrgb(" + opArg1 + ")";
break;
case POp::invoke_from_linear_srgb:
opText = opArg1 + " = fromLinearSrgb(" + opArg1 + ")";
break;
case POp::branch_if_no_active_lanes_eq:
opText = "branch " + opArg1 + " if no lanes of " + opArg2 + " == " + opArg3;
break;
case POp::label:
opText = "label " + opArg1;
break;
case POp::case_op:
opText = "if (" + opArg1 + " == " + opArg3 +
") { LoopMask = true; " + opArg2 + " = false; }";
break;
case POp::continue_op:
opText = opArg1 +
" |= Mask(0xFFFFFFFF); LoopMask &= ~(CondMask & LoopMask & RetMask)";
break;
default:
break;
}
opName = opName.substr(0, 30);
if (!opText.empty()) {
out->writeText(SkSL::String::printf("%-30.*s %s\n",
(int)opName.size(), opName.data(),
opText.c_str()).c_str());
} else {
out->writeText(SkSL::String::printf("%.*s\n",
(int)opName.size(), opName.data()).c_str());
}
}
}