| |
| // Copyright 2019 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| |
| #include "GPUTestConfig.h" |
| |
| #include <stdint.h> |
| #include <iostream> |
| |
| #include "common/angleutils.h" |
| #include "common/debug.h" |
| #include "common/platform.h" |
| #include "common/string_utils.h" |
| #include "gpu_info_util/SystemInfo.h" |
| |
| #if defined(ANGLE_PLATFORM_APPLE) |
| # include "GPUTestConfig_mac.h" |
| #endif |
| |
| namespace angle |
| { |
| |
| namespace |
| { |
| |
| // Generic function call to get the OS version information from any platform |
| // defined below. This function will also cache the OS version info in static |
| // variables. |
| inline bool OperatingSystemVersionNumbers(int32_t *majorVersion, int32_t *minorVersion) |
| { |
| static int32_t sSavedMajorVersion = -1; |
| static int32_t sSavedMinorVersion = -1; |
| bool ret = false; |
| if (sSavedMajorVersion == -1 || sSavedMinorVersion == -1) |
| { |
| #if defined(ANGLE_PLATFORM_WINDOWS) |
| OSVERSIONINFOEX version_info = {}; |
| version_info.dwOSVersionInfoSize = sizeof(version_info); |
| ::GetVersionEx(reinterpret_cast<OSVERSIONINFO *>(&version_info)); |
| sSavedMajorVersion = version_info.dwMajorVersion; |
| *majorVersion = sSavedMajorVersion; |
| sSavedMinorVersion = version_info.dwMinorVersion; |
| *minorVersion = sSavedMinorVersion; |
| ret = true; |
| |
| #elif defined(ANGLE_PLATFORM_APPLE) |
| GetOperatingSystemVersionNumbers(&sSavedMajorVersion, &sSavedMinorVersion); |
| *majorVersion = sSavedMajorVersion; |
| *minorVersion = sSavedMinorVersion; |
| ret = true; |
| |
| #else |
| ret = false; |
| #endif |
| } |
| else |
| { |
| ret = true; |
| } |
| *majorVersion = sSavedMajorVersion; |
| *minorVersion = sSavedMinorVersion; |
| return ret; |
| } |
| |
| // Check if the OS is any version of Windows |
| inline bool IsWin() |
| { |
| #if defined(ANGLE_PLATFORM_WINDOWS) |
| return true; |
| #else |
| return false; |
| #endif |
| } |
| |
| // Check if the OS is a specific major version of windows. |
| inline bool IsWinVersion(const int32_t majorVersion) |
| { |
| if (IsWin()) |
| { |
| int32_t currentMajorVersion = 0; |
| int32_t currentMinorVersion = 0; |
| if (OperatingSystemVersionNumbers(¤tMajorVersion, ¤tMinorVersion)) |
| { |
| if (currentMajorVersion == majorVersion) |
| { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| // Check if the OS is a specific major and minor version of windows. |
| inline bool IsWinVersion(const int32_t majorVersion, const int32_t minorVersion) |
| { |
| if (IsWin()) |
| { |
| int32_t currentMajorVersion = 0; |
| int32_t currentMinorVersion = 0; |
| if (OperatingSystemVersionNumbers(¤tMajorVersion, ¤tMinorVersion)) |
| { |
| if (currentMajorVersion == majorVersion && currentMinorVersion == minorVersion) |
| { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| // Check if the OS is Windows XP |
| inline bool IsWinXP() |
| { |
| if (IsWinVersion(5)) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| // Check if the OS is Windows Vista |
| inline bool IsWinVista() |
| { |
| if (IsWinVersion(6, 0)) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| // Check if the OS is Windows 7 |
| inline bool IsWin7() |
| { |
| if (IsWinVersion(6, 1)) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| // Check if the OS is Windows 8 |
| inline bool IsWin8() |
| { |
| if (IsWinVersion(6, 2) || IsWinVersion(6, 3)) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| // Check if the OS is Windows 10 |
| inline bool IsWin10() |
| { |
| if (IsWinVersion(10)) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| // Check if the OS is any version of OSX |
| inline bool IsMac() |
| { |
| #if defined(ANGLE_PLATFORM_APPLE) |
| return true; |
| #else |
| return false; |
| #endif |
| } |
| |
| // Check if the OS is a specific major and minor version of OSX |
| inline bool IsMacVersion(const int32_t majorVersion, const int32_t minorVersion) |
| { |
| if (IsMac()) |
| { |
| int32_t currentMajorVersion = 0; |
| int32_t currentMinorVersion = 0; |
| if (OperatingSystemVersionNumbers(¤tMajorVersion, ¤tMinorVersion)) |
| { |
| if (currentMajorVersion == majorVersion && currentMinorVersion == minorVersion) |
| { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| // Check if the OS is OSX Leopard |
| inline bool IsMacLeopard() |
| { |
| if (IsMacVersion(10, 5)) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| // Check if the OS is OSX Snow Leopard |
| inline bool IsMacSnowLeopard() |
| { |
| if (IsMacVersion(10, 6)) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| // Check if the OS is OSX Lion |
| inline bool IsMacLion() |
| { |
| if (IsMacVersion(10, 7)) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| // Check if the OS is OSX Mountain Lion |
| inline bool IsMacMountainLion() |
| { |
| if (IsMacVersion(10, 8)) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| // Check if the OS is OSX Mavericks |
| inline bool IsMacMavericks() |
| { |
| if (IsMacVersion(10, 9)) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| // Check if the OS is OSX Yosemite |
| inline bool IsMacYosemite() |
| { |
| if (IsMacVersion(10, 10)) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| // Check if the OS is OSX El Capitan |
| inline bool IsMacElCapitan() |
| { |
| if (IsMacVersion(10, 11)) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| // Check if the OS is OSX Sierra |
| inline bool IsMacSierra() |
| { |
| if (IsMacVersion(10, 12)) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| // Check if the OS is OSX High Sierra |
| inline bool IsMacHighSierra() |
| { |
| if (IsMacVersion(10, 13)) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| // Check if the OS is OSX Mojave |
| inline bool IsMacMojave() |
| { |
| if (IsMacVersion(10, 14)) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| // Check if the OS is any version of Linux |
| inline bool IsLinux() |
| { |
| #if defined(ANGLE_PLATFORM_LINUX) |
| return true; |
| #else |
| return false; |
| #endif |
| } |
| |
| // Check if the OS is any version of Android |
| inline bool IsAndroid() |
| { |
| #if defined(ANGLE_PLATFORM_ANDROID) |
| return true; |
| #else |
| return false; |
| #endif |
| } |
| |
| // Generic function call to populate the SystemInfo struct. This function will |
| // also cache the SystemInfo struct for future calls. Returns false if the |
| // struct was not fully populated. Guaranteed to set sysInfo to a valid pointer |
| inline bool GetGPUTestSystemInfo(SystemInfo **sysInfo) |
| { |
| static SystemInfo *sSystemInfo = nullptr; |
| static bool sPopulated = false; |
| if (sSystemInfo == nullptr) |
| { |
| sSystemInfo = new SystemInfo; |
| if (!GetSystemInfo(sSystemInfo)) |
| { |
| std::cout << "Error populating SystemInfo for dEQP tests." << std::endl; |
| } |
| else |
| { |
| // On dual-GPU Macs we want the active GPU to always appear to be the |
| // high-performance GPU for tests. |
| // We can call the generic GPU info collector which selects the |
| // non-Intel GPU as the active one on dual-GPU machines. |
| // See https://anglebug.com/3701. |
| if (IsMac()) |
| { |
| GetDualGPUInfo(sSystemInfo); |
| } |
| sPopulated = true; |
| } |
| } |
| *sysInfo = sSystemInfo; |
| ASSERT(*sysInfo != nullptr); |
| return sPopulated; |
| } |
| |
| // Get the active GPUDeviceInfo from the SystemInfo struct. |
| // Returns false if devInfo is not guaranteed to be set to the active device. |
| inline bool GetActiveGPU(GPUDeviceInfo **devInfo) |
| { |
| SystemInfo *systemInfo = nullptr; |
| GetGPUTestSystemInfo(&systemInfo); |
| if (systemInfo->gpus.size() <= 0) |
| { |
| return false; |
| } |
| // Default to the first index |
| uint32_t index = 0; |
| // See if the activeGPUIndex was set first |
| if (systemInfo->activeGPUIndex != -1) |
| { |
| index = systemInfo->activeGPUIndex; |
| } |
| ASSERT(index < systemInfo->gpus.size()); |
| *devInfo = &(systemInfo->gpus[index]); |
| return true; |
| } |
| |
| // Get the vendor ID of the active GPU from the SystemInfo struct. |
| // Returns 0 if there is an error. |
| inline VendorID GetActiveGPUVendorID() |
| { |
| GPUDeviceInfo *activeGPU = nullptr; |
| if (GetActiveGPU(&activeGPU)) |
| { |
| return activeGPU->vendorId; |
| } |
| else |
| { |
| return static_cast<VendorID>(0); |
| } |
| } |
| |
| // Get the device ID of the active GPU from the SystemInfo struct. |
| // Returns 0 if there is an error. |
| inline DeviceID GetActiveGPUDeviceID() |
| { |
| GPUDeviceInfo *activeGPU = nullptr; |
| if (GetActiveGPU(&activeGPU)) |
| { |
| return activeGPU->deviceId; |
| } |
| else |
| { |
| return static_cast<DeviceID>(0); |
| } |
| } |
| |
| // Check whether the active GPU is NVIDIA. |
| inline bool IsNVIDIA() |
| { |
| return angle::IsNVIDIA(GetActiveGPUVendorID()); |
| } |
| |
| // Check whether the active GPU is AMD. |
| inline bool IsAMD() |
| { |
| return angle::IsAMD(GetActiveGPUVendorID()); |
| } |
| |
| // Check whether the active GPU is Intel. |
| inline bool IsIntel() |
| { |
| return angle::IsIntel(GetActiveGPUVendorID()); |
| } |
| |
| // Check whether the active GPU is VMWare. |
| inline bool IsVMWare() |
| { |
| return angle::IsVMWare(GetActiveGPUVendorID()); |
| } |
| |
| // Check whether this is a debug build. |
| inline bool IsDebug() |
| { |
| #if !defined(NDEBUG) |
| return true; |
| #else |
| return false; |
| #endif |
| } |
| |
| // Check whether this is a release build. |
| inline bool IsRelease() |
| { |
| return !IsDebug(); |
| } |
| |
| // Check whether the system is a specific Android device based on the name. |
| inline bool IsAndroidDevice(const std::string &deviceName) |
| { |
| if (!IsAndroid()) |
| { |
| return false; |
| } |
| SystemInfo *systemInfo = nullptr; |
| GetGPUTestSystemInfo(&systemInfo); |
| if (systemInfo->machineModelName == deviceName) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| // Check whether the system is a Nexus 5X device. |
| inline bool IsNexus5X() |
| { |
| return IsAndroidDevice("Nexus 5X"); |
| } |
| |
| // Check whether the system is a Pixel 2 device. |
| inline bool IsPixel2() |
| { |
| return IsAndroidDevice("Pixel 2"); |
| } |
| |
| // Check whether the system is a Pixel 2XL device. |
| inline bool IsPixel2XL() |
| { |
| return IsAndroidDevice("Pixel 2 XL"); |
| } |
| |
| // Check whether the active GPU is a specific device based on the string device ID. |
| inline bool IsDeviceIdGPU(const std::string &gpuDeviceId) |
| { |
| uint32_t deviceId = 0; |
| if (!HexStringToUInt(gpuDeviceId, &deviceId) || deviceId == 0) |
| { |
| // PushErrorMessage(kErrorMessage[kErrorEntryWithGpuDeviceIdConflicts], line_number); |
| return false; |
| } |
| return (deviceId == GetActiveGPUDeviceID()); |
| } |
| |
| // Check whether the active GPU is a NVIDIA Quadro P400 |
| inline bool IsNVIDIAQuadroP400() |
| { |
| if (!IsNVIDIA()) |
| { |
| return false; |
| } |
| return IsDeviceIdGPU("0x1CB3"); |
| } |
| |
| // Check whether the backend API has been set to D3D9 in the constructor |
| inline bool IsD3D9(const GPUTestConfig::API &api) |
| { |
| return (api == GPUTestConfig::kAPID3D9); |
| } |
| |
| // Check whether the backend API has been set to D3D11 in the constructor |
| inline bool IsD3D11(const GPUTestConfig::API &api) |
| { |
| return (api == GPUTestConfig::kAPID3D11); |
| } |
| |
| // Check whether the backend API has been set to OpenGL in the constructor |
| inline bool IsGLDesktop(const GPUTestConfig::API &api) |
| { |
| return (api == GPUTestConfig::kAPIGLDesktop); |
| } |
| |
| // Check whether the backend API has been set to OpenGLES in the constructor |
| inline bool IsGLES(const GPUTestConfig::API &api) |
| { |
| return (api == GPUTestConfig::kAPIGLES); |
| } |
| |
| // Check whether the backend API has been set to Vulkan in the constructor |
| inline bool IsVulkan(const GPUTestConfig::API &api) |
| { |
| return (api == GPUTestConfig::kAPIVulkan) || (api == GPUTestConfig::kAPISwiftShader); |
| } |
| |
| inline bool IsSwiftShader(const GPUTestConfig::API &api) |
| { |
| return (api == GPUTestConfig::kAPISwiftShader); |
| } |
| |
| // Check whether the backend API has been set to Metal in the constructor |
| inline bool IsMetal(const GPUTestConfig::API &api) |
| { |
| return (api == GPUTestConfig::kAPIMetal); |
| } |
| |
| } // anonymous namespace |
| |
| // Load all conditions in the constructor since this data will not change during a test set. |
| GPUTestConfig::GPUTestConfig() |
| { |
| mConditions[kConditionNone] = false; |
| mConditions[kConditionWinXP] = IsWinXP(); |
| mConditions[kConditionWinVista] = IsWinVista(); |
| mConditions[kConditionWin7] = IsWin7(); |
| mConditions[kConditionWin8] = IsWin8(); |
| mConditions[kConditionWin10] = IsWin10(); |
| mConditions[kConditionWin] = IsWin(); |
| mConditions[kConditionMacLeopard] = IsMacLeopard(); |
| mConditions[kConditionMacSnowLeopard] = IsMacSnowLeopard(); |
| mConditions[kConditionMacLion] = IsMacLion(); |
| mConditions[kConditionMacMountainLion] = IsMacMountainLion(); |
| mConditions[kConditionMacMavericks] = IsMacMavericks(); |
| mConditions[kConditionMacYosemite] = IsMacYosemite(); |
| mConditions[kConditionMacElCapitan] = IsMacElCapitan(); |
| mConditions[kConditionMacSierra] = IsMacSierra(); |
| mConditions[kConditionMacHighSierra] = IsMacHighSierra(); |
| mConditions[kConditionMacMojave] = IsMacMojave(); |
| mConditions[kConditionMac] = IsMac(); |
| mConditions[kConditionLinux] = IsLinux(); |
| mConditions[kConditionAndroid] = IsAndroid(); |
| mConditions[kConditionNVIDIA] = IsNVIDIA(); |
| mConditions[kConditionAMD] = IsAMD(); |
| mConditions[kConditionIntel] = IsIntel(); |
| mConditions[kConditionVMWare] = IsVMWare(); |
| mConditions[kConditionRelease] = IsRelease(); |
| mConditions[kConditionDebug] = IsDebug(); |
| // If no API provided, pass these conditions by default |
| mConditions[kConditionD3D9] = true; |
| mConditions[kConditionD3D11] = true; |
| mConditions[kConditionGLDesktop] = true; |
| mConditions[kConditionGLES] = true; |
| mConditions[kConditionVulkan] = true; |
| mConditions[kConditionSwiftShader] = true; |
| mConditions[kConditionMetal] = true; |
| |
| mConditions[kConditionNexus5X] = IsNexus5X(); |
| mConditions[kConditionPixel2OrXL] = IsPixel2() || IsPixel2XL(); |
| mConditions[kConditionNVIDIAQuadroP400] = IsNVIDIAQuadroP400(); |
| } |
| |
| // If the constructor is passed an API, load those conditions as well |
| GPUTestConfig::GPUTestConfig(const API &api) : GPUTestConfig() |
| { |
| mConditions[kConditionD3D9] = IsD3D9(api); |
| mConditions[kConditionD3D11] = IsD3D11(api); |
| mConditions[kConditionGLDesktop] = IsGLDesktop(api); |
| mConditions[kConditionGLES] = IsGLES(api); |
| mConditions[kConditionVulkan] = IsVulkan(api); |
| mConditions[kConditionSwiftShader] = IsSwiftShader(api); |
| mConditions[kConditionMetal] = IsMetal(api); |
| } |
| |
| // Return a const reference to the list of all pre-calculated conditions. |
| const GPUTestConfig::ConditionArray &GPUTestConfig::getConditions() const |
| { |
| return mConditions; |
| } |
| |
| } // namespace angle |