Added HardwareInfo class
Former-commit-id: 3db2f8f11d58b4b71b85f749ce2a12dcfff986bc
This commit is contained in:
parent
e3316c4e10
commit
faee0b93b5
|
|
@ -7,6 +7,44 @@
|
|||
#ifndef NAZARA_ENUMS_CORE_HPP
|
||||
#define NAZARA_ENUMS_CORE_HPP
|
||||
|
||||
enum nzProcessorCap
|
||||
{
|
||||
nzProcessorCap_AVX,
|
||||
nzProcessorCap_FMA3,
|
||||
nzProcessorCap_FMA4,
|
||||
nzProcessorCap_MMX,
|
||||
nzProcessorCap_XOP,
|
||||
nzProcessorCap_SSE,
|
||||
nzProcessorCap_SSE2,
|
||||
nzProcessorCap_SSE3,
|
||||
nzProcessorCap_SSSE3,
|
||||
nzProcessorCap_SSE41,
|
||||
nzProcessorCap_SSE42,
|
||||
nzProcessorCap_SSE4a,
|
||||
|
||||
nzProcessorCap_Max = nzProcessorCap_SSE4a
|
||||
};
|
||||
|
||||
enum nzProcessorVendor
|
||||
{
|
||||
nzProcessorVendor_Unknown = -1,
|
||||
|
||||
nzProcessorVendor_AMD,
|
||||
nzProcessorVendor_Centaur,
|
||||
nzProcessorVendor_Cyrix,
|
||||
nzProcessorVendor_Intel,
|
||||
nzProcessorVendor_Transmeta,
|
||||
nzProcessorVendor_NSC,
|
||||
nzProcessorVendor_NexGen,
|
||||
nzProcessorVendor_Rise,
|
||||
nzProcessorVendor_SIS,
|
||||
nzProcessorVendor_UMC,
|
||||
nzProcessorVendor_VIA,
|
||||
nzProcessorVendor_Vortex,
|
||||
|
||||
nzProcessorVendor_Max = nzProcessorVendor_Vortex
|
||||
};
|
||||
|
||||
enum nzEndianness
|
||||
{
|
||||
nzEndianness_Unknown = -1,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_HARDWAREINFO_HPP
|
||||
#define NAZARA_HARDWAREINFO_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Enums.hpp>
|
||||
|
||||
class NAZARA_API NzHardwareInfo
|
||||
{
|
||||
public:
|
||||
static unsigned int GetProcessorCount();
|
||||
static nzProcessorVendor GetProcessorVendor();
|
||||
static void GetProcessorVendor(char vendor[12]);
|
||||
|
||||
static bool HasCapability(nzProcessorCap capability);
|
||||
|
||||
static bool Initialize();
|
||||
|
||||
static bool Is64Bits();
|
||||
|
||||
static void Uninitialize();
|
||||
};
|
||||
|
||||
#endif // NAZARA_HARDWAREINFO_HPP
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/HardwareInfo.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <cstring>
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Core/Win32/HardwareInfoImpl.hpp>
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
#include <Nazara/Core/Posix/HardwareInfoImpl.hpp>
|
||||
#else
|
||||
#error Lack of implementation: HardwareInfo
|
||||
#endif
|
||||
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
nzProcessorVendor s_vendorEnum = nzProcessorVendor_Unknown;
|
||||
bool s_capabilities[nzProcessorCap_Max+1] = {false};
|
||||
bool s_x64 = false;
|
||||
|
||||
char s_vendor[12] = {'C', 'P', 'U', 'i', 's', 'U', 'n', 'k', 'n', 'o', 'w', 'n'};
|
||||
|
||||
struct VendorString
|
||||
{
|
||||
nzProcessorVendor vendorEnum;
|
||||
char vendor[13]; // +1 pour le \0 automatiquement ajouté par le compilateur
|
||||
};
|
||||
}
|
||||
|
||||
unsigned int NzHardwareInfo::GetProcessorCount()
|
||||
{
|
||||
static unsigned int processorCount = std::max(NzHardwareInfoImpl::GetProcessorCount(), 1U);
|
||||
return processorCount;
|
||||
}
|
||||
|
||||
nzProcessorVendor NzHardwareInfo::GetProcessorVendor()
|
||||
{
|
||||
return s_vendorEnum;
|
||||
}
|
||||
|
||||
void NzHardwareInfo::GetProcessorVendor(char vendor[12])
|
||||
{
|
||||
std::memcpy(vendor, s_vendor, 12);
|
||||
}
|
||||
|
||||
bool NzHardwareInfo::HasCapability(nzProcessorCap capability)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (capability > nzProcessorCap_Max)
|
||||
{
|
||||
NazaraError("Capability type out of enum");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return s_capabilities[capability];
|
||||
}
|
||||
|
||||
bool NzHardwareInfo::Initialize()
|
||||
{
|
||||
if (!NzHardwareInfoImpl::IsCpuidSupported())
|
||||
return false;
|
||||
|
||||
nzUInt32 result[4];
|
||||
|
||||
NzHardwareInfoImpl::Cpuid(0, result);
|
||||
std::memcpy(&s_vendor[0], &result[1], 4);
|
||||
std::memcpy(&s_vendor[4], &result[3], 4);
|
||||
std::memcpy(&s_vendor[8], &result[2], 4);
|
||||
|
||||
VendorString s_vendorStrings[] =
|
||||
{
|
||||
{nzProcessorVendor_AMD, "AMDisbetter!"},
|
||||
{nzProcessorVendor_AMD, "AuthenticAMD"},
|
||||
{nzProcessorVendor_Centaur, "CentaurHauls"},
|
||||
{nzProcessorVendor_Cyrix, "CyrixInstead"},
|
||||
{nzProcessorVendor_Intel, "GenuineIntel"},
|
||||
{nzProcessorVendor_NexGen, "NexGenDriven"},
|
||||
{nzProcessorVendor_NSC, "Geode by NSC"},
|
||||
{nzProcessorVendor_SIS, "SiS SiS SiS "},
|
||||
{nzProcessorVendor_Transmeta, "GenuineTMx86"},
|
||||
{nzProcessorVendor_Transmeta, "TransmetaCPU"},
|
||||
{nzProcessorVendor_UMC, "UMC UMC UMC "},
|
||||
{nzProcessorVendor_VIA, "VIA VIA VIA "},
|
||||
{nzProcessorVendor_VIA, "Vortex86 SoC"}
|
||||
};
|
||||
|
||||
// Identification du vendeur
|
||||
s_vendorEnum = nzProcessorVendor_Unknown;
|
||||
for (const VendorString& vendorString : s_vendorStrings)
|
||||
{
|
||||
if (std::memcmp(s_vendor, vendorString.vendor, 12) == 0)
|
||||
{
|
||||
s_vendorEnum = vendorString.vendorEnum;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int ids = result[0];
|
||||
|
||||
if (ids >= 1)
|
||||
{
|
||||
NzHardwareInfoImpl::Cpuid(1, result);
|
||||
s_capabilities[nzProcessorCap_AVX] = (result[2] & (1U << 28)) != 0;
|
||||
s_capabilities[nzProcessorCap_FMA3] = (result[2] & (1U << 12)) != 0;
|
||||
s_capabilities[nzProcessorCap_MMX] = (result[3] & (1U << 23)) != 0;
|
||||
s_capabilities[nzProcessorCap_SSE] = (result[3] & (1U << 25)) != 0;
|
||||
s_capabilities[nzProcessorCap_SSE2] = (result[3] & (1U << 26)) != 0;
|
||||
s_capabilities[nzProcessorCap_SSE3] = (result[2] & (1U << 0)) != 0;
|
||||
s_capabilities[nzProcessorCap_SSSE3] = (result[2] & (1U << 9)) != 0;
|
||||
s_capabilities[nzProcessorCap_SSE41] = (result[2] & (1U << 19)) != 0;
|
||||
s_capabilities[nzProcessorCap_SSE42] = (result[2] & (1U << 20)) != 0;
|
||||
}
|
||||
|
||||
NzHardwareInfoImpl::Cpuid(0x80000000, result);
|
||||
unsigned int exIds = result[0];
|
||||
|
||||
if (exIds >= 0x80000001)
|
||||
{
|
||||
NzHardwareInfoImpl::Cpuid(0x80000001, result);
|
||||
s_capabilities[nzProcessorCap_FMA4] = (result[2] & (1U << 16)) != 0;
|
||||
s_capabilities[nzProcessorCap_SSE4a] = (result[2] & (1U << 6)) != 0;
|
||||
s_capabilities[nzProcessorCap_XOP] = (result[2] & (1U << 11)) != 0;
|
||||
s_x64 = (result[3] & (1U << 29)) != 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzHardwareInfo::Is64Bits()
|
||||
{
|
||||
return s_x64;
|
||||
}
|
||||
|
||||
void NzHardwareInfo::Uninitialize()
|
||||
{
|
||||
// Rien à faire
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Win32/HardwareInfoImpl.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef NAZARA_COMPILER_MSVC
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
void NzHardwareInfoImpl::Cpuid(nzUInt32 code, nzUInt32 result[4])
|
||||
{
|
||||
#if defined(NAZARA_COMPILER_MSVC)
|
||||
__cpuid(reinterpret_cast<int*>(result), static_cast<int>(code));
|
||||
#elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
|
||||
// Source: http://stackoverflow.com/questions/1666093/cpuid-implementations-in-c
|
||||
asm volatile
|
||||
("cpuid"
|
||||
:"=a" (result[0]), "=b" (result[1]), "=c" (result[2]), "=d" (result[3])
|
||||
:"a" (code), "c" (0));
|
||||
#else
|
||||
NazaraInternalError("Cpuid has been called although it is not supported");
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int NzHardwareInfoImpl::GetProcessorCount()
|
||||
{
|
||||
// Plus simple (et plus portable) que de passer par le CPUID
|
||||
SYSTEM_INFO infos;
|
||||
GetSystemInfo(&infos);
|
||||
|
||||
return infos.dwNumberOfProcessors;
|
||||
}
|
||||
|
||||
bool NzHardwareInfoImpl::IsCpuidSupported()
|
||||
{
|
||||
#if defined(NAZARA_COMPILER_MSVC)
|
||||
int supported;
|
||||
__asm
|
||||
{
|
||||
pushfd
|
||||
pop eax
|
||||
mov ecx, eax
|
||||
xor eax, 0x200000
|
||||
push eax
|
||||
popfd
|
||||
pushfd
|
||||
pop eax
|
||||
xor eax, ecx
|
||||
mov supported, eax
|
||||
push ecx
|
||||
popfd
|
||||
};
|
||||
|
||||
return supported != 0;
|
||||
#elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
|
||||
int supported;
|
||||
asm volatile
|
||||
(" pushfl\n"
|
||||
" pop %%eax\n"
|
||||
" mov %%eax, %%ecx\n"
|
||||
" xor $0x200000, %%eax\n"
|
||||
" push %%eax\n"
|
||||
" popfl\n"
|
||||
" pushfl\n"
|
||||
" pop %%eax\n"
|
||||
" xor %%ecx, %%eax\n"
|
||||
" mov %%eax, %0\n"
|
||||
" push %%ecx\n"
|
||||
" popfl\n"
|
||||
: "=m" (supported)
|
||||
: :"eax", "ecx", "memory");
|
||||
|
||||
return supported != 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_HARDWAREINFOIMPL_WINDOWS_HPP
|
||||
#define NAZARA_HARDWAREINFOIMPL_WINDOWS_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
|
||||
class NzHardwareInfoImpl
|
||||
{
|
||||
public:
|
||||
static void Cpuid(unsigned int code, nzUInt32 result[4]);
|
||||
static unsigned int GetProcessorCount();
|
||||
static bool IsCpuidSupported();
|
||||
};
|
||||
|
||||
#endif // NAZARA_HARDWAREINFOIMPL_WINDOWS_HPP
|
||||
Loading…
Reference in New Issue