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.

Reply via email to