src/cpuinfo/SDL_cpuinfo.c
changeset 11984 987c5dc71309
parent 11811 5d94cb6b24d3
child 11985 36aa0bf7312b
equal deleted inserted replaced
11983:3a50eb90e4b2 11984:987c5dc71309
    36 #endif
    36 #endif
    37 
    37 
    38 /* CPU feature detection for SDL */
    38 /* CPU feature detection for SDL */
    39 
    39 
    40 #include "SDL_cpuinfo.h"
    40 #include "SDL_cpuinfo.h"
       
    41 #include "SDL_assert.h"
    41 
    42 
    42 #ifdef HAVE_SYSCONF
    43 #ifdef HAVE_SYSCONF
    43 #include <unistd.h>
    44 #include <unistd.h>
    44 #endif
    45 #endif
    45 #ifdef HAVE_SYSCTLBYNAME
    46 #ifdef HAVE_SYSCTLBYNAME
   569         return SDL_CACHELINE_SIZE;
   570         return SDL_CACHELINE_SIZE;
   570     }
   571     }
   571 }
   572 }
   572 
   573 
   573 static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
   574 static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
       
   575 static Uint32 SDL_SIMDAlignment = 0xFFFFFFFF;
   574 
   576 
   575 static Uint32
   577 static Uint32
   576 SDL_GetCPUFeatures(void)
   578 SDL_GetCPUFeatures(void)
   577 {
   579 {
   578     if (SDL_CPUFeatures == 0xFFFFFFFF) {
   580     if (SDL_CPUFeatures == 0xFFFFFFFF) {
   579         CPU_calcCPUIDFeatures();
   581         CPU_calcCPUIDFeatures();
   580         SDL_CPUFeatures = 0;
   582         SDL_CPUFeatures = 0;
       
   583         SDL_SIMDAlignment = 4;  /* a good safe base value */
   581         if (CPU_haveRDTSC()) {
   584         if (CPU_haveRDTSC()) {
   582             SDL_CPUFeatures |= CPU_HAS_RDTSC;
   585             SDL_CPUFeatures |= CPU_HAS_RDTSC;
   583         }
   586         }
   584         if (CPU_haveAltiVec()) {
   587         if (CPU_haveAltiVec()) {
   585             SDL_CPUFeatures |= CPU_HAS_ALTIVEC;
   588             SDL_CPUFeatures |= CPU_HAS_ALTIVEC;
       
   589             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
   586         }
   590         }
   587         if (CPU_haveMMX()) {
   591         if (CPU_haveMMX()) {
   588             SDL_CPUFeatures |= CPU_HAS_MMX;
   592             SDL_CPUFeatures |= CPU_HAS_MMX;
       
   593             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 8);
   589         }
   594         }
   590         if (CPU_have3DNow()) {
   595         if (CPU_have3DNow()) {
   591             SDL_CPUFeatures |= CPU_HAS_3DNOW;
   596             SDL_CPUFeatures |= CPU_HAS_3DNOW;
       
   597             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 8);
   592         }
   598         }
   593         if (CPU_haveSSE()) {
   599         if (CPU_haveSSE()) {
   594             SDL_CPUFeatures |= CPU_HAS_SSE;
   600             SDL_CPUFeatures |= CPU_HAS_SSE;
       
   601             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
   595         }
   602         }
   596         if (CPU_haveSSE2()) {
   603         if (CPU_haveSSE2()) {
   597             SDL_CPUFeatures |= CPU_HAS_SSE2;
   604             SDL_CPUFeatures |= CPU_HAS_SSE2;
       
   605             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
   598         }
   606         }
   599         if (CPU_haveSSE3()) {
   607         if (CPU_haveSSE3()) {
   600             SDL_CPUFeatures |= CPU_HAS_SSE3;
   608             SDL_CPUFeatures |= CPU_HAS_SSE3;
       
   609             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
   601         }
   610         }
   602         if (CPU_haveSSE41()) {
   611         if (CPU_haveSSE41()) {
   603             SDL_CPUFeatures |= CPU_HAS_SSE41;
   612             SDL_CPUFeatures |= CPU_HAS_SSE41;
       
   613             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
   604         }
   614         }
   605         if (CPU_haveSSE42()) {
   615         if (CPU_haveSSE42()) {
   606             SDL_CPUFeatures |= CPU_HAS_SSE42;
   616             SDL_CPUFeatures |= CPU_HAS_SSE42;
       
   617             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
   607         }
   618         }
   608         if (CPU_haveAVX()) {
   619         if (CPU_haveAVX()) {
   609             SDL_CPUFeatures |= CPU_HAS_AVX;
   620             SDL_CPUFeatures |= CPU_HAS_AVX;
       
   621             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 32);
   610         }
   622         }
   611         if (CPU_haveAVX2()) {
   623         if (CPU_haveAVX2()) {
   612             SDL_CPUFeatures |= CPU_HAS_AVX2;
   624             SDL_CPUFeatures |= CPU_HAS_AVX2;
       
   625             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 32);
   613         }
   626         }
   614         if (CPU_haveNEON()) {
   627         if (CPU_haveNEON()) {
   615             SDL_CPUFeatures |= CPU_HAS_NEON;
   628             SDL_CPUFeatures |= CPU_HAS_NEON;
       
   629             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
   616         }
   630         }
   617     }
   631     }
   618     return SDL_CPUFeatures;
   632     return SDL_CPUFeatures;
   619 }
   633 }
   620 
   634 
   743     }
   757     }
   744     return SDL_SystemRAM;
   758     return SDL_SystemRAM;
   745 }
   759 }
   746 
   760 
   747 
   761 
       
   762 size_t
       
   763 SDL_SIMDGetAlignment(void)
       
   764 {
       
   765     if (SDL_SIMDAlignment == 0xFFFFFFFF) {
       
   766         SDL_GetCPUFeatures();  /* make sure this has been calculated */
       
   767     }
       
   768     SDL_assert(SDL_SIMDAlignment != 0);
       
   769     return SDL_SIMDAlignment;
       
   770 }
       
   771 
       
   772 void *
       
   773 SDL_SIMDAlloc(const size_t len)
       
   774 {
       
   775     const size_t alignment = SDL_SIMDGetAlignment();
       
   776     const size_t padding = alignment - (len % alignment);
       
   777     const size_t padded = (padding != alignment) ? (len + padding) : len;
       
   778     Uint8 *retval = NULL;
       
   779     Uint8 *ptr = (Uint8 *) SDL_malloc(padded + alignment + sizeof (void *));
       
   780     if (ptr) {
       
   781         /* store the actual malloc pointer right before our aligned pointer. */
       
   782         retval = ptr + sizeof (void *);
       
   783         retval += alignment - (((size_t) retval) % alignment);
       
   784         *(((void **) retval) - 1) = ptr;
       
   785     }
       
   786     return retval;
       
   787 }
       
   788 
       
   789 void
       
   790 SDL_SIMDFree(void *ptr)
       
   791 {
       
   792     if (ptr) {
       
   793         void **realptr = (void **) ptr;
       
   794         realptr--;
       
   795         SDL_free(*(((void **) ptr) - 1));
       
   796     }
       
   797 }
       
   798 
       
   799 
   748 #ifdef TEST_MAIN
   800 #ifdef TEST_MAIN
   749 
   801 
   750 #include <stdio.h>
   802 #include <stdio.h>
   751 
   803 
   752 int
   804 int