зеркало из https://github.com/AvaloniaUI/angle.git
Support ANGLE_PREFERRED_DEVICE on CGL
Add the possibility to test both integrated and discrete GPU with ANGLE tests. Previously it was using only discrete. The binaries need the NSSupportsAutomaticGraphicsSwitching bundle property. This is needed to test ANGLE_power_preference. Changes the behavior of test apps: Previously, ./angle_end2end_tests would use discrete GPU. After, ./angle_end2end_tests or ANGLE_PREFERRED_DEVICE=intel ./angle_end2end_tests will use integrated GPU. ANGLE_PREFERRED_DEVICE=amd ./angle_end2end_tests will use discrete GPU. Bug: angleproject:7093 Change-Id: Ia64f6024e3215e69c2a1bde3ba4f67c3ca595476 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3516114 Reviewed-by: Kenneth Russell <kbr@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Yuly Novikov <ynovikov@chromium.org>
This commit is contained in:
Родитель
23558369a5
Коммит
ba04fcfd10
15
BUILD.gn
15
BUILD.gn
|
@ -1413,6 +1413,21 @@ if (angle_standalone || build_with_chromium) {
|
|||
}
|
||||
}
|
||||
|
||||
if (angle_enable_cgl) {
|
||||
config("supports_automatic_graphics_switching") {
|
||||
# For discussion about config, inputs, etc, see:
|
||||
# https://bugs.chromium.org/p/chromium/issues/detail?id=781858
|
||||
_plist_file = "util/osx/supports_automatic_graphics_switching.plist"
|
||||
inputs = [ _plist_file ]
|
||||
ldflags = [
|
||||
"-sectcreate",
|
||||
"__TEXT",
|
||||
"__info_plist",
|
||||
rebase_path(_plist_file, root_build_dir),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (is_android && symbol_level != 0) {
|
||||
action_foreach("compressed_symbols") {
|
||||
sources = []
|
||||
|
|
|
@ -478,10 +478,15 @@ if (angle_standalone || build_with_chromium) {
|
|||
]
|
||||
}
|
||||
|
||||
if (is_mac && angle_enable_metal) {
|
||||
# On macOS, compiling Metal shader sometimes takes very long time due to internal caching
|
||||
# mechanism. This hooking library is a way to bypass this caching mechanism.
|
||||
data_deps += [ "$angle_root/src/libANGLE/renderer/metal/file_hooking:metal_shader_cache_file_hooking" ]
|
||||
if (is_mac) {
|
||||
if (angle_enable_metal) {
|
||||
# On macOS, compiling Metal shader sometimes takes very long time due to internal caching
|
||||
# mechanism. This hooking library is a way to bypass this caching mechanism.
|
||||
data_deps += [ "$angle_root/src/libANGLE/renderer/metal/file_hooking:metal_shader_cache_file_hooking" ]
|
||||
}
|
||||
if (angle_enable_cgl) {
|
||||
configs += [ "$angle_root:supports_automatic_graphics_switching" ]
|
||||
}
|
||||
}
|
||||
|
||||
if ((is_linux && !is_chromeos) ||
|
||||
|
|
|
@ -12,11 +12,18 @@
|
|||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "anglebase/no_destructor.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/string_utils.h"
|
||||
#include "common/system_utils.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
namespace
|
||||
{
|
||||
constexpr char kANGLEPreferredDeviceEnv[] = "ANGLE_PREFERRED_DEVICE";
|
||||
}
|
||||
|
||||
std::string VendorName(VendorID vendor)
|
||||
{
|
||||
switch (vendor)
|
||||
|
@ -102,6 +109,22 @@ bool SystemInfo::hasAMDGPU() const
|
|||
return false;
|
||||
}
|
||||
|
||||
std::optional<size_t> SystemInfo::getPreferredGPUIndex() const
|
||||
{
|
||||
std::string device = GetPreferredDeviceString();
|
||||
if (!device.empty())
|
||||
{
|
||||
for (size_t i = 0; i < gpus.size(); ++i)
|
||||
{
|
||||
std::string vendor = VendorName(gpus[i].vendorId);
|
||||
ToLower(&vendor);
|
||||
if (vendor == device)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool IsAMD(VendorID vendorId)
|
||||
{
|
||||
return vendorId == kVendorID_AMD;
|
||||
|
@ -385,4 +408,11 @@ uint32_t GetSystemDeviceIdLowPart(uint64_t systemDeviceId)
|
|||
return systemDeviceId & 0xffffffff;
|
||||
}
|
||||
|
||||
std::string GetPreferredDeviceString()
|
||||
{
|
||||
std::string device = angle::GetEnvironmentVar(kANGLEPreferredDeviceEnv);
|
||||
ToLower(&device);
|
||||
return device;
|
||||
}
|
||||
|
||||
} // namespace angle
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#define GPU_INFO_UTIL_SYSTEM_INFO_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -60,6 +61,9 @@ struct SystemInfo
|
|||
bool hasIntelGPU() const;
|
||||
bool hasAMDGPU() const;
|
||||
|
||||
// Returns the index to `gpus` if the entry matches the preferred device string.
|
||||
std::optional<size_t> getPreferredGPUIndex() const;
|
||||
|
||||
std::vector<GPUDeviceInfo> gpus;
|
||||
|
||||
// Index of the GPU expected to be used for 3D graphics. Based on a best-guess heuristic on
|
||||
|
@ -162,6 +166,9 @@ uint64_t GetSystemDeviceIdFromParts(uint32_t highPart, uint32_t lowPart);
|
|||
uint32_t GetSystemDeviceIdHighPart(uint64_t systemDeviceId);
|
||||
uint32_t GetSystemDeviceIdLowPart(uint64_t systemDeviceId);
|
||||
|
||||
// Returns lower-case of ANGLE_PREFERRED_DEVICE environment variable contents.
|
||||
std::string GetPreferredDeviceString();
|
||||
|
||||
} // namespace angle
|
||||
|
||||
#endif // GPU_INFO_UTIL_SYSTEM_INFO_H_
|
||||
|
|
|
@ -209,8 +209,26 @@ egl::Error DisplayCGL::initialize(egl::Display *display)
|
|||
|
||||
if (mSupportsGPUSwitching)
|
||||
{
|
||||
// Determine the currently active GPU on the system.
|
||||
mCurrentGPUID = angle::GetGpuIDFromDisplayID(kCGDirectMainDisplay);
|
||||
auto gpuIndex = info.getPreferredGPUIndex();
|
||||
if (gpuIndex)
|
||||
{
|
||||
auto gpuID = info.gpus[*gpuIndex].systemDeviceId;
|
||||
auto virtualScreen = GetVirtualScreenByRegistryID(mPixelFormat, gpuID);
|
||||
if (virtualScreen)
|
||||
{
|
||||
CGLError error = CGLSetVirtualScreen(mContext, *virtualScreen);
|
||||
ASSERT(error == kCGLNoError);
|
||||
if (error == kCGLNoError)
|
||||
{
|
||||
mCurrentGPUID = gpuID;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mCurrentGPUID == 0)
|
||||
{
|
||||
// Determine the currently active GPU on the system.
|
||||
mCurrentGPUID = angle::GetGpuIDFromDisplayID(kCGDirectMainDisplay);
|
||||
}
|
||||
}
|
||||
|
||||
if (CGLSetCurrentContext(mContext) != kCGLNoError)
|
||||
|
|
|
@ -33,10 +33,6 @@
|
|||
|
||||
#include "EGL/eglext.h"
|
||||
|
||||
#if defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_MACCATALYST)
|
||||
constexpr char kANGLEPreferredDeviceEnv[] = "ANGLE_PREFERRED_DEVICE";
|
||||
#endif
|
||||
|
||||
namespace rx
|
||||
{
|
||||
|
||||
|
@ -294,15 +290,13 @@ mtl::AutoObjCPtr<id<MTLDevice>> DisplayMtl::getMetalDeviceMatchingAttribute(
|
|||
}
|
||||
}
|
||||
|
||||
// Check the ANGLE_PREFERRED_DEVICE environment variable for device preference
|
||||
const std::string anglePreferredDevice = angle::GetEnvironmentVar(kANGLEPreferredDeviceEnv);
|
||||
if (anglePreferredDevice != "")
|
||||
const std::string preferredDeviceString = angle::GetPreferredDeviceString();
|
||||
if (!preferredDeviceString.empty())
|
||||
{
|
||||
for (id<MTLDevice> device in deviceList.get())
|
||||
{
|
||||
if ([device.name.lowercaseString
|
||||
containsString:[NSString stringWithUTF8String:anglePreferredDevice.c_str()]
|
||||
.lowercaseString])
|
||||
containsString:[NSString stringWithUTF8String:preferredDeviceString.c_str()]])
|
||||
{
|
||||
NSLog(@"Using Metal Device: %@", [device name]);
|
||||
return device;
|
||||
|
|
|
@ -19,13 +19,7 @@
|
|||
#include "util/OSWindow.h"
|
||||
|
||||
using namespace angle;
|
||||
namespace
|
||||
{
|
||||
// TODO(anglebug.com/7093): Implement bundling of Info.plist to angle_end2end_tests
|
||||
// In the mean time, change this manually to true and cp src/tests/end2end_tests/mac/Info.plist
|
||||
// out/Debug/
|
||||
const bool testRunnerSupportsAutomaticGraphicsSwitching = false;
|
||||
} // namespace
|
||||
|
||||
class EGLPowerPreferenceTest : public ANGLETest
|
||||
{
|
||||
public:
|
||||
|
@ -46,7 +40,6 @@ class EGLPowerPreferenceTest : public ANGLETest
|
|||
|
||||
TEST_P(EGLPowerPreferenceTest, ForceGPUSwitch)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!testRunnerSupportsAutomaticGraphicsSwitching);
|
||||
ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(getDisplay(), "EGL_ANGLE_power_preference"));
|
||||
size_t lowPower = FindLowPowerGPU(mSystemInfo);
|
||||
size_t highPower = FindHighPowerGPU(mSystemInfo);
|
||||
|
@ -69,14 +62,16 @@ TEST_P(EGLPowerPreferenceTest, ForceGPUSwitch)
|
|||
|
||||
TEST_P(EGLPowerPreferenceTest, HandleGPUSwitchAfterForceGPUSwitch)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!testRunnerSupportsAutomaticGraphicsSwitching);
|
||||
ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(getDisplay(), "EGL_ANGLE_power_preference"));
|
||||
size_t initialGPU = FindActiveOpenGLGPU(mSystemInfo);
|
||||
size_t changedGPU = FindLowPowerGPU(mSystemInfo);
|
||||
if (initialGPU == changedGPU)
|
||||
{
|
||||
changedGPU = FindHighPowerGPU(mSystemInfo);
|
||||
}
|
||||
// On all platforms the extension is implemented (e.g. CGL): If we start with integrated, and
|
||||
// force DGPU, we cannot eglHandleGPUSwitchANGLE() from DGPU to integrated.
|
||||
// eglHandleGPUSwitchANGLE() will switch to the "default", which will be DGPU.
|
||||
// If we start with DGPU and switch to integrated, we *can* eglHandleGPUSwitchANGLE() back
|
||||
// to the default, DGPU.
|
||||
ANGLE_SKIP_TEST_IF(initialGPU == changedGPU);
|
||||
|
||||
EGLint hi = 0;
|
||||
EGLint lo = 0;
|
||||
for (int i = 0; i < 5; ++i)
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>angle_end2end_tests</string>
|
||||
<string>angle_test</string> <!-- Generic name so we don't need per target .plist file.-->
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.chromium.angle.angle_end2end_tests</string>
|
||||
<string>org.chromium.angle.angle_test</string>
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<true/>
|
||||
</dict>
|
Загрузка…
Ссылка в новой задаче