Merge "Fix color change verification in dithering tests" into nougat-cts-dev am:...
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglChooseConfigReference.cpp
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
72         AttribRule (void)
73                 : name                  (EGL_NONE)
74                 , value                 (EGL_NONE)
75                 , criteria              (CRITERIA_LAST)
76                 , sortOrder             (SORTORDER_LAST)
77         {
78         }
79
80         AttribRule (EGLenum name_, EGLint value_, Criteria criteria_, SortOrder sortOrder_)
81                 : name                  (name_)
82                 , value                 (value_)
83                 , criteria              (criteria_)
84                 , sortOrder             (sortOrder_)
85         {
86         }
87 };
88
89 class SurfaceConfig
90 {
91 private:
92         static int getCaveatRank (EGLenum caveat)
93         {
94                 switch (caveat)
95                 {
96                         case EGL_NONE:                                  return 0;
97                         case EGL_SLOW_CONFIG:                   return 1;
98                         case EGL_NON_CONFORMANT_CONFIG: return 2;
99                         default:
100                                 TCU_THROW(TestError, (std::string("Unknown config caveat: ") + eglu::getConfigCaveatStr(caveat).toString()).c_str());
101                 }
102         }
103
104         static int getColorBufferTypeRank (EGLenum type)
105         {
106                 switch (type)
107                 {
108                         case EGL_RGB_BUFFER:                    return 0;
109                         case EGL_LUMINANCE_BUFFER:              return 1;
110                         case EGL_YUV_BUFFER_EXT:                return 2;
111                         default:
112                                 TCU_THROW(TestError, (std::string("Unknown color buffer type: ") + eglu::getColorBufferTypeStr(type).toString()).c_str());
113                 }
114         }
115
116         static int getYuvOrderRank (EGLenum order)
117         {
118                 switch (order)
119                 {
120                         case EGL_NONE:                                  return 0;
121                         case EGL_YUV_ORDER_YUV_EXT:             return 1;
122                         case EGL_YUV_ORDER_YVU_EXT:             return 2;
123                         case EGL_YUV_ORDER_YUYV_EXT:    return 3;
124                         case EGL_YUV_ORDER_YVYU_EXT:    return 4;
125                         case EGL_YUV_ORDER_UYVY_EXT:    return 5;
126                         case EGL_YUV_ORDER_VYUY_EXT:    return 6;
127                         case EGL_YUV_ORDER_AYUV_EXT:    return 7;
128                         default:
129                                 TCU_THROW(TestError, (std::string("Unknown YUV order: ") + eglu::getYuvOrderStr(order).toString()).c_str());
130                 }
131         }
132
133         static int getYuvPlaneBppValue (EGLenum bpp)
134         {
135                 switch (bpp)
136                 {
137                         case EGL_YUV_PLANE_BPP_0_EXT:   return 0;
138                         case EGL_YUV_PLANE_BPP_8_EXT:   return 8;
139                         case EGL_YUV_PLANE_BPP_10_EXT:  return 10;
140                         default:
141                                 TCU_THROW(TestError, (std::string("Unknown YUV plane BPP: ") + eglu::getYuvPlaneBppStr(bpp).toString()).c_str());
142                 }
143         }
144
145         static int getColorComponentTypeRank (EGLenum compType)
146         {
147                 switch (compType)
148                 {
149                         case EGL_COLOR_COMPONENT_TYPE_FIXED_EXT:        return 0;
150                         case EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT:        return 1;
151                         default:
152                                 TCU_THROW(TestError, (std::string("Unknown color component type: ") + eglu::getColorComponentTypeStr(compType).toString()).c_str());
153                 }
154         }
155
156         typedef bool (*CompareFunc) (const SurfaceConfig& a, const SurfaceConfig& b);
157
158         static bool compareCaveat (const SurfaceConfig& a, const SurfaceConfig& b)
159         {
160                 return getCaveatRank((EGLenum)a.m_info.configCaveat) < getCaveatRank((EGLenum)b.m_info.configCaveat);
161         }
162
163         static bool compareColorBufferType (const SurfaceConfig& a, const SurfaceConfig& b)
164         {
165                 return getColorBufferTypeRank((EGLenum)a.m_info.colorBufferType) < getColorBufferTypeRank((EGLenum)b.m_info.colorBufferType);
166         }
167
168         static bool compareYuvOrder (const SurfaceConfig& a, const SurfaceConfig& b)
169         {
170                 return getYuvOrderRank((EGLenum)a.m_info.yuvOrder) < getYuvOrderRank((EGLenum)b.m_info.yuvOrder);
171         }
172
173         static bool compareColorComponentType (const SurfaceConfig& a, const SurfaceConfig& b)
174         {
175                 return getColorComponentTypeRank((EGLenum)a.m_info.colorComponentType) < getColorComponentTypeRank((EGLenum)b.m_info.colorComponentType);
176         }
177
178         static bool compareColorBufferBits (const SurfaceConfig& a, const SurfaceConfig& b, const tcu::BVec4& specifiedRGBColors, const tcu::BVec2& specifiedLuminanceColors, bool yuvPlaneBppSpecified)
179         {
180                 DE_ASSERT(a.m_info.colorBufferType == b.m_info.colorBufferType);
181                 switch (a.m_info.colorBufferType)
182                 {
183                         case EGL_RGB_BUFFER:
184                         {
185                                 const tcu::IVec4        mask    (specifiedRGBColors.cast<deInt32>());
186
187                                 return (a.m_info.redSize * mask[0] + a.m_info.greenSize * mask[1] + a.m_info.blueSize * mask[2] + a.m_info.alphaSize * mask[3])
188                                                 > (b.m_info.redSize * mask[0] + b.m_info.greenSize * mask[1] + b.m_info.blueSize * mask[2] + b.m_info.alphaSize * mask[3]);
189                         }
190
191                         case EGL_LUMINANCE_BUFFER:
192                         {
193                                 const tcu::IVec2        mask    (specifiedLuminanceColors.cast<deInt32>());
194
195                                 return (a.m_info.luminanceSize * mask[0] + a.m_info.alphaSize * mask[1]) > (b.m_info.luminanceSize * mask[0] + b.m_info.alphaSize * mask[1]);
196                         }
197
198                         case EGL_YUV_BUFFER_EXT:
199                                 return yuvPlaneBppSpecified ? (a.m_info.yuvPlaneBpp > b.m_info.yuvPlaneBpp) : false;
200
201                         default:
202                                 DE_ASSERT(DE_FALSE);
203                                 return true;
204                 }
205         }
206
207         template <EGLenum Attribute>
208         static bool compareAttributeSmaller (const SurfaceConfig& a, const SurfaceConfig& b)
209         {
210                 return a.getAttribute(Attribute) < b.getAttribute(Attribute);
211         }
212 public:
213         SurfaceConfig (EGLConfig config, ConfigInfo &info)
214                 : m_config(config)
215                 , m_info(info)
216         {
217         }
218
219         EGLConfig getEglConfig (void) const
220         {
221                 return m_config;
222         }
223
224         EGLint getAttribute (const EGLenum attribute) const
225         {
226                 return m_info.getAttribute(attribute);
227         }
228
229         friend bool operator== (const SurfaceConfig& a, const SurfaceConfig& b)
230         {
231                 const std::map<EGLenum, AttribRule> defaultRules = getDefaultRules();
232
233                 for (std::map<EGLenum, AttribRule>::const_iterator iter = defaultRules.begin(); iter != defaultRules.end(); iter++)
234                 {
235                         const EGLenum attribute = iter->first;
236
237                         if (a.getAttribute(attribute) != b.getAttribute(attribute)) return false;
238                 }
239                 return true;
240         }
241
242         bool compareTo (const SurfaceConfig& b, const tcu::BVec4& specifiedRGBColors, const tcu::BVec2& specifiedLuminanceColors, bool yuvPlaneBppSpecified) const
243         {
244                 static const SurfaceConfig::CompareFunc compareFuncs[] =
245                 {
246                         SurfaceConfig::compareCaveat,
247                         SurfaceConfig::compareColorBufferType,
248                         SurfaceConfig::compareColorComponentType,
249                         DE_NULL, // SurfaceConfig::compareColorBufferBits,
250                         SurfaceConfig::compareAttributeSmaller<EGL_BUFFER_SIZE>,
251                         SurfaceConfig::compareAttributeSmaller<EGL_SAMPLE_BUFFERS>,
252                         SurfaceConfig::compareAttributeSmaller<EGL_SAMPLES>,
253                         SurfaceConfig::compareAttributeSmaller<EGL_DEPTH_SIZE>,
254                         SurfaceConfig::compareAttributeSmaller<EGL_STENCIL_SIZE>,
255                         SurfaceConfig::compareAttributeSmaller<EGL_ALPHA_MASK_SIZE>,
256                         SurfaceConfig::compareYuvOrder,
257                         SurfaceConfig::compareAttributeSmaller<EGL_CONFIG_ID>
258                 };
259
260                 if (*this == b)
261                         return false; // std::sort() can compare object to itself.
262
263                 for (int ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(compareFuncs); ndx++)
264                 {
265                         if (!compareFuncs[ndx])
266                         {
267                                 if (compareColorBufferBits(*this, b, specifiedRGBColors, specifiedLuminanceColors, yuvPlaneBppSpecified))
268                                         return true;
269                                 else if (compareColorBufferBits(b, *this, specifiedRGBColors, specifiedLuminanceColors, yuvPlaneBppSpecified))
270                                         return false;
271
272                                 continue;
273                         }
274
275                         if (compareFuncs[ndx](*this, b))
276                                 return true;
277                         else if (compareFuncs[ndx](b, *this))
278                                 return false;
279                 }
280
281                 TCU_FAIL("Unable to compare configs - duplicate ID?");
282         }
283
284         static std::map<EGLenum, AttribRule> getDefaultRules (void)
285         {
286                 // \todo [2011-03-24 pyry] From EGL 1.4 spec - check that this is valid for other versions as well
287                 std::map<EGLenum, AttribRule> rules;
288
289                 //                                                                      Attribute                                                                       Default                         Selection Criteria      Sort Order                      Sort Priority
290                 rules[EGL_BUFFER_SIZE]                          = AttribRule(EGL_BUFFER_SIZE,                           0,                                      CRITERIA_AT_LEAST,      SORTORDER_SMALLER);     //      4
291                 rules[EGL_RED_SIZE]                                     = AttribRule(EGL_RED_SIZE,                                      0,                                      CRITERIA_AT_LEAST,      SORTORDER_SPECIAL);     //      3
292                 rules[EGL_GREEN_SIZE]                           = AttribRule(EGL_GREEN_SIZE,                            0,                                      CRITERIA_AT_LEAST,      SORTORDER_SPECIAL);     //      3
293                 rules[EGL_BLUE_SIZE]                            = AttribRule(EGL_BLUE_SIZE,                                     0,                                      CRITERIA_AT_LEAST,      SORTORDER_SPECIAL);     //      3
294                 rules[EGL_LUMINANCE_SIZE]                       = AttribRule(EGL_LUMINANCE_SIZE,                        0,                                      CRITERIA_AT_LEAST,      SORTORDER_SPECIAL);     //      3
295                 rules[EGL_ALPHA_SIZE]                           = AttribRule(EGL_ALPHA_SIZE,                            0,                                      CRITERIA_AT_LEAST,      SORTORDER_SPECIAL);     //      3
296                 rules[EGL_ALPHA_MASK_SIZE]                      = AttribRule(EGL_ALPHA_MASK_SIZE,                       0,                                      CRITERIA_AT_LEAST,      SORTORDER_SMALLER);     //      9
297                 rules[EGL_BIND_TO_TEXTURE_RGB]          = AttribRule(EGL_BIND_TO_TEXTURE_RGB,           EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_NONE);
298                 rules[EGL_BIND_TO_TEXTURE_RGBA]         = AttribRule(EGL_BIND_TO_TEXTURE_RGBA,          EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_NONE);
299                 rules[EGL_COLOR_BUFFER_TYPE]            = AttribRule(EGL_COLOR_BUFFER_TYPE,                     EGL_RGB_BUFFER,         CRITERIA_EXACT,         SORTORDER_NONE);        //      2
300                 rules[EGL_CONFIG_CAVEAT]                        = AttribRule(EGL_CONFIG_CAVEAT,                         EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_SPECIAL);     //      1
301                 rules[EGL_CONFIG_ID]                            = AttribRule(EGL_CONFIG_ID,                                     EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_SMALLER);     //      11
302                 rules[EGL_CONFORMANT]                           = AttribRule(EGL_CONFORMANT,                            0,                                      CRITERIA_MASK,          SORTORDER_NONE);
303                 rules[EGL_DEPTH_SIZE]                           = AttribRule(EGL_DEPTH_SIZE,                            0,                                      CRITERIA_AT_LEAST,      SORTORDER_SMALLER);     //      7
304                 rules[EGL_LEVEL]                                        = AttribRule(EGL_LEVEL,                                         0,                                      CRITERIA_EXACT,         SORTORDER_NONE);
305                 rules[EGL_MAX_SWAP_INTERVAL]            = AttribRule(EGL_MAX_SWAP_INTERVAL,                     EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_NONE);
306                 rules[EGL_MIN_SWAP_INTERVAL]            = AttribRule(EGL_MIN_SWAP_INTERVAL,                     EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_NONE);
307                 rules[EGL_NATIVE_RENDERABLE]            = AttribRule(EGL_NATIVE_RENDERABLE,                     EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_NONE);
308                 rules[EGL_NATIVE_VISUAL_TYPE]           = AttribRule(EGL_NATIVE_VISUAL_TYPE,            EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_SPECIAL);     //      10
309                 rules[EGL_RENDERABLE_TYPE]                      = AttribRule(EGL_RENDERABLE_TYPE,                       EGL_OPENGL_ES_BIT,      CRITERIA_MASK,          SORTORDER_NONE);
310                 rules[EGL_SAMPLE_BUFFERS]                       = AttribRule(EGL_SAMPLE_BUFFERS,                        0,                                      CRITERIA_AT_LEAST,      SORTORDER_SMALLER);     //      5
311                 rules[EGL_SAMPLES]                                      = AttribRule(EGL_SAMPLES,                                       0,                                      CRITERIA_AT_LEAST,      SORTORDER_SMALLER);     //      6
312                 rules[EGL_STENCIL_SIZE]                         = AttribRule(EGL_STENCIL_SIZE,                          0,                                      CRITERIA_AT_LEAST,      SORTORDER_SMALLER);     //      8
313                 rules[EGL_SURFACE_TYPE]                         = AttribRule(EGL_SURFACE_TYPE,                          EGL_WINDOW_BIT,         CRITERIA_MASK,          SORTORDER_NONE);
314                 rules[EGL_TRANSPARENT_TYPE]                     = AttribRule(EGL_TRANSPARENT_TYPE,                      EGL_NONE,                       CRITERIA_EXACT,         SORTORDER_NONE);
315                 rules[EGL_TRANSPARENT_RED_VALUE]        = AttribRule(EGL_TRANSPARENT_RED_VALUE,         EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_NONE);
316                 rules[EGL_TRANSPARENT_GREEN_VALUE]      = AttribRule(EGL_TRANSPARENT_GREEN_VALUE,       EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_NONE);
317                 rules[EGL_TRANSPARENT_BLUE_VALUE]       = AttribRule(EGL_TRANSPARENT_BLUE_VALUE,        EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_NONE);
318
319                 // EGL_EXT_yuv_surface
320                 rules[EGL_YUV_ORDER_EXT]                        = AttribRule(EGL_YUV_ORDER_EXT,                         EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_SPECIAL);
321                 rules[EGL_YUV_NUMBER_OF_PLANES_EXT]     = AttribRule(EGL_YUV_NUMBER_OF_PLANES_EXT,      EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_NONE);
322                 rules[EGL_YUV_SUBSAMPLE_EXT]            = AttribRule(EGL_YUV_SUBSAMPLE_EXT,                     EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_NONE);
323                 rules[EGL_YUV_DEPTH_RANGE_EXT]          = AttribRule(EGL_YUV_DEPTH_RANGE_EXT,           EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_NONE);
324                 rules[EGL_YUV_CSC_STANDARD_EXT]         = AttribRule(EGL_YUV_CSC_STANDARD_EXT,          EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_NONE);
325                 rules[EGL_YUV_PLANE_BPP_EXT]            = AttribRule(EGL_YUV_PLANE_BPP_EXT,                     EGL_DONT_CARE,          CRITERIA_AT_LEAST,      SORTORDER_SPECIAL);     //      3
326
327                 // EGL_EXT_pixel_format_float
328                 rules[EGL_COLOR_COMPONENT_TYPE_EXT]     = AttribRule(EGL_COLOR_COMPONENT_TYPE_EXT,      EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,             CRITERIA_EXACT,         SORTORDER_SPECIAL);     //      2
329
330                 return rules;
331         }
332 private:
333         EGLConfig m_config;
334         ConfigInfo m_info;
335 };
336
337 class CompareConfigs
338 {
339 public:
340         CompareConfigs (const tcu::BVec4& specifiedRGBColors, const tcu::BVec2& specifiedLuminanceColors, bool yuvPlaneBppSpecified)
341                 : m_specifiedRGBColors                  (specifiedRGBColors)
342                 , m_specifiedLuminanceColors    (specifiedLuminanceColors)
343                 , m_yuvPlaneBppSpecified                (yuvPlaneBppSpecified)
344         {
345         }
346
347         bool operator() (const SurfaceConfig& a, const SurfaceConfig& b)
348         {
349                 return a.compareTo(b, m_specifiedRGBColors, m_specifiedLuminanceColors, m_yuvPlaneBppSpecified);
350         }
351
352 private:
353         const tcu::BVec4        m_specifiedRGBColors;
354         const tcu::BVec2        m_specifiedLuminanceColors;
355         const bool                      m_yuvPlaneBppSpecified;
356 };
357
358 class ConfigFilter
359 {
360 private:
361         std::map<EGLenum, AttribRule> m_rules;
362 public:
363         ConfigFilter ()
364                 : m_rules(SurfaceConfig::getDefaultRules())
365         {
366         }
367
368         void setValue (EGLenum name, EGLint value)
369         {
370                 DE_ASSERT(de::contains(m_rules, name));
371                 m_rules[name].value = value;
372         }
373
374         void setValues (std::vector<std::pair<EGLenum, EGLint> > values)
375         {
376                 for (size_t ndx = 0; ndx < values.size(); ndx++)
377                 {
378                         const EGLenum   name    = values[ndx].first;
379                         const EGLint    value   = values[ndx].second;
380
381                         setValue(name, value);
382                 }
383         }
384
385         AttribRule getAttribute (EGLenum name) const
386         {
387                 DE_ASSERT(de::contains(m_rules, name));
388                 return m_rules.find(name)->second;
389         }
390
391         bool isMatch (const SurfaceConfig& config) const
392         {
393                 for (std::map<EGLenum, AttribRule>::const_iterator iter = m_rules.begin(); iter != m_rules.end(); iter++)
394                 {
395                         const AttribRule rule = iter->second;
396
397                         if (rule.value == EGL_DONT_CARE)
398                                 continue;
399                         else if (rule.name == EGL_MATCH_NATIVE_PIXMAP)
400                                 TCU_CHECK(rule.value == EGL_NONE); // Not supported
401                         else if (rule.name == EGL_TRANSPARENT_RED_VALUE || rule.name == EGL_TRANSPARENT_GREEN_VALUE || rule.name == EGL_TRANSPARENT_BLUE_VALUE)
402                                 continue;
403                         else
404                         {
405                                 const EGLint cfgValue = config.getAttribute(rule.name);
406
407                                 switch (rule.criteria)
408                                 {
409                                         case CRITERIA_EXACT:
410                                                 if (rule.value != cfgValue)
411                                                         return false;
412                                                 break;
413
414                                         case CRITERIA_AT_LEAST:
415                                                 if (rule.value > cfgValue)
416                                                         return false;
417                                                 break;
418
419                                         case CRITERIA_MASK:
420                                                 if ((rule.value & cfgValue) != rule.value)
421                                                         return false;
422                                                 break;
423
424                                         default:
425                                                 TCU_FAIL("Unknown criteria");
426                                 }
427                         }
428                 }
429
430                 return true;
431         }
432
433         tcu::BVec4 getSpecifiedRGBColors (void) const
434         {
435                 const EGLenum bitAttribs[] =
436                 {
437                         EGL_RED_SIZE,
438                         EGL_GREEN_SIZE,
439                         EGL_BLUE_SIZE,
440                         EGL_ALPHA_SIZE
441                 };
442
443                 tcu::BVec4 result;
444
445                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bitAttribs); ndx++)
446                 {
447                         const EGLenum   attrib  = bitAttribs[ndx];
448                         const EGLint    value   = getAttribute(attrib).value;
449
450                         if (value != 0 && value != EGL_DONT_CARE)
451                                 result[ndx] = true;
452                         else
453                                 result[ndx] = false;
454                 }
455
456                 return result;
457         }
458
459         tcu::BVec2 getSpecifiedLuminanceColors (void) const
460         {
461                 const EGLenum bitAttribs[] =
462                 {
463                         EGL_LUMINANCE_SIZE,
464                         EGL_ALPHA_SIZE
465                 };
466
467                 tcu::BVec2 result;
468
469                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bitAttribs); ndx++)
470                 {
471                         const EGLenum   attrib  = bitAttribs[ndx];
472                         const EGLint    value   = getAttribute(attrib).value;
473
474                         if (value != 0 && value != EGL_DONT_CARE)
475                                 result[ndx] = true;
476                         else
477                                 result[ndx] = false;
478                 }
479
480                 return result;
481         }
482
483         bool isYuvPlaneBppSpecified (void) const
484         {
485                 const EGLenum   attrib  = EGL_YUV_PLANE_BPP_EXT;
486                 const EGLint    value   = getAttribute(attrib).value;
487
488                 return (value != 0) && (value != EGL_DONT_CARE);
489         }
490
491         std::vector<SurfaceConfig> filter (const std::vector<SurfaceConfig>& configs) const
492         {
493                 std::vector<SurfaceConfig> out;
494
495                 for (std::vector<SurfaceConfig>::const_iterator iter = configs.begin(); iter != configs.end(); iter++)
496                 {
497                         if (isMatch(*iter)) out.push_back(*iter);
498                 }
499
500                 return out;
501         }
502 };
503
504 void chooseConfigReference (const Library& egl, EGLDisplay display, std::vector<EGLConfig>& dst, const std::vector<std::pair<EGLenum, EGLint> >& attributes)
505 {
506         // Get all configs
507         std::vector<EGLConfig> eglConfigs = eglu::getConfigs(egl, display);
508
509         // Config infos - including extension attributes
510         std::vector<ConfigInfo> configInfos;
511         configInfos.resize(eglConfigs.size());
512
513         for (size_t ndx = 0; ndx < eglConfigs.size(); ndx++)
514         {
515                 eglu::queryCoreConfigInfo(egl, display, eglConfigs[ndx], &configInfos[ndx]);
516                 eglu::queryExtConfigInfo(egl, display, eglConfigs[ndx], &configInfos[ndx]);
517         }
518
519         // Pair configs with info
520         std::vector<SurfaceConfig> configs;
521         for (size_t ndx = 0; ndx < eglConfigs.size(); ndx++)
522                 configs.push_back(SurfaceConfig(eglConfigs[ndx], configInfos[ndx]));
523
524         // Filter configs
525         ConfigFilter configFilter;
526         configFilter.setValues(attributes);
527
528         std::vector<SurfaceConfig> filteredConfigs = configFilter.filter(configs);
529
530         // Sort configs
531         std::sort(filteredConfigs.begin(), filteredConfigs.end(), CompareConfigs(configFilter.getSpecifiedRGBColors(), configFilter.getSpecifiedLuminanceColors(), configFilter.isYuvPlaneBppSpecified()));
532
533         // Write to dst list
534         dst.resize(filteredConfigs.size());
535         for (size_t ndx = 0; ndx < filteredConfigs.size(); ndx++)
536                 dst[ndx] = filteredConfigs[ndx].getEglConfig();
537 }
538
539 } // egl
540 } // deqp