Add support for casting ints and floats to bool.
These casts are implemented as `notEqual(x, 0)`.
This causes five additional tests to pass (58/190):
inliner/TernaryTestCanBeInlined.sksl
inliner/TernaryResultsCannotBeInlined.sksl
inliner/ShortCircuitEvaluationsCannotInlineRightHandSide.sksl
inliner/IfTestCanBeInlined.sksl
inliner/IfElseChainWithReturnsCanBeInlined.sksl
Change-Id: I6ad5442fdd4f3d5d9aaaa4b04db14ecc305465c7
Bug: skia:13676
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/625677
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/codegen/SkSLRasterPipelineBuilder.cpp b/src/sksl/codegen/SkSLRasterPipelineBuilder.cpp
index 213e2af..2c10df5 100644
--- a/src/sksl/codegen/SkSLRasterPipelineBuilder.cpp
+++ b/src/sksl/codegen/SkSLRasterPipelineBuilder.cpp
@@ -127,6 +127,7 @@
case BuilderOp::push_slots:
case BuilderOp::push_uniform:
+ case BuilderOp::push_zeros:
return inst.fImmA;
case ALL_SINGLE_SLOT_BINARY_OP_CASES:
@@ -557,6 +558,11 @@
this->appendCopyConstants(pipeline, alloc, dst, UniformA(), inst.fImmA);
break;
}
+ case BuilderOp::push_zeros: {
+ float* dst = tempStackPtr;
+ this->appendMultiSlotUnaryOp(pipeline, SkRP::zero_slot_unmasked, dst, inst.fImmA);
+ break;
+ }
case BuilderOp::push_condition_mask: {
float* dst = tempStackPtr;
this->append(pipeline, SkRP::store_condition_mask, dst);
diff --git a/src/sksl/codegen/SkSLRasterPipelineBuilder.h b/src/sksl/codegen/SkSLRasterPipelineBuilder.h
index de76bee..1e79020 100644
--- a/src/sksl/codegen/SkSLRasterPipelineBuilder.h
+++ b/src/sksl/codegen/SkSLRasterPipelineBuilder.h
@@ -47,6 +47,7 @@
push_literal_f,
push_slots,
push_uniform,
+ push_zeros,
copy_stack_to_slots,
copy_stack_to_slots_unmasked,
discard_stack,
@@ -272,6 +273,11 @@
fInstructions.push_back({BuilderOp::push_uniform, {src.index}, src.count});
}
+ void push_zeros(int count) {
+ // Translates into zero_slot_unmasked in Raster Pipeline.
+ fInstructions.push_back({BuilderOp::push_zeros, {}, count});
+ }
+
void push_slots(SlotRange src) {
SkASSERT(src.count >= 0);
if (src.count > 0) {
diff --git a/src/sksl/codegen/SkSLRasterPipelineCodeGenerator.cpp b/src/sksl/codegen/SkSLRasterPipelineCodeGenerator.cpp
index 731ced3..dee1aa0 100644
--- a/src/sksl/codegen/SkSLRasterPipelineCodeGenerator.cpp
+++ b/src/sksl/codegen/SkSLRasterPipelineCodeGenerator.cpp
@@ -1050,6 +1050,7 @@
bool Generator::pushConstructorCast(const AnyConstructor& c) {
SkASSERT(c.argumentSpan().size() == 1);
const Expression& inner = *c.argumentSpan().front();
+ SkASSERT(inner.type().slotCount() == c.type().slotCount());
if (!this->pushExpression(inner)) {
return unsupported();
@@ -1058,6 +1059,11 @@
// Since we ignore type precision, this cast is effectively a no-op.
return true;
}
+ if (c.type().componentType().isBoolean()) {
+ // Converting int or float to boolean can be accomplished via `notEqual(x, 0)`.
+ fBuilder.push_zeros(c.type().slotCount());
+ return this->binaryOp(inner.type(), kNotEqualOps);
+ }
// TODO: add RP op to convert values on stack from the inner type to the outer type
return unsupported();
diff --git a/tests/RasterPipelineBuilderTest.cpp b/tests/RasterPipelineBuilderTest.cpp
index 267965a..ac99cb1 100644
--- a/tests/RasterPipelineBuilderTest.cpp
+++ b/tests/RasterPipelineBuilderTest.cpp
@@ -423,6 +423,7 @@
5. bitwise_not $4 = ~$4
)");
}
+
DEF_TEST(RasterPipelineBuilderUniforms, r) {
// Create a very simple nonsense program.
SkSL::RP::Builder builder;
@@ -444,6 +445,27 @@
)");
}
+DEF_TEST(RasterPipelineBuilderPushZeros, r) {
+ // Create a very simple nonsense program.
+ SkSL::RP::Builder builder;
+ builder.push_zeros(1); // push into 0
+ builder.push_zeros(2); // push into 1~2
+ builder.push_zeros(3); // push into 3~5
+ builder.push_zeros(4); // push into 6~9
+ builder.push_zeros(5); // push into 10~14
+ builder.discard_stack(15); // balance stack
+ std::unique_ptr<SkSL::RP::Program> program = builder.finish(/*numValueSlots=*/0,
+ /*numUniformSlots=*/10);
+ check(r, *program,
+R"( 1. zero_slot_unmasked $0 = 0
+ 2. zero_2_slots_unmasked $1..2 = 0
+ 3. zero_3_slots_unmasked $3..5 = 0
+ 4. zero_4_slots_unmasked $6..9 = 0
+ 5. zero_4_slots_unmasked $10..13 = 0
+ 6. zero_slot_unmasked $14 = 0
+)");
+}
+
DEF_TEST(RasterPipelineBuilderTernaryFloatOps, r) {
using BuilderOp = SkSL::RP::BuilderOp;