Home | History | Annotate | Download | only in egl
      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 		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 
    437 	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 
    463 	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 
    487 	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 
    495 	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 
    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