mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-22 06:23:04 +01:00
Move SSE41 and AVX2 detection into Platform namespace
This commit is contained in:
@@ -20,7 +20,6 @@
|
||||
#include "../rct1/Csg.h"
|
||||
#include "../sprites.h"
|
||||
#include "../ui/UiContext.h"
|
||||
#include "../util/Util.h"
|
||||
#include "ScrollingText.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "../object/WaterEntry.h"
|
||||
#include "../platform/Platform.h"
|
||||
#include "../sprites.h"
|
||||
#include "../util/Util.h"
|
||||
#include "../world/Climate.h"
|
||||
#include "../world/Location.hpp"
|
||||
#include "LightFX.h"
|
||||
@@ -668,12 +667,12 @@ ImageCatalogue ImageId::GetCatalogue() const
|
||||
|
||||
static auto GetMaskFunction()
|
||||
{
|
||||
if (AVX2Available())
|
||||
if (Platform::AVX2Available())
|
||||
{
|
||||
LOG_VERBOSE("registering AVX2 mask function");
|
||||
return MaskAvx2;
|
||||
}
|
||||
else if (SSE41Available())
|
||||
else if (Platform::SSE41Available())
|
||||
{
|
||||
LOG_VERBOSE("registering SSE4.1 mask function");
|
||||
return MaskSse4_1;
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "../ride/Ride.h"
|
||||
#include "../ride/RideData.h"
|
||||
#include "../ride/Vehicle.h"
|
||||
#include "../util/Util.h"
|
||||
#include "../world/Map.h"
|
||||
#include "Drawing.h"
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "../ride/TrackDesign.h"
|
||||
#include "../scenario/Scenario.h"
|
||||
#include "../ui/UiContext.h"
|
||||
#include "../util/Util.h"
|
||||
#include "../world/Climate.h"
|
||||
#include "Drawing.h"
|
||||
#include "IDrawingEngine.h"
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "../interface/Window.h"
|
||||
#include "../scenes/intro/IntroScene.h"
|
||||
#include "../ui/UiContext.h"
|
||||
#include "../util/Util.h"
|
||||
#include "Drawing.h"
|
||||
#include "IDrawingContext.h"
|
||||
#include "IDrawingEngine.h"
|
||||
|
||||
@@ -17,6 +17,15 @@
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
|
||||
# include <cpuid.h>
|
||||
# define OpenRCT2_CPUID_GNUC_X86
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_X64) || defined(_M_IX86)) // VS2008
|
||||
# include <intrin.h>
|
||||
# include <nmmintrin.h>
|
||||
# define OpenRCT2_CPUID_MSVC_X86
|
||||
#endif
|
||||
|
||||
#include "../Context.h"
|
||||
#include "../Game.h"
|
||||
#include "../core/File.h"
|
||||
@@ -138,4 +147,61 @@ namespace Platform
|
||||
return static_cast<uint32_t>(std::chrono::duration_cast<std::chrono::milliseconds>(processTime).count());
|
||||
}
|
||||
|
||||
#ifdef OPENRCT2_X86
|
||||
static bool CPUIDX86(uint32_t* cpuid_outdata, int32_t eax)
|
||||
{
|
||||
# if defined(OpenRCT2_CPUID_GNUC_X86)
|
||||
int ret = __get_cpuid(eax, &cpuid_outdata[0], &cpuid_outdata[1], &cpuid_outdata[2], &cpuid_outdata[3]);
|
||||
return ret == 1;
|
||||
# elif defined(OpenRCT2_CPUID_MSVC_X86)
|
||||
__cpuid(reinterpret_cast<int*>(cpuid_outdata), static_cast<int>(eax));
|
||||
return true;
|
||||
# else
|
||||
return false;
|
||||
# endif
|
||||
}
|
||||
#endif // OPENRCT2_X86
|
||||
|
||||
bool SSE41Available()
|
||||
{
|
||||
#ifdef OPENRCT2_X86
|
||||
// SSE4.1 support is declared as the 19th bit of ECX with CPUID(EAX = 1).
|
||||
uint32_t regs[4] = { 0 };
|
||||
if (CPUIDX86(regs, 1))
|
||||
{
|
||||
return (regs[2] & (1 << 19));
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AVX2Available()
|
||||
{
|
||||
#ifdef OPENRCT2_X86
|
||||
// For GCC and similar use the builtin function, as cpuid changed its semantics in
|
||||
// https://github.com/gcc-mirror/gcc/commit/132fa33ce998df69a9f793d63785785f4b93e6f1
|
||||
// which causes it to ignore subleafs, but the new function is unavailable on
|
||||
// Ubuntu 18.04's toolchains.
|
||||
# if defined(OpenRCT2_CPUID_GNUC_X86) && (!defined(__FreeBSD__) || (__FreeBSD__ > 10))
|
||||
return __builtin_cpu_supports("avx2");
|
||||
# else
|
||||
// AVX2 support is declared as the 5th bit of EBX with CPUID(EAX = 7, ECX = 0).
|
||||
uint32_t regs[4] = { 0 };
|
||||
if (CPUIDX86(regs, 7))
|
||||
{
|
||||
bool avxCPUSupport = (regs[1] & (1 << 5)) != 0;
|
||||
if (avxCPUSupport)
|
||||
{
|
||||
// Need to check if OS also supports the register of xmm/ymm
|
||||
// This check has to be conditional, otherwise INVALID_INSTRUCTION exception.
|
||||
uint64_t xcrFeatureMask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
|
||||
avxCPUSupport = (xcrFeatureMask & 0x6) || false;
|
||||
}
|
||||
return avxCPUSupport;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Platform
|
||||
|
||||
@@ -124,6 +124,9 @@ namespace Platform
|
||||
uint32_t GetTicks();
|
||||
|
||||
void Sleep(uint32_t ms);
|
||||
|
||||
bool SSE41Available();
|
||||
bool AVX2Available();
|
||||
} // namespace Platform
|
||||
|
||||
#ifdef __ANDROID__
|
||||
|
||||
@@ -106,72 +106,6 @@ int32_t UtilBitScanForward(int64_t source)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
|
||||
# include <cpuid.h>
|
||||
# define OpenRCT2_CPUID_GNUC_X86
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_X64) || defined(_M_IX86)) // VS2008
|
||||
# include <intrin.h>
|
||||
# include <nmmintrin.h>
|
||||
# define OpenRCT2_CPUID_MSVC_X86
|
||||
#endif
|
||||
|
||||
#ifdef OPENRCT2_X86
|
||||
static bool CPUIDX86(uint32_t* cpuid_outdata, int32_t eax)
|
||||
{
|
||||
# if defined(OpenRCT2_CPUID_GNUC_X86)
|
||||
int ret = __get_cpuid(eax, &cpuid_outdata[0], &cpuid_outdata[1], &cpuid_outdata[2], &cpuid_outdata[3]);
|
||||
return ret == 1;
|
||||
# elif defined(OpenRCT2_CPUID_MSVC_X86)
|
||||
__cpuid(reinterpret_cast<int*>(cpuid_outdata), static_cast<int>(eax));
|
||||
return true;
|
||||
# else
|
||||
return false;
|
||||
# endif
|
||||
}
|
||||
#endif // OPENRCT2_X86
|
||||
|
||||
bool SSE41Available()
|
||||
{
|
||||
#ifdef OPENRCT2_X86
|
||||
// SSE4.1 support is declared as the 19th bit of ECX with CPUID(EAX = 1).
|
||||
uint32_t regs[4] = { 0 };
|
||||
if (CPUIDX86(regs, 1))
|
||||
{
|
||||
return (regs[2] & (1 << 19));
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AVX2Available()
|
||||
{
|
||||
#ifdef OPENRCT2_X86
|
||||
// For GCC and similar use the builtin function, as cpuid changed its semantics in
|
||||
// https://github.com/gcc-mirror/gcc/commit/132fa33ce998df69a9f793d63785785f4b93e6f1
|
||||
// which causes it to ignore subleafs, but the new function is unavailable on
|
||||
// Ubuntu 18.04's toolchains.
|
||||
# if defined(OpenRCT2_CPUID_GNUC_X86) && (!defined(__FreeBSD__) || (__FreeBSD__ > 10))
|
||||
return __builtin_cpu_supports("avx2");
|
||||
# else
|
||||
// AVX2 support is declared as the 5th bit of EBX with CPUID(EAX = 7, ECX = 0).
|
||||
uint32_t regs[4] = { 0 };
|
||||
if (CPUIDX86(regs, 7))
|
||||
{
|
||||
bool avxCPUSupport = (regs[1] & (1 << 5)) != 0;
|
||||
if (avxCPUSupport)
|
||||
{
|
||||
// Need to check if OS also supports the register of xmm/ymm
|
||||
// This check has to be conditional, otherwise INVALID_INSTRUCTION exception.
|
||||
uint64_t xcrFeatureMask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
|
||||
avxCPUSupport = (xcrFeatureMask & 0x6) || false;
|
||||
}
|
||||
return avxCPUSupport;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Case insensitive logical compare */
|
||||
// Example:
|
||||
// - Guest 10
|
||||
|
||||
@@ -24,9 +24,6 @@ int32_t MetresToFeet(int32_t metres);
|
||||
int32_t MphToKmph(int32_t mph);
|
||||
int32_t MphToDmps(int32_t mph);
|
||||
|
||||
bool SSE41Available();
|
||||
bool AVX2Available();
|
||||
|
||||
int32_t UtilBitScanForward(int32_t source);
|
||||
int32_t UtilBitScanForward(int64_t source);
|
||||
int32_t StrLogicalCmp(char const* a, char const* b);
|
||||
|
||||
Reference in New Issue
Block a user