Limit CPU features through a hint
parent
b5d4206b30
commit
1d0e5286aa
|
@ -371,6 +371,37 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
#define SDL_HINT_CAMERA_DRIVER "SDL_CAMERA_DRIVER"
|
#define SDL_HINT_CAMERA_DRIVER "SDL_CAMERA_DRIVER"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A variable that limits what CPU features are available.
|
||||||
|
*
|
||||||
|
* By default, SDL marks all features the current CPU supports as available.
|
||||||
|
* This hint allows to limit these to a subset.
|
||||||
|
*
|
||||||
|
* When the hint is unset, or empty, SDL will enable all detected CPU
|
||||||
|
* features.
|
||||||
|
*
|
||||||
|
* The variable can be set to a comma separated list containing the following items:
|
||||||
|
* "all"
|
||||||
|
* "altivec"
|
||||||
|
* "sse"
|
||||||
|
* "sse2"
|
||||||
|
* "sse3"
|
||||||
|
* "sse41"
|
||||||
|
* "sse42"
|
||||||
|
* "avx"
|
||||||
|
* "avx2"
|
||||||
|
* "avx512f"
|
||||||
|
* "arm-simd"
|
||||||
|
* "neon"
|
||||||
|
* "lsx"
|
||||||
|
* "lasx"
|
||||||
|
*
|
||||||
|
* The items can be prefixed by '+'/'-' to add/remove features.
|
||||||
|
*
|
||||||
|
* This hint is available since SDL 3.0.0.
|
||||||
|
*/
|
||||||
|
#define SDL_HINT_CPU_FEATURE_MASK "SDL_CPU_FEATURE_MASK"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A variable controlling whether DirectInput should be used for controllers
|
* A variable controlling whether DirectInput should be used for controllers
|
||||||
*
|
*
|
||||||
|
|
|
@ -858,6 +858,80 @@ int SDL_GetCPUCacheLineSize(void)
|
||||||
static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
|
static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
|
||||||
static Uint32 SDL_SIMDAlignment = 0xFFFFFFFF;
|
static Uint32 SDL_SIMDAlignment = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
static SDL_bool ref_string_equals(const char *ref, const char *test, const char *end_test) {
|
||||||
|
size_t len_test = end_test - test;
|
||||||
|
return SDL_strncmp(ref, test, len_test) == 0 && ref[len_test] == '\0' && (test[len_test] == '\0' || test[len_test] == ',');
|
||||||
|
}
|
||||||
|
|
||||||
|
static Uint32 SDLCALL SDL_CPUFeatureMaskFromHint(void)
|
||||||
|
{
|
||||||
|
Uint32 result_mask = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
const char *hint = SDL_GetHint(SDL_HINT_CPU_FEATURE_MASK);
|
||||||
|
|
||||||
|
if (hint) {
|
||||||
|
for (const char *spot = hint, *next; *spot; spot = next) {
|
||||||
|
const char *end = SDL_strchr(spot, ',');
|
||||||
|
Uint32 spot_mask;
|
||||||
|
SDL_bool add_spot_mask = SDL_TRUE;
|
||||||
|
if (end) {
|
||||||
|
next = end + 1;
|
||||||
|
} else {
|
||||||
|
size_t len = SDL_strlen(spot);
|
||||||
|
end = spot + len;
|
||||||
|
next = end;
|
||||||
|
}
|
||||||
|
if (spot[0] == '+') {
|
||||||
|
add_spot_mask = SDL_TRUE;
|
||||||
|
spot += 1;
|
||||||
|
} else if (spot[0] == '-') {
|
||||||
|
add_spot_mask = SDL_FALSE;
|
||||||
|
spot += 1;
|
||||||
|
}
|
||||||
|
if (ref_string_equals("all", spot, end)) {
|
||||||
|
spot_mask = 0xFFFFFFFF;
|
||||||
|
} else if (ref_string_equals("altivec", spot, end)) {
|
||||||
|
spot_mask= CPU_HAS_ALTIVEC;
|
||||||
|
} else if (ref_string_equals("mmx", spot, end)) {
|
||||||
|
spot_mask = CPU_HAS_MMX;
|
||||||
|
} else if (ref_string_equals("sse", spot, end)) {
|
||||||
|
spot_mask = CPU_HAS_SSE;
|
||||||
|
} else if (ref_string_equals("sse2", spot, end)) {
|
||||||
|
spot_mask = CPU_HAS_SSE2;
|
||||||
|
} else if (ref_string_equals("sse3", spot, end)) {
|
||||||
|
spot_mask = CPU_HAS_SSE3;
|
||||||
|
} else if (ref_string_equals("sse41", spot, end)) {
|
||||||
|
spot_mask = CPU_HAS_SSE41;
|
||||||
|
} else if (ref_string_equals("sse42", spot, end)) {
|
||||||
|
spot_mask = CPU_HAS_SSE42;
|
||||||
|
} else if (ref_string_equals("avx", spot, end)) {
|
||||||
|
spot_mask = CPU_HAS_AVX;
|
||||||
|
} else if (ref_string_equals("avx2", spot, end)) {
|
||||||
|
spot_mask = CPU_HAS_AVX2;
|
||||||
|
} else if (ref_string_equals("avx512f", spot, end)) {
|
||||||
|
spot_mask = CPU_HAS_AVX512F;
|
||||||
|
} else if (ref_string_equals("arm-simd", spot, end)) {
|
||||||
|
spot_mask = CPU_HAS_ARM_SIMD;
|
||||||
|
} else if (ref_string_equals("neon", spot, end)) {
|
||||||
|
spot_mask = CPU_HAS_NEON;
|
||||||
|
} else if (ref_string_equals("lsx", spot, end)) {
|
||||||
|
spot_mask = CPU_HAS_LSX;
|
||||||
|
} else if (ref_string_equals("lasx", spot, end)) {
|
||||||
|
spot_mask = CPU_HAS_LASX;
|
||||||
|
} else {
|
||||||
|
/* Ignore unknown/incorrect cpu feature(s) */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (add_spot_mask) {
|
||||||
|
result_mask |= spot_mask;
|
||||||
|
} else {
|
||||||
|
result_mask &= ~spot_mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result_mask;
|
||||||
|
}
|
||||||
|
|
||||||
static Uint32 SDL_GetCPUFeatures(void)
|
static Uint32 SDL_GetCPUFeatures(void)
|
||||||
{
|
{
|
||||||
if (SDL_CPUFeatures == 0xFFFFFFFF) {
|
if (SDL_CPUFeatures == 0xFFFFFFFF) {
|
||||||
|
@ -920,6 +994,7 @@ static Uint32 SDL_GetCPUFeatures(void)
|
||||||
SDL_CPUFeatures |= CPU_HAS_LASX;
|
SDL_CPUFeatures |= CPU_HAS_LASX;
|
||||||
SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 32);
|
SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 32);
|
||||||
}
|
}
|
||||||
|
SDL_CPUFeatures &= SDL_CPUFeatureMaskFromHint();
|
||||||
}
|
}
|
||||||
return SDL_CPUFeatures;
|
return SDL_CPUFeatures;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue