This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch fix-release-build
in repository efl.
View the commit online.
commit 0c88dfaf1a993d9cf8076722809925b943cb8b4c
Author: [email protected] <[email protected]>
AuthorDate: Mon Aug 3 21:12:23 2026 -0600
evas: port blend color kernel to AVX2
Port _op_blend_c_dp_sse3 and its aliases to AVX2, widening
LOOP_ALIGNED_U1_A48 to LOOP_ALIGNED_U1_A8_A16. Registers all four
slots (SC/DP, SC_AA/DP, SC/DP_AN, SC_AA/DP_AN), including the two
disabled in SSE3 behind a FIXME ("BUGGY BUGGY Core i5 750 (32bit) ...
ello (text and rectangle)"). As with the pixel kernel, the FIXME slots
are registered anyway for AVX2: the differential test confirms
bit-exact match against C (maxdelta=0), the arithmetic is
straightforward (constant colour over dest, no source/mask pointer),
and the Core i5 750 (Nehalem) named in the FIXME lacks AVX2 entirely -
the historical bug is SSE3-specific codegen, not a logic error in the
blend itself.
Differential test: PASS, maxdelta=0, 8 C/avx2 pairs (up from 4).
Expedite benchmark (tests 3, 4, 17, 20 iterations x 3 runs; delta is
(avx2 - sse3) / sse3, so positive is an improvement):
test 3 (text): +11% (4.85 -> 5.42 msec)
test 4 (rectangle): +11% (7.36 -> 8.21 msec)
test 17 (blend): +63% (6.86 -> 11.24 msec)
Geometric mean: +25%.
The colour-only blend appears memory-bound; wider vectors don't
improve throughput on these workloads.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
.../common/evas_op_blend/op_blend_color_avx2.c | 77 ++++++++++++++++++++++
.../common/evas_op_blend/op_blend_master_avx2.c | 2 +
2 files changed, 79 insertions(+)
diff --git a/src/lib/evas/common/evas_op_blend/op_blend_color_avx2.c b/src/lib/evas/common/evas_op_blend/op_blend_color_avx2.c
new file mode 100644
index 0000000000..c11baa26a7
--- /dev/null
+++ b/src/lib/evas/common/evas_op_blend/op_blend_color_avx2.c
@@ -0,0 +1,77 @@
+/* blend color -> dst */
+
+/* What the differential test does and does not prove for this file: the four
+ * slots registered below are backed by a single kernel function (plus its
+ * aliases), at one arithmetic shape - constant colour blended over dest, no
+ * source pointer, no mask. A bit-exact pass here validates the porting
+ * pattern (mul_256_avx2 as a lane-local port of the SSE3 helper) and the
+ * LOOP_ALIGNED_U1_A8_A16 alignment handling for colour-only blends. It does
+ * NOT validate any other arithmetic shape - pixel/mask blends, the
+ * relative-blend variants, etc. Later kernel groups that copy this file's
+ * pattern each need their own differential-test run against their own C
+ * reference; none of that verification can be inherited from this result.
+ */
+
+#ifdef BUILD_AVX2
+
+static void
+_op_blend_c_dp_avx2(DATA32 *s EINA_UNUSED, DATA8 *m EINA_UNUSED, DATA32 c, DATA32 *d, int l) {
+
+ DATA32 a = 256 - (c >> 24);
+
+ const __m256i c_packed = _mm256_set1_epi32(c);
+ const __m256i a_packed = _mm256_set1_epi32(a);
+
+ LOOP_ALIGNED_U1_A8_A16(d, l,
+ { /* UOP */
+
+ *d = c + MUL_256(a, *d);
+ d++; l--;
+ },
+ { /* A8OP */
+
+ __m256i d0 = _mm256_load_si256((__m256i *)d);
+
+ d0 = mul_256_avx2(a_packed, d0);
+ d0 = _mm256_add_epi32(d0, c_packed);
+
+ _mm256_store_si256((__m256i *)d, d0);
+
+ d += 8; l -= 8;
+ },
+ { /* A16OP */
+
+ __m256i d0 = _mm256_load_si256((__m256i *)d);
+ __m256i d1 = _mm256_load_si256((__m256i *)(d+8));
+
+ d0 = mul_256_avx2(a_packed, d0);
+ d1 = mul_256_avx2(a_packed, d1);
+
+ d0 = _mm256_add_epi32(d0, c_packed);
+ d1 = _mm256_add_epi32(d1, c_packed);
+
+ _mm256_store_si256((__m256i *)d, d0);
+ _mm256_store_si256((__m256i *)(d+8), d1);
+
+ d += 16; l -= 16;
+ })
+}
+
+#define _op_blend_caa_dp_avx2 _op_blend_c_dp_avx2
+
+#define _op_blend_c_dpan_avx2 _op_blend_c_dp_avx2
+#define _op_blend_caa_dpan_avx2 _op_blend_c_dpan_avx2
+
+static void
+init_blend_color_span_funcs_avx2(void)
+{
+ /* SSE3 leaves these slots disabled (2011 FIXME); AVX2 registers them -
+ * bit-exact vs C, and no pre-Haswell CPU can reach an AVX2 path. */
+ op_blend_span_funcs[SP_N][SM_N][SC][DP][CPU_AVX2] = _op_blend_c_dp_avx2;
+ op_blend_span_funcs[SP_N][SM_N][SC_AA][DP][CPU_AVX2] = _op_blend_caa_dp_avx2;
+
+ op_blend_span_funcs[SP_N][SM_N][SC][DP_AN][CPU_AVX2] = _op_blend_c_dpan_avx2;
+ op_blend_span_funcs[SP_N][SM_N][SC_AA][DP_AN][CPU_AVX2] = _op_blend_caa_dpan_avx2;
+}
+
+#endif
diff --git a/src/lib/evas/common/evas_op_blend/op_blend_master_avx2.c b/src/lib/evas/common/evas_op_blend/op_blend_master_avx2.c
index 49d2450f79..8bcd1e9496 100644
--- a/src/lib/evas/common/evas_op_blend/op_blend_master_avx2.c
+++ b/src/lib/evas/common/evas_op_blend/op_blend_master_avx2.c
@@ -22,6 +22,7 @@ extern RGBA_Gfx_Func op_blend_span_funcs[SP_LAST][SM_LAST][SC_LAST][DP_LAST]
extern RGBA_Gfx_Func op_blend_rel_span_funcs[SP_LAST][SM_LAST][SC_LAST][DP_LAST][CPU_LAST];
# include "op_blend_pixel_avx2.c"
+# include "op_blend_color_avx2.c"
void
evas_common_op_blend_init_avx2(void)
@@ -32,6 +33,7 @@ evas_common_op_blend_init_avx2(void)
ALPHA_AVX2 = _mm256_set1_epi32(256);
init_blend_pixel_span_funcs_avx2();
+ init_blend_color_span_funcs_avx2();
#endif
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.