Skip to content

Commit

Permalink
cmake: Detect AVX + allow build system to disable Intel intrinsics
Browse files Browse the repository at this point in the history
  • Loading branch information
madebr committed Mar 15, 2023
1 parent 683411e commit 4681240
Show file tree
Hide file tree
Showing 16 changed files with 175 additions and 116 deletions.
72 changes: 67 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ option_string(SDL_ASSERTIONS "Enable internal sanity checks (auto/disabled/relea
#set_option(SDL_DEPENDENCY_TRACKING "Use gcc -MMD -MT dependency tracking" ON)
set_option(SDL_ASSEMBLY "Enable assembly routines" ${SDL_ASSEMBLY_DEFAULT})
dep_option(SDL_SSEMATH "Allow GCC to use SSE floating point math" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF)
dep_option(SDL_AVX "Use AVX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF)
dep_option(SDL_SSE "Use SSE assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF)
dep_option(SDL_SSE2 "Use SSE2 assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF)
dep_option(SDL_SSE3 "Use SSE3 assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF)
Expand Down Expand Up @@ -711,6 +712,32 @@ if(SDL_ASSEMBLY)
# TODO: Those all seem to be quite GCC specific - needs to be
# reworked for better compiler support
set(HAVE_ASSEMBLY TRUE)

if(SDL_AVX)
cmake_push_check_state()
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -mavx")
check_c_source_compiles("
#ifdef __MINGW32__
#include <_mingw.h>
#ifdef __MINGW64_VERSION_MAJOR
#include <intrin.h>
#else
#include <immintrin.h>
#endif
#else
#include <immintrin.h>
#endif
#ifndef __AVX__
#error Assembler CPP flag not enabled
#endif
int main(int argc, char **argv) { return 0; }" CPU_SUPPORTS_AVX)
cmake_pop_check_state()
if(CPU_SUPPORTS_AVX)
set(HAVE_AVX TRUE)
target_compile_options(sdl-build-options INTERFACE "-mavx")
endif()
endif()

if(SDL_MMX)
cmake_push_check_state()
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -mmmx")
Expand All @@ -728,9 +755,10 @@ if(SDL_ASSEMBLY)
#ifndef __MMX__
#error Assembler CPP flag not enabled
#endif
int main(int argc, char **argv) { return 0; }" HAVE_MMX)
int main(int argc, char **argv) { return 0; }" CPU_SUPPORTS_MMX)
cmake_pop_check_state()
if(HAVE_MMX)
if(CPU_SUPPORTS_MMX)
set(HAVE_MMX TRUE)
target_compile_options(sdl-build-options INTERFACE "-mmmx")
endif()
endif()
Expand Down Expand Up @@ -823,8 +851,6 @@ if(SDL_ASSEMBLY)
set(HAVE_SSEMATH TRUE)
endif()

check_include_file("immintrin.h" HAVE_IMMINTRIN_H)

if(SDL_ALTIVEC)
cmake_push_check_state()
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -maltivec")
Expand Down Expand Up @@ -954,10 +980,46 @@ if(SDL_ASSEMBLY)
if(SDL_SSE3)
set(HAVE_SSE3 TRUE)
endif()
check_include_file("immintrin.h" HAVE_IMMINTRIN_H)
if(SDL_AVX)
cmake_push_check_state()
# FIXME: should be CMAKE_REQUIRED_LINK_OPTIONS for CMake 3.14+
list(APPEND CMAKE_REQUIRED_LIBRARIES "/ARCH:AVX")
check_c_source_compiles("
#include <immintrin.h>
#ifndef __AVX__
#error Assembler CPP flag not enabled
#endif
int main(int argc, char **argv) { return 0; }" CPU_SUPPORTS_AVX)
cmake_pop_check_state()
if(CPU_SUPPORTS_AVX)
# FIXME: should be target_link_options for CMake 3.13+
target_link_libraries(sdl-build-options INTERFACE "/ARCH:AVX")
set(HAVE_AVX TRUE)
endif()
endif()
endif()
endif()

if(NOT HAVE_AVX)
set(SDL_DISABLE_AVX 1)
endif()

if(NOT HAVE_MMX)
set(SDL_DISABLE_MMX 1)
endif()

if(NOT HAVE_SSE)
set(SDL_DISABLE_SSE 1)
endif()

if(NOT HAVE_SSE2)
set(SDL_DISABLE_SSE2 1)
endif()

if(NOT HAVE_SSE3)
set(SDL_DISABLE_SSE3 1)
endif()

# TODO: Can't deactivate on FreeBSD? w/o LIBC, SDL_stdinc.h can't define
# anything.
if(SDL_LIBC)
Expand Down
13 changes: 6 additions & 7 deletions include/SDL3/SDL_intrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,21 +101,20 @@ _m_prefetch(void *__P)
#include <lasxintrin.h>
#define __LASX__
#endif
#if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H)
#if defined(__AVX__) && !defined(SDL_DISABLE_AVX)
#include <immintrin.h>
#else
#if defined(__MMX__) && !defined(SDL_DISABLE_MMINTRIN_H)
#endif
#if defined(__MMX__) && !defined(SDL_DISABLE_MMX)
#include <mmintrin.h>
#endif
#if defined(__SSE__) && !defined(SDL_DISABLE_XMMINTRIN_H)
#if defined(__SSE__) && !defined(SDL_DISABLE_SSE)
#include <xmmintrin.h>
#endif
#if defined(__SSE2__) && !defined(SDL_DISABLE_EMMINTRIN_H)
#if defined(__SSE2__) && !defined(SDL_DISABLE_SSE2)
#include <emmintrin.h>
#endif
#if defined(__SSE3__) && !defined(SDL_DISABLE_PMMINTRIN_H)
#if defined(__SSE3__) && !defined(SDL_DISABLE_SSE3)
#include <pmmintrin.h>
#endif
#endif /* HAVE_IMMINTRIN_H */

#endif /* SDL_intrin_h_ */
19 changes: 7 additions & 12 deletions include/build_config/SDL_build_config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -226,18 +226,6 @@
#cmakedefine HAVE_LIBUSB 1
#cmakedefine HAVE_O_CLOEXEC 1

/* Apple platforms might be building universal binaries, where Intel builds
can use immintrin.h but other architectures can't. */
#ifdef __APPLE__
# if defined(__has_include) && (defined(__i386__) || defined(__x86_64))
# if __has_include(<immintrin.h>)
# define HAVE_IMMINTRIN_H 1
# endif
# endif
#else /* non-Apple platforms can use the normal CMake check for this. */
#cmakedefine HAVE_IMMINTRIN_H 1
#endif

#cmakedefine HAVE_LIBUDEV_H 1
#cmakedefine HAVE_LIBSAMPLERATE_H 1
#cmakedefine HAVE_LIBDECOR_H 1
Expand Down Expand Up @@ -597,4 +585,11 @@ typedef unsigned int uintptr_t;
#endif /* Visual Studio 2008 */
#endif /* !_STDINT_H_ && !HAVE_STDINT_H */

/* Configure use of intrinsics */

#cmakedefine SDL_DISABLE_SSE 1
#cmakedefine SDL_DISABLE_SSE2 1
#cmakedefine SDL_DISABLE_SSE3 1
#cmakedefine SDL_DISABLE_AVX 1

#endif /* SDL_build_config_h_ */
4 changes: 2 additions & 2 deletions include/build_config/SDL_build_config_macos.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@
#define HAVE_SYSCTLBYNAME 1

#if defined(__has_include) && (defined(__i386__) || defined(__x86_64))
# if __has_include(<immintrin.h>)
# define HAVE_IMMINTRIN_H 1
# if !__has_include(<immintrin.h>)
# define SDL_DISABLE_AVX 1
# endif
#endif

Expand Down
7 changes: 4 additions & 3 deletions include/build_config/SDL_build_config_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,12 @@ typedef unsigned int uintptr_t;
#define HAVE_TPCSHRD_H 1
#define HAVE_SENSORSAPI_H 1
#if (defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64)) && (defined(_MSC_VER) && _MSC_VER >= 1600)
#define HAVE_IMMINTRIN_H 1
#elif defined(__has_include) && (defined(__i386__) || defined(__x86_64))
# if __has_include(<immintrin.h>)
# define HAVE_IMMINTRIN_H 1
# if !__has_include(<immintrin.h>)
# define SDL_DISABLE_AVX 1
# endif
#else
# define SDL_DISABLE_AVX 1
#endif

/* This is disabled by default to avoid C runtime dependencies and manifest requirements */
Expand Down
7 changes: 4 additions & 3 deletions include/build_config/SDL_build_config_wingdk.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@
#define HAVE_TPCSHRD_H 1
#define HAVE_SENSORSAPI_H 1
#if (defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64)) && (defined(_MSC_VER) && _MSC_VER >= 1600)
#define HAVE_IMMINTRIN_H 1
#elif defined(__has_include) && (defined(__i386__) || defined(__x86_64))
# if __has_include(<immintrin.h>)
# define HAVE_IMMINTRIN_H 1
# if !__has_include(<immintrin.h>)
# define SDL_DISABLE_AVX 1
# endif
#else
# define SDL_DISABLE_AVX 1
#endif

/* This is disabled by default to avoid C runtime dependencies and manifest requirements */
Expand Down
7 changes: 4 additions & 3 deletions include/build_config/SDL_build_config_xbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@
/*#define HAVE_TPCSHRD_H 1*/
/*#define HAVE_SENSORSAPI_H 1*/
#if (defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64)) && (defined(_MSC_VER) && _MSC_VER >= 1600)
#define HAVE_IMMINTRIN_H 1
#elif defined(__has_include) && (defined(__i386__) || defined(__x86_64))
# if __has_include(<immintrin.h>)
# define HAVE_IMMINTRIN_H 1
# if !__has_include(<immintrin.h>)
# define SDL_DISABLE_AVX 1
# endif
#else
# define SDL_DISABLE_AVX 1
#endif

/* This is disabled by default to avoid C runtime dependencies and manifest requirements */
Expand Down
40 changes: 40 additions & 0 deletions src/SDL_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,46 @@

#include <SDL3/SDL.h>
#include <SDL3/SDL_intrin.h>


#ifdef __ARM_NEON
#define HAVE_NEON_INTRINSICS 1
#endif

#if defined(__MMX__) && !defined(SDL_DISABLE_MMX)
#define HAVE_MMX_INTRINSICS 1
#endif

#if defined(__SSE__) && !defined(SDL_DISABLE_SSE)
#define HAVE_SSE_INTRINSICS 1
#endif

#if defined(__SSE2__) && !defined(SDL_DISABLE_SSE2)
#define HAVE_SSE2_INTRINSICS 1
#endif

#if defined(__SSE3__) && !defined(SDL_DISABLE_SSE3)
#define HAVE_SSE3_INTRINSICS 1
#endif

#if defined(__AVX__) && !defined(SDL_DISABLE_AVX)
#define HAVE_AVX_INTRINSICS 1
#endif

#if defined __clang__
#if (!__has_attribute(target))
#undef HAVE_AVX_INTRINSICS
#endif
#if (defined(_MSC_VER) || defined(__SCE__)) && !defined(__AVX__)
#undef HAVE_AVX_INTRINSICS
#endif
#elif defined __GNUC__
#if (__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 9)
#undef HAVE_AVX_INTRINSICS
#endif
#endif


#define SDL_MAIN_NOIMPL /* don't drag in header-only implementation of SDL_main */
#include <SDL3/SDL_main.h>

Expand Down
29 changes: 0 additions & 29 deletions src/audio/SDL_audiocvt.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,35 +29,6 @@

#define DEBUG_AUDIOSTREAM 0

#ifdef __ARM_NEON
#define HAVE_NEON_INTRINSICS 1
#endif

#ifdef __SSE__
#define HAVE_SSE_INTRINSICS 1
#endif

#ifdef __SSE3__
#define HAVE_SSE3_INTRINSICS 1
#endif

#if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H)
#define HAVE_AVX_INTRINSICS 1
#endif
#if defined __clang__
#if (!__has_attribute(target))
#undef HAVE_AVX_INTRINSICS
#endif
#if (defined(_MSC_VER) || defined(__SCE__)) && !defined(__AVX__)
#undef HAVE_AVX_INTRINSICS
#endif
#elif defined __GNUC__
#if (__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 9)
#undef HAVE_AVX_INTRINSICS
#endif
#endif


/**
* Initialize an SDL_AudioCVT structure for conversion.
*
Expand Down
4 changes: 0 additions & 4 deletions src/audio/SDL_audiotypecvt.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@
#define HAVE_NEON_INTRINSICS 1
#endif

#ifdef __SSE2__
#define HAVE_SSE2_INTRINSICS 1
#endif

#if defined(__x86_64__) && HAVE_SSE2_INTRINSICS
#define NEED_SCALAR_CONVERTER_FALLBACKS 0 /* x86_64 guarantees SSE2. */
#elif __MACOS__ && HAVE_SSE2_INTRINSICS
Expand Down
Loading

0 comments on commit 4681240

Please sign in to comment.