Revert "Metal: Reintroduce GPU power preference selection code."

This reverts commit 017161701b.

Reason for revert: Blocking roller, please re-land with the fix.

Original change's description:
> Metal: Reintroduce GPU power preference selection code.
>
> This CL re-introduces the GPU power preference code to
> the metal backend. It also reworks EGLDisplay caching
> in the frontend to cache based on the native display
> as well as the power preference attribute.
> A new extension, EGL_ANGLE_display_power_preference is
> added based on EGL_ANGLE_power_preference. This extension
> is a client extension that allows selection of GPU on
> display creation, similar to how GPUs are selected on
> context creation in EGL_ANGLE_power_preference.
> This CL adds EGLDisplayPowerPreferenceTest and enables it on
> the metal backend.
>
> Bug: angleproject:6143
> Change-Id: I0a081dcd2e3f18ab365fdd3498ddcb6e2ba35212
> Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3231986
> Reviewed-by: Kenneth Russell <kbr@chromium.org>
> Reviewed-by: Jamie Madill <jmadill@chromium.org>
> Reviewed-by: Gregg Tavares <gman@chromium.org>
> Commit-Queue: Jonah Ryan-Davis <jonahr@google.com>

TBR=kbr@chromium.org,gman@chromium.org,jonahr@google.com,jmadill@chromium.org,angle-scoped@luci-project-accounts.iam.gserviceaccount.com

Change-Id: I4f775bf7139253a87b033a30e0da2100b3c1bb02
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: angleproject:6143
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3270749
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Jamie Madill 2021-11-09 15:10:50 +00:00 коммит произвёл Angle LUCI CQ
Родитель c9595b37ae
Коммит 67a8cf07a7
19 изменённых файлов: 23 добавлений и 563 удалений

Просмотреть файл

@ -1,84 +0,0 @@
Name
ANGLE_display_power_preference
Name Strings
EGL_ANGLE_display_power_preference
Contributors
Kenneth Russell
Jonah Ryan-Davis
Contacts
Kenneth Russell, Google Inc. (kbr 'at' google.com)
Jonah Ryan-Davis, Google Inc. (jonahr 'at' google.com)
Status
Draft
Version
Version 1, Oct 20, 2021
Number
EGL Extension #??
Extension Type
EGL client extension
Dependencies
This extension is written against the wording of the EGL 1.4
Specification.
Overview
This extension allows selection of the high- or low-power GPU on
dual-GPU systems, specifically on macOS.
New Types
None
New Tokens
Accepted as an attribute name in the <attrib_list> argument to
eglGetPlatformDisplayEXT:
EGL_POWER_PREFERENCE_ANGLE 0x3482
Accepted as an attribute value in the <attrib_list> argument to
eglGetPlatformDisplayEXT:
EGL_LOW_POWER_ANGLE 0x0001
EGL_HIGH_POWER_ANGLE 0x0002
Additions to the EGL 1.4 Specification
Add the following to section 3.7.1 "Creating Rendering Contexts":
EGL_POWER_PREFERENCE_ANGLE indicates whether the display should be
created on the integrated (low-power) or discrete (high-power) GPU
on dual-GPU systems. EGL_POWER_PREFERENCE_ANGLE is only a legal
display creation attribute when the EGL_ANGLE_power_preference
extension is advertised. The valid values for this attribute are
EGL_LOW_POWER_ANGLE and EGL_HIGH_POWER_ANGLE. If this extension is
advertised and this display creation attribute is not specified,
the default value is EGL_LOW_POWER_ANGLE.
Issues
None yet.
Revision History
Rev. Date Author Changes
---- ------------- --------- ----------------------------------------
1 Oct 20, 2021 jonahr Extension based off
EGL_ANGLE_power_preference

Просмотреть файл

@ -103,10 +103,10 @@ New Behavior
The <native_display> parameter is of type EGLNativeDisplayType. If The <native_display> parameter is of type EGLNativeDisplayType. If
<native_display> is EGL_DEFAULT_DISPLAY a default display is returned. <native_display> is EGL_DEFAULT_DISPLAY a default display is returned.
Multiple calls with the same parameters will return the same EGLDisplay Multiple calls with the same <native_display> will return the same
handle. If <platform> is set to EGL_PLATFORM_ANGLE_ANGLE and the returned EGLDisplay handle. If <platform> is set to EGL_PLATFORM_ANGLE_ANGLE and
display is in an uninitialized state, its attributes are overwritten by the returned display is in an uninitialized state, its attributes are
those provided in the <attrib_list>, if any. overwritten by those provided in the <attrib_list>, if any.
If no <attrib_list> is specified, the value of If no <attrib_list> is specified, the value of
EGL_PLATFORM_ANGLE_TYPE_ANGLE is implicitly set to EGL_PLATFORM_ANGLE_TYPE_ANGLE is implicitly set to

