• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)
73 		: name			(EGL_NONE)
74 		, value			(EGL_NONE)
75 		, criteria		(CRITERIA_LAST)
76 		, sortOrder		(SORTORDER_LAST)
77 	{
78 	}
79 
AttribRuledeqp::egl::AttribRule80 	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:
getCaveatRank(EGLenum caveat)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 
getColorBufferTypeRank(EGLenum type)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 
getYuvOrderRank(EGLenum order)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 
getYuvPlaneBppValue(EGLenum bpp)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 
getColorComponentTypeRank(EGLenum compType)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 
compareCaveat(const SurfaceConfig & a,const SurfaceConfig & b)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 
compareColorBufferType(const SurfaceConfig & a,const SurfaceConfig & b)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 
compareYuvOrder(const SurfaceConfig & a,const SurfaceConfig & b)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 
compareColorComponentType(const SurfaceConfig & a,const SurfaceConfig & b)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 
compareColorBufferBits(const SurfaceConfig & a,const SurfaceConfig & b,const tcu::BVec4 & specifiedRGBColors,const tcu::BVec2 & specifiedLuminanceColors,bool yuvPlaneBppSpecified)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>
compareAttributeSmaller(const SurfaceConfig & a,const SurfaceConfig & b)208 	static bool compareAttributeSmaller (const SurfaceConfig& a, const SurfaceConfig& b)
209 	{
210 		return a.getAttribute(Attribute) < b.getAttribute(Attribute);
211 	}
212 public:
SurfaceConfig(EGLConfig config,ConfigInfo & info)213 	SurfaceConfig (EGLConfig config, ConfigInfo &info)
214 		: m_config(config)
215 		, m_info(info)
216 	{
217 	}
218 
getEglConfig(void) const219 	EGLConfig getEglConfig (void) const
220 	{
221 		return m_config;
222 	}
223 
getAttribute(const EGLenum attribute) const224 	EGLint getAttribute (const EGLenum attribute) const
225 	{
226 		return m_info.getAttribute(attribute);
227 	}
228 
operator ==(const SurfaceConfig & a,const SurfaceConfig & b)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 
compareTo(const SurfaceConfig & b,const tcu::BVec4 & specifiedRGBColors,const tcu::BVec2 & specifiedLuminanceColors,bool yuvPlaneBppSpecified) const242 	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::compareColorComponentType,
248 			SurfaceConfig::compareColorBufferType,
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 
getDefaultRules(void)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:
CompareConfigs(const tcu::BVec4 & specifiedRGBColors,const tcu::BVec2 & specifiedLuminanceColors,bool yuvPlaneBppSpecified)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 
operator ()(const SurfaceConfig & a,const SurfaceConfig & b)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:
ConfigFilter()363 	ConfigFilter ()
364 		: m_rules(SurfaceConfig::getDefaultRules())
365 	{
366 	}
367 
setValue(EGLenum name,EGLint value)368 	void setValue (EGLenum name, EGLint value)
369 	{
370 		DE_ASSERT(de::contains(m_rules, name));
371 		m_rules[name].value = value;
372 	}
373 
setValues(std::vector<std::pair<EGLenum,EGLint>> values)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 
getAttribute(EGLenum name) const385 	AttribRule getAttribute (EGLenum name) const
386 	{
387 		DE_ASSERT(de::contains(m_rules, name));
388 		return m_rules.find(name)->second;
389 	}
390 
isMatch(const SurfaceConfig & config) const391 	bool isMatch (const SurfaceConfig& config) const
392 	{
393 		bool match = true;
394 		for (std::map<EGLenum, AttribRule>::const_iterator iter = m_rules.begin(); iter != m_rules.end(); iter++)
395 		{
396 			const AttribRule rule = iter->second;
397 
398 			if (rule.value == EGL_DONT_CARE)
399 				continue;
400 			else if (rule.name == EGL_MATCH_NATIVE_PIXMAP)
401 				TCU_CHECK(rule.value == EGL_NONE); // Not supported
402 			else if (rule.name == EGL_TRANSPARENT_RED_VALUE || rule.name == EGL_TRANSPARENT_GREEN_VALUE || rule.name == EGL_TRANSPARENT_BLUE_VALUE)
403 				continue;
404 			else
405 			{
406 				const EGLint cfgValue = config.getAttribute(rule.name);
407 
408 				if (rule.name == EGL_CONFIG_ID)
409 					return (rule.value == cfgValue);
410 
411 				switch (rule.criteria)
412 				{
413 					case CRITERIA_EXACT:
414 						if (rule.value != cfgValue)
415 							match = false;
416 						break;
417 
418 					case CRITERIA_AT_LEAST:
419 						if (rule.value > cfgValue)
420 							match = false;
421 						break;
422 
423 					case CRITERIA_MASK:
424 						if ((rule.value & cfgValue) != rule.value)
425 							match = false;
426 						break;
427 
428 					default:
429 						TCU_FAIL("Unknown criteria");
430 				}
431 			}
432 		}
433 
434 		return match;
435 	}
436 
getSpecifiedRGBColors(void) const437 	tcu::BVec4 getSpecifiedRGBColors (void) const
438 	{
439 		const EGLenum bitAttribs[] =
440 		{
441 			EGL_RED_SIZE,
442 			EGL_GREEN_SIZE,
443 			EGL_BLUE_SIZE,
444 			EGL_ALPHA_SIZE
445 		};
446 
447 		tcu::BVec4 result;
448 
449 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bitAttribs); ndx++)
450 		{
451 			const EGLenum	attrib	= bitAttribs[ndx];
452 			const EGLint	value	= getAttribute(attrib).value;
453 
454 			if (value != 0 && value != EGL_DONT_CARE)
455 				result[ndx] = true;
456 			else
457 				result[ndx] = false;
458 		}
459 
460 		return result;
461 	}
462 
getSpecifiedLuminanceColors(void) const463 	tcu::BVec2 getSpecifiedLuminanceColors (void) const
464 	{
465 		const EGLenum bitAttribs[] =
466 		{
467 			EGL_LUMINANCE_SIZE,
468 			EGL_ALPHA_SIZE
469 		};
470 
471 		tcu::BVec2 result;
472 
473 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bitAttribs); ndx++)
474 		{
475 			const EGLenum	attrib	= bitAttribs[ndx];
476 			const EGLint	value	= getAttribute(attrib).value;
477 
478 			if (value != 0 && value != EGL_DONT_CARE)
479 				result[ndx] = true;
480 			else
481 				result[ndx] = false;
482 		}
483 
484 		return result;
485 	}
486 
isYuvPlaneBppSpecified(void) const487 	bool isYuvPlaneBppSpecified (void) const
488 	{
489 		const EGLenum	attrib	= EGL_YUV_PLANE_BPP_EXT;
490 		const EGLint	value	= getAttribute(attrib).value;
491 
492 		return (value != 0) && (value != EGL_DONT_CARE);
493 	}
494 
filter(const std::vector<SurfaceConfig> & configs) const495 	std::vector<SurfaceConfig> filter (const std::vector<SurfaceConfig>& configs) const
496 	{
497 		std::vector<SurfaceConfig> out;
498 
499 		for (std::vector<SurfaceConfig>::const_iterator iter = configs.begin(); iter != configs.end(); iter++)
500 		{
501 			if (isMatch(*iter)) out.push_back(*iter);
502 		}
503 
504 		return out;
505 	}
506 };
507 
chooseConfigReference(const Library & egl,EGLDisplay display,std::vector<EGLConfig> & dst,const std::vector<std::pair<EGLenum,EGLint>> & attributes)508 void chooseConfigReference (const Library& egl, EGLDisplay display, std::vector<EGLConfig>& dst, const std::vector<std::pair<EGLenum, EGLint> >& attributes)
509 {
510 	// Get all configs
511 	std::vector<EGLConfig> eglConfigs = eglu::getConfigs(egl, display);
512 
513 	// Config infos - including extension attributes
514 	std::vector<ConfigInfo> configInfos;
515 	configInfos.resize(eglConfigs.size());
516 
517 	for (size_t ndx = 0; ndx < eglConfigs.size(); ndx++)
518 	{
519 		eglu::queryCoreConfigInfo(egl, display, eglConfigs[ndx], &configInfos[ndx]);
520 		eglu::queryExtConfigInfo(egl, display, eglConfigs[ndx], &configInfos[ndx]);
521 	}
522 
523 	// Pair configs with info
524 	std::vector<SurfaceConfig> configs;
525 	for (size_t ndx = 0; ndx < eglConfigs.size(); ndx++)
526 		configs.push_back(SurfaceConfig(eglConfigs[ndx], configInfos[ndx]));
527 
528 	// Filter configs
529 	ConfigFilter configFilter;
530 	configFilter.setValues(attributes);
531 
532 	std::vector<SurfaceConfig> filteredConfigs = configFilter.filter(configs);
533 
534 	// Sort configs
535 	std::sort(filteredConfigs.begin(), filteredConfigs.end(), CompareConfigs(configFilter.getSpecifiedRGBColors(), configFilter.getSpecifiedLuminanceColors(), configFilter.isYuvPlaneBppSpecified()));
536 
537 	// Write to dst list
538 	dst.resize(filteredConfigs.size());
539 	for (size_t ndx = 0; ndx < filteredConfigs.size(); ndx++)
540 		dst[ndx] = filteredConfigs[ndx].getEglConfig();
541 }
542 
543 } // egl
544 } // deqp
545