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