Просмотреть файл

@ -17,6 +17,8 @@
namespace angle namespace angle
{ {
namespace
{
std::string VendorName(VendorID vendor) std::string VendorName(VendorID vendor)
{ {
switch (vendor) switch (vendor)
@ -51,7 +53,7 @@ std::string VendorName(VendorID vendor)
return "Unknown (" + std::to_string(vendor) + ")"; return "Unknown (" + std::to_string(vendor) + ")";
} }
} }
} // anonymous namespace
GPUDeviceInfo::GPUDeviceInfo() = default; GPUDeviceInfo::GPUDeviceInfo() = default;
GPUDeviceInfo::~GPUDeviceInfo() = default; GPUDeviceInfo::~GPUDeviceInfo() = default;

Просмотреть файл

@ -129,9 +129,6 @@ bool IsVMWare(VendorID vendorId);
bool IsVivante(VendorID vendorId); bool IsVivante(VendorID vendorId);
bool IsApple(VendorID vendorId); bool IsApple(VendorID vendorId);
// Returns a readable vendor name given the VendorID
std::string VendorName(VendorID vendor);
// Use a heuristic to attempt to find the GPU used for 3D graphics. Sets activeGPUIndex, // Use a heuristic to attempt to find the GPU used for 3D graphics. Sets activeGPUIndex,
// isOptimus, and isAMDSwitchable. // isOptimus, and isAMDSwitchable.
// Always assumes the non-Intel GPU is active on dual-GPU machines. // Always assumes the non-Intel GPU is active on dual-GPU machines.

Просмотреть файл

@ -1346,7 +1346,6 @@ std::vector<std::string> ClientExtensions::getStrings() const
InsertExtensionString("EGL_KHR_client_get_all_proc_addresses", clientGetAllProcAddresses, &extensionStrings); InsertExtensionString("EGL_KHR_client_get_all_proc_addresses", clientGetAllProcAddresses, &extensionStrings);
InsertExtensionString("EGL_KHR_debug", debug, &extensionStrings); InsertExtensionString("EGL_KHR_debug", debug, &extensionStrings);
InsertExtensionString("EGL_ANGLE_feature_control", featureControlANGLE, &extensionStrings); InsertExtensionString("EGL_ANGLE_feature_control", featureControlANGLE, &extensionStrings);
InsertExtensionString("EGL_ANGLE_display_power_preference", displayPowerPreferenceANGLE, &extensionStrings);
// clang-format on // clang-format on
return extensionStrings; return extensionStrings;

Просмотреть файл

@ -734,9 +734,6 @@ struct ClientExtensions
// EGL_EXT_device_query // EGL_EXT_device_query
bool deviceQueryEXT = false; bool deviceQueryEXT = false;
// EGL_ANGLE_display_power_preference
bool displayPowerPreferenceANGLE = false;
}; };
} // namespace egl } // namespace egl

Просмотреть файл

