// 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 #include #include #if defined(NAZARA_PLATFORM_WINDOWS) #include #elif defined(NAZARA_PLATFORM_POSIX) #include #else #error Lack of implementation: HardwareInfo #endif #include 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 }