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 Surface query tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "teglQuerySurfaceTests.hpp"
     25 
     26 #include "teglSimpleConfigCase.hpp"
     27 
     28 #include "egluNativeDisplay.hpp"
     29 #include "egluNativeWindow.hpp"
     30 #include "egluNativePixmap.hpp"
     31 #include "egluStrUtil.hpp"
     32 #include "egluUtil.hpp"
     33 #include "egluUnique.hpp"
     34 
     35 #include "eglwLibrary.hpp"
     36 #include "eglwEnums.hpp"
     37 
     38 #include "tcuTestLog.hpp"
     39 #include "tcuTestContext.hpp"
     40 #include "tcuCommandLine.hpp"
     41 
     42 #include "deUniquePtr.hpp"
     43 
     44 #include <string>
     45 #include <vector>
     46 
     47 namespace deqp
     48 {
     49 namespace egl
     50 {
     51 
     52 using eglu::ConfigInfo;
     53 using tcu::TestLog;
     54 using namespace eglw;
     55 
     56 static void logSurfaceAttribute (tcu::TestLog& log, EGLint attribute, EGLint value)
     57 {
     58 	const char*								name		= eglu::getSurfaceAttribName(attribute);
     59 	const eglu::SurfaceAttribValueFmt		valueFmt	(attribute, value);
     60 
     61 	log << TestLog::Message << "  " << name << ": " << valueFmt << TestLog::EndMessage;
     62 }
     63 
     64 static void logSurfaceAttributes (tcu::TestLog& log, const Library& egl, EGLDisplay display, EGLSurface surface, const EGLint* attributes, int numAttribs)
     65 {
     66 	for (int ndx = 0; ndx < numAttribs; ndx++)
     67 		logSurfaceAttribute(log, attributes[ndx], eglu::querySurfaceInt(egl, display, surface, attributes[ndx]));
     68 }
     69 
     70 static void logCommonSurfaceAttributes (tcu::TestLog& log, const Library& egl, EGLDisplay display, EGLSurface surface)
     71 {
     72 	static const EGLint	attributes[] =
     73 	{
     74 		EGL_CONFIG_ID,
     75 		EGL_WIDTH,
     76 		EGL_HEIGHT,
     77 		EGL_HORIZONTAL_RESOLUTION,
     78 		EGL_VERTICAL_RESOLUTION,
     79 		EGL_MULTISAMPLE_RESOLVE,
     80 		EGL_PIXEL_ASPECT_RATIO,
     81 		EGL_RENDER_BUFFER,
     82 		EGL_SWAP_BEHAVIOR,
     83 		EGL_ALPHA_FORMAT,
     84 		EGL_COLORSPACE
     85 	};
     86 
     87 	logSurfaceAttributes(log, egl, display, surface, attributes, DE_LENGTH_OF_ARRAY(attributes));
     88 }
     89 
     90 static void logPbufferSurfaceAttributes (tcu::TestLog& log, const Library& egl, EGLDisplay display, EGLSurface surface)
     91 {
     92 	static const EGLint	attributes[] =
     93 	{
     94 		EGL_LARGEST_PBUFFER,
     95 		EGL_TEXTURE_FORMAT,
     96 		EGL_TEXTURE_TARGET,
     97 		EGL_MIPMAP_TEXTURE,
     98 		EGL_MIPMAP_LEVEL,
     99 	};
    100 
    101 	logSurfaceAttributes(log, egl, display, surface, attributes, DE_LENGTH_OF_ARRAY(attributes));
    102 }
    103 
    104 class QuerySurfaceCase : public SimpleConfigCase
    105 {
    106 public:
    107 			QuerySurfaceCase			(EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters);
    108 
    109 	void	checkCommonAttributes		(EGLDisplay display, EGLSurface surface, const ConfigInfo& info);
    110 	void	checkNonPbufferAttributes	(EGLDisplay display, EGLSurface surface);
    111 };
    112 
    113 QuerySurfaceCase::QuerySurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
    114 	: SimpleConfigCase(eglTestCtx, name, description, filters)
    115 {
    116 }
    117 
    118 void QuerySurfaceCase::checkCommonAttributes (EGLDisplay display, EGLSurface surface, const ConfigInfo& info)
    119 {
    120 	const Library&	egl		= m_eglTestCtx.getLibrary();
    121 	tcu::TestLog&	log		= m_testCtx.getLog();
    122 
    123 	// Attributes which are common to all surface types
    124 
    125 	// Config ID
    126 	{
    127 		const EGLint	id	= eglu::querySurfaceInt(egl, display, surface, EGL_CONFIG_ID);
    128 
    129 		if (id != info.configId)
    130 		{
    131 			log << TestLog::Message << "    Fail, config ID " << id << " does not match the one used to create the surface" << TestLog::EndMessage;
    132 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Config ID mismatch");
    133 		}
    134 	}
    135 
    136 	// Width and height
    137 	{
    138 		const EGLint	width	= eglu::querySurfaceInt(egl, display, surface, EGL_WIDTH);
    139 		const EGLint	height	= eglu::querySurfaceInt(egl, display, surface, EGL_HEIGHT);
    140 
    141 		if (width <= 0 || height <= 0)
    142 		{
    143 			log << TestLog::Message << "    Fail, invalid surface size " << width << "x" << height << TestLog::EndMessage;
    144 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
    145 		}
    146 	}
    147 
    148 	// Horizontal and vertical resolution
    149 	{
    150 		const EGLint	hRes	= eglu::querySurfaceInt(egl, display, surface, EGL_HORIZONTAL_RESOLUTION);
    151 		const EGLint	vRes	= eglu::querySurfaceInt(egl, display, surface, EGL_VERTICAL_RESOLUTION);
    152 
    153 		if ((hRes <= 0 || vRes <= 0) && (hRes != EGL_UNKNOWN && vRes != EGL_UNKNOWN))
    154 		{
    155 			log << TestLog::Message << "    Fail, invalid surface resolution " << hRes << "x" << vRes << TestLog::EndMessage;
    156 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface resolution");
    157 		}
    158 	}
    159 
    160 	// Pixel aspect ratio
    161 	{
    162 		const EGLint	pixelRatio	= eglu::querySurfaceInt(egl, display, surface, EGL_PIXEL_ASPECT_RATIO);
    163 
    164 		if (pixelRatio <= 0 && pixelRatio != EGL_UNKNOWN)
    165 		{
    166 			log << TestLog::Message << "    Fail, invalid pixel aspect ratio " << eglu::querySurfaceInt(egl, display, surface, EGL_PIXEL_ASPECT_RATIO) << TestLog::EndMessage;
    167 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid pixel aspect ratio");
    168 		}
    169 	}
    170 
    171 	// Render buffer
    172 	{
    173 		const EGLint	renderBuffer	= eglu::querySurfaceInt(egl, display, surface, EGL_RENDER_BUFFER);
    174 
    175 		if (renderBuffer != EGL_BACK_BUFFER && renderBuffer != EGL_SINGLE_BUFFER)
    176 		{
    177 			log << TestLog::Message << "    Fail, invalid render buffer value " << renderBuffer << TestLog::EndMessage;
    178 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid render buffer");
    179 		}
    180 	}
    181 
    182 	// Multisample resolve
    183 	{
    184 		const EGLint	multisampleResolve	= eglu::querySurfaceInt(egl, display, surface, EGL_MULTISAMPLE_RESOLVE);
    185 
    186 		if (multisampleResolve != EGL_MULTISAMPLE_RESOLVE_DEFAULT && multisampleResolve != EGL_MULTISAMPLE_RESOLVE_BOX)
    187 		{
    188 			log << TestLog::Message << "    Fail, invalid multisample resolve value " << multisampleResolve << TestLog::EndMessage;
    189 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid multisample resolve");
    190 		}
    191 
    192 		if (multisampleResolve == EGL_MULTISAMPLE_RESOLVE_BOX && !(info.surfaceType & EGL_MULTISAMPLE_RESOLVE_BOX_BIT))
    193 		{
    194 			log << TestLog::Message << "    Fail, multisample resolve is reported as box filter but configuration does not support it." << TestLog::EndMessage;
    195 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid multisample resolve");
    196 		}
    197 	}
    198 
    199 	// Swap behavior
    200 	{
    201 		const EGLint	swapBehavior	= eglu::querySurfaceInt(egl, display, surface, EGL_SWAP_BEHAVIOR);
    202 
    203 		if (swapBehavior != EGL_BUFFER_DESTROYED && swapBehavior != EGL_BUFFER_PRESERVED)
    204 		{
    205 			log << TestLog::Message << "    Fail, invalid swap behavior value " << swapBehavior << TestLog::EndMessage;
    206 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid swap behavior");
    207 		}
    208 
    209 		if (swapBehavior == EGL_BUFFER_PRESERVED && !(info.surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
    210 		{
    211 			log << TestLog::Message << "    Fail, swap behavior is reported as preserve but configuration does not support it." << TestLog::EndMessage;
    212 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid swap behavior");
    213 		}
    214 	}
    215 
    216 	// alpha format
    217 	{
    218 		const EGLint	alphaFormat	= eglu::querySurfaceInt(egl, display, surface, EGL_ALPHA_FORMAT);
    219 
    220 		if (alphaFormat != EGL_ALPHA_FORMAT_NONPRE && alphaFormat != EGL_ALPHA_FORMAT_PRE)
    221 		{
    222 			log << TestLog::Message << "    Fail, invalid alpha format value " << alphaFormat << TestLog::EndMessage;
    223 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid alpha format");
    224 		}
    225 
    226 		if (alphaFormat == EGL_ALPHA_FORMAT_PRE && !(info.surfaceType & EGL_VG_ALPHA_FORMAT_PRE_BIT))
    227 		{
    228 			log << TestLog::Message << "    Fail, is set to use premultiplied alpha but configuration does not support it." << TestLog::EndMessage;
    229 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid alpha format");
    230 		}
    231 	}
    232 
    233 	// color space
    234 	{
    235 		const EGLint	colorspace	= eglu::querySurfaceInt(egl, display, surface, EGL_COLORSPACE);
    236 
    237 		if (colorspace != EGL_VG_COLORSPACE_sRGB && colorspace != EGL_VG_COLORSPACE_LINEAR)
    238 		{
    239 			log << TestLog::Message << "    Fail, invalid color space value " << colorspace << TestLog::EndMessage;
    240 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid color space");
    241 		}
    242 
    243 		if (colorspace == EGL_VG_COLORSPACE_LINEAR && !(info.surfaceType & EGL_VG_COLORSPACE_LINEAR_BIT))
    244 		{
    245 			log << TestLog::Message << "    Fail, is set to use a linear color space but configuration does not support it." << TestLog::EndMessage;
    246 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid color space");
    247 		}
    248 	}
    249 }
    250 
    251 void QuerySurfaceCase::checkNonPbufferAttributes (EGLDisplay display, EGLSurface surface)
    252 {
    253 	const Library&	egl						= m_eglTestCtx.getLibrary();
    254 	const EGLint	uninitializedMagicValue	= -42;
    255 	tcu::TestLog&	log						= m_testCtx.getLog();
    256 	EGLint			value					= uninitializedMagicValue;
    257 
    258 	static const EGLint pbufferAttribs[] =
    259 	{
    260 		EGL_LARGEST_PBUFFER,
    261 		EGL_TEXTURE_FORMAT,
    262 		EGL_TEXTURE_TARGET,
    263 		EGL_MIPMAP_TEXTURE,
    264 		EGL_MIPMAP_LEVEL,
    265 	};
    266 
    267 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pbufferAttribs); ndx++)
    268 	{
    269 		const EGLint		attribute	= pbufferAttribs[ndx];
    270 		const std::string	name		= eglu::getSurfaceAttribName(pbufferAttribs[ndx]);
    271 
    272 		egl.querySurface(display, surface, attribute, &value);
    273 
    274 		{
    275 			const EGLint	error	= egl.getError();
    276 
    277 			if (error != EGL_SUCCESS)
    278 			{
    279 				log << TestLog::Message << "    Fail, querying " << name << " from a non-pbuffer surface should not result in an error, received "
    280 					<< eglu::getErrorStr(error) << TestLog::EndMessage;
    281 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Illegal error condition");
    282 				break;
    283 			}
    284 		}
    285 
    286 		// "For a window or pixmap surface, the contents of value are not modified."
    287 		if (value != uninitializedMagicValue)
    288 		{
    289 			log << TestLog::Message << "    Fail, return value contents were modified when querying " << name << " from a non-pbuffer surface." << TestLog::EndMessage;
    290 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Illegal modification of return value");
    291 		}
    292 	}
    293 }
    294 
    295 class QuerySurfaceSimpleWindowCase : public QuerySurfaceCase
    296 {
    297 public:
    298 	QuerySurfaceSimpleWindowCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
    299 		: QuerySurfaceCase(eglTestCtx, name, description, filters)
    300 	{
    301 	}
    302 
    303 	void executeForConfig (EGLDisplay display, EGLConfig config)
    304 	{
    305 		const Library&						egl				= m_eglTestCtx.getLibrary();
    306 		tcu::TestLog&						log				= m_testCtx.getLog();
    307 		const int							width			= 64;
    308 		const int							height			= 64;
    309 		const eglu::NativeWindowFactory&	windowFactory	= eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
    310 		ConfigInfo							info;
    311 
    312 		eglu::queryCoreConfigInfo(egl, display, config, &info);
    313 
    314 		log << TestLog::Message << "Creating window surface with config ID " << info.configId << TestLog::EndMessage;
    315 		EGLU_CHECK_MSG(egl, "before queries");
    316 
    317 		de::UniquePtr<eglu::NativeWindow>	window	(windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, eglu::WindowParams(width, height, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
    318 		eglu::UniqueSurface					surface	(egl, display, eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, display, config, DE_NULL));
    319 
    320 		logCommonSurfaceAttributes	(log, egl, display, *surface);
    321 		checkCommonAttributes		(display, *surface, info);
    322 		checkNonPbufferAttributes	(display, *surface);
    323 	}
    324 };
    325 
    326 class QuerySurfaceSimplePixmapCase : public QuerySurfaceCase
    327 {
    328 public:
    329 	QuerySurfaceSimplePixmapCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
    330 		: QuerySurfaceCase(eglTestCtx, name, description, filters)
    331 	{
    332 	}
    333 
    334 	void executeForConfig (EGLDisplay display, EGLConfig config)
    335 	{
    336 		const Library&						egl				= m_eglTestCtx.getLibrary();
    337 		tcu::TestLog&						log				= m_testCtx.getLog();
    338 		const int							width			= 64;
    339 		const int							height			= 64;
    340 		const eglu::NativePixmapFactory&	pixmapFactory	= eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
    341 		ConfigInfo							info;
    342 
    343 		eglu::queryCoreConfigInfo(egl, display, config, &info);
    344 
    345 		log << TestLog::Message << "Creating pixmap surface with config ID " << info.configId << TestLog::EndMessage;
    346 		EGLU_CHECK_MSG(egl, "before queries");
    347 
    348 		de::UniquePtr<eglu::NativePixmap>	pixmap	(pixmapFactory.createPixmap(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, width, height));
    349 		eglu::UniqueSurface					surface	(egl, display, eglu::createPixmapSurface(m_eglTestCtx.getNativeDisplay(), *pixmap, display, config, DE_NULL));
    350 
    351 		logCommonSurfaceAttributes	(log, egl, display, *surface);
    352 		checkCommonAttributes		(display, *surface, info);
    353 		checkNonPbufferAttributes	(display, *surface);
    354 	}
    355 };
    356 
    357 class QuerySurfaceSimplePbufferCase : public QuerySurfaceCase
    358 {
    359 public:
    360 	QuerySurfaceSimplePbufferCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
    361 		: QuerySurfaceCase(eglTestCtx, name, description, filters)
    362 	{
    363 	}
    364 
    365 	void executeForConfig (EGLDisplay display, EGLConfig config)
    366 	{
    367 		const Library&	egl		= m_eglTestCtx.getLibrary();
    368 		tcu::TestLog&	log		= m_testCtx.getLog();
    369 		int				width	= 64;
    370 		int				height	= 64;
    371 		ConfigInfo		info;
    372 
    373 		eglu::queryCoreConfigInfo(egl, display, config, &info);
    374 
    375 		log << TestLog::Message << "Creating pbuffer surface with config ID " << info.configId << TestLog::EndMessage;
    376 		EGLU_CHECK_MSG(egl, "before queries");
    377 
    378 		// Clamp to maximums reported by implementation
    379 		width	= deMin32(width, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_WIDTH));
    380 		height	= deMin32(height, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_HEIGHT));
    381 
    382 		if (width == 0 || height == 0)
    383 		{
    384 			log << TestLog::Message << "    Fail, maximum pbuffer size of " << width << "x" << height << " reported" << TestLog::EndMessage;
    385 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid maximum pbuffer size");
    386 			return;
    387 		}
    388 
    389 		const EGLint attribs[] =
    390 		{
    391 			EGL_WIDTH,			width,
    392 			EGL_HEIGHT,			height,
    393 			EGL_TEXTURE_FORMAT,	EGL_NO_TEXTURE,
    394 			EGL_NONE
    395 		};
    396 
    397 		{
    398 			eglu::UniqueSurface surface(egl, display, egl.createPbufferSurface(display, config, attribs));
    399 
    400 			logCommonSurfaceAttributes	(log, egl, display, *surface);
    401 			logPbufferSurfaceAttributes	(log, egl, display, *surface);
    402 			checkCommonAttributes		(display, *surface, info);
    403 
    404 			// Pbuffer-specific attributes
    405 
    406 			// Largest pbuffer
    407 			{
    408 				const EGLint	largestPbuffer	= eglu::querySurfaceInt(egl, display, *surface, EGL_LARGEST_PBUFFER);
    409 
    410 				if (largestPbuffer != EGL_FALSE && largestPbuffer != EGL_TRUE)
    411 				{
    412 					log << TestLog::Message << "    Fail, invalid largest pbuffer value " << largestPbuffer << TestLog::EndMessage;
    413 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid largest pbuffer");
    414 				}
    415 			}
    416 
    417 			// Texture format
    418 			{
    419 				const EGLint	textureFormat	= eglu::querySurfaceInt(egl, display, *surface, EGL_TEXTURE_FORMAT);
    420 
    421 				if (textureFormat != EGL_NO_TEXTURE && textureFormat != EGL_TEXTURE_RGB && textureFormat != EGL_TEXTURE_RGBA)
    422 				{
    423 					log << TestLog::Message << "    Fail, invalid texture format value " << textureFormat << TestLog::EndMessage;
    424 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid texture format");
    425 				}
    426 			}
    427 
    428 			// Texture target
    429 			{
    430 				const EGLint	textureTarget	= eglu::querySurfaceInt(egl, display, *surface, EGL_TEXTURE_TARGET);
    431 
    432 				if (textureTarget != EGL_NO_TEXTURE && textureTarget != EGL_TEXTURE_2D)
    433 				{
    434 					log << TestLog::Message << "    Fail, invalid texture target value " << textureTarget << TestLog::EndMessage;
    435 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid texture target");
    436 				}
    437 			}
    438 
    439 			// Mipmap texture
    440 			{
    441 				const EGLint	mipmapTexture	= eglu::querySurfaceInt(egl, display, *surface, EGL_MIPMAP_TEXTURE);
    442 
    443 				if (mipmapTexture != EGL_FALSE && mipmapTexture != EGL_TRUE)
    444 				{
    445 					log << TestLog::Message << "    Fail, invalid mipmap texture value " << mipmapTexture << TestLog::EndMessage;
    446 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid mipmap texture");
    447 				}
    448 			}
    449 		}
    450 	}
    451 };
    452 
    453 class SurfaceAttribCase : public SimpleConfigCase
    454 {
    455 public:
    456 			SurfaceAttribCase	(EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters);
    457 	virtual	~SurfaceAttribCase	(void) {}
    458 
    459 	void	testAttributes		(EGLDisplay display, EGLSurface surface, EGLint surfaceType, const ConfigInfo& info);
    460 };
    461 
    462 SurfaceAttribCase::SurfaceAttribCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
    463 		: SimpleConfigCase(eglTestCtx, name, description, filters)
    464 {
    465 }
    466 
    467 void SurfaceAttribCase::testAttributes (EGLDisplay display, EGLSurface surface, EGLint surfaceType, const ConfigInfo& info)
    468 {
    469 	const Library&		egl		= m_eglTestCtx.getLibrary();
    470 	tcu::TestLog&		log		= m_testCtx.getLog();
    471 	const eglu::Version	version	= eglu::getVersion(egl, display);
    472 
    473 	if (version.getMajor() == 1 && version.getMinor() == 0)
    474 	{
    475 		log << TestLog::Message << "No attributes can be set in EGL 1.0" << TestLog::EndMessage;
    476 		return;
    477 	}
    478 
    479 	// Mipmap level
    480 	if (info.renderableType & EGL_OPENGL_ES_BIT || info.renderableType & EGL_OPENGL_ES2_BIT)
    481 	{
    482 		const EGLint initialValue = 0xDEADBAAD;
    483 		EGLint value = initialValue;
    484 
    485 		EGLU_CHECK_CALL(egl, querySurface(display, surface, EGL_MIPMAP_LEVEL, &value));
    486 
    487 		logSurfaceAttribute(log, EGL_MIPMAP_LEVEL, value);
    488 
    489 		if (surfaceType == EGL_PBUFFER_BIT)
    490 		{
    491 			if (value != 0)
    492 			{
    493 				log << TestLog::Message << "    Fail, initial mipmap level value should be 0, is " << value << TestLog::EndMessage;
    494 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid default mipmap level");
    495 			}
    496 		}
    497 		else if (value != initialValue)
    498 		{
    499 			log << TestLog::Message << "    Fail, eglQuerySurface changed value when querying EGL_MIPMAP_LEVEL for non-pbuffer surface. Result: " << value << ". Expected: " << initialValue << TestLog::EndMessage;
    500 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "EGL_MIPMAP_LEVEL query modified result for non-pbuffer surface.");
    501 		}
    502 
    503 		egl.surfaceAttrib(display, surface, EGL_MIPMAP_LEVEL, 1);
    504 
    505 		{
    506 			const EGLint	error	= egl.getError();
    507 
    508 			if (error != EGL_SUCCESS)
    509 			{
    510 				log << TestLog::Message << "    Fail, setting EGL_MIPMAP_LEVEL should not result in an error, received " << eglu::getErrorStr(error) << TestLog::EndMessage;
    511 
    512 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Illegal error condition");
    513 			}
    514 		}
    515 	}
    516 
    517 	// Only mipmap level can be set in EGL 1.3 and lower
    518 	if (version.getMajor() == 1 && version.getMinor() <= 3) return;
    519 
    520 	// Multisample resolve
    521 	{
    522 		const EGLint	value	= eglu::querySurfaceInt(egl, display, surface, EGL_MULTISAMPLE_RESOLVE);
    523 
    524 		logSurfaceAttribute(log, EGL_MULTISAMPLE_RESOLVE, value);
    525 
    526 		if (value != EGL_MULTISAMPLE_RESOLVE_DEFAULT)
    527 		{
    528 			log << TestLog::Message << "    Fail, initial multisample resolve value should be EGL_MULTISAMPLE_RESOLVE_DEFAULT, is "
    529 				<< eglu::getSurfaceAttribValueStr(EGL_MULTISAMPLE_RESOLVE, value) << TestLog::EndMessage;
    530 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid default multisample resolve");
    531 		}
    532 
    533 		if (info.renderableType & EGL_MULTISAMPLE_RESOLVE_BOX_BIT)
    534 		{
    535 			log << TestLog::Message << "    Box filter is supported by surface, trying to set." << TestLog::EndMessage;
    536 
    537 			egl.surfaceAttrib(display, surface, EGL_MULTISAMPLE_RESOLVE, EGL_MULTISAMPLE_RESOLVE_BOX);
    538 
    539 			if (eglu::querySurfaceInt(egl, display, surface, EGL_MULTISAMPLE_RESOLVE) != EGL_MULTISAMPLE_RESOLVE_BOX)
    540 			{
    541 				log << TestLog::Message << "    Fail, tried to enable box filter but value did not change.";
    542 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to set multisample resolve");
    543 			}
    544 		}
    545 	}
    546 
    547 	// Swap behavior
    548 	{
    549 		const EGLint	value	= eglu::querySurfaceInt(egl, display, surface, EGL_SWAP_BEHAVIOR);
    550 
    551 		logSurfaceAttribute(log, EGL_SWAP_BEHAVIOR, value);
    552 
    553 		if (info.renderableType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)
    554 		{
    555 			const EGLint	nextValue	= (value == EGL_BUFFER_DESTROYED) ? EGL_BUFFER_PRESERVED : EGL_BUFFER_DESTROYED;
    556 
    557 			egl.surfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, nextValue);
    558 
    559 			if (eglu::querySurfaceInt(egl, display, surface, EGL_SWAP_BEHAVIOR) != nextValue)
    560 			{
    561 				log << TestLog::Message << "  Fail, tried to set swap behavior to " << eglu::getSurfaceAttribStr(nextValue) << TestLog::EndMessage;
    562 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to set swap behavior");
    563 			}
    564 		}
    565 	}
    566 }
    567 
    568 class SurfaceAttribWindowCase : public SurfaceAttribCase
    569 {
    570 public:
    571 	SurfaceAttribWindowCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
    572 		: SurfaceAttribCase(eglTestCtx, name, description, filters)
    573 	{
    574 	}
    575 
    576 	void executeForConfig (EGLDisplay display, EGLConfig config)
    577 	{
    578 		const Library&						egl				= m_eglTestCtx.getLibrary();
    579 		tcu::TestLog&						log				= m_testCtx.getLog();
    580 		const int							width			= 64;
    581 		const int							height			= 64;
    582 		const eglu::NativeWindowFactory&	windowFactory	= eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
    583 		ConfigInfo							info;
    584 
    585 		eglu::queryCoreConfigInfo(egl, display, config, &info);
    586 
    587 		log << TestLog::Message << "Creating window surface with config ID " << info.configId << TestLog::EndMessage;
    588 		EGLU_CHECK_MSG(egl, "before queries");
    589 
    590 		de::UniquePtr<eglu::NativeWindow>	window	(windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, eglu::WindowParams(width, height, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
    591 		eglu::UniqueSurface					surface	(egl, display, eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, display, config, DE_NULL));
    592 
    593 		testAttributes(display, *surface, EGL_WINDOW_BIT, info);
    594 	}
    595 };
    596 
    597 class SurfaceAttribPixmapCase : public SurfaceAttribCase
    598 {
    599 public:
    600 	SurfaceAttribPixmapCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
    601 		: SurfaceAttribCase(eglTestCtx, name, description, filters)
    602 	{
    603 	}
    604 
    605 	void executeForConfig (EGLDisplay display, EGLConfig config)
    606 	{
    607 		const Library&						egl				= m_eglTestCtx.getLibrary();
    608 		tcu::TestLog&						log				= m_testCtx.getLog();
    609 		const int							width			= 64;
    610 		const int							height			= 64;
    611 		const eglu::NativePixmapFactory&	pixmapFactory	= eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
    612 		ConfigInfo							info;
    613 
    614 		eglu::queryCoreConfigInfo(egl, display, config, &info);
    615 
    616 		log << TestLog::Message << "Creating pixmap surface with config ID " << info.configId << TestLog::EndMessage;
    617 		EGLU_CHECK_MSG(egl, "before queries");
    618 
    619 		de::UniquePtr<eglu::NativePixmap>	pixmap	(pixmapFactory.createPixmap(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, width, height));
    620 		eglu::UniqueSurface					surface	(egl, display, eglu::createPixmapSurface(m_eglTestCtx.getNativeDisplay(), *pixmap, display, config, DE_NULL));
    621 
    622 		testAttributes(display, *surface, EGL_PIXMAP_BIT, info);
    623 	}
    624 };
    625 
    626 class SurfaceAttribPbufferCase : public SurfaceAttribCase
    627 {
    628 public:
    629 	SurfaceAttribPbufferCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
    630 		: SurfaceAttribCase(eglTestCtx, name, description, filters)
    631 	{
    632 	}
    633 
    634 	void executeForConfig (EGLDisplay display, EGLConfig config)
    635 	{
    636 		const Library&	egl		= m_eglTestCtx.getLibrary();
    637 		tcu::TestLog&	log		= m_testCtx.getLog();
    638 		int				width	= 64;
    639 		int				height	= 64;
    640 		ConfigInfo		info;
    641 
    642 		eglu::queryCoreConfigInfo(egl, display, config, &info);
    643 
    644 		log << TestLog::Message << "Creating pbuffer surface with config ID " << info.configId << TestLog::EndMessage;
    645 		EGLU_CHECK_MSG(egl, "before queries");
    646 
    647 		// Clamp to maximums reported by implementation
    648 		width	= deMin32(width, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_WIDTH));
    649 		height	= deMin32(height, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_HEIGHT));
    650 
    651 		if (width == 0 || height == 0)
    652 		{
    653 			log << TestLog::Message << "    Fail, maximum pbuffer size of " << width << "x" << height << " reported" << TestLog::EndMessage;
    654 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid maximum pbuffer size");
    655 			return;
    656 		}
    657 
    658 		const EGLint attribs[] =
    659 		{
    660 			EGL_WIDTH,			width,
    661 			EGL_HEIGHT,			height,
    662 			EGL_TEXTURE_FORMAT,	EGL_NO_TEXTURE,
    663 			EGL_NONE
    664 		};
    665 
    666 		eglu::UniqueSurface surface(egl, display, egl.createPbufferSurface(display, config, attribs));
    667 
    668 		testAttributes(display, *surface, EGL_PBUFFER_BIT, info);
    669 	}
    670 };
    671 
    672 QuerySurfaceTests::QuerySurfaceTests (EglTestContext& eglTestCtx)
    673 	: TestCaseGroup(eglTestCtx, "query_surface", "Surface Query Tests")
    674 {
    675 }
    676 
    677 QuerySurfaceTests::~QuerySurfaceTests (void)
    678 {
    679 }
    680 
    681 template <deUint32 Type>
    682 static bool surfaceType (const eglu::CandidateConfig& c)
    683 {
    684 	return (c.surfaceType() & Type) == Type;
    685 }
    686 
    687 void QuerySurfaceTests::init (void)
    688 {
    689 	// Simple queries
    690 	{
    691 		tcu::TestCaseGroup* simpleGroup = new tcu::TestCaseGroup(m_testCtx, "simple", "Simple queries");
    692 		addChild(simpleGroup);
    693 
    694 		// Window
    695 		{
    696 			tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "window", "Window surfaces");
    697 			simpleGroup->addChild(windowGroup);
    698 
    699 			eglu::FilterList baseFilters;
    700 			baseFilters << surfaceType<EGL_WINDOW_BIT>;
    701 
    702 			std::vector<NamedFilterList> filterLists;
    703 			getDefaultFilterLists(filterLists, baseFilters);
    704 
    705 			for (std::vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
    706 				windowGroup->addChild(new QuerySurfaceSimpleWindowCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
    707 		}
    708 
    709 		// Pixmap
    710 		{
    711 			tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "pixmap", "Pixmap surfaces");
    712 			simpleGroup->addChild(pixmapGroup);
    713 
    714 			eglu::FilterList baseFilters;
    715 			baseFilters << surfaceType<EGL_PIXMAP_BIT>;
    716 
    717 			std::vector<NamedFilterList> filterLists;
    718 			getDefaultFilterLists(filterLists, baseFilters);
    719 
    720 			for (std::vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
    721 				pixmapGroup->addChild(new QuerySurfaceSimplePixmapCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
    722 		}
    723 
    724 		// Pbuffer
    725 		{
    726 			tcu::TestCaseGroup* pbufferGroup = new tcu::TestCaseGroup(m_testCtx, "pbuffer", "Pbuffer surfaces");
    727 			simpleGroup->addChild(pbufferGroup);
    728 
    729 			eglu::FilterList baseFilters;
    730 			baseFilters << surfaceType<EGL_PBUFFER_BIT>;
    731 
    732 			std::vector<NamedFilterList> filterLists;
    733 			getDefaultFilterLists(filterLists, baseFilters);
    734 
    735 			for (std::vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
    736 				pbufferGroup->addChild(new QuerySurfaceSimplePbufferCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
    737 		}
    738 	}
    739 
    740 	// Set surface attributes
    741 	{
    742 		tcu::TestCaseGroup* setAttributeGroup = new tcu::TestCaseGroup(m_testCtx, "set_attribute", "Setting attributes");
    743 		addChild(setAttributeGroup);
    744 
    745 		// Window
    746 		{
    747 			tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "window", "Window surfaces");
    748 			setAttributeGroup->addChild(windowGroup);
    749 
    750 			eglu::FilterList baseFilters;
    751 			baseFilters << surfaceType<EGL_WINDOW_BIT>;
    752 
    753 			std::vector<NamedFilterList> filterLists;
    754 			getDefaultFilterLists(filterLists, baseFilters);
    755 
    756 			for (std::vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
    757 				windowGroup->addChild(new SurfaceAttribWindowCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
    758 		}
    759 
    760 		// Pixmap
    761 		{
    762 			tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "pixmap", "Pixmap surfaces");
    763 			setAttributeGroup->addChild(pixmapGroup);
    764 
    765 			eglu::FilterList baseFilters;
    766 			baseFilters << surfaceType<EGL_PIXMAP_BIT>;
    767 
    768 			std::vector<NamedFilterList> filterLists;
    769 			getDefaultFilterLists(filterLists, baseFilters);
    770 
    771 			for (std::vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
    772 				pixmapGroup->addChild(new SurfaceAttribPixmapCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
    773 		}
    774 
    775 		// Pbuffer
    776 		{
    777 			tcu::TestCaseGroup* pbufferGroup = new tcu::TestCaseGroup(m_testCtx, "pbuffer", "Pbuffer surfaces");
    778 			setAttributeGroup->addChild(pbufferGroup);
    779 
    780 			eglu::FilterList baseFilters;
    781 			baseFilters << surfaceType<EGL_PBUFFER_BIT>;
    782 
    783 			std::vector<NamedFilterList> filterLists;
    784 			getDefaultFilterLists(filterLists, baseFilters);
    785 
    786 			for (std::vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
    787 				pbufferGroup->addChild(new SurfaceAttribPbufferCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
    788 		}
    789 	}
    790 }
    791 
    792 } // egl
    793 } // deqp
    794