@ -99,30 +99,7 @@ static WindowSurfaceMap *GetWindowSurfaces()
return windowSurfaces.get(); return windowSurfaces.get();
} }
struct ANGLEPlatformDisplay typedef std::map<EGLNativeDisplayType, Display *> ANGLEPlatformDisplayMap;
{
ANGLEPlatformDisplay() = default;
ANGLEPlatformDisplay(EGLNativeDisplayType nativeDisplayType)
: nativeDisplayType(nativeDisplayType), powerPreference(EGL_LOW_POWER_ANGLE)
{}
ANGLEPlatformDisplay(EGLNativeDisplayType nativeDisplayType, EGLAttrib powerPreference)
: nativeDisplayType(nativeDisplayType), powerPreference(powerPreference)
{}
auto tie() const { return std::tie(nativeDisplayType, powerPreference); }
EGLNativeDisplayType nativeDisplayType;
EGLAttrib powerPreference;
};
inline bool operator<(const ANGLEPlatformDisplay &a, const ANGLEPlatformDisplay &b)
{
return a.tie() < b.tie();
}
typedef std::map<ANGLEPlatformDisplay, Display *> ANGLEPlatformDisplayMap;
static ANGLEPlatformDisplayMap *GetANGLEPlatformDisplayMap() static ANGLEPlatformDisplayMap *GetANGLEPlatformDisplayMap()
{ {
static angle::base::NoDestructor<ANGLEPlatformDisplayMap> displays; static angle::base::NoDestructor<ANGLEPlatformDisplayMap> displays;
@ -641,9 +618,8 @@ Display *Display::GetDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay
{ {
Display *display = nullptr; Display *display = nullptr;
EGLAttrib powerPreference = attribMap.get(EGL_POWER_PREFERENCE_ANGLE, EGL_LOW_POWER_ANGLE);
ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap(); ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
const auto &iter = displays->find(ANGLEPlatformDisplay(nativeDisplay, powerPreference)); const auto &iter = displays->find(nativeDisplay);
if (iter != displays->end()) if (iter != displays->end())
{ {
display = iter->second; display = iter->second;
@ -658,9 +634,9 @@ Display *Display::GetDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay
} }
display = new Display(EGL_PLATFORM_ANGLE_ANGLE, nativeDisplay, nullptr); display = new Display(EGL_PLATFORM_ANGLE_ANGLE, nativeDisplay, nullptr);
displays->insert( displays->insert(std::make_pair(nativeDisplay, display));
std::make_pair(ANGLEPlatformDisplay(nativeDisplay, powerPreference), display));
} }
// Apply new attributes if the display is not initialized yet. // Apply new attributes if the display is not initialized yet.
if (!display->isInitialized()) if (!display->isInitialized())
{ {
@ -785,8 +761,7 @@ Display::~Display()
if (mPlatform == EGL_PLATFORM_ANGLE_ANGLE) if (mPlatform == EGL_PLATFORM_ANGLE_ANGLE)
{ {
ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap(); ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
ANGLEPlatformDisplayMap::iterator iter = displays->find(ANGLEPlatformDisplay( ANGLEPlatformDisplayMap::iterator iter = displays->find(mState.displayId);
mState.displayId, mAttributeMap.get(EGL_POWER_PREFERENCE_ANGLE, EGL_LOW_POWER_ANGLE)));
if (iter != displays->end()) if (iter != displays->end())
{ {
displays->erase(iter); displays->erase(iter);
@ -1799,10 +1774,6 @@ static ClientExtensions GenerateClientExtensions()
extensions.platformANGLEDeviceContextVolatileCgl = true; extensions.platformANGLEDeviceContextVolatileCgl = true;
#endif #endif
#if defined(ANGLE_ENABLE_METAL)
extensions.displayPowerPreferenceANGLE = true;
#endif
extensions.clientGetAllProcAddresses = true; extensions.clientGetAllProcAddresses = true;
extensions.debug = true; extensions.debug = true;
extensions.featureControlANGLE = true; extensions.featureControlANGLE = true;

Просмотреть файл

@ -309,6 +309,8 @@ void DisplayEAGL::generateExtensions(egl::DisplayExtensions *outExtensions) cons
outExtensions->displayTextureShareGroup = true; outExtensions->displayTextureShareGroup = true;
outExtensions->displaySemaphoreShareGroup = true; outExtensions->displaySemaphoreShareGroup = true;
outExtensions->powerPreference = false;
DisplayGL::generateExtensions(outExtensions); DisplayGL::generateExtensions(outExtensions);
} }

Просмотреть файл

@ -232,50 +232,8 @@ mtl::AutoObjCPtr<id<MTLDevice>> DisplayMtl::getMetalDeviceMatchingAttribute(
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
#if defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_MACCATALYST) #if defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_MACCATALYST)
auto deviceList = mtl::adoptObjCObj(MTLCopyAllDevices());
NSMutableArray<id<MTLDevice>> *externalGPUs = [[NSMutableArray alloc] init];
NSMutableArray<id<MTLDevice>> *integratedGPUs = [[NSMutableArray alloc] init];
NSMutableArray<id<MTLDevice>> *discreteGPUs = [[NSMutableArray alloc] init];
for (id<MTLDevice> device in deviceList.get())
{
if (device.removable)
{
[externalGPUs addObject:device];
}
else if (device.lowPower)
{
[integratedGPUs addObject:device];
}
else
{
[discreteGPUs addObject:device];
}
}
// TODO(kpiddington: External GPU support. Do we prefer high power / low bandwidth for general
// WebGL applications?
// Can we support hot-swapping in GPU's?
if (attribs.get(EGL_POWER_PREFERENCE_ANGLE, 0) == EGL_HIGH_POWER_ANGLE)
{
// Search for a discrete GPU first.
for (id<MTLDevice> device in discreteGPUs)
{
if (![device isHeadless])
return device;
}
}
else if (attribs.get(EGL_POWER_PREFERENCE_ANGLE, 0) == EGL_LOW_POWER_ANGLE)
{
// If we've selected a low power device, look through integrated devices.
for (id<MTLDevice> device in integratedGPUs)
{
if (![device isHeadless])
return device;
}
}
// Check the ANGLE_PREFERRED_DEVICE environment variable for device preference
const std::string anglePreferredDevice = angle::GetEnvironmentVar(kANGLEPreferredDeviceEnv); const std::string anglePreferredDevice = angle::GetEnvironmentVar(kANGLEPreferredDeviceEnv);
auto deviceList = mtl::adoptObjCObj(MTLCopyAllDevices());
if (anglePreferredDevice != "") if (anglePreferredDevice != "")
{ {
for (id<MTLDevice> device in deviceList.get()) for (id<MTLDevice> device in deviceList.get())
@ -290,17 +248,11 @@ mtl::AutoObjCPtr<id<MTLDevice>> DisplayMtl::getMetalDeviceMatchingAttribute(
} }
} }
// Default to use a low power device, look through integrated devices. // TODO(anglebug.com/6143): reintroduce Apple's GPU selection code
for (id<MTLDevice> device in integratedGPUs) // under a run-time check; don't perform it on macOS versions
{ // earlier than 10.15. Respecify EGL_ANGLE_power_preference to
if (![device isHeadless]) // allow it to be used at display creation time rather than
return device; // context creation time.
}
// If we selected a low power device and there's no low-power devices avaialble, return the
// first (default) device.
if (deviceList.get().count > 0)
return deviceList[0];
#endif #endif
// If we can't find anything, or are on a platform that doesn't support power options, create a // If we can't find anything, or are on a platform that doesn't support power options, create a
// default device. // default device.
@ -466,6 +418,7 @@ void DisplayMtl::generateExtensions(egl::DisplayExtensions *outExtensions) const
// this extension so that ANGLE can be initialized in Chrome. WebGL will fail to use // this extension so that ANGLE can be initialized in Chrome. WebGL will fail to use
// this extension (anglebug.com/4929) // this extension (anglebug.com/4929)
outExtensions->robustResourceInitializationANGLE = true; outExtensions->robustResourceInitializationANGLE = true;
outExtensions->powerPreference = true;
// EGL_KHR_image // EGL_KHR_image
outExtensions->image = true; outExtensions->image = true;

Просмотреть файл

@ -883,25 +883,6 @@ bool ValidateGetPlatformDisplayCommon(const ValidationContext *val,
UNREACHABLE(); UNREACHABLE();
} }
if (attribMap.contains(EGL_POWER_PREFERENCE_ANGLE))
{
if (!clientExtensions.displayPowerPreferenceANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"Attribute EGL_POWER_PREFERENCE_ANGLE "
"requires EGL_ANGLE_display_power_preference.");
return false;
}
EGLAttrib value = attribMap.get(EGL_POWER_PREFERENCE_ANGLE, 0);
if (value != EGL_LOW_POWER_ANGLE && value != EGL_HIGH_POWER_ANGLE)
{
val->setError(EGL_BAD_ATTRIBUTE,
"EGL_POWER_PREFERENCE_ANGLE must be "
"either EGL_LOW_POWER_ANGLE or EGL_HIGH_POWER_ANGLE.");
return false;
}
}
if (attribMap.contains(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE)) if (attribMap.contains(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE))
{ {
if (!clientExtensions.featureControlANGLE) if (!clientExtensions.featureControlANGLE)

Просмотреть файл

@ -13,7 +13,6 @@ angle_end2end_tests_sources = [
"egl_tests/EGLContextSharingTest.cpp", "egl_tests/EGLContextSharingTest.cpp",
"egl_tests/EGLCreateContextAttribsTest.cpp", "egl_tests/EGLCreateContextAttribsTest.cpp",
"egl_tests/EGLDebugTest.cpp", "egl_tests/EGLDebugTest.cpp",
"egl_tests/EGLDisplayPowerPreferenceTest.cpp",
"egl_tests/EGLMultiContextTest.cpp", "egl_tests/EGLMultiContextTest.cpp",
"egl_tests/EGLNoConfigContextTest.cpp", "egl_tests/EGLNoConfigContextTest.cpp",
"egl_tests/EGLPreRotationTest.cpp", "egl_tests/EGLPreRotationTest.cpp",

Просмотреть файл

@ -156,7 +156,6 @@
6418 MAC NVIDIA METAL : UniformBlockWithOneLargeArrayMemberTest.TwoUniformBlocksInDiffProgram/ES3_Metal = SKIP 6418 MAC NVIDIA METAL : UniformBlockWithOneLargeArrayMemberTest.TwoUniformBlocksInDiffProgram/ES3_Metal = SKIP
6418 MAC NVIDIA METAL : UniformBlockWithOneLargeArrayMemberTest.TwoUniformBlocksInSameProgram/ES3_Metal = SKIP 6418 MAC NVIDIA METAL : UniformBlockWithOneLargeArrayMemberTest.TwoUniformBlocksInSameProgram/ES3_Metal = SKIP
6418 MAC NVIDIA METAL : UniformBlockWithOneLargeArrayMemberTest.SharedSameBufferWithOtherOne/ES3_Metal = SKIP 6418 MAC NVIDIA METAL : UniformBlockWithOneLargeArrayMemberTest.SharedSameBufferWithOtherOne/ES3_Metal = SKIP
6418 MAC NVIDIA METAL : UniformBlockWithOneLargeArrayMemberTest.MemberTypeIsStruct/ES3_Metal = SKIP
6418 MAC APPLE METAL : UniformBlockWithOneLargeArrayMemberTest.MemberTypeIsMatrixAndInstanced/ES3_Metal = SKIP 6418 MAC APPLE METAL : UniformBlockWithOneLargeArrayMemberTest.MemberTypeIsMatrixAndInstanced/ES3_Metal = SKIP
6418 MAC APPLE METAL : UniformBlockWithOneLargeArrayMemberTest.MemberTypeIsStructAndInstancedArray/ES3_Metal = SKIP 6418 MAC APPLE METAL : UniformBlockWithOneLargeArrayMemberTest.MemberTypeIsStructAndInstancedArray/ES3_Metal = SKIP

Просмотреть файл

@ -1,288 +0,0 @@
//
// Copyright 2021 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.
//
// EGLPowerPreferenceTest.cpp:
// EGL extension EGL_ANGLE_display_power_preference
//
#include <gtest/gtest.h>
#include "common/debug.h"
#include "gpu_info_util/SystemInfo.h"
#include "test_utils/ANGLETest.h"
#include "util/OSWindow.h"
using namespace angle;
class EGLDisplayPowerPreferenceTest : public ANGLETest
{
public:
void testSetUp() override { (void)GetSystemInfo(&mSystemInfo); }
protected:
// Returns the index of the low or high power GPU in SystemInfo depending on the argument.
int findGPU(bool lowPower)
{
if (mSystemInfo.gpus.size() < 2)
{
return 0;
}
for (int i = 0; i < static_cast<int>(mSystemInfo.gpus.size()); ++i)
{
if (lowPower && IsIntel(mSystemInfo.gpus[i].vendorId))
{
return i;
}
// Return the high power GPU, i.e any non-intel GPU
else if (!lowPower && !IsIntel(mSystemInfo.gpus[i].vendorId))
{
return i;
}
}
ASSERT(false);
return 0;
}
// Returns the index of the active GPU in SystemInfo based on the renderer string.
int findActiveGPU()
{
char *renderer = (char *)glGetString(GL_RENDERER);
std::string rendererString(renderer);
for (int i = 0; i < static_cast<int>(mSystemInfo.gpus.size()); ++i)
{
if (rendererString.find(VendorName(mSystemInfo.gpus[i].vendorId)) != std::string::npos)
{
return i;
}
}
return 0;
}
SystemInfo mSystemInfo;
};
class EGLDisplayPowerPreferenceTestMultiDisplay : public EGLDisplayPowerPreferenceTest
{
protected:
void terminateWindow()
{
if (mOSWindow)
{
OSWindow::Delete(&mOSWindow);
}
}
void terminateDisplay(EGLDisplay display)
{
// EXPECT_EGL_TRUE(eglTerminate(display));
// EXPECT_EGL_SUCCESS();
}
void terminateContext(EGLDisplay display, EGLContext context)
{
if (context != EGL_NO_CONTEXT)
{
eglDestroyContext(display, context);
ASSERT_EGL_SUCCESS();
}
}
void initializeWindow()
{
mOSWindow = OSWindow::New();
mOSWindow->initialize("EGLDisplayPowerPreferenceTestMultiDisplay", kWindowWidth,
kWindowHeight);
setWindowVisible(mOSWindow, true);
}
void initializeDisplayWithPowerPreference(EGLDisplay *display, EGLAttrib powerPreference)
{
GLenum platformType = GetParam().getRenderer();
GLenum deviceType = GetParam().getDeviceType();
std::vector<EGLint> displayAttributes;
displayAttributes.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
displayAttributes.push_back(platformType);
displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE);
displayAttributes.push_back(EGL_DONT_CARE);
displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE);
displayAttributes.push_back(EGL_DONT_CARE);
displayAttributes.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
displayAttributes.push_back(deviceType);
displayAttributes.push_back(EGL_POWER_PREFERENCE_ANGLE);
displayAttributes.push_back(powerPreference);
displayAttributes.push_back(EGL_NONE);
*display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,
reinterpret_cast<void *>(mOSWindow->getNativeDisplay()),
displayAttributes.data());
ASSERT_TRUE(*display != EGL_NO_DISPLAY);
EGLint majorVersion, minorVersion;
ASSERT_TRUE(eglInitialize(*display, &majorVersion, &minorVersion) == EGL_TRUE);
eglBindAPI(EGL_OPENGL_ES_API);
ASSERT_EGL_SUCCESS();
}
void initializeContextForDisplay(EGLDisplay display, EGLContext *context)
{
// Find a default config.
const EGLint configAttributes[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, EGL_DONT_CARE, EGL_GREEN_SIZE,
EGL_DONT_CARE, EGL_BLUE_SIZE, EGL_DONT_CARE, EGL_ALPHA_SIZE, EGL_DONT_CARE,
EGL_DEPTH_SIZE, EGL_DONT_CARE, EGL_STENCIL_SIZE, EGL_DONT_CARE, EGL_NONE};
EGLint configCount;
EGLConfig config;
EGLint ret = eglChooseConfig(display, configAttributes, &config, 1, &configCount);
if (!ret || configCount == 0)
{
return;
}
EGLint contextAttributes[] = {
EGL_CONTEXT_MAJOR_VERSION_KHR,
GetParam().majorVersion,
EGL_CONTEXT_MINOR_VERSION_KHR,
GetParam().minorVersion,
EGL_NONE,
};
*context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes);
ASSERT_TRUE(*context != EGL_NO_CONTEXT);
}
void runReinitializeDisplay(EGLAttrib powerPreference)
{
initializeWindow();
// Initialize the display with the selected power preferenc
EGLDisplay display;
EGLContext context;
initializeDisplayWithPowerPreference(&display, powerPreference);
initializeContextForDisplay(display, &context);
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, context);
bool lowPower = (powerPreference == EGL_LOW_POWER_ANGLE);
ASSERT_EQ(findGPU(lowPower), findActiveGPU());
// Terminate the display
terminateContext(display, context);
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
terminateDisplay(display);
// Change the power preference
if (powerPreference == EGL_LOW_POWER_ANGLE)
{
powerPreference = EGL_HIGH_POWER_ANGLE;
}
else
{
powerPreference = EGL_LOW_POWER_ANGLE;
}
// Reinitialize the display with a new power preference
initializeDisplayWithPowerPreference(&display, powerPreference);
initializeContextForDisplay(display, &context);
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, context);
// Expect that the power preference has changed
lowPower = (powerPreference == EGL_LOW_POWER_ANGLE);
ASSERT_EQ(findGPU(lowPower), findActiveGPU());
// Terminate the display
terminateContext(display, context);
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
terminateDisplay(display);
terminateWindow();
}
void runMultiDisplay()
{
initializeWindow();
// Initialize the first display with low power
EGLDisplay display1;
EGLContext context1;
initializeDisplayWithPowerPreference(&display1, EGL_LOW_POWER_ANGLE);
initializeContextForDisplay(display1, &context1);
eglMakeCurrent(display1, EGL_NO_SURFACE, EGL_NO_SURFACE, context1);
ASSERT_EQ(findGPU(true), findActiveGPU());
// Initialize the second display with high power
EGLDisplay display2;
EGLContext context2;
initializeDisplayWithPowerPreference(&display2, EGL_HIGH_POWER_ANGLE);
initializeContextForDisplay(display2, &context2);
eglMakeCurrent(display2, EGL_NO_SURFACE, EGL_NO_SURFACE, context2);
ASSERT_EQ(findGPU(false), findActiveGPU());
// Switch back to the first display to verify
eglMakeCurrent(display1, EGL_NO_SURFACE, EGL_NO_SURFACE, context1);
ASSERT_EQ(findGPU(true), findActiveGPU());
// Terminate the displays
terminateContext(display1, context1);
eglMakeCurrent(display1, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
terminateDisplay(display1);
terminateContext(display2, context2);
eglMakeCurrent(display2, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
terminateDisplay(display2);
terminateWindow();
}
static constexpr int kWindowWidth = 16;
static constexpr int kWindowHeight = 8;
OSWindow *mOSWindow = nullptr;
};
TEST_P(EGLDisplayPowerPreferenceTest, SelectGPU)
{
ANGLE_SKIP_TEST_IF(!IsEGLClientExtensionEnabled("EGL_ANGLE_display_power_preference"));
ASSERT_NE(GetParam().eglParameters.displayPowerPreference, EGL_DONT_CARE);
bool lowPower = (GetParam().eglParameters.displayPowerPreference == EGL_LOW_POWER_ANGLE);
ASSERT_EQ(findGPU(lowPower), findActiveGPU());
}
TEST_P(EGLDisplayPowerPreferenceTestMultiDisplay, ReInitializePowerPreferenceLowToHigh)
{
ANGLE_SKIP_TEST_IF(!IsEGLClientExtensionEnabled("EGL_ANGLE_display_power_preference"));
runReinitializeDisplay(EGL_LOW_POWER_ANGLE);
}
TEST_P(EGLDisplayPowerPreferenceTestMultiDisplay, ReInitializePowerPreferenceHighToLow)
{
ANGLE_SKIP_TEST_IF(!IsEGLClientExtensionEnabled("EGL_ANGLE_display_power_preference"));
runReinitializeDisplay(EGL_HIGH_POWER_ANGLE);
}
TEST_P(EGLDisplayPowerPreferenceTestMultiDisplay, MultiDisplayTest)
{
ANGLE_SKIP_TEST_IF(!IsEGLClientExtensionEnabled("EGL_ANGLE_display_power_preference"));
runMultiDisplay();
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLDisplayPowerPreferenceTest);
ANGLE_INSTANTIATE_TEST(EGLDisplayPowerPreferenceTest,
WithLowPowerGPU(ES2_METAL()),
WithLowPowerGPU(ES3_METAL()),
WithHighPowerGPU(ES2_METAL()),
WithHighPowerGPU(ES3_METAL()));
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLDisplayPowerPreferenceTestMultiDisplay);
ANGLE_INSTANTIATE_TEST(EGLDisplayPowerPreferenceTestMultiDisplay,
WithNoFixture(ES2_METAL()),
WithNoFixture(ES3_METAL()));

Просмотреть файл

@ -298,16 +298,6 @@ std::ostream &operator<<(std::ostream &stream, const PlatformParameters &pp)
stream << "_FallbackFormat"; stream << "_FallbackFormat";
} }
if (pp.eglParameters.displayPowerPreference == EGL_LOW_POWER_ANGLE)
{
stream << "_LowPowerGPU";
}
if (pp.eglParameters.displayPowerPreference == EGL_HIGH_POWER_ANGLE)
{
stream << "_HighPowerGPU";
}
return stream; return stream;
} }

