1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // Tests the eglQueryStringiANGLE and eglQueryDisplayAttribANGLE functions exposed by the
7*8975f5c5SAndroid Build Coastguard Worker // extension EGL_ANGLE_feature_control.
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include <gtest/gtest.h>
10*8975f5c5SAndroid Build Coastguard Worker #include <optional>
11*8975f5c5SAndroid Build Coastguard Worker
12*8975f5c5SAndroid Build Coastguard Worker #include "common/string_utils.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Display.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
15*8975f5c5SAndroid Build Coastguard Worker
16*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
17*8975f5c5SAndroid Build Coastguard Worker
18*8975f5c5SAndroid Build Coastguard Worker class EGLFeatureControlTest : public ANGLETest<>
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker public:
testSetUp()21*8975f5c5SAndroid Build Coastguard Worker void testSetUp() override { mDisplay = EGL_NO_DISPLAY; }
22*8975f5c5SAndroid Build Coastguard Worker
testTearDown()23*8975f5c5SAndroid Build Coastguard Worker void testTearDown() override
24*8975f5c5SAndroid Build Coastguard Worker {
25*8975f5c5SAndroid Build Coastguard Worker if (mDisplay != EGL_NO_DISPLAY)
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker eglTerminate(mDisplay);
28*8975f5c5SAndroid Build Coastguard Worker }
29*8975f5c5SAndroid Build Coastguard Worker }
30*8975f5c5SAndroid Build Coastguard Worker
31*8975f5c5SAndroid Build Coastguard Worker protected:
32*8975f5c5SAndroid Build Coastguard Worker EGLDisplay mDisplay;
33*8975f5c5SAndroid Build Coastguard Worker
initTest()34*8975f5c5SAndroid Build Coastguard Worker bool initTest()
35*8975f5c5SAndroid Build Coastguard Worker {
36*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42262291 This test sporadically times out on Win10/Intel
37*8975f5c5SAndroid Build Coastguard Worker if (IsWindows() && IsIntel())
38*8975f5c5SAndroid Build Coastguard Worker return false;
39*8975f5c5SAndroid Build Coastguard Worker
40*8975f5c5SAndroid Build Coastguard Worker EGLAttrib dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(), EGL_NONE};
41*8975f5c5SAndroid Build Coastguard Worker mDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
42*8975f5c5SAndroid Build Coastguard Worker reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
43*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(mDisplay, EGL_NO_DISPLAY);
44*8975f5c5SAndroid Build Coastguard Worker
45*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(eglInitialize(mDisplay, nullptr, nullptr), static_cast<EGLBoolean>(EGL_TRUE));
46*8975f5c5SAndroid Build Coastguard Worker
47*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(IsEGLClientExtensionEnabled("EGL_ANGLE_feature_control"));
48*8975f5c5SAndroid Build Coastguard Worker
49*8975f5c5SAndroid Build Coastguard Worker return true;
50*8975f5c5SAndroid Build Coastguard Worker }
51*8975f5c5SAndroid Build Coastguard Worker
52*8975f5c5SAndroid Build Coastguard Worker using FeatureNameModifier = std::function<std::string(const std::string &)>;
53*8975f5c5SAndroid Build Coastguard Worker void testOverrideFeatures(FeatureNameModifier modifyName);
54*8975f5c5SAndroid Build Coastguard Worker };
55*8975f5c5SAndroid Build Coastguard Worker
56*8975f5c5SAndroid Build Coastguard Worker // Ensure eglQueryStringiANGLE generates EGL_BAD_DISPLAY if the display passed in is invalid.
TEST_P(EGLFeatureControlTest,InvalidDisplay)57*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLFeatureControlTest, InvalidDisplay)
58*8975f5c5SAndroid Build Coastguard Worker {
59*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!initTest());
60*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, eglQueryStringiANGLE(EGL_NO_DISPLAY, EGL_FEATURE_NAME_ANGLE, 0));
61*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);
62*8975f5c5SAndroid Build Coastguard Worker }
63*8975f5c5SAndroid Build Coastguard Worker
64*8975f5c5SAndroid Build Coastguard Worker // Ensure eglQueryStringiANGLE generates EGL_BAD_PARAMETER if the index is negative.
TEST_P(EGLFeatureControlTest,NegativeIndex)65*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLFeatureControlTest, NegativeIndex)
66*8975f5c5SAndroid Build Coastguard Worker {
67*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!initTest());
68*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, eglQueryStringiANGLE(mDisplay, EGL_FEATURE_NAME_ANGLE, -1));
69*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
70*8975f5c5SAndroid Build Coastguard Worker }
71*8975f5c5SAndroid Build Coastguard Worker
72*8975f5c5SAndroid Build Coastguard Worker // Ensure eglQueryStringiANGLE generates EGL_BAD_PARAMETER if the index is out of bounds.
TEST_P(EGLFeatureControlTest,IndexOutOfBounds)73*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLFeatureControlTest, IndexOutOfBounds)
74*8975f5c5SAndroid Build Coastguard Worker {
75*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!initTest());
76*8975f5c5SAndroid Build Coastguard Worker egl::Display *display = static_cast<egl::Display *>(mDisplay);
77*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, eglQueryStringiANGLE(mDisplay, EGL_FEATURE_NAME_ANGLE,
78*8975f5c5SAndroid Build Coastguard Worker display->getFeatures().size()));
79*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
80*8975f5c5SAndroid Build Coastguard Worker }
81*8975f5c5SAndroid Build Coastguard Worker
82*8975f5c5SAndroid Build Coastguard Worker // Ensure eglQueryStringiANGLE generates EGL_BAD_PARAMETER if the name is not one of the valid
83*8975f5c5SAndroid Build Coastguard Worker // options specified in EGL_ANGLE_feature_control.
TEST_P(EGLFeatureControlTest,InvalidName)84*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLFeatureControlTest, InvalidName)
85*8975f5c5SAndroid Build Coastguard Worker {
86*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!initTest());
87*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, eglQueryStringiANGLE(mDisplay, 100, 0));
88*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
89*8975f5c5SAndroid Build Coastguard Worker }
90*8975f5c5SAndroid Build Coastguard Worker
91*8975f5c5SAndroid Build Coastguard Worker // For each valid name and index in the feature description arrays, query the values and ensure
92*8975f5c5SAndroid Build Coastguard Worker // that no error is generated, and that the values match the correct values frim ANGLE's display's
93*8975f5c5SAndroid Build Coastguard Worker // FeatureList.
TEST_P(EGLFeatureControlTest,QueryAll)94*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLFeatureControlTest, QueryAll)
95*8975f5c5SAndroid Build Coastguard Worker {
96*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!initTest());
97*8975f5c5SAndroid Build Coastguard Worker egl::Display *display = static_cast<egl::Display *>(mDisplay);
98*8975f5c5SAndroid Build Coastguard Worker angle::FeatureList features = display->getFeatures();
99*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < features.size(); i++)
100*8975f5c5SAndroid Build Coastguard Worker {
101*8975f5c5SAndroid Build Coastguard Worker EXPECT_STREQ(features[i]->name, eglQueryStringiANGLE(mDisplay, EGL_FEATURE_NAME_ANGLE, i));
102*8975f5c5SAndroid Build Coastguard Worker EXPECT_STREQ(FeatureCategoryToString(features[i]->category),
103*8975f5c5SAndroid Build Coastguard Worker eglQueryStringiANGLE(mDisplay, EGL_FEATURE_CATEGORY_ANGLE, i));
104*8975f5c5SAndroid Build Coastguard Worker EXPECT_STREQ(FeatureStatusToString(features[i]->enabled),
105*8975f5c5SAndroid Build Coastguard Worker eglQueryStringiANGLE(mDisplay, EGL_FEATURE_STATUS_ANGLE, i));
106*8975f5c5SAndroid Build Coastguard Worker ASSERT_EGL_SUCCESS();
107*8975f5c5SAndroid Build Coastguard Worker }
108*8975f5c5SAndroid Build Coastguard Worker }
109*8975f5c5SAndroid Build Coastguard Worker
110*8975f5c5SAndroid Build Coastguard Worker // Ensure eglQueryDisplayAttribANGLE returns the correct number of features when queried with
111*8975f5c5SAndroid Build Coastguard Worker // attribute EGL_FEATURE_COUNT_ANGLE
TEST_P(EGLFeatureControlTest,FeatureCount)112*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLFeatureControlTest, FeatureCount)
113*8975f5c5SAndroid Build Coastguard Worker {
114*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!initTest());
115*8975f5c5SAndroid Build Coastguard Worker egl::Display *display = static_cast<egl::Display *>(mDisplay);
116*8975f5c5SAndroid Build Coastguard Worker EGLAttrib value = -1;
117*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<EGLBoolean>(EGL_TRUE),
118*8975f5c5SAndroid Build Coastguard Worker eglQueryDisplayAttribANGLE(mDisplay, EGL_FEATURE_COUNT_ANGLE, &value));
119*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(display->getFeatures().size(), static_cast<size_t>(value));
120*8975f5c5SAndroid Build Coastguard Worker ASSERT_EGL_SUCCESS();
121*8975f5c5SAndroid Build Coastguard Worker }
122*8975f5c5SAndroid Build Coastguard Worker
testOverrideFeatures(FeatureNameModifier modifyName)123*8975f5c5SAndroid Build Coastguard Worker void EGLFeatureControlTest::testOverrideFeatures(FeatureNameModifier modifyName)
124*8975f5c5SAndroid Build Coastguard Worker {
125*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!initTest());
126*8975f5c5SAndroid Build Coastguard Worker egl::Display *display = static_cast<egl::Display *>(mDisplay);
127*8975f5c5SAndroid Build Coastguard Worker angle::FeatureList features = display->getFeatures();
128*8975f5c5SAndroid Build Coastguard Worker
129*8975f5c5SAndroid Build Coastguard Worker // Build lists of features to enable/disabled. Toggle features we know are ok to toggle based
130*8975f5c5SAndroid Build Coastguard Worker // from this list.
131*8975f5c5SAndroid Build Coastguard Worker std::vector<const char *> enabled;
132*8975f5c5SAndroid Build Coastguard Worker std::vector<const char *> disabled;
133*8975f5c5SAndroid Build Coastguard Worker std::vector<std::string> modifiedNameStorage;
134*8975f5c5SAndroid Build Coastguard Worker std::vector<bool> shouldBe;
135*8975f5c5SAndroid Build Coastguard Worker std::vector<std::string> testedFeatures = {
136*8975f5c5SAndroid Build Coastguard Worker // Safe to toggle on GL
137*8975f5c5SAndroid Build Coastguard Worker angle::GetFeatureName(angle::Feature::AddAndTrueToLoopCondition),
138*8975f5c5SAndroid Build Coastguard Worker angle::GetFeatureName(angle::Feature::ClampFragDepth),
139*8975f5c5SAndroid Build Coastguard Worker // Safe to toggle on GL and Vulkan
140*8975f5c5SAndroid Build Coastguard Worker angle::GetFeatureName(angle::Feature::ClampPointSize),
141*8975f5c5SAndroid Build Coastguard Worker // Safe to toggle on D3D
142*8975f5c5SAndroid Build Coastguard Worker angle::GetFeatureName(angle::Feature::ZeroMaxLodWorkaround),
143*8975f5c5SAndroid Build Coastguard Worker angle::GetFeatureName(angle::Feature::ExpandIntegerPowExpressions),
144*8975f5c5SAndroid Build Coastguard Worker angle::GetFeatureName(angle::Feature::RewriteUnaryMinusOperator),
145*8975f5c5SAndroid Build Coastguard Worker };
146*8975f5c5SAndroid Build Coastguard Worker
147*8975f5c5SAndroid Build Coastguard Worker modifiedNameStorage.reserve(features.size());
148*8975f5c5SAndroid Build Coastguard Worker shouldBe.reserve(features.size());
149*8975f5c5SAndroid Build Coastguard Worker
150*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < features.size(); i++)
151*8975f5c5SAndroid Build Coastguard Worker {
152*8975f5c5SAndroid Build Coastguard Worker modifiedNameStorage.push_back(modifyName(features[i]->name));
153*8975f5c5SAndroid Build Coastguard Worker
154*8975f5c5SAndroid Build Coastguard Worker bool toggle = std::find(testedFeatures.begin(), testedFeatures.end(),
155*8975f5c5SAndroid Build Coastguard Worker std::string(features[i]->name)) != testedFeatures.end();
156*8975f5c5SAndroid Build Coastguard Worker if (features[i]->enabled ^ toggle)
157*8975f5c5SAndroid Build Coastguard Worker {
158*8975f5c5SAndroid Build Coastguard Worker enabled.push_back(modifiedNameStorage[i].c_str());
159*8975f5c5SAndroid Build Coastguard Worker }
160*8975f5c5SAndroid Build Coastguard Worker else
161*8975f5c5SAndroid Build Coastguard Worker {
162*8975f5c5SAndroid Build Coastguard Worker disabled.push_back(modifiedNameStorage[i].c_str());
163*8975f5c5SAndroid Build Coastguard Worker }
164*8975f5c5SAndroid Build Coastguard Worker // Save what we expect the feature status will be when checking later.
165*8975f5c5SAndroid Build Coastguard Worker shouldBe.push_back(features[i]->enabled ^ toggle);
166*8975f5c5SAndroid Build Coastguard Worker }
167*8975f5c5SAndroid Build Coastguard Worker disabled.push_back(0);
168*8975f5c5SAndroid Build Coastguard Worker enabled.push_back(0);
169*8975f5c5SAndroid Build Coastguard Worker
170*8975f5c5SAndroid Build Coastguard Worker // Terminate the old display (we just used it to collect features)
171*8975f5c5SAndroid Build Coastguard Worker eglTerminate(mDisplay);
172*8975f5c5SAndroid Build Coastguard Worker
173*8975f5c5SAndroid Build Coastguard Worker // Create a new display with these overridden features.
174*8975f5c5SAndroid Build Coastguard Worker EGLAttrib dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE,
175*8975f5c5SAndroid Build Coastguard Worker GetParam().getRenderer(),
176*8975f5c5SAndroid Build Coastguard Worker EGL_FEATURE_OVERRIDES_ENABLED_ANGLE,
177*8975f5c5SAndroid Build Coastguard Worker reinterpret_cast<EGLAttrib>(enabled.data()),
178*8975f5c5SAndroid Build Coastguard Worker EGL_FEATURE_OVERRIDES_DISABLED_ANGLE,
179*8975f5c5SAndroid Build Coastguard Worker reinterpret_cast<EGLAttrib>(disabled.data()),
180*8975f5c5SAndroid Build Coastguard Worker EGL_NONE};
181*8975f5c5SAndroid Build Coastguard Worker mDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
182*8975f5c5SAndroid Build Coastguard Worker reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
183*8975f5c5SAndroid Build Coastguard Worker ASSERT_EGL_SUCCESS();
184*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(mDisplay, EGL_NO_DISPLAY);
185*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(eglInitialize(mDisplay, nullptr, nullptr), EGLBoolean(EGL_TRUE));
186*8975f5c5SAndroid Build Coastguard Worker
187*8975f5c5SAndroid Build Coastguard Worker // Check that all features have the correct status (even the ones we toggled).
188*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < features.size(); i++)
189*8975f5c5SAndroid Build Coastguard Worker {
190*8975f5c5SAndroid Build Coastguard Worker EXPECT_STREQ(FeatureStatusToString(shouldBe[i]),
191*8975f5c5SAndroid Build Coastguard Worker eglQueryStringiANGLE(mDisplay, EGL_FEATURE_STATUS_ANGLE, i))
192*8975f5c5SAndroid Build Coastguard Worker << modifiedNameStorage[i];
193*8975f5c5SAndroid Build Coastguard Worker }
194*8975f5c5SAndroid Build Coastguard Worker }
195*8975f5c5SAndroid Build Coastguard Worker
196*8975f5c5SAndroid Build Coastguard Worker // Submit a list of features to override when creating the display with eglGetPlatformDisplay, and
197*8975f5c5SAndroid Build Coastguard Worker // ensure that the features are correctly overridden.
TEST_P(EGLFeatureControlTest,OverrideFeatures)198*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLFeatureControlTest, OverrideFeatures)
199*8975f5c5SAndroid Build Coastguard Worker {
200*8975f5c5SAndroid Build Coastguard Worker testOverrideFeatures([](const std::string &featureName) { return featureName; });
201*8975f5c5SAndroid Build Coastguard Worker }
202*8975f5c5SAndroid Build Coastguard Worker
203*8975f5c5SAndroid Build Coastguard Worker // Similar to OverrideFeatures, but ensures that camelCase variants of the name match as well.
TEST_P(EGLFeatureControlTest,OverrideFeaturesCamelCase)204*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLFeatureControlTest, OverrideFeaturesCamelCase)
205*8975f5c5SAndroid Build Coastguard Worker {
206*8975f5c5SAndroid Build Coastguard Worker testOverrideFeatures(
207*8975f5c5SAndroid Build Coastguard Worker [](const std::string &featureName) { return angle::ToCamelCase(featureName); });
208*8975f5c5SAndroid Build Coastguard Worker }
209*8975f5c5SAndroid Build Coastguard Worker
210*8975f5c5SAndroid Build Coastguard Worker // Similar to OverrideFeatures, but ensures wildcard matching works
TEST_P(EGLFeatureControlTest,OverrideFeaturesWildcard)211*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLFeatureControlTest, OverrideFeaturesWildcard)
212*8975f5c5SAndroid Build Coastguard Worker {
213*8975f5c5SAndroid Build Coastguard Worker for (int j = 0; j < 2; j++)
214*8975f5c5SAndroid Build Coastguard Worker {
215*8975f5c5SAndroid Build Coastguard Worker const bool testEnableOverride = (j != 0);
216*8975f5c5SAndroid Build Coastguard Worker
217*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!initTest());
218*8975f5c5SAndroid Build Coastguard Worker
219*8975f5c5SAndroid Build Coastguard Worker egl::Display *display = static_cast<egl::Display *>(mDisplay);
220*8975f5c5SAndroid Build Coastguard Worker angle::FeatureList features = display->getFeatures();
221*8975f5c5SAndroid Build Coastguard Worker
222*8975f5c5SAndroid Build Coastguard Worker // Note that we don't use the broader 'prefer_*' here because
223*8975f5c5SAndroid Build Coastguard Worker // prefer_monolithic_pipelines_over_libraries may affect other feature
224*8975f5c5SAndroid Build Coastguard Worker // flags.
225*8975f5c5SAndroid Build Coastguard Worker std::vector<const char *> featuresToOverride = {"prefer_d*", nullptr};
226*8975f5c5SAndroid Build Coastguard Worker
227*8975f5c5SAndroid Build Coastguard Worker std::vector<std::string> featureNameStorage;
228*8975f5c5SAndroid Build Coastguard Worker std::vector<bool> shouldBe;
229*8975f5c5SAndroid Build Coastguard Worker
230*8975f5c5SAndroid Build Coastguard Worker shouldBe.reserve(features.size());
231*8975f5c5SAndroid Build Coastguard Worker featureNameStorage.reserve(features.size());
232*8975f5c5SAndroid Build Coastguard Worker
233*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < features.size(); i++)
234*8975f5c5SAndroid Build Coastguard Worker {
235*8975f5c5SAndroid Build Coastguard Worker std::string featureName = std::string(features[i]->name);
236*8975f5c5SAndroid Build Coastguard Worker std::transform(featureName.begin(), featureName.end(), featureName.begin(),
237*8975f5c5SAndroid Build Coastguard Worker [](unsigned char c) { return std::tolower(c); });
238*8975f5c5SAndroid Build Coastguard Worker
239*8975f5c5SAndroid Build Coastguard Worker const bool featureMatch = strncmp(featureName.c_str(), "preferd", 7) == 0;
240*8975f5c5SAndroid Build Coastguard Worker
241*8975f5c5SAndroid Build Coastguard Worker std::optional<bool> overrideState;
242*8975f5c5SAndroid Build Coastguard Worker if (featureMatch)
243*8975f5c5SAndroid Build Coastguard Worker {
244*8975f5c5SAndroid Build Coastguard Worker overrideState = testEnableOverride;
245*8975f5c5SAndroid Build Coastguard Worker }
246*8975f5c5SAndroid Build Coastguard Worker
247*8975f5c5SAndroid Build Coastguard Worker // Save what we expect the feature status will be when checking later.
248*8975f5c5SAndroid Build Coastguard Worker shouldBe.push_back(overrideState.value_or(features[i]->enabled));
249*8975f5c5SAndroid Build Coastguard Worker featureNameStorage.push_back(features[i]->name);
250*8975f5c5SAndroid Build Coastguard Worker }
251*8975f5c5SAndroid Build Coastguard Worker
252*8975f5c5SAndroid Build Coastguard Worker // Terminate the old display (we just used it to collect features)
253*8975f5c5SAndroid Build Coastguard Worker eglTerminate(mDisplay);
254*8975f5c5SAndroid Build Coastguard Worker mDisplay = nullptr;
255*8975f5c5SAndroid Build Coastguard Worker
256*8975f5c5SAndroid Build Coastguard Worker // Create a new display with these overridden features.
257*8975f5c5SAndroid Build Coastguard Worker EGLAttrib dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(),
258*8975f5c5SAndroid Build Coastguard Worker testEnableOverride ? EGL_FEATURE_OVERRIDES_ENABLED_ANGLE
259*8975f5c5SAndroid Build Coastguard Worker : EGL_FEATURE_OVERRIDES_DISABLED_ANGLE,
260*8975f5c5SAndroid Build Coastguard Worker reinterpret_cast<EGLAttrib>(featuresToOverride.data()), EGL_NONE};
261*8975f5c5SAndroid Build Coastguard Worker mDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
262*8975f5c5SAndroid Build Coastguard Worker reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
263*8975f5c5SAndroid Build Coastguard Worker ASSERT_EGL_SUCCESS();
264*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(mDisplay, EGL_NO_DISPLAY);
265*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(eglInitialize(mDisplay, nullptr, nullptr), EGLBoolean(EGL_TRUE));
266*8975f5c5SAndroid Build Coastguard Worker
267*8975f5c5SAndroid Build Coastguard Worker // Check that all features have the correct status (even the ones we toggled).
268*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < features.size(); i++)
269*8975f5c5SAndroid Build Coastguard Worker {
270*8975f5c5SAndroid Build Coastguard Worker EXPECT_STREQ(FeatureStatusToString(shouldBe[i]),
271*8975f5c5SAndroid Build Coastguard Worker eglQueryStringiANGLE(mDisplay, EGL_FEATURE_STATUS_ANGLE, i))
272*8975f5c5SAndroid Build Coastguard Worker << featureNameStorage[i];
273*8975f5c5SAndroid Build Coastguard Worker }
274*8975f5c5SAndroid Build Coastguard Worker
275*8975f5c5SAndroid Build Coastguard Worker // Clean up display for next iteration.
276*8975f5c5SAndroid Build Coastguard Worker eglTerminate(mDisplay);
277*8975f5c5SAndroid Build Coastguard Worker mDisplay = nullptr;
278*8975f5c5SAndroid Build Coastguard Worker }
279*8975f5c5SAndroid Build Coastguard Worker }
280*8975f5c5SAndroid Build Coastguard Worker
281*8975f5c5SAndroid Build Coastguard Worker // Ensure that dependent features are affected properly by overrides
TEST_P(EGLFeatureControlTest,OverrideFeaturesDependent)282*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLFeatureControlTest, OverrideFeaturesDependent)
283*8975f5c5SAndroid Build Coastguard Worker {
284*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!initTest());
285*8975f5c5SAndroid Build Coastguard Worker
286*8975f5c5SAndroid Build Coastguard Worker egl::Display *display = static_cast<egl::Display *>(mDisplay);
287*8975f5c5SAndroid Build Coastguard Worker angle::FeatureList features = display->getFeatures();
288*8975f5c5SAndroid Build Coastguard Worker
289*8975f5c5SAndroid Build Coastguard Worker const std::vector<const char *> featuresDisabled = {
290*8975f5c5SAndroid Build Coastguard Worker GetFeatureName(Feature::SupportsRenderpass2),
291*8975f5c5SAndroid Build Coastguard Worker GetFeatureName(Feature::SupportsImage2dViewOf3d), nullptr};
292*8975f5c5SAndroid Build Coastguard Worker
293*8975f5c5SAndroid Build Coastguard Worker const std::vector<const char *> featuresExpectDisabled = {
294*8975f5c5SAndroid Build Coastguard Worker // Features we changed
295*8975f5c5SAndroid Build Coastguard Worker GetFeatureName(Feature::SupportsRenderpass2),
296*8975f5c5SAndroid Build Coastguard Worker GetFeatureName(Feature::SupportsImage2dViewOf3d),
297*8975f5c5SAndroid Build Coastguard Worker
298*8975f5c5SAndroid Build Coastguard Worker // Features that must become disabled as a result of the above
299*8975f5c5SAndroid Build Coastguard Worker GetFeatureName(Feature::SupportsDepthStencilResolve),
300*8975f5c5SAndroid Build Coastguard Worker GetFeatureName(Feature::SupportsDepthStencilIndependentResolveNone),
301*8975f5c5SAndroid Build Coastguard Worker GetFeatureName(Feature::SupportsSampler2dViewOf3d),
302*8975f5c5SAndroid Build Coastguard Worker GetFeatureName(Feature::SupportsFragmentShadingRate),
303*8975f5c5SAndroid Build Coastguard Worker };
304*8975f5c5SAndroid Build Coastguard Worker
305*8975f5c5SAndroid Build Coastguard Worker std::vector<std::string> featureNameStorage;
306*8975f5c5SAndroid Build Coastguard Worker std::vector<bool> shouldBe;
307*8975f5c5SAndroid Build Coastguard Worker
308*8975f5c5SAndroid Build Coastguard Worker shouldBe.reserve(features.size());
309*8975f5c5SAndroid Build Coastguard Worker featureNameStorage.reserve(features.size());
310*8975f5c5SAndroid Build Coastguard Worker
311*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < features.size(); i++)
312*8975f5c5SAndroid Build Coastguard Worker {
313*8975f5c5SAndroid Build Coastguard Worker bool featureMatch = false;
314*8975f5c5SAndroid Build Coastguard Worker for (auto *ptr : featuresExpectDisabled)
315*8975f5c5SAndroid Build Coastguard Worker {
316*8975f5c5SAndroid Build Coastguard Worker if (strcmp(ptr, features[i]->name) == 0)
317*8975f5c5SAndroid Build Coastguard Worker {
318*8975f5c5SAndroid Build Coastguard Worker featureMatch = true;
319*8975f5c5SAndroid Build Coastguard Worker break;
320*8975f5c5SAndroid Build Coastguard Worker }
321*8975f5c5SAndroid Build Coastguard Worker }
322*8975f5c5SAndroid Build Coastguard Worker
323*8975f5c5SAndroid Build Coastguard Worker std::string featureName = std::string(features[i]->name);
324*8975f5c5SAndroid Build Coastguard Worker std::transform(featureName.begin(), featureName.end(), featureName.begin(),
325*8975f5c5SAndroid Build Coastguard Worker [](unsigned char c) { return std::tolower(c); });
326*8975f5c5SAndroid Build Coastguard Worker
327*8975f5c5SAndroid Build Coastguard Worker // Save what we expect the feature status will be when checking later.
328*8975f5c5SAndroid Build Coastguard Worker shouldBe.push_back(features[i]->enabled && !featureMatch);
329*8975f5c5SAndroid Build Coastguard Worker
330*8975f5c5SAndroid Build Coastguard Worker // Store copy of the feature name string, in case we need to print for a test failure
331*8975f5c5SAndroid Build Coastguard Worker featureNameStorage.push_back(features[i]->name);
332*8975f5c5SAndroid Build Coastguard Worker }
333*8975f5c5SAndroid Build Coastguard Worker
334*8975f5c5SAndroid Build Coastguard Worker // Terminate the old display (we just used it to collect features)
335*8975f5c5SAndroid Build Coastguard Worker eglTerminate(mDisplay);
336*8975f5c5SAndroid Build Coastguard Worker
337*8975f5c5SAndroid Build Coastguard Worker // Create a new display with these overridden features.
338*8975f5c5SAndroid Build Coastguard Worker EGLAttrib dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(),
339*8975f5c5SAndroid Build Coastguard Worker EGL_FEATURE_OVERRIDES_DISABLED_ANGLE,
340*8975f5c5SAndroid Build Coastguard Worker reinterpret_cast<EGLAttrib>(featuresDisabled.data()), EGL_NONE};
341*8975f5c5SAndroid Build Coastguard Worker mDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
342*8975f5c5SAndroid Build Coastguard Worker reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
343*8975f5c5SAndroid Build Coastguard Worker ASSERT_EGL_SUCCESS();
344*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(mDisplay, EGL_NO_DISPLAY);
345*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(eglInitialize(mDisplay, nullptr, nullptr), EGLBoolean(EGL_TRUE));
346*8975f5c5SAndroid Build Coastguard Worker
347*8975f5c5SAndroid Build Coastguard Worker // Check that all features have the correct status (even the ones we toggled).
348*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < features.size(); i++)
349*8975f5c5SAndroid Build Coastguard Worker {
350*8975f5c5SAndroid Build Coastguard Worker EXPECT_STREQ(FeatureStatusToString(shouldBe[i]),
351*8975f5c5SAndroid Build Coastguard Worker eglQueryStringiANGLE(mDisplay, EGL_FEATURE_STATUS_ANGLE, i))
352*8975f5c5SAndroid Build Coastguard Worker << featureNameStorage[i];
353*8975f5c5SAndroid Build Coastguard Worker }
354*8975f5c5SAndroid Build Coastguard Worker }
355*8975f5c5SAndroid Build Coastguard Worker
356*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(EGLFeatureControlTest,
357*8975f5c5SAndroid Build Coastguard Worker WithNoFixture(ES2_D3D9()),
358*8975f5c5SAndroid Build Coastguard Worker WithNoFixture(ES2_D3D11()),
359*8975f5c5SAndroid Build Coastguard Worker WithNoFixture(ES2_METAL()),
360*8975f5c5SAndroid Build Coastguard Worker WithNoFixture(ES2_OPENGL()),
361*8975f5c5SAndroid Build Coastguard Worker WithNoFixture(ES2_VULKAN()),
362*8975f5c5SAndroid Build Coastguard Worker WithNoFixture(ES3_D3D11()),
363*8975f5c5SAndroid Build Coastguard Worker WithNoFixture(ES3_METAL()),
364*8975f5c5SAndroid Build Coastguard Worker WithNoFixture(ES3_OPENGL()));
365