xref: /aosp_15_r20/external/deqp/modules/egl/teglChooseConfigReference.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program EGL Module
3  * ---------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Choose config reference implementation.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "teglChooseConfigReference.hpp"
25 
26 #include "egluUtil.hpp"
27 #include "egluConfigInfo.hpp"
28 #include "egluStrUtil.hpp"
29 #include "eglwLibrary.hpp"
30 #include "eglwEnums.hpp"
31 
32 #include "deSTLUtil.hpp"
33 
34 #include <algorithm>
35 #include <vector>
36 #include <map>
37 
38 namespace deqp
39 {
40 namespace egl
41 {
42 
43 using namespace eglw;
44 using eglu::ConfigInfo;
45 
46 enum Criteria
47 {
48     CRITERIA_AT_LEAST = 0,
49     CRITERIA_EXACT,
50     CRITERIA_MASK,
51     CRITERIA_SPECIAL,
52 
53     CRITERIA_LAST
54 };
55 
56 enum SortOrder
57 {
58     SORTORDER_NONE = 0,
59     SORTORDER_SMALLER,
60     SORTORDER_SPECIAL,
61 
62     SORTORDER_LAST
63 };
64 
65 struct AttribRule
66 {
67     EGLenum name;
68     EGLint value;
69     Criteria criteria;
70     SortOrder sortOrder;
71 
AttribRuledeqp::egl::AttribRule72     AttribRule(void) : name(EGL_NONE), value(EGL_NONE), criteria(CRITERIA_LAST), sortOrder(SORTORDER_LAST)
73     {
74     }
75 
AttribRuledeqp::egl::AttribRule76     AttribRule(EGLenum name_, EGLint value_, Criteria criteria_, SortOrder sortOrder_)
77         : name(name_)
78         , value(value_)
79         , criteria(criteria_)
80         , sortOrder(sortOrder_)
81     {
82     }
83 };
84 
85 class SurfaceConfig
86 {
87 private:
getCaveatRank(EGLenum caveat)88     static int getCaveatRank(EGLenum caveat)
89     {
90         switch (caveat)
91         {
92         case EGL_NONE:
93             return 0;
94         case EGL_SLOW_CONFIG:
95             return 1;
96         case EGL_NON_CONFORMANT_CONFIG:
97             return 2;
98         default:
99             TCU_THROW(TestError,
100                       (std::string("Unknown config caveat: ") + eglu::getConfigCaveatStr(caveat).toString()).c_str());
101         }
102     }
103 
getColorBufferTypeRank(EGLenum type)104     static int getColorBufferTypeRank(EGLenum type)
105     {
106         switch (type)
107         {
108         case EGL_RGB_BUFFER:
109             return 0;
110         case EGL_LUMINANCE_BUFFER:
111             return 1;
112         case EGL_YUV_BUFFER_EXT:
113             return 2;
114         default:
115             TCU_THROW(
116                 TestError,
117                 (std::string("Unknown color buffer type: ") + eglu::getColorBufferTypeStr(type).toString()).c_str());
118         }
119     }
120 
getYuvOrderRank(EGLenum order)121     static int getYuvOrderRank(EGLenum order)
122     {
123         switch (order)
124         {
125         case EGL_NONE:
126             return 0;
127         case EGL_YUV_ORDER_YUV_EXT:
128             return 1;
129         case EGL_YUV_ORDER_YVU_EXT:
130             return 2;
131         case EGL_YUV_ORDER_YUYV_EXT:
132             return 3;
133         case EGL_YUV_ORDER_YVYU_EXT:
134             return 4;
135         case EGL_YUV_ORDER_UYVY_EXT:
136             return 5;
137         case EGL_YUV_ORDER_VYUY_EXT:
138             return 6;
139         case EGL_YUV_ORDER_AYUV_EXT:
140             return 7;
141         default:
142             TCU_THROW(TestError, (std::string("Unknown YUV order: ") + eglu::getYuvOrderStr(order).toString()).c_str());
143         }
144     }
145 
getYuvPlaneBppValue(EGLenum bpp)146     static int getYuvPlaneBppValue(EGLenum bpp)
147     {
148         switch (bpp)
149         {
150         case EGL_YUV_PLANE_BPP_0_EXT:
151             return 0;
152         case EGL_YUV_PLANE_BPP_8_EXT:
153             return 8;
154         case EGL_YUV_PLANE_BPP_10_EXT:
155             return 10;
156         default:
157             TCU_THROW(TestError,
158                       (std::string("Unknown YUV plane BPP: ") + eglu::getYuvPlaneBppStr(bpp).toString()).c_str());
159         }
160     }
161 
getColorComponentTypeRank(EGLenum compType)162     static int getColorComponentTypeRank(EGLenum compType)
163     {
164         switch (compType)
165         {
166         case EGL_COLOR_COMPONENT_TYPE_FIXED_EXT:
167             return 0;
168         case EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT:
169             return 1;
170         default:
171             TCU_THROW(TestError, (std::string("Unknown color component type: ") +
172                                   eglu::getColorComponentTypeStr(compType).toString())
173                                      .c_str());
174         }
175     }
176 
177     typedef bool (*CompareFunc)(const SurfaceConfig &a, const SurfaceConfig &b);
178 
compareCaveat(const SurfaceConfig & a,const SurfaceConfig & b)179     static bool compareCaveat(const SurfaceConfig &a, const SurfaceConfig &b)
180     {
181         return getCaveatRank((EGLenum)a.m_info.configCaveat) < getCaveatRank((EGLenum)b.m_info.configCaveat);
182     }
183 
compareColorBufferType(const SurfaceConfig & a,const SurfaceConfig & b)184     static bool compareColorBufferType(const SurfaceConfig &a, const SurfaceConfig &b)
185     {
186         return getColorBufferTypeRank((EGLenum)a.m_info.colorBufferType) <
187                getColorBufferTypeRank((EGLenum)b.m_info.colorBufferType);
188     }
189 
compareYuvOrder(const SurfaceConfig & a,const SurfaceConfig & b)190     static bool compareYuvOrder(const SurfaceConfig &a, const SurfaceConfig &b)
191     {
192         return getYuvOrderRank((EGLenum)a.m_info.yuvOrder) < getYuvOrderRank((EGLenum)b.m_info.yuvOrder);
193     }
194 
compareColorComponentType(const SurfaceConfig & a,const SurfaceConfig & b)195     static bool compareColorComponentType(const SurfaceConfig &a, const SurfaceConfig &b)
196     {
197         return getColorComponentTypeRank((EGLenum)a.m_info.colorComponentType) <
198                getColorComponentTypeRank((EGLenum)b.m_info.colorComponentType);
199     }
200 
compareColorBufferBits(const SurfaceConfig & a,const SurfaceConfig & b,const tcu::BVec4 & specifiedRGBColors,const tcu::BVec2 & specifiedLuminanceColors,bool yuvPlaneBppSpecified)201     static bool compareColorBufferBits(const SurfaceConfig &a, const SurfaceConfig &b,
202                                        const tcu::BVec4 &specifiedRGBColors, const tcu::BVec2 &specifiedLuminanceColors,
203                                        bool yuvPlaneBppSpecified)
204     {
205         DE_ASSERT(a.m_info.colorBufferType == b.m_info.colorBufferType);
206         switch (a.m_info.colorBufferType)
207         {
208         case EGL_RGB_BUFFER:
209         {
210             const tcu::IVec4 mask(specifiedRGBColors.cast<int32_t>());
211 
212             return (a.m_info.redSize * mask[0] + a.m_info.greenSize * mask[1] + a.m_info.blueSize * mask[2] +
213                     a.m_info.alphaSize * mask[3]) > (b.m_info.redSize * mask[0] + b.m_info.greenSize * mask[1] +
214                                                      b.m_info.blueSize * mask[2] + b.m_info.alphaSize * mask[3]);
215         }
216 
217         case EGL_LUMINANCE_BUFFER:
218         {
219             const tcu::IVec2 mask(specifiedLuminanceColors.cast<int32_t>());
220 
221             return (a.m_info.luminanceSize * mask[0] + a.m_info.alphaSize * mask[1]) >
222                    (b.m_info.luminanceSize * mask[0] + b.m_info.alphaSize * mask[1]);
223         }
224 
225         case EGL_YUV_BUFFER_EXT:
226             return yuvPlaneBppSpecified ? (a.m_info.yuvPlaneBpp > b.m_info.yuvPlaneBpp) : false;
227 
228         default:
229             DE_ASSERT(false);
230             return true;
231         }
232     }
233 
234     template <EGLenum Attribute>
compareAttributeSmaller(const SurfaceConfig & a,const SurfaceConfig & b)235     static bool compareAttributeSmaller(const SurfaceConfig &a, const SurfaceConfig &b)
236     {
237         return a.getAttribute(Attribute) < b.getAttribute(Attribute);
238     }
239 
240 public:
SurfaceConfig(EGLConfig config,ConfigInfo & info)241     SurfaceConfig(EGLConfig config, ConfigInfo &info) : m_config(config), m_info(info)
242     {
243     }
244 
getEglConfig(void) const245     EGLConfig getEglConfig(void) const
246     {
247         return m_config;
248     }
249 
getAttribute(const EGLenum attribute) const250     EGLint getAttribute(const EGLenum attribute) const
251     {
252         return m_info.getAttribute(attribute);
253     }
254 
operator ==(const SurfaceConfig & a,const SurfaceConfig & b)255     friend bool operator==(const SurfaceConfig &a, const SurfaceConfig &b)
256     {
257         const std::map<EGLenum, AttribRule> defaultRules = getDefaultRules();
258 
259         for (std::map<EGLenum, AttribRule>::const_iterator iter = defaultRules.begin(); iter != defaultRules.end();
260              iter++)
261         {
262             const EGLenum attribute = iter->first;
263 
264             if (a.getAttribute(attribute) != b.getAttribute(attribute))
265                 return false;
266         }
267         return true;
268     }
269 
compareTo(const SurfaceConfig & b,const tcu::BVec4 & specifiedRGBColors,const tcu::BVec2 & specifiedLuminanceColors,bool yuvPlaneBppSpecified) const270     bool compareTo(const SurfaceConfig &b, const tcu::BVec4 &specifiedRGBColors,
271                    const tcu::BVec2 &specifiedLuminanceColors, bool yuvPlaneBppSpecified) const
272     {
273         static const SurfaceConfig::CompareFunc compareFuncs[] = {
274             SurfaceConfig::compareCaveat,
275             SurfaceConfig::compareColorComponentType,
276             SurfaceConfig::compareColorBufferType,
277             DE_NULL, // SurfaceConfig::compareColorBufferBits,
278             SurfaceConfig::compareAttributeSmaller<EGL_BUFFER_SIZE>,
279             SurfaceConfig::compareAttributeSmaller<EGL_SAMPLE_BUFFERS>,
280             SurfaceConfig::compareAttributeSmaller<EGL_SAMPLES>,
281             SurfaceConfig::compareAttributeSmaller<EGL_DEPTH_SIZE>,
282             SurfaceConfig::compareAttributeSmaller<EGL_STENCIL_SIZE>,
283             SurfaceConfig::compareAttributeSmaller<EGL_ALPHA_MASK_SIZE>,
284             SurfaceConfig::compareYuvOrder,
285             SurfaceConfig::compareAttributeSmaller<EGL_CONFIG_ID>};
286 
287         if (*this == b)
288             return false; // std::sort() can compare object to itself.
289 
290         for (int ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(compareFuncs); ndx++)
291         {
292             if (!compareFuncs[ndx])
293             {
294                 if (compareColorBufferBits(*this, b, specifiedRGBColors, specifiedLuminanceColors,
295                                            yuvPlaneBppSpecified))
296                     return true;
297                 else if (compareColorBufferBits(b, *this, specifiedRGBColors, specifiedLuminanceColors,
298                                                 yuvPlaneBppSpecified))
299                     return false;
300 
301                 continue;
302             }
303 
304             if (compareFuncs[ndx](*this, b))
305                 return true;
306             else if (compareFuncs[ndx](b, *this))
307                 return false;
308         }
309 
310         TCU_FAIL("Unable to compare configs - duplicate ID?");
311     }
312 
getDefaultRules(void)313     static std::map<EGLenum, AttribRule> getDefaultRules(void)
314     {
315         // \todo [2011-03-24 pyry] From EGL 1.4 spec - check that this is valid for other versions as well
316         std::map<EGLenum, AttribRule> rules;
317 
318         //                                    Attribute                                    Default                Selection Criteria    Sort Order            Sort Priority
319         rules[EGL_BUFFER_SIZE]     = AttribRule(EGL_BUFFER_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SMALLER);     //    4
320         rules[EGL_RED_SIZE]        = AttribRule(EGL_RED_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SPECIAL);        //    3
321         rules[EGL_GREEN_SIZE]      = AttribRule(EGL_GREEN_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SPECIAL);      //    3
322         rules[EGL_BLUE_SIZE]       = AttribRule(EGL_BLUE_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SPECIAL);       //    3
323         rules[EGL_LUMINANCE_SIZE]  = AttribRule(EGL_LUMINANCE_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SPECIAL);  //    3
324         rules[EGL_ALPHA_SIZE]      = AttribRule(EGL_ALPHA_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SPECIAL);      //    3
325         rules[EGL_ALPHA_MASK_SIZE] = AttribRule(EGL_ALPHA_MASK_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SMALLER); //    9
326         rules[EGL_BIND_TO_TEXTURE_RGB] =
327             AttribRule(EGL_BIND_TO_TEXTURE_RGB, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
328         rules[EGL_BIND_TO_TEXTURE_RGBA] =
329             AttribRule(EGL_BIND_TO_TEXTURE_RGBA, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
330         rules[EGL_COLOR_BUFFER_TYPE] =
331             AttribRule(EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, CRITERIA_EXACT, SORTORDER_NONE); //    2
332         rules[EGL_CONFIG_CAVEAT] =
333             AttribRule(EGL_CONFIG_CAVEAT, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_SPECIAL);                 //    1
334         rules[EGL_CONFIG_ID]  = AttribRule(EGL_CONFIG_ID, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_SMALLER); //    11
335         rules[EGL_CONFORMANT] = AttribRule(EGL_CONFORMANT, 0, CRITERIA_MASK, SORTORDER_NONE);
336         rules[EGL_DEPTH_SIZE] = AttribRule(EGL_DEPTH_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SMALLER); //    7
337         rules[EGL_LEVEL]      = AttribRule(EGL_LEVEL, 0, CRITERIA_EXACT, SORTORDER_NONE);
338         rules[EGL_MAX_SWAP_INTERVAL] = AttribRule(EGL_MAX_SWAP_INTERVAL, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
339         rules[EGL_MIN_SWAP_INTERVAL] = AttribRule(EGL_MIN_SWAP_INTERVAL, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
340         rules[EGL_NATIVE_RENDERABLE] = AttribRule(EGL_NATIVE_RENDERABLE, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
341         rules[EGL_NATIVE_VISUAL_TYPE] =
342             AttribRule(EGL_NATIVE_VISUAL_TYPE, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_SPECIAL); //    10
343         rules[EGL_RENDERABLE_TYPE]  = AttribRule(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, CRITERIA_MASK, SORTORDER_NONE);
344         rules[EGL_SAMPLE_BUFFERS]   = AttribRule(EGL_SAMPLE_BUFFERS, 0, CRITERIA_AT_LEAST, SORTORDER_SMALLER); //    5
345         rules[EGL_SAMPLES]          = AttribRule(EGL_SAMPLES, 0, CRITERIA_AT_LEAST, SORTORDER_SMALLER);        //    6
346         rules[EGL_STENCIL_SIZE]     = AttribRule(EGL_STENCIL_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SMALLER);   //    8
347         rules[EGL_SURFACE_TYPE]     = AttribRule(EGL_SURFACE_TYPE, EGL_WINDOW_BIT, CRITERIA_MASK, SORTORDER_NONE);
348         rules[EGL_TRANSPARENT_TYPE] = AttribRule(EGL_TRANSPARENT_TYPE, EGL_NONE, CRITERIA_EXACT, SORTORDER_NONE);
349         rules[EGL_TRANSPARENT_RED_VALUE] =
350             AttribRule(EGL_TRANSPARENT_RED_VALUE, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
351         rules[EGL_TRANSPARENT_GREEN_VALUE] =
352             AttribRule(EGL_TRANSPARENT_GREEN_VALUE, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
353         rules[EGL_TRANSPARENT_BLUE_VALUE] =
354             AttribRule(EGL_TRANSPARENT_BLUE_VALUE, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
355 
356         // EGL_EXT_yuv_surface
357         rules[EGL_YUV_ORDER_EXT] = AttribRule(EGL_YUV_ORDER_EXT, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_SPECIAL);
358         rules[EGL_YUV_NUMBER_OF_PLANES_EXT] =
359             AttribRule(EGL_YUV_NUMBER_OF_PLANES_EXT, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
360         rules[EGL_YUV_SUBSAMPLE_EXT] = AttribRule(EGL_YUV_SUBSAMPLE_EXT, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
361         rules[EGL_YUV_DEPTH_RANGE_EXT] =
362             AttribRule(EGL_YUV_DEPTH_RANGE_EXT, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
363         rules[EGL_YUV_CSC_STANDARD_EXT] =
364             AttribRule(EGL_YUV_CSC_STANDARD_EXT, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
365         rules[EGL_YUV_PLANE_BPP_EXT] =
366             AttribRule(EGL_YUV_PLANE_BPP_EXT, EGL_DONT_CARE, CRITERIA_AT_LEAST, SORTORDER_SPECIAL); //    3
367 
368         // EGL_EXT_pixel_format_float
369         rules[EGL_COLOR_COMPONENT_TYPE_EXT] =
370             AttribRule(EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT, CRITERIA_EXACT,
371                        SORTORDER_SPECIAL); //    2
372 
373         // EGL_ANDROID_recordable
374         rules[EGL_RECORDABLE_ANDROID] =
375             AttribRule(EGL_RECORDABLE_ANDROID, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
376 
377         return rules;
378     }
379 
380 private:
381     EGLConfig m_config;
382     ConfigInfo m_info;
383 };
384 
385 class CompareConfigs
386 {
387 public:
CompareConfigs(const tcu::BVec4 & specifiedRGBColors,const tcu::BVec2 & specifiedLuminanceColors,bool yuvPlaneBppSpecified)388     CompareConfigs(const tcu::BVec4 &specifiedRGBColors, const tcu::BVec2 &specifiedLuminanceColors,
389                    bool yuvPlaneBppSpecified)
390         : m_specifiedRGBColors(specifiedRGBColors)
391         , m_specifiedLuminanceColors(specifiedLuminanceColors)
392         , m_yuvPlaneBppSpecified(yuvPlaneBppSpecified)
393     {
394     }
395 
operator ()(const SurfaceConfig & a,const SurfaceConfig & b)396     bool operator()(const SurfaceConfig &a, const SurfaceConfig &b)
397     {
398         return a.compareTo(b, m_specifiedRGBColors, m_specifiedLuminanceColors, m_yuvPlaneBppSpecified);
399     }
400 
401 private:
402     const tcu::BVec4 m_specifiedRGBColors;
403     const tcu::BVec2 m_specifiedLuminanceColors;
404     const bool m_yuvPlaneBppSpecified;
405 };
406 
407 class ConfigFilter
408 {
409 private:
410     std::map<EGLenum, AttribRule> m_rules;
411 
412 public:
ConfigFilter()413     ConfigFilter() : m_rules(SurfaceConfig::getDefaultRules())
414     {
415     }
416 
setValue(EGLenum name,EGLint value)417     void setValue(EGLenum name, EGLint value)
418     {
419         DE_ASSERT(de::contains(m_rules, name));
420         m_rules[name].value = value;
421     }
422 
setValues(std::vector<std::pair<EGLenum,EGLint>> values)423     void setValues(std::vector<std::pair<EGLenum, EGLint>> values)
424     {
425         for (size_t ndx = 0; ndx < values.size(); ndx++)
426         {
427             const EGLenum name = values[ndx].first;
428             const EGLint value = values[ndx].second;
429 
430             setValue(name, value);
431         }
432     }
433 
getAttribute(EGLenum name) const434     AttribRule getAttribute(EGLenum name) const
435     {
436         DE_ASSERT(de::contains(m_rules, name));
437         return m_rules.find(name)->second;
438     }
439 
isMatch(const SurfaceConfig & config) const440     bool isMatch(const SurfaceConfig &config) const
441     {
442         bool match = true;
443         for (std::map<EGLenum, AttribRule>::const_iterator iter = m_rules.begin(); iter != m_rules.end(); iter++)
444         {
445             const AttribRule rule = iter->second;
446 
447             if (rule.value == EGL_DONT_CARE)
448                 continue;
449             else if (rule.name == EGL_MATCH_NATIVE_PIXMAP)
450                 TCU_CHECK(rule.value == EGL_NONE); // Not supported
451             else if (rule.name == EGL_TRANSPARENT_RED_VALUE || rule.name == EGL_TRANSPARENT_GREEN_VALUE ||
452                      rule.name == EGL_TRANSPARENT_BLUE_VALUE)
453                 continue;
454             else
455             {
456                 const EGLint cfgValue = config.getAttribute(rule.name);
457 
458                 if (rule.name == EGL_CONFIG_ID)
459                     return (rule.value == cfgValue);
460 
461                 switch (rule.criteria)
462                 {
463                 case CRITERIA_EXACT:
464                     if (rule.value != cfgValue)
465                         match = false;
466                     break;
467 
468                 case CRITERIA_AT_LEAST:
469                     if (rule.value > cfgValue)
470                         match = false;
471                     break;
472 
473                 case CRITERIA_MASK:
474                     if ((rule.value & cfgValue) != rule.value)
475                         match = false;
476                     break;
477 
478                 default:
479                     TCU_FAIL("Unknown criteria");
480                 }
481             }
482         }
483 
484         return match;
485     }
486 
getSpecifiedRGBColors(void) const487     tcu::BVec4 getSpecifiedRGBColors(void) const
488     {
489         const EGLenum bitAttribs[] = {EGL_RED_SIZE, EGL_GREEN_SIZE, EGL_BLUE_SIZE, EGL_ALPHA_SIZE};
490 
491         tcu::BVec4 result;
492 
493         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bitAttribs); ndx++)
494         {
495             const EGLenum attrib = bitAttribs[ndx];
496             const EGLint value   = getAttribute(attrib).value;
497 
498             if (value != 0 && value != EGL_DONT_CARE)
499                 result[ndx] = true;
500             else
501                 result[ndx] = false;
502         }
503 
504         return result;
505     }
506 
getSpecifiedLuminanceColors(void) const507     tcu::BVec2 getSpecifiedLuminanceColors(void) const
508     {
509         const EGLenum bitAttribs[] = {EGL_LUMINANCE_SIZE, EGL_ALPHA_SIZE};
510 
511         tcu::BVec2 result;
512 
513         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bitAttribs); ndx++)
514         {
515             const EGLenum attrib = bitAttribs[ndx];
516             const EGLint value   = getAttribute(attrib).value;
517 
518             if (value != 0 && value != EGL_DONT_CARE)
519                 result[ndx] = true;
520             else
521                 result[ndx] = false;
522         }
523 
524         return result;
525     }
526 
isYuvPlaneBppSpecified(void) const527     bool isYuvPlaneBppSpecified(void) const
528     {
529         const EGLenum attrib = EGL_YUV_PLANE_BPP_EXT;
530         const EGLint value   = getAttribute(attrib).value;
531 
532         return (value != 0) && (value != EGL_DONT_CARE);
533     }
534 
filter(const std::vector<SurfaceConfig> & configs) const535     std::vector<SurfaceConfig> filter(const std::vector<SurfaceConfig> &configs) const
536     {
537         std::vector<SurfaceConfig> out;
538 
539         for (std::vector<SurfaceConfig>::const_iterator iter = configs.begin(); iter != configs.end(); iter++)
540         {
541             if (isMatch(*iter))
542                 out.push_back(*iter);
543         }
544 
545         return out;
546     }
547 };
548 
chooseConfigReference(const Library & egl,EGLDisplay display,std::vector<EGLConfig> & dst,const std::vector<std::pair<EGLenum,EGLint>> & attributes)549 void chooseConfigReference(const Library &egl, EGLDisplay display, std::vector<EGLConfig> &dst,
550                            const std::vector<std::pair<EGLenum, EGLint>> &attributes)
551 {
552     // Get all configs
553     std::vector<EGLConfig> eglConfigs = eglu::getConfigs(egl, display);
554 
555     // Config infos - including extension attributes
556     std::vector<ConfigInfo> configInfos;
557     configInfos.resize(eglConfigs.size());
558 
559     for (size_t ndx = 0; ndx < eglConfigs.size(); ndx++)
560     {
561         eglu::queryCoreConfigInfo(egl, display, eglConfigs[ndx], &configInfos[ndx]);
562         eglu::queryExtConfigInfo(egl, display, eglConfigs[ndx], &configInfos[ndx]);
563     }
564 
565     // Pair configs with info
566     std::vector<SurfaceConfig> configs;
567     for (size_t ndx = 0; ndx < eglConfigs.size(); ndx++)
568         configs.push_back(SurfaceConfig(eglConfigs[ndx], configInfos[ndx]));
569 
570     // Filter configs
571     ConfigFilter configFilter;
572     configFilter.setValues(attributes);
573 
574     std::vector<SurfaceConfig> filteredConfigs = configFilter.filter(configs);
575 
576     // Sort configs
577     std::sort(filteredConfigs.begin(), filteredConfigs.end(),
578               CompareConfigs(configFilter.getSpecifiedRGBColors(), configFilter.getSpecifiedLuminanceColors(),
579                              configFilter.isYuvPlaneBppSpecified()));
580 
581     // Write to dst list
582     dst.resize(filteredConfigs.size());
583     for (size_t ndx = 0; ndx < filteredConfigs.size(); ndx++)
584         dst[ndx] = filteredConfigs[ndx].getEglConfig();
585 }
586 
587 } // namespace egl
588 } // namespace deqp
589