Fixed bug 2376 - no SDL_HasAVX
authorSam Lantinga <slouken@libsdl.org>
Sun, 02 Feb 2014 00:33:31 -0800
changeset 814856ba41ac64fe
parent 8147 9802c269104f
child 8149 681eb46b8ac4
Fixed bug 2376 - no SDL_HasAVX

Haneef Mubarak

AVX is the successor to SSE* and is fairly widely available. As such, it really ought to be detectable.

This functionality ought to be trivial to implement, and not having it means being forced to write an ugly workaround to check for AVX (so that normal SSE can be used if AVX is not available).

Here is an example on detecting AVX from SO (it actually shows ways to cehck for all of teh fancy instructions):

http://stackoverflow.com/questions/6121792/how-to-check-if-a-cpu-supports-the-sse3-instruction-set
include/SDL_cpuinfo.h
src/cpuinfo/SDL_cpuinfo.c
src/dynapi/SDL_dynapi_overrides.h
src/dynapi/SDL_dynapi_procs.h
test/testautomation_platform.c
test/testplatform.c
     1.1 --- a/include/SDL_cpuinfo.h	Thu Jan 30 20:29:58 2014 -0300
     1.2 +++ b/include/SDL_cpuinfo.h	Sun Feb 02 00:33:31 2014 -0800
     1.3 @@ -135,6 +135,11 @@
     1.4  extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE42(void);
     1.5  
     1.6  /**
     1.7 + *  This function returns true if the CPU has AVX features.
     1.8 + */
     1.9 +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX(void);
    1.10 +
    1.11 +/**
    1.12   *  This function returns the amount of RAM configured in the system, in MB.
    1.13   */
    1.14  extern DECLSPEC int SDLCALL SDL_GetSystemRAM(void);
     2.1 --- a/src/cpuinfo/SDL_cpuinfo.c	Thu Jan 30 20:29:58 2014 -0300
     2.2 +++ b/src/cpuinfo/SDL_cpuinfo.c	Sun Feb 02 00:33:31 2014 -0800
     2.3 @@ -18,7 +18,11 @@
     2.4       misrepresented as being the original software.
     2.5    3. This notice may not be removed or altered from any source distribution.
     2.6  */
     2.7 +#ifdef TEST_MAIN
     2.8 +#include "SDL_config.h"
     2.9 +#else
    2.10  #include "../SDL_internal.h"
    2.11 +#endif
    2.12  
    2.13  #if defined(__WIN32__)
    2.14  #include "../core/windows/SDL_windows.h"
    2.15 @@ -55,6 +59,7 @@
    2.16  #define CPU_HAS_SSE3    0x00000040
    2.17  #define CPU_HAS_SSE41   0x00000100
    2.18  #define CPU_HAS_SSE42   0x00000200
    2.19 +#define CPU_HAS_AVX     0x00000400
    2.20  
    2.21  #if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__
    2.22  /* This is the brute force way of detecting instruction sets...
    2.23 @@ -329,6 +334,21 @@
    2.24      return 0;
    2.25  }
    2.26  
    2.27 +static SDL_INLINE int
    2.28 +CPU_haveAVX(void)
    2.29 +{
    2.30 +    if (CPU_haveCPUID()) {
    2.31 +        int a, b, c, d;
    2.32 +
    2.33 +        cpuid(1, a, b, c, d);
    2.34 +        if (a >= 1) {
    2.35 +            cpuid(1, a, b, c, d);
    2.36 +            return (c & 0x10000000);
    2.37 +        }
    2.38 +    }
    2.39 +    return 0;
    2.40 +}
    2.41 +
    2.42  static int SDL_CPUCount = 0;
    2.43  
    2.44  int
    2.45 @@ -523,6 +543,9 @@
    2.46          if (CPU_haveSSE42()) {
    2.47              SDL_CPUFeatures |= CPU_HAS_SSE42;
    2.48          }
    2.49 +        if (CPU_haveAVX()) {
    2.50 +            SDL_CPUFeatures |= CPU_HAS_AVX;
    2.51 +        }
    2.52      }
    2.53      return SDL_CPUFeatures;
    2.54  }
    2.55 @@ -608,6 +631,15 @@
    2.56      return SDL_FALSE;
    2.57  }
    2.58  
    2.59 +SDL_bool
    2.60 +SDL_HasAVX(void)
    2.61 +{
    2.62 +    if (SDL_GetCPUFeatures() & CPU_HAS_AVX) {
    2.63 +        return SDL_TRUE;
    2.64 +    }
    2.65 +    return SDL_FALSE;
    2.66 +}
    2.67 +
    2.68  static int SDL_SystemRAM = 0;
    2.69  
    2.70  int
    2.71 @@ -673,6 +705,7 @@
    2.72      printf("SSE3: %d\n", SDL_HasSSE3());
    2.73      printf("SSE4.1: %d\n", SDL_HasSSE41());
    2.74      printf("SSE4.2: %d\n", SDL_HasSSE42());
    2.75 +    printf("AVX: %d\n", SDL_HasAVX());
    2.76      printf("RAM: %d MB\n", SDL_GetSystemRAM());
    2.77      return 0;
    2.78  }
     3.1 --- a/src/dynapi/SDL_dynapi_overrides.h	Thu Jan 30 20:29:58 2014 -0300
     3.2 +++ b/src/dynapi/SDL_dynapi_overrides.h	Sun Feb 02 00:33:31 2014 -0800
     3.3 @@ -571,3 +571,4 @@
     3.4  #define SDL_vsscanf SDL_vsscanf_REAL
     3.5  #define SDL_GameControllerAddMappingsFromRW SDL_GameControllerAddMappingsFromRW_REAL
     3.6  #define SDL_GL_ResetAttributes SDL_GL_ResetAttributes_REAL
     3.7 +#define SDL_HasAVX SDL_HasAVX_REAL
     4.1 --- a/src/dynapi/SDL_dynapi_procs.h	Thu Jan 30 20:29:58 2014 -0300
     4.2 +++ b/src/dynapi/SDL_dynapi_procs.h	Sun Feb 02 00:33:31 2014 -0800
     4.3 @@ -600,3 +600,4 @@
     4.4  SDL_DYNAPI_PROC(int,SDL_vsscanf,(const char *a, const char *b, va_list c),(a,b,c),return)
     4.5  SDL_DYNAPI_PROC(int,SDL_GameControllerAddMappingsFromRW,(SDL_RWops *a, int b),(a,b),return)
     4.6  SDL_DYNAPI_PROC(void,SDL_GL_ResetAttributes,(void),(),)
     4.7 +SDL_DYNAPI_PROC(SDL_bool,SDL_HasAVX,(void),(),return)
     5.1 --- a/test/testautomation_platform.c	Thu Jan 30 20:29:58 2014 -0300
     5.2 +++ b/test/testautomation_platform.c	Sun Feb 02 00:33:31 2014 -0800
     5.3 @@ -163,6 +163,7 @@
     5.4   * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE3
     5.5   * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE41
     5.6   * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE42
     5.7 + * http://wiki.libsdl.org/moin.cgi/SDL_HasAVX
     5.8   */
     5.9  int platform_testHasFunctions (void *arg)
    5.10  {
    5.11 @@ -197,6 +198,9 @@
    5.12     ret = SDL_HasSSE42();
    5.13     SDLTest_AssertPass("SDL_HasSSE42()");
    5.14  
    5.15 +   ret = SDL_HasAVX();
    5.16 +   SDLTest_AssertPass("SDL_HasAVX()");
    5.17 +
    5.18     return TEST_COMPLETED;
    5.19  }
    5.20  
     6.1 --- a/test/testplatform.c	Thu Jan 30 20:29:58 2014 -0300
     6.2 +++ b/test/testplatform.c	Sun Feb 02 00:33:31 2014 -0800
     6.3 @@ -153,6 +153,7 @@
     6.4          SDL_Log("SSE3 %s\n", SDL_HasSSE3()? "detected" : "not detected");
     6.5          SDL_Log("SSE4.1 %s\n", SDL_HasSSE41()? "detected" : "not detected");
     6.6          SDL_Log("SSE4.2 %s\n", SDL_HasSSE42()? "detected" : "not detected");
     6.7 +        SDL_Log("AVX %s\n", SDL_HasAVX()? "detected" : "not detected");
     6.8          SDL_Log("System RAM %d MB\n", SDL_GetSystemRAM());
     6.9      }
    6.10      return (0);