Просмотреть файл

@ -313,20 +313,6 @@ inline PlatformParameters WithForceVulkanFallbackFormat(const PlatformParameters
paramsOut.eglParameters.forceVulkanFallbackFormat = EGL_TRUE; paramsOut.eglParameters.forceVulkanFallbackFormat = EGL_TRUE;
return paramsOut; return paramsOut;
} }
inline PlatformParameters WithLowPowerGPU(const PlatformParameters &paramsIn)
{
PlatformParameters paramsOut = paramsIn;
paramsOut.eglParameters.displayPowerPreference = EGL_LOW_POWER_ANGLE;
return paramsOut;
}
inline PlatformParameters WithHighPowerGPU(const PlatformParameters &paramsIn)
{
PlatformParameters paramsOut = paramsIn;
paramsOut.eglParameters.displayPowerPreference = EGL_HIGH_POWER_ANGLE;
return paramsOut;
}
} // namespace angle } // namespace angle
#endif // ANGLE_TEST_CONFIGS_H_ #endif // ANGLE_TEST_CONFIGS_H_

Просмотреть файл

@ -1038,8 +1038,7 @@ TestSuite::TestSuite(int *argc, char **argv)
mBatchId(-1), mBatchId(-1),
mFlakyRetries(0), mFlakyRetries(0),
mMaxFailures(kDefaultMaxFailures), mMaxFailures(kDefaultMaxFailures),
mFailureCount(0), mFailureCount(0)
mModifiedPreferredDevice(false)
{ {
ASSERT(mInstance == nullptr); ASSERT(mInstance == nullptr);
mInstance = this; mInstance = this;
@ -1130,34 +1129,6 @@ TestSuite::TestSuite(int *argc, char **argv)
} }
} }
// The test harness reads the active GPU from SystemInfo and uses that for test expectations.
// However, some ANGLE backends don't have a concept of an "active" GPU, and instead use power
// preference to select GPU. We can use the environment variable ANGLE_PREFERRED_DEVICE to
// ensure ANGLE's selected GPU matches the GPU expected for this test suite.
const GPUTestConfig testConfig = GPUTestConfig();
const char kPreferredDeviceEnvVar[] = "ANGLE_PREFERRED_DEVICE";
if (GetEnvironmentVar(kPreferredDeviceEnvVar).empty())
{
mModifiedPreferredDevice = true;
const GPUTestConfig::ConditionArray &conditions = testConfig.getConditions();
if (conditions[GPUTestConfig::kConditionAMD])
{
SetEnvironmentVar(kPreferredDeviceEnvVar, "amd");
}
else if (conditions[GPUTestConfig::kConditionNVIDIA])
{
SetEnvironmentVar(kPreferredDeviceEnvVar, "nvidia");
}
else if (conditions[GPUTestConfig::kConditionIntel])
{
SetEnvironmentVar(kPreferredDeviceEnvVar, "intel");
}
else if (conditions[GPUTestConfig::kConditionApple])
{
SetEnvironmentVar(kPreferredDeviceEnvVar, "apple");
}
}
if ((mShardIndex == -1) != (mShardCount == -1)) if ((mShardIndex == -1) != (mShardCount == -1))
{ {
printf("Shard index and shard count must be specified together.\n"); printf("Shard index and shard count must be specified together.\n");
@ -1312,12 +1283,6 @@ TestSuite::TestSuite(int *argc, char **argv)
TestSuite::~TestSuite() TestSuite::~TestSuite()
{ {
const char kPreferredDeviceEnvVar[] = "ANGLE_PREFERRED_DEVICE";
if (mModifiedPreferredDevice && !angle::GetEnvironmentVar(kPreferredDeviceEnvVar).empty())
{
angle::UnsetEnvironmentVar(kPreferredDeviceEnvVar);
}
if (mWatchdogThread.joinable()) if (mWatchdogThread.joinable())
{ {
mWatchdogThread.detach(); mWatchdogThread.detach();

Просмотреть файл

@ -198,7 +198,6 @@ class TestSuite
int mFlakyRetries; int mFlakyRetries;
int mMaxFailures; int mMaxFailures;
int mFailureCount; int mFailureCount;
bool mModifiedPreferredDevice;
std::vector<std::string> mChildProcessArgs; std::vector<std::string> mChildProcessArgs;
std::map<TestIdentifier, FileLine> mTestFileLines; std::map<TestIdentifier, FileLine> mTestFileLines;
std::vector<ProcessInfo> mCurrentProcesses; std::vector<ProcessInfo> mCurrentProcesses;

Просмотреть файл

@ -66,8 +66,7 @@ struct EGLPlatformParameters
hasExplicitMemBarrierFeatureMtl, hasCheapRenderPassFeatureMtl, hasExplicitMemBarrierFeatureMtl, hasCheapRenderPassFeatureMtl,
forceBufferGPUStorageFeatureMtl, supportsVulkanViewportFlip, emulatedVAOs, forceBufferGPUStorageFeatureMtl, supportsVulkanViewportFlip, emulatedVAOs,
generateSPIRVThroughGlslang, captureLimits, forceRobustResourceInit, generateSPIRVThroughGlslang, captureLimits, forceRobustResourceInit,
directMetalGeneration, forceInitShaderVariables, forceVulkanFallbackFormat, directMetalGeneration, forceInitShaderVariables, forceVulkanFallbackFormat);
displayPowerPreference);
} }
EGLint renderer = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE; EGLint renderer = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
@ -95,7 +94,6 @@ struct EGLPlatformParameters
EGLint directMetalGeneration = EGL_DONT_CARE; EGLint directMetalGeneration = EGL_DONT_CARE;
EGLint forceInitShaderVariables = EGL_DONT_CARE; EGLint forceInitShaderVariables = EGL_DONT_CARE;
EGLint forceVulkanFallbackFormat = EGL_DONT_CARE; EGLint forceVulkanFallbackFormat = EGL_DONT_CARE;
EGLint displayPowerPreference = EGL_DONT_CARE;
angle::PlatformMethods *platformMethods = nullptr; angle::PlatformMethods *platformMethods = nullptr;
}; };

Просмотреть файл

@ -196,12 +196,6 @@ bool EGLWindow::initializeDisplay(OSWindow *osWindow,
displayAttributes.push_back(reinterpret_cast<EGLAttrib>(params.platformMethods)); displayAttributes.push_back(reinterpret_cast<EGLAttrib>(params.platformMethods));
} }
if (params.displayPowerPreference != EGL_DONT_CARE)
{
displayAttributes.push_back(EGL_POWER_PREFERENCE_ANGLE);
displayAttributes.push_back(params.displayPowerPreference);
}
std::vector<const char *> disabledFeatureOverrides; std::vector<const char *> disabledFeatureOverrides;
std::vector<const char *> enabledFeatureOverrides; std::vector<const char *> enabledFeatureOverrides;