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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
diff --git a/include/SDL_cpuinfo.h b/include/SDL_cpuinfo.h
index 6d72bbb..96099a2 100644
--- a/include/SDL_cpuinfo.h
+++ b/include/SDL_cpuinfo.h
@@ -135,6 +135,11 @@ extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE41(void);
extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE42(void);
/**
+ * This function returns true if the CPU has AVX features.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX(void);
+
+/**
* This function returns the amount of RAM configured in the system, in MB.
*/
extern DECLSPEC int SDLCALL SDL_GetSystemRAM(void);
diff --git a/src/cpuinfo/SDL_cpuinfo.c b/src/cpuinfo/SDL_cpuinfo.c
index c73dd80..ebd21bd 100644
--- a/src/cpuinfo/SDL_cpuinfo.c
+++ b/src/cpuinfo/SDL_cpuinfo.c
@@ -18,7 +18,11 @@
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
+#ifdef TEST_MAIN
+#include "SDL_config.h"
+#else
#include "../SDL_internal.h"
+#endif
#if defined(__WIN32__)
#include "../core/windows/SDL_windows.h"
@@ -55,6 +59,7 @@
#define CPU_HAS_SSE3 0x00000040
#define CPU_HAS_SSE41 0x00000100
#define CPU_HAS_SSE42 0x00000200
+#define CPU_HAS_AVX 0x00000400
#if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__
/* This is the brute force way of detecting instruction sets...
@@ -329,6 +334,21 @@ CPU_haveSSE42(void)
return 0;
}
+static SDL_INLINE int
+CPU_haveAVX(void)
+{
+ if (CPU_haveCPUID()) {
+ int a, b, c, d;
+
+ cpuid(1, a, b, c, d);
+ if (a >= 1) {
+ cpuid(1, a, b, c, d);
+ return (c & 0x10000000);
+ }
+ }
+ return 0;
+}
+
static int SDL_CPUCount = 0;
int
@@ -523,6 +543,9 @@ SDL_GetCPUFeatures(void)
if (CPU_haveSSE42()) {
SDL_CPUFeatures |= CPU_HAS_SSE42;
}
+ if (CPU_haveAVX()) {
+ SDL_CPUFeatures |= CPU_HAS_AVX;
+ }
}
return SDL_CPUFeatures;
}
@@ -608,6 +631,15 @@ SDL_HasSSE42(void)
return SDL_FALSE;
}
+SDL_bool
+SDL_HasAVX(void)
+{
+ if (SDL_GetCPUFeatures() & CPU_HAS_AVX) {
+ return SDL_TRUE;
+ }
+ return SDL_FALSE;
+}
+
static int SDL_SystemRAM = 0;
int
@@ -673,6 +705,7 @@ main()
printf("SSE3: %d\n", SDL_HasSSE3());
printf("SSE4.1: %d\n", SDL_HasSSE41());
printf("SSE4.2: %d\n", SDL_HasSSE42());
+ printf("AVX: %d\n", SDL_HasAVX());
printf("RAM: %d MB\n", SDL_GetSystemRAM());
return 0;
}
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index f58dde0..2d683b6 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -571,3 +571,4 @@
#define SDL_vsscanf SDL_vsscanf_REAL
#define SDL_GameControllerAddMappingsFromRW SDL_GameControllerAddMappingsFromRW_REAL
#define SDL_GL_ResetAttributes SDL_GL_ResetAttributes_REAL
+#define SDL_HasAVX SDL_HasAVX_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 8291d22..93bcf45 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -600,3 +600,4 @@ SDL_DYNAPI_PROC(void,SDL_GL_DeleteContext,(SDL_GLContext a),(a),)
SDL_DYNAPI_PROC(int,SDL_vsscanf,(const char *a, const char *b, va_list c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_GameControllerAddMappingsFromRW,(SDL_RWops *a, int b),(a,b),return)
SDL_DYNAPI_PROC(void,SDL_GL_ResetAttributes,(void),(),)
+SDL_DYNAPI_PROC(SDL_bool,SDL_HasAVX,(void),(),return)
diff --git a/test/testautomation_platform.c b/test/testautomation_platform.c
index 19896b4..ba7d303 100644
--- a/test/testautomation_platform.c
+++ b/test/testautomation_platform.c
@@ -163,6 +163,7 @@ int platform_testGetFunctions (void *arg)
* http://wiki.libsdl.org/moin.cgi/SDL_HasSSE3
* http://wiki.libsdl.org/moin.cgi/SDL_HasSSE41
* http://wiki.libsdl.org/moin.cgi/SDL_HasSSE42
+ * http://wiki.libsdl.org/moin.cgi/SDL_HasAVX
*/
int platform_testHasFunctions (void *arg)
{
@@ -197,6 +198,9 @@ int platform_testHasFunctions (void *arg)
ret = SDL_HasSSE42();
SDLTest_AssertPass("SDL_HasSSE42()");
+ ret = SDL_HasAVX();
+ SDLTest_AssertPass("SDL_HasAVX()");
+
return TEST_COMPLETED;
}
diff --git a/test/testplatform.c b/test/testplatform.c
index a8ed39d..d3da8a7 100644
--- a/test/testplatform.c
+++ b/test/testplatform.c
@@ -153,6 +153,7 @@ TestCPUInfo(SDL_bool verbose)
SDL_Log("SSE3 %s\n", SDL_HasSSE3()? "detected" : "not detected");
SDL_Log("SSE4.1 %s\n", SDL_HasSSE41()? "detected" : "not detected");
SDL_Log("SSE4.2 %s\n", SDL_HasSSE42()? "detected" : "not detected");
+ SDL_Log("AVX %s\n", SDL_HasAVX()? "detected" : "not detected");
SDL_Log("System RAM %d MB\n", SDL_GetSystemRAM());
}
return (0);