Replace raster pipeline nextafter() calls with SkNu nudging
(courtesy of mtklein@)
nanobench -m gradient_linear_clamp\$ --config f16 --ms 2000 -q
Before: 753.66
After: 658.69
R=mtklein@google.com,herb@google.com
CQ_INCLUDE_TRYBOTS=skia.primary:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD
Change-Id: Ie1442da340f6cfc9aef65bec1f114c0e5db89fcb
Reviewed-on: https://skia-review.googlesource.com/7351
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/src/opts/SkRasterPipeline_opts.h b/src/opts/SkRasterPipeline_opts.h
index aa66d73..5491535 100644
--- a/src/opts/SkRasterPipeline_opts.h
+++ b/src/opts/SkRasterPipeline_opts.h
@@ -871,21 +871,28 @@
return v;
}
+SI SkNf ulp_before(float v) {
+ SkASSERT(v > 0);
+ SkNf vs(v);
+ SkNu uvs = SkNu::Load(&vs) - 1;
+ return SkNf::Load(&uvs);
+}
+
SI SkNf clamp(const SkNf& v, float limit) {
- SkNf result = SkNf::Max(0, SkNf::Min(v, nextafterf(limit, 0)));
+ SkNf result = SkNf::Max(0, SkNf::Min(v, ulp_before(limit)));
return assert_in_tile(result, limit);
}
SI SkNf repeat(const SkNf& v, float limit) {
SkNf result = v - (v/limit).floor()*limit;
// For small negative v, (v/limit).floor()*limit can dominate v in the subtraction,
// which leaves result == limit. We want result < limit, so clamp it one ULP.
- result = SkNf::Min(result, nextafterf(limit, 0));
+ result = SkNf::Min(result, ulp_before(limit));
return assert_in_tile(result, limit);
}
SI SkNf mirror(const SkNf& v, float l/*imit*/) {
SkNf result = ((v - l) - ((v - l) / (2*l)).floor()*(2*l) - l).abs();
// Same deal as repeat.
- result = SkNf::Min(result, nextafterf(l, 0));
+ result = SkNf::Min(result, ulp_before(l));
return assert_in_tile(result, l);
}
STAGE_CTX( clamp_x, const float*) { r = clamp (r, *ctx); }