# --- T2-COPYRIGHT-BEGIN --- # t2/package/*/libsdl2/x86-simd-target.patch # Copyright (C) 2026 The T2 SDE Project # SPDX-License-Identifier: GPL-2.0 or patched project license # --- T2-COPYRIGHT-END --- Build x86 MMX/SSE* code per function with target attributes instead of global -mmmx/-msse*, which let the compiler use cmov, SSE, etc. in all generic code, breaking the i586 baseline. The SIMD code paths are still selected by the existing runtime CPUID detection, and SSE2/SSE3 are now also available on i586 builds. Signed-off-by: René Rebe diff -Nurp a/configure b/configure --- a/configure 2025-09-01 23:33:27.000000000 +0200 +++ b/configure 2026-11-07 11:16:08.771944381 +0100 @@ -1674,8 +1674,8 @@ Optional Features: --enable-mmx use MMX assembly routines [default=yes] --enable-3dnow use 3DNow! assembly routines [default=no] --enable-sse use SSE assembly routines [default=yes] - --enable-sse2 use SSE2 assembly routines [default=maybe] - --enable-sse3 use SSE3 assembly routines [default=maybe] + --enable-sse2 use SSE2 assembly routines [default=yes] + --enable-sse3 use SSE3 assembly routines [default=yes] --enable-altivec use Altivec assembly routines [default=yes] --enable-lsx use LSX assembly routines [default=yes] --enable-oss support the OSS audio API [default=maybe] @@ -20693,10 +20693,12 @@ printf "%s\n" "$have_gcc_mmx" >&6; } CFLAGS="$save_CFLAGS" if test x$have_gcc_mmx = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS $mmx_CFLAGS" SUMMARY_math="${SUMMARY_math} mmx" fi fi + if test x$have_gcc_mmx != xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -DSDL_DISABLE_MMX" + fi # Check whether --enable-3dnow was given. if test ${enable_3dnow+y} @@ -20800,17 +20802,19 @@ printf "%s\n" "$have_gcc_sse" >&6; } CFLAGS="$save_CFLAGS" if test x$have_gcc_sse = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS $sse_CFLAGS" SUMMARY_math="${SUMMARY_math} sse" fi fi + if test x$have_gcc_sse != xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -DSDL_DISABLE_SSE" + fi # Check whether --enable-sse2 was given. if test ${enable_sse2+y} then : enableval=$enable_sse2; else $as_nop - enable_sse2=$default_ssemath + enable_sse2=yes fi if test x$enable_sse2 = xyes; then @@ -20856,17 +20860,19 @@ printf "%s\n" "$have_gcc_sse2" >&6; } CFLAGS="$save_CFLAGS" if test x$have_gcc_sse2 = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS $sse2_CFLAGS" SUMMARY_math="${SUMMARY_math} sse2" fi fi + if test x$have_gcc_sse2 != xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -DSDL_DISABLE_SSE2" + fi # Check whether --enable-sse3 was given. if test ${enable_sse3+y} then : enableval=$enable_sse3; else $as_nop - enable_sse3=$default_ssemath + enable_sse3=yes fi if test x$enable_sse3 = xyes; then @@ -20912,10 +20918,12 @@ printf "%s\n" "$have_gcc_sse3" >&6; } CFLAGS="$save_CFLAGS" if test x$have_gcc_sse3 = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS $sse3_CFLAGS" SUMMARY_math="${SUMMARY_math} sse3" fi fi + if test x$have_gcc_sse3 != xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -DSDL_DISABLE_SSE3" + fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for immintrin.h" >&5 printf %s "checking for immintrin.h... " >&6; } diff -Nurp a/configure.ac b/configure.ac --- a/configure.ac 2025-09-01 23:33:27.000000000 +0200 +++ b/configure.ac 2026-11-07 11:16:19.653660145 +0100 @@ -692,10 +692,13 @@ dnl Check for various instruction suppor CFLAGS="$save_CFLAGS" if test x$have_gcc_mmx = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS $mmx_CFLAGS" SUMMARY_math="${SUMMARY_math} mmx" fi fi + dnl SIMD code is built per function with target attributes and runtime dispatched + if test x$have_gcc_mmx != xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -DSDL_DISABLE_MMX" + fi AC_ARG_ENABLE(3dnow, [AS_HELP_STRING([--enable-3dnow], [use 3DNow! assembly routines [default=no]])], @@ -755,14 +758,16 @@ dnl Check for various instruction suppor CFLAGS="$save_CFLAGS" if test x$have_gcc_sse = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS $sse_CFLAGS" SUMMARY_math="${SUMMARY_math} sse" fi fi + if test x$have_gcc_sse != xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -DSDL_DISABLE_SSE" + fi AC_ARG_ENABLE(sse2, -[AS_HELP_STRING([--enable-sse2], [use SSE2 assembly routines [default=maybe]])], - , enable_sse2=$default_ssemath) +[AS_HELP_STRING([--enable-sse2], [use SSE2 assembly routines [default=yes]])], + , enable_sse2=yes) if test x$enable_sse2 = xyes; then save_CFLAGS="$CFLAGS" have_gcc_sse2=no @@ -789,14 +794,16 @@ dnl Check for various instruction suppor CFLAGS="$save_CFLAGS" if test x$have_gcc_sse2 = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS $sse2_CFLAGS" SUMMARY_math="${SUMMARY_math} sse2" fi fi + if test x$have_gcc_sse2 != xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -DSDL_DISABLE_SSE2" + fi AC_ARG_ENABLE(sse3, -[AS_HELP_STRING([--enable-sse3], [use SSE3 assembly routines [default=maybe]])], - , enable_sse3=$default_ssemath) +[AS_HELP_STRING([--enable-sse3], [use SSE3 assembly routines [default=yes]])], + , enable_sse3=yes) if test x$enable_sse3 = xyes; then save_CFLAGS="$CFLAGS" have_gcc_sse3=no @@ -823,10 +830,12 @@ dnl Check for various instruction suppor CFLAGS="$save_CFLAGS" if test x$have_gcc_sse3 = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS $sse3_CFLAGS" SUMMARY_math="${SUMMARY_math} sse3" fi fi + if test x$have_gcc_sse3 != xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -DSDL_DISABLE_SSE3" + fi AC_MSG_CHECKING(for immintrin.h) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]])], diff -Nurp a/src/SDL_intrin.h b/src/SDL_intrin.h --- a/src/SDL_intrin.h 1970-01-01 01:00:00.000000000 +0100 +++ b/src/SDL_intrin.h 2026-11-07 11:13:22.136704751 +0100 @@ -0,0 +1,67 @@ +/* + Simple DirectMedia Layer + Copyright (C) 2026 René Rebe + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* x86 SIMD code is compiled per function via target attributes and selected + by runtime CPU detection, so no global -mmmx/-msse* is required. */ + +#ifndef SDL_intrin_h_ +#define SDL_intrin_h_ + +#include "SDL_cpuinfo.h" + +#if defined(__clang__) || defined(__GNUC__) +#ifdef __has_attribute +#if __has_attribute(target) +#define SDL_HAS_TARGET_ATTRIBS 1 +#endif +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) +#define SDL_HAS_TARGET_ATTRIBS 1 +#endif +#endif + +#ifdef SDL_HAS_TARGET_ATTRIBS +#define SDL_TARGETING(x) __attribute__((target(x))) +#else +#define SDL_TARGETING(x) +#endif + +#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64) +#if !defined(SDL_DISABLE_MMX) && (defined(__MMX__) || defined(SDL_HAS_TARGET_ATTRIBS)) +#define SDL_MMX_INTRINSICS 1 +#include +#endif +#if !defined(SDL_DISABLE_SSE) && (defined(__SSE__) || defined(SDL_HAS_TARGET_ATTRIBS)) +#define SDL_SSE_INTRINSICS 1 +#include +#endif +#if !defined(SDL_DISABLE_SSE2) && (defined(__SSE2__) || defined(SDL_HAS_TARGET_ATTRIBS)) +#define SDL_SSE2_INTRINSICS 1 +#include +#endif +#if !defined(SDL_DISABLE_SSE3) && (defined(__SSE3__) || defined(SDL_HAS_TARGET_ATTRIBS)) +#define SDL_SSE3_INTRINSICS 1 +#include +#endif +#endif /* x86 */ + +#endif /* SDL_intrin_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -Nurp a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c --- a/src/audio/SDL_audiocvt.c 2025-01-01 16:47:53.000000000 +0100 +++ b/src/audio/SDL_audiocvt.c 2026-11-07 11:16:26.295982959 +0100 @@ -29,6 +30,7 @@ #include "SDL_loadso.h" #include "../SDL_dataqueue.h" #include "SDL_cpuinfo.h" +#include "../SDL_intrin.h" #define DEBUG_AUDIOSTREAM 0 @@ -36,11 +38,11 @@ #define HAVE_NEON_INTRINSICS 1 #endif -#ifdef __SSE__ +#ifdef SDL_SSE_INTRINSICS #define HAVE_SSE_INTRINSICS 1 #endif -#ifdef __SSE3__ +#ifdef SDL_SSE3_INTRINSICS #define HAVE_SSE3_INTRINSICS 1 #endif @@ -95,7 +97,7 @@ #ifdef HAVE_SSE3_INTRINSICS /* Convert from stereo to mono. Average left and right. */ -static void SDLCALL SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT *cvt, SDL_AudioFormat format) +static void SDLCALL SDL_TARGETING("sse3") SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const __m128 divby2 = _mm_set1_ps(0.5f); float *dst = (float *)cvt->buf; @@ -132,7 +134,7 @@ static void SDLCALL SDL_ConvertStereoToM #ifdef HAVE_SSE_INTRINSICS /* Convert from mono to stereo. Duplicate to stereo left and right. */ -static void SDLCALL SDL_ConvertMonoToStereo_SSE(SDL_AudioCVT *cvt, SDL_AudioFormat format) +static void SDLCALL SDL_TARGETING("sse") SDL_ConvertMonoToStereo_SSE(SDL_AudioCVT *cvt, SDL_AudioFormat format) { float *dst = ((float *)(cvt->buf + (cvt->len_cvt * 2))) - 8; const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 4; diff -Nurp a/src/audio/SDL_audiotypecvt.c b/src/audio/SDL_audiotypecvt.c --- a/src/audio/SDL_audiotypecvt.c 2025-01-01 16:47:53.000000000 +0100 +++ b/src/audio/SDL_audiotypecvt.c 2026-11-07 11:16:26.296301003 +0100 @@ -23,12 +24,13 @@ #include "SDL_audio.h" #include "SDL_audio_c.h" #include "SDL_cpuinfo.h" +#include "../SDL_intrin.h" #ifdef __ARM_NEON #define HAVE_NEON_INTRINSICS 1 #endif -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS #define HAVE_SSE2_INTRINSICS #endif @@ -329,7 +331,7 @@ static void SDLCALL SDL_Convert_F32_to_S #endif #ifdef HAVE_SSE2_INTRINSICS -static void SDLCALL SDL_Convert_S8_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +static void SDLCALL SDL_TARGETING("sse2") SDL_Convert_S8_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const Sint8 *src = (const Sint8 *)cvt->buf; float *dst = (float *)cvt->buf; @@ -378,7 +380,7 @@ static void SDLCALL SDL_Convert_S8_to_F3 } } -static void SDLCALL SDL_Convert_U8_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +static void SDLCALL SDL_TARGETING("sse2") SDL_Convert_U8_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const Sint8 *src = (const Sint8 *)cvt->buf; float *dst = (float *)cvt->buf; @@ -425,7 +427,7 @@ static void SDLCALL SDL_Convert_U8_to_F3 } } -static void SDLCALL SDL_Convert_S16_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +static void SDLCALL SDL_TARGETING("sse2") SDL_Convert_S16_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const Sint16 *src = (const Sint16 *)cvt->buf; float *dst = (float *)cvt->buf; @@ -471,7 +473,7 @@ static void SDLCALL SDL_Convert_S16_to_F } } -static void SDLCALL SDL_Convert_U16_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +static void SDLCALL SDL_TARGETING("sse2") SDL_Convert_U16_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const Uint16 *src = ((const Uint16 *)(cvt->buf + cvt->len_cvt)) - 1; float *dst = ((float *)(cvt->buf + cvt->len_cvt * 2)) - 1; @@ -525,7 +527,7 @@ static void SDLCALL SDL_Convert_U16_to_F } } -static void SDLCALL SDL_Convert_S32_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +static void SDLCALL SDL_TARGETING("sse2") SDL_Convert_S32_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const Sint32 *src = (const Sint32 *)cvt->buf; float *dst = (float *)cvt->buf; @@ -567,7 +569,7 @@ static void SDLCALL SDL_Convert_S32_to_F } } -static void SDLCALL SDL_Convert_F32_to_S8_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +static void SDLCALL SDL_TARGETING("sse2") SDL_Convert_F32_to_S8_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const float *src = (const float *)cvt->buf; Sint8 *dst = (Sint8 *)cvt->buf; @@ -620,7 +622,7 @@ static void SDLCALL SDL_Convert_F32_to_S } } -static void SDLCALL SDL_Convert_F32_to_U8_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +static void SDLCALL SDL_TARGETING("sse2") SDL_Convert_F32_to_U8_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const float *src = (const float *)cvt->buf; Uint8 *dst = cvt->buf; @@ -673,7 +675,7 @@ static void SDLCALL SDL_Convert_F32_to_U } } -static void SDLCALL SDL_Convert_F32_to_S16_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +static void SDLCALL SDL_TARGETING("sse2") SDL_Convert_F32_to_S16_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const float *src = (const float *)cvt->buf; Sint16 *dst = (Sint16 *)cvt->buf; @@ -725,7 +727,7 @@ static void SDLCALL SDL_Convert_F32_to_S } } -static void SDLCALL SDL_Convert_F32_to_U16_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +static void SDLCALL SDL_TARGETING("sse2") SDL_Convert_F32_to_U16_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const float *src = (const float *)cvt->buf; Uint16 *dst = (Uint16 *)cvt->buf; @@ -794,7 +796,7 @@ static void SDLCALL SDL_Convert_F32_to_U } } -static void SDLCALL SDL_Convert_F32_to_S32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +static void SDLCALL SDL_TARGETING("sse2") SDL_Convert_F32_to_S32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const float *src = (const float *)cvt->buf; Sint32 *dst = (Sint32 *)cvt->buf; diff -Nurp a/src/video/SDL_blit_A.c b/src/video/SDL_blit_A.c --- a/src/video/SDL_blit_A.c 2025-01-01 16:47:53.000000000 +0100 +++ b/src/video/SDL_blit_A.c 2026-11-07 11:16:26.296533684 +0100 @@ -24,6 +25,7 @@ #include "SDL_video.h" #include "SDL_blit.h" +#include "../SDL_intrin.h" /* Functions to perform alpha blended blitting */ @@ -167,10 +169,10 @@ static void BlitNto1SurfaceAlphaKey(SDL_ } } -#ifdef __MMX__ +#ifdef SDL_MMX_INTRINSICS /* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */ -static void BlitRGBtoRGBSurfaceAlpha128MMX(SDL_BlitInfo *info) +static void SDL_TARGETING("mmx") BlitRGBtoRGBSurfaceAlpha128MMX(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -224,7 +226,7 @@ static void BlitRGBtoRGBSurfaceAlpha128M } /* fast RGB888->(A)RGB888 blending with surface alpha */ -static void BlitRGBtoRGBSurfaceAlphaMMX(SDL_BlitInfo *info) +static void SDL_TARGETING("mmx") BlitRGBtoRGBSurfaceAlphaMMX(SDL_BlitInfo *info) { SDL_PixelFormat *df = info->dst_fmt; Uint32 chanmask; @@ -319,7 +321,7 @@ static void BlitRGBtoRGBSurfaceAlphaMMX( } /* fast ARGB888->(A)RGB888 blending with pixel alpha */ -static void BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo *info) +static void SDL_TARGETING("mmx") BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -410,7 +412,7 @@ static void BlitRGBtoRGBPixelAlphaMMX(SD _mm_empty(); } -#endif /* __MMX__ */ +#endif /* SDL_MMX_INTRINSICS */ #ifdef SDL_ARM_SIMD_BLITTERS void BlitARGBto565PixelAlphaARMSIMDAsm(int32_t w, int32_t h, uint16_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride); @@ -851,10 +853,10 @@ static void Blit16to16SurfaceAlpha128(SD } } -#ifdef __MMX__ +#ifdef SDL_MMX_INTRINSICS /* fast RGB565->RGB565 blending with surface alpha */ -static void Blit565to565SurfaceAlphaMMX(SDL_BlitInfo *info) +static void SDL_TARGETING("mmx") Blit565to565SurfaceAlphaMMX(SDL_BlitInfo *info) { unsigned alpha = info->a; if (alpha == 128) { @@ -992,7 +994,7 @@ static void Blit565to565SurfaceAlphaMMX( } /* fast RGB555->RGB555 blending with surface alpha */ -static void Blit555to555SurfaceAlphaMMX(SDL_BlitInfo *info) +static void SDL_TARGETING("mmx") Blit555to555SurfaceAlphaMMX(SDL_BlitInfo *info) { unsigned alpha = info->a; if (alpha == 128) { @@ -1129,7 +1131,7 @@ static void Blit555to555SurfaceAlphaMMX( } } -#endif /* __MMX__ */ +#endif /* SDL_MMX_INTRINSICS */ /* fast RGB565->RGB565 blending with surface alpha */ static void Blit565to565SurfaceAlpha(SDL_BlitInfo *info) @@ -1456,20 +1458,20 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surf case 4: if (sf->Rmask == df->Rmask && sf->Gmask == df->Gmask && sf->Bmask == df->Bmask && sf->BytesPerPixel == 4) { -#if defined(__MMX__) || defined(__3dNOW__) +#if defined(SDL_MMX_INTRINSICS) || defined(__3dNOW__) if (sf->Rshift % 8 == 0 && sf->Gshift % 8 == 0 && sf->Bshift % 8 == 0 && sf->Ashift % 8 == 0 && sf->Aloss == 0) { #ifdef __3dNOW__ if (SDL_Has3DNow()) { return BlitRGBtoRGBPixelAlphaMMX3DNOW; } #endif -#ifdef __MMX__ +#ifdef SDL_MMX_INTRINSICS if (SDL_HasMMX()) { return BlitRGBtoRGBPixelAlphaMMX; } #endif } -#endif /* __MMX__ || __3dNOW__ */ +#endif /* SDL_MMX_INTRINSICS || __3dNOW__ */ if (sf->Amask == 0xff000000) { #ifdef SDL_ARM_NEON_BLITTERS if (SDL_HasNEON()) { @@ -1511,7 +1513,7 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surf case 2: if (surface->map->identity) { if (df->Gmask == 0x7e0) { -#ifdef __MMX__ +#ifdef SDL_MMX_INTRINSICS if (SDL_HasMMX()) { return Blit565to565SurfaceAlphaMMX; } else @@ -1520,7 +1522,7 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surf return Blit565to565SurfaceAlpha; } } else if (df->Gmask == 0x3e0) { -#ifdef __MMX__ +#ifdef SDL_MMX_INTRINSICS if (SDL_HasMMX()) { return Blit555to555SurfaceAlphaMMX; } else @@ -1534,7 +1536,7 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surf case 4: if (sf->Rmask == df->Rmask && sf->Gmask == df->Gmask && sf->Bmask == df->Bmask && sf->BytesPerPixel == 4) { -#ifdef __MMX__ +#ifdef SDL_MMX_INTRINSICS if (sf->Rshift % 8 == 0 && sf->Gshift % 8 == 0 && sf->Bshift % 8 == 0 && SDL_HasMMX()) { return BlitRGBtoRGBSurfaceAlphaMMX; } diff -Nurp a/src/video/SDL_blit_copy.c b/src/video/SDL_blit_copy.c --- a/src/video/SDL_blit_copy.c 2025-01-01 16:47:53.000000000 +0100 +++ b/src/video/SDL_blit_copy.c 2026-11-07 11:16:26.296688761 +0100 @@ -23,10 +24,11 @@ #include "SDL_video.h" #include "SDL_blit.h" #include "SDL_blit_copy.h" +#include "../SDL_intrin.h" -#ifdef __SSE__ +#ifdef SDL_SSE_INTRINSICS /* This assumes 16-byte aligned src and dst */ -static SDL_INLINE void SDL_memcpySSE(Uint8 *dst, const Uint8 *src, int len) +static SDL_INLINE void SDL_TARGETING("sse") SDL_memcpySSE(Uint8 *dst, const Uint8 *src, int len) { int i; @@ -49,13 +51,13 @@ static SDL_INLINE void SDL_memcpySSE(Uin SDL_memcpy(dst, src, len & 63); } } -#endif /* __SSE__ */ +#endif /* SDL_SSE_INTRINSICS */ -#ifdef __MMX__ +#ifdef SDL_MMX_INTRINSICS #ifdef _MSC_VER #pragma warning(disable : 4799) #endif -static SDL_INLINE void SDL_memcpyMMX(Uint8 *dst, const Uint8 *src, int len) +static SDL_INLINE void SDL_TARGETING("mmx") SDL_memcpyMMX(Uint8 *dst, const Uint8 *src, int len) { int remain = len & 63; int i; @@ -86,7 +88,12 @@ static SDL_INLINE void SDL_memcpyMMX(Uin } } } -#endif /* __MMX__ */ + +static void SDL_TARGETING("mmx") SDL_EmptyMMX(void) +{ + _mm_empty(); +} +#endif /* SDL_MMX_INTRINSICS */ void SDL_BlitCopy(SDL_BlitInfo *info) { @@ -127,7 +134,7 @@ void SDL_BlitCopy(SDL_BlitInfo *info) return; } -#ifdef __SSE__ +#ifdef SDL_SSE_INTRINSICS if (SDL_HasSSE() && !((uintptr_t)src & 15) && !(srcskip & 15) && !((uintptr_t)dst & 15) && !(dstskip & 15)) { @@ -140,14 +147,14 @@ void SDL_BlitCopy(SDL_BlitInfo *info) } #endif -#ifdef __MMX__ +#ifdef SDL_MMX_INTRINSICS if (SDL_HasMMX() && !(srcskip & 7) && !(dstskip & 7)) { while (h--) { SDL_memcpyMMX(dst, src, w); src += srcskip; dst += dstskip; } - _mm_empty(); + SDL_EmptyMMX(); return; } #endif diff -Nurp a/src/video/SDL_fillrect.c b/src/video/SDL_fillrect.c --- a/src/video/SDL_fillrect.c 2025-01-01 16:47:53.000000000 +0100 +++ b/src/video/SDL_fillrect.c 2026-11-07 11:16:26.296761614 +0100 @@ -23,8 +24,9 @@ #include "SDL_video.h" #include "SDL_blit.h" #include "SDL_cpuinfo.h" +#include "../SDL_intrin.h" -#ifdef __SSE__ +#ifdef SDL_SSE_INTRINSICS /* *INDENT-OFF* */ /* clang-format off */ #if defined(_MSC_VER) && !defined(__clang__) @@ -57,7 +59,7 @@ #define SSE_END #define DEFINE_SSE_FILLRECT(bpp, type) \ -static void SDL_FillRect##bpp##SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \ +static void SDL_TARGETING("sse") SDL_FillRect##bpp##SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \ { \ int i, n; \ Uint8 *p = NULL; \ @@ -101,7 +103,7 @@ static void SDL_FillRect##bpp##SSE(Uint8 SSE_END; \ } -static void SDL_FillRect1SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) +static void SDL_TARGETING("sse") SDL_FillRect1SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) { int i, n; @@ -133,7 +135,7 @@ DEFINE_SSE_FILLRECT(2, Uint16) DEFINE_SSE_FILLRECT(4, Uint32) /* *INDENT-ON* */ /* clang-format on */ -#endif /* __SSE__ */ +#endif /* SDL_SSE_INTRINSICS */ static void SDL_FillRect1(Uint8 *pixels, int pitch, Uint32 color, int w, int h) { @@ -385,7 +387,7 @@ int SDL_FillRects(SDL_Surface *dst, cons { color |= (color << 8); color |= (color << 16); -#ifdef __SSE__ +#ifdef SDL_SSE_INTRINSICS if (SDL_HasSSE()) { fill_function = SDL_FillRect1SSE; break; @@ -398,7 +400,7 @@ int SDL_FillRects(SDL_Surface *dst, cons case 2: { color |= (color << 16); -#ifdef __SSE__ +#ifdef SDL_SSE_INTRINSICS if (SDL_HasSSE()) { fill_function = SDL_FillRect2SSE; break; @@ -417,7 +419,7 @@ int SDL_FillRects(SDL_Surface *dst, cons case 4: { -#ifdef __SSE__ +#ifdef SDL_SSE_INTRINSICS if (SDL_HasSSE()) { fill_function = SDL_FillRect4SSE; break; diff -Nurp a/src/video/SDL_stretch.c b/src/video/SDL_stretch.c --- a/src/video/SDL_stretch.c 2025-01-01 16:47:53.000000000 +0100 +++ b/src/video/SDL_stretch.c 2026-11-07 11:16:26.296881249 +0100 @@ -23,6 +24,7 @@ #include "SDL_video.h" #include "SDL_blit.h" #include "SDL_render.h" +#include "../SDL_intrin.h" static int SDL_LowerSoftStretchNearest(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect); static int SDL_LowerSoftStretchLinear(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect); @@ -337,7 +339,7 @@ static int scale_mat(const Uint32 *src, return 0; } -#if defined(__SSE2__) +#if defined(SDL_SSE2_INTRINSICS) #define HAVE_SSE2_INTRINSICS #endif @@ -377,7 +379,7 @@ static SDL_INLINE int hasSSE2(void) return val; } -static SDL_INLINE void INTERPOL_BILINEAR_SSE(const Uint32 *s0, const Uint32 *s1, int frac_w, __m128i v_frac_h0, __m128i v_frac_h1, Uint32 *dst, __m128i zero) +static SDL_INLINE void SDL_TARGETING("sse2") INTERPOL_BILINEAR_SSE(const Uint32 *s0, const Uint32 *s1, int frac_w, __m128i v_frac_h0, __m128i v_frac_h1, Uint32 *dst, __m128i zero) { __m128i x_00_01, x_10_11; /* Pixels in 4*uint8 in row */ __m128i v_frac_w0, k0, l0, d0, e0; @@ -414,7 +416,7 @@ static SDL_INLINE void INTERPOL_BILINEAR *dst = _mm_cvtsi128_si32(e0); } -static int scale_mat_SSE(const Uint32 *src, int src_w, int src_h, int src_pitch, Uint32 *dst, int dst_w, int dst_h, int dst_pitch) +static int SDL_TARGETING("sse2") scale_mat_SSE(const Uint32 *src, int src_w, int src_h, int src_pitch, Uint32 *dst, int dst_w, int dst_h, int dst_pitch) { BILINEAR___START diff -Nurp a/src/video/SDL_yuv.c b/src/video/SDL_yuv.c --- a/src/video/SDL_yuv.c 2025-01-01 16:47:53.000000000 +0100 +++ b/src/video/SDL_yuv.c 2026-11-07 11:16:26.297094690 +0100 @@ -26,6 +27,7 @@ #include "SDL_yuv_c.h" #include "yuv2rgb/yuv_rgb.h" +#include "../SDL_intrin.h" #define SDL_YUV_SD_THRESHOLD 576 @@ -312,7 +314,7 @@ static SDL_bool yuv_rgb_sse( Uint8 *rgb, Uint32 rgb_stride, YCbCrType yuv_type) { -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS if (!SDL_HasSSE2()) { return SDL_FALSE; } @@ -1104,6 +1106,27 @@ static int SDL_ConvertPixels_SwapUVPlane return 0; } +#ifdef SDL_SSE2_INTRINSICS +/* returns the number of UV pairs processed */ +static int SDL_TARGETING("sse2") SDL_PackUVPlanes_to_NV_Row_SSE2(const Uint8 *src1, const Uint8 *src2, Uint8 *dstUV, int x) +{ + int n = 0; + while (x - n >= 16) { + __m128i u = _mm_loadu_si128((__m128i *)src1); + __m128i v = _mm_loadu_si128((__m128i *)src2); + __m128i uv1 = _mm_unpacklo_epi8(u, v); + __m128i uv2 = _mm_unpackhi_epi8(u, v); + _mm_storeu_si128((__m128i *)dstUV, uv1); + _mm_storeu_si128((__m128i *)(dstUV + 16), uv2); + src1 += 16; + src2 += 16; + dstUV += 32; + n += 16; + } + return n; +} +#endif + static int SDL_ConvertPixels_PackUVPlanes_to_NV(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch, SDL_bool reverseUV) { int x, y; @@ -1116,7 +1139,7 @@ static int SDL_ConvertPixels_PackUVPlane const Uint8 *src1, *src2; Uint8 *dstUV; Uint8 *tmp = NULL; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS const SDL_bool use_SSE2 = SDL_HasSSE2(); #endif @@ -1146,20 +1169,13 @@ static int SDL_ConvertPixels_PackUVPlane y = UVheight; while (y--) { x = UVwidth; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS if (use_SSE2) { - while (x >= 16) { - __m128i u = _mm_loadu_si128((__m128i *)src1); - __m128i v = _mm_loadu_si128((__m128i *)src2); - __m128i uv1 = _mm_unpacklo_epi8(u, v); - __m128i uv2 = _mm_unpackhi_epi8(u, v); - _mm_storeu_si128((__m128i *)dstUV, uv1); - _mm_storeu_si128((__m128i *)(dstUV + 16), uv2); - src1 += 16; - src2 += 16; - dstUV += 32; - x -= 16; - } + const int n = SDL_PackUVPlanes_to_NV_Row_SSE2(src1, src2, dstUV, x); + src1 += n; + src2 += n; + dstUV += n * 2; + x -= n; } #endif while (x--) { @@ -1177,6 +1193,32 @@ static int SDL_ConvertPixels_PackUVPlane return 0; } +#ifdef SDL_SSE2_INTRINSICS +/* returns the number of UV pairs processed */ +static int SDL_TARGETING("sse2") SDL_SplitNV_to_UVPlanes_Row_SSE2(const Uint8 *srcUV, Uint8 *dst1, Uint8 *dst2, int x) +{ + const __m128i mask = _mm_set1_epi16(0x00FF); + int n = 0; + while (x - n >= 16) { + __m128i uv1 = _mm_loadu_si128((__m128i *)srcUV); + __m128i uv2 = _mm_loadu_si128((__m128i *)(srcUV + 16)); + __m128i u1 = _mm_and_si128(uv1, mask); + __m128i u2 = _mm_and_si128(uv2, mask); + __m128i u = _mm_packus_epi16(u1, u2); + __m128i v1 = _mm_srli_epi16(uv1, 8); + __m128i v2 = _mm_srli_epi16(uv2, 8); + __m128i v = _mm_packus_epi16(v1, v2); + _mm_storeu_si128((__m128i *)dst1, u); + _mm_storeu_si128((__m128i *)dst2, v); + srcUV += 32; + dst1 += 16; + dst2 += 16; + n += 16; + } + return n; +} +#endif + static int SDL_ConvertPixels_SplitNV_to_UVPlanes(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch, SDL_bool reverseUV) { int x, y; @@ -1189,7 +1231,7 @@ static int SDL_ConvertPixels_SplitNV_to_ const Uint8 *srcUV; Uint8 *dst1, *dst2; Uint8 *tmp = NULL; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS const SDL_bool use_SSE2 = SDL_HasSSE2(); #endif @@ -1219,25 +1261,13 @@ static int SDL_ConvertPixels_SplitNV_to_ y = UVheight; while (y--) { x = UVwidth; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS if (use_SSE2) { - __m128i mask = _mm_set1_epi16(0x00FF); - while (x >= 16) { - __m128i uv1 = _mm_loadu_si128((__m128i *)srcUV); - __m128i uv2 = _mm_loadu_si128((__m128i *)(srcUV + 16)); - __m128i u1 = _mm_and_si128(uv1, mask); - __m128i u2 = _mm_and_si128(uv2, mask); - __m128i u = _mm_packus_epi16(u1, u2); - __m128i v1 = _mm_srli_epi16(uv1, 8); - __m128i v2 = _mm_srli_epi16(uv2, 8); - __m128i v = _mm_packus_epi16(v1, v2); - _mm_storeu_si128((__m128i *)dst1, u); - _mm_storeu_si128((__m128i *)dst2, v); - srcUV += 32; - dst1 += 16; - dst2 += 16; - x -= 16; - } + const int n = SDL_SplitNV_to_UVPlanes_Row_SSE2(srcUV, dst1, dst2, x); + srcUV += n * 2; + dst1 += n; + dst2 += n; + x -= n; } #endif while (x--) { @@ -1255,6 +1285,25 @@ static int SDL_ConvertPixels_SplitNV_to_ return 0; } +#ifdef SDL_SSE2_INTRINSICS +/* returns the number of UV pairs processed */ +static int SDL_TARGETING("sse2") SDL_SwapNV_Row_SSE2(const Uint16 *srcUV, Uint16 *dstUV, int x) +{ + int n = 0; + while (x - n >= 8) { + __m128i uv = _mm_loadu_si128((__m128i *)srcUV); + __m128i v = _mm_slli_epi16(uv, 8); + __m128i u = _mm_srli_epi16(uv, 8); + __m128i vu = _mm_or_si128(v, u); + _mm_storeu_si128((__m128i *)dstUV, vu); + srcUV += 8; + dstUV += 8; + n += 8; + } + return n; +} +#endif + static int SDL_ConvertPixels_SwapNV(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) { int x, y; @@ -1266,7 +1315,7 @@ static int SDL_ConvertPixels_SwapNV(int const int dstUVPitchLeft = (dstUVPitch - UVwidth * 2) / sizeof(Uint16); const Uint16 *srcUV; Uint16 *dstUV; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS const SDL_bool use_SSE2 = SDL_HasSSE2(); #endif @@ -1279,18 +1328,12 @@ static int SDL_ConvertPixels_SwapNV(int y = UVheight; while (y--) { x = UVwidth; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS if (use_SSE2) { - while (x >= 8) { - __m128i uv = _mm_loadu_si128((__m128i *)srcUV); - __m128i v = _mm_slli_epi16(uv, 8); - __m128i u = _mm_srli_epi16(uv, 8); - __m128i vu = _mm_or_si128(v, u); - _mm_storeu_si128((__m128i *)dstUV, vu); - srcUV += 8; - dstUV += 8; - x -= 8; - } + const int n = SDL_SwapNV_Row_SSE2(srcUV, dstUV, x); + srcUV += n; + dstUV += n; + x -= n; } #endif while (x--) { @@ -1374,23 +1417,41 @@ static int SDL_ConvertPixels_Planar2x2_t SDL_GetPixelFormatName(dst_format)); } -#ifdef __SSE2__ -#define PACKED4_TO_PACKED4_ROW_SSE2(shuffle) \ - while (x >= 4) { \ - __m128i yuv = _mm_loadu_si128((__m128i *)srcYUV); \ - __m128i lo = _mm_unpacklo_epi8(yuv, _mm_setzero_si128()); \ - __m128i hi = _mm_unpackhi_epi8(yuv, _mm_setzero_si128()); \ - lo = _mm_shufflelo_epi16(lo, shuffle); \ - lo = _mm_shufflehi_epi16(lo, shuffle); \ - hi = _mm_shufflelo_epi16(hi, shuffle); \ - hi = _mm_shufflehi_epi16(hi, shuffle); \ - yuv = _mm_packus_epi16(lo, hi); \ - _mm_storeu_si128((__m128i *)dstYUV, yuv); \ - srcYUV += 16; \ - dstYUV += 16; \ - x -= 4; \ +#ifdef SDL_SSE2_INTRINSICS +/* row function returns the number of 4 byte pixel pairs processed */ +#define DEFINE_PACKED4_TO_PACKED4_ROW_SSE2(name, shuffle) \ + static int SDL_TARGETING("sse2") name(const Uint8 *srcYUV, Uint8 *dstYUV, int x) \ + { \ + int n = 0; \ + while (x - n >= 4) { \ + __m128i yuv = _mm_loadu_si128((__m128i *)srcYUV); \ + __m128i lo = _mm_unpacklo_epi8(yuv, _mm_setzero_si128()); \ + __m128i hi = _mm_unpackhi_epi8(yuv, _mm_setzero_si128()); \ + lo = _mm_shufflelo_epi16(lo, shuffle); \ + lo = _mm_shufflehi_epi16(lo, shuffle); \ + hi = _mm_shufflelo_epi16(hi, shuffle); \ + hi = _mm_shufflehi_epi16(hi, shuffle); \ + yuv = _mm_packus_epi16(lo, hi); \ + _mm_storeu_si128((__m128i *)dstYUV, yuv); \ + srcYUV += 16; \ + dstYUV += 16; \ + n += 4; \ + } \ + return n; \ + } + +DEFINE_PACKED4_TO_PACKED4_ROW_SSE2(SDL_Packed4_Row_2301_SSE2, _MM_SHUFFLE(2, 3, 0, 1)) +DEFINE_PACKED4_TO_PACKED4_ROW_SSE2(SDL_Packed4_Row_1230_SSE2, _MM_SHUFFLE(1, 2, 3, 0)) +DEFINE_PACKED4_TO_PACKED4_ROW_SSE2(SDL_Packed4_Row_0321_SSE2, _MM_SHUFFLE(0, 3, 2, 1)) +DEFINE_PACKED4_TO_PACKED4_ROW_SSE2(SDL_Packed4_Row_2103_SSE2, _MM_SHUFFLE(2, 1, 0, 3)) + +#define PACKED4_TO_PACKED4_ROW_SSE2(name) \ + { \ + const int n = name(srcYUV, dstYUV, x); \ + srcYUV += n * 4; \ + dstYUV += n * 4; \ + x -= n; \ } - #endif static int SDL_ConvertPixels_YUY2_to_UYVY(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) @@ -1401,16 +1462,16 @@ static int SDL_ConvertPixels_YUY2_to_UYV const int dstYUVPitchLeft = (dst_pitch - YUVwidth * 4); const Uint8 *srcYUV = (const Uint8 *)src; Uint8 *dstYUV = (Uint8 *)dst; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS const SDL_bool use_SSE2 = SDL_HasSSE2(); #endif y = height; while (y--) { x = YUVwidth; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS if (use_SSE2) { - PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(2, 3, 0, 1)); + PACKED4_TO_PACKED4_ROW_SSE2(SDL_Packed4_Row_2301_SSE2); } #endif while (x--) { @@ -1442,16 +1503,16 @@ static int SDL_ConvertPixels_YUY2_to_YVY const int dstYUVPitchLeft = (dst_pitch - YUVwidth * 4); const Uint8 *srcYUV = (const Uint8 *)src; Uint8 *dstYUV = (Uint8 *)dst; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS const SDL_bool use_SSE2 = SDL_HasSSE2(); #endif y = height; while (y--) { x = YUVwidth; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS if (use_SSE2) { - PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(1, 2, 3, 0)); + PACKED4_TO_PACKED4_ROW_SSE2(SDL_Packed4_Row_1230_SSE2); } #endif while (x--) { @@ -1483,16 +1544,16 @@ static int SDL_ConvertPixels_UYVY_to_YUY const int dstYUVPitchLeft = (dst_pitch - YUVwidth * 4); const Uint8 *srcYUV = (const Uint8 *)src; Uint8 *dstYUV = (Uint8 *)dst; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS const SDL_bool use_SSE2 = SDL_HasSSE2(); #endif y = height; while (y--) { x = YUVwidth; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS if (use_SSE2) { - PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(2, 3, 0, 1)); + PACKED4_TO_PACKED4_ROW_SSE2(SDL_Packed4_Row_2301_SSE2); } #endif while (x--) { @@ -1524,16 +1585,16 @@ static int SDL_ConvertPixels_UYVY_to_YVY const int dstYUVPitchLeft = (dst_pitch - YUVwidth * 4); const Uint8 *srcYUV = (const Uint8 *)src; Uint8 *dstYUV = (Uint8 *)dst; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS const SDL_bool use_SSE2 = SDL_HasSSE2(); #endif y = height; while (y--) { x = YUVwidth; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS if (use_SSE2) { - PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(0, 3, 2, 1)); + PACKED4_TO_PACKED4_ROW_SSE2(SDL_Packed4_Row_0321_SSE2); } #endif while (x--) { @@ -1565,16 +1626,16 @@ static int SDL_ConvertPixels_YVYU_to_YUY const int dstYUVPitchLeft = (dst_pitch - YUVwidth * 4); const Uint8 *srcYUV = (const Uint8 *)src; Uint8 *dstYUV = (Uint8 *)dst; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS const SDL_bool use_SSE2 = SDL_HasSSE2(); #endif y = height; while (y--) { x = YUVwidth; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS if (use_SSE2) { - PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(1, 2, 3, 0)); + PACKED4_TO_PACKED4_ROW_SSE2(SDL_Packed4_Row_1230_SSE2); } #endif while (x--) { @@ -1606,16 +1667,16 @@ static int SDL_ConvertPixels_YVYU_to_UYV const int dstYUVPitchLeft = (dst_pitch - YUVwidth * 4); const Uint8 *srcYUV = (const Uint8 *)src; Uint8 *dstYUV = (Uint8 *)dst; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS const SDL_bool use_SSE2 = SDL_HasSSE2(); #endif y = height; while (y--) { x = YUVwidth; -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS if (use_SSE2) { - PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(2, 1, 0, 3)); + PACKED4_TO_PACKED4_ROW_SSE2(SDL_Packed4_Row_2103_SSE2); } #endif while (x--) { diff -Nurp a/src/video/yuv2rgb/yuv_rgb_sse.c b/src/video/yuv2rgb/yuv_rgb_sse.c --- a/src/video/yuv2rgb/yuv_rgb_sse.c 2024-01-19 02:06:27.000000000 +0100 +++ b/src/video/yuv2rgb/yuv_rgb_sse.c 2026-11-07 11:16:26.297290038 +0100 @@ -7,9 +8,10 @@ #include "yuv_rgb_internal.h" #include "SDL_cpuinfo.h" +#include "../../SDL_intrin.h" /*#include */ -#ifdef __SSE2__ +#ifdef SDL_SSE2_INTRINSICS /* SDL doesn't use these atm and compiling them adds seconds onto the build. --ryan. #define SSE_FUNCTION_NAME yuv420_rgb565_sse @@ -459,6 +461,6 @@ void rgb24_yuv420_sseu(uint32_t width, u } */ -#endif //__SSE2__ +#endif //SDL_SSE2_INTRINSICS #endif /* SDL_HAVE_YUV */ diff -Nurp a/src/video/yuv2rgb/yuv_rgb_sse_func.h b/src/video/yuv2rgb/yuv_rgb_sse_func.h --- a/src/video/yuv2rgb/yuv_rgb_sse_func.h 2024-01-03 15:07:50.000000000 +0100 +++ b/src/video/yuv2rgb/yuv_rgb_sse_func.h 2026-11-07 11:16:26.297381523 +0100 @@ -382,7 +383,7 @@ PACK_RGB24_32_STEP1(R1, R2, G1, G2, B1, \ -void SSE_FUNCTION_NAME(uint32_t width, uint32_t height, +void SDL_TARGETING("sse2") SSE_FUNCTION_NAME(uint32_t width, uint32_t height, const uint8_t *Y, const uint8_t *U, const uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, uint8_t *RGB, uint32_t RGB_stride, YCbCrType yuv_type)