teglQuerySurfaceTests.cpp revision 193f59811b2c0fe57808a06923b82ed00c41bd0f
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
47namespace deqp
48{
49namespace egl
50{
51
52using eglu::ConfigInfo;
53using tcu::TestLog;
54using namespace eglw;
55
56static 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
64static 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
70static 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
90static 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
104class QuerySurfaceCase : public SimpleConfigCase
105{
106public:
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
113QuerySurfaceCase::QuerySurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
114	: SimpleConfigCase(eglTestCtx, name, description, filters)
115{
116}
117
118void 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
251void 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
295class QuerySurfaceSimpleWindowCase : public QuerySurfaceCase
296{
297public:
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		if (!windowFactory)
313			TCU_THROW(NotSupportedError, "Windows not supported");
314
315		eglu::queryConfigInfo(egl, display, config, &info);
316
317		log << TestLog::Message << "Creating window surface with config ID " << info.configId << TestLog::EndMessage;
318		EGLU_CHECK_MSG(egl, "before queries");
319
320		de::UniquePtr<eglu::NativeWindow>	window	(windowFactory->createWindow(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, eglu::WindowParams(width, height, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
321		eglu::UniqueSurface					surface	(egl, display, eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, display, config, DE_NULL));
322
323		logCommonSurfaceAttributes	(log, egl, display, *surface);
324		checkCommonAttributes		(display, *surface, info);
325		checkNonPbufferAttributes	(display, *surface);
326	}
327};
328
329class QuerySurfaceSimplePixmapCase : public QuerySurfaceCase
330{
331public:
332	QuerySurfaceSimplePixmapCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
333		: QuerySurfaceCase(eglTestCtx, name, description, filters)
334	{
335	}
336
337	void executeForConfig (EGLDisplay display, EGLConfig config)
338	{
339		const Library&						egl				= m_eglTestCtx.getLibrary();
340		tcu::TestLog&						log				= m_testCtx.getLog();
341		const int							width			= 64;
342		const int							height			= 64;
343		const eglu::NativePixmapFactory*	pixmapFactory	= eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
344		ConfigInfo							info;
345
346		if (!pixmapFactory)
347			TCU_THROW(NotSupportedError, "Pixmaps not supported");
348
349		eglu::queryConfigInfo(egl, display, config, &info);
350
351		log << TestLog::Message << "Creating pixmap surface with config ID " << info.configId << TestLog::EndMessage;
352		EGLU_CHECK_MSG(egl, "before queries");
353
354		de::UniquePtr<eglu::NativePixmap>	pixmap	(pixmapFactory->createPixmap(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, width, height));
355		eglu::UniqueSurface					surface	(egl, display, eglu::createPixmapSurface(m_eglTestCtx.getNativeDisplay(), *pixmap, display, config, DE_NULL));
356
357		logCommonSurfaceAttributes	(log, egl, display, *surface);
358		checkCommonAttributes		(display, *surface, info);
359		checkNonPbufferAttributes	(display, *surface);
360	}
361};
362
363class QuerySurfaceSimplePbufferCase : public QuerySurfaceCase
364{
365public:
366	QuerySurfaceSimplePbufferCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
367		: QuerySurfaceCase(eglTestCtx, name, description, filters)
368	{
369	}
370
371	void executeForConfig (EGLDisplay display, EGLConfig config)
372	{
373		const Library&	egl		= m_eglTestCtx.getLibrary();
374		tcu::TestLog&	log		= m_testCtx.getLog();
375		int				width	= 64;
376		int				height	= 64;
377		ConfigInfo		info;
378
379		eglu::queryConfigInfo(egl, display, config, &info);
380
381		log << TestLog::Message << "Creating pbuffer surface with config ID " << info.configId << TestLog::EndMessage;
382		EGLU_CHECK_MSG(egl, "before queries");
383
384		// Clamp to maximums reported by implementation
385		width	= deMin32(width, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_WIDTH));
386		height	= deMin32(height, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_HEIGHT));
387
388		if (width == 0 || height == 0)
389		{
390			log << TestLog::Message << "    Fail, maximum pbuffer size of " << width << "x" << height << " reported" << TestLog::EndMessage;
391			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid maximum pbuffer size");
392			return;
393		}
394
395		const EGLint attribs[] =
396		{
397			EGL_WIDTH,			width,
398			EGL_HEIGHT,			height,
399			EGL_TEXTURE_FORMAT,	EGL_NO_TEXTURE,
400			EGL_NONE
401		};
402
403		{
404			eglu::UniqueSurface surface(egl, display, egl.createPbufferSurface(display, config, attribs));
405
406			logCommonSurfaceAttributes	(log, egl, display, *surface);
407			logPbufferSurfaceAttributes	(log, egl, display, *surface);
408			checkCommonAttributes		(display, *surface, info);
409
410			// Pbuffer-specific attributes
411
412			// Largest pbuffer
413			{
414				const EGLint	largestPbuffer	= eglu::querySurfaceInt(egl, display, *surface, EGL_LARGEST_PBUFFER);
415
416				if (largestPbuffer != EGL_FALSE && largestPbuffer != EGL_TRUE)
417				{
418					log << TestLog::Message << "    Fail, invalid largest pbuffer value " << largestPbuffer << TestLog::EndMessage;
419					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid largest pbuffer");
420				}
421			}
422
423			// Texture format
424			{
425				const EGLint	textureFormat	= eglu::querySurfaceInt(egl, display, *surface, EGL_TEXTURE_FORMAT);
426
427				if (textureFormat != EGL_NO_TEXTURE && textureFormat != EGL_TEXTURE_RGB && textureFormat != EGL_TEXTURE_RGBA)
428				{
429					log << TestLog::Message << "    Fail, invalid texture format value " << textureFormat << TestLog::EndMessage;
430					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid texture format");
431				}
432			}
433
434			// Texture target
435			{
436				const EGLint	textureTarget	= eglu::querySurfaceInt(egl, display, *surface, EGL_TEXTURE_TARGET);
437
438				if (textureTarget != EGL_NO_TEXTURE && textureTarget != EGL_TEXTURE_2D)
439				{
440					log << TestLog::Message << "    Fail, invalid texture target value " << textureTarget << TestLog::EndMessage;
441					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid texture target");
442				}
443			}
444
445			// Mipmap texture
446			{
447				const EGLint	mipmapTexture	= eglu::querySurfaceInt(egl, display, *surface, EGL_MIPMAP_TEXTURE);
448
449				if (mipmapTexture != EGL_FALSE && mipmapTexture != EGL_TRUE)
450				{
451					log << TestLog::Message << "    Fail, invalid mipmap texture value " << mipmapTexture << TestLog::EndMessage;
452					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid mipmap texture");
453				}
454			}
455		}
456	}
457};
458
459class SurfaceAttribCase : public SimpleConfigCase
460{
461public:
462			SurfaceAttribCase	(EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters);
463	virtual	~SurfaceAttribCase	(void) {}
464
465	void	testAttributes		(EGLDisplay display, EGLSurface surface, EGLint surfaceType, const ConfigInfo& info);
466};
467
468SurfaceAttribCase::SurfaceAttribCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
469		: SimpleConfigCase(eglTestCtx, name, description, filters)
470{
471}
472
473void SurfaceAttribCase::testAttributes (EGLDisplay display, EGLSurface surface, EGLint surfaceType, const ConfigInfo& info)
474{
475	const Library&		egl		= m_eglTestCtx.getLibrary();
476	tcu::TestLog&		log		= m_testCtx.getLog();
477	const eglu::Version	version	= eglu::getVersion(egl, display);
478
479	if (version.getMajor() == 1 && version.getMinor() == 0)
480	{
481		log << TestLog::Message << "No attributes can be set in EGL 1.0" << TestLog::EndMessage;
482		return;
483	}
484
485	// Mipmap level
486	if (info.renderableType & EGL_OPENGL_ES_BIT || info.renderableType & EGL_OPENGL_ES2_BIT)
487	{
488		const EGLint initialValue = 0xDEADBAAD;
489		EGLint value = initialValue;
490
491		EGLU_CHECK_CALL(egl, querySurface(display, surface, EGL_MIPMAP_LEVEL, &value));
492
493		logSurfaceAttribute(log, EGL_MIPMAP_LEVEL, value);
494
495		if (surfaceType == EGL_PBUFFER_BIT)
496		{
497			if (value != 0)
498			{
499				log << TestLog::Message << "    Fail, initial mipmap level value should be 0, is " << value << TestLog::EndMessage;
500				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid default mipmap level");
501			}
502		}
503		else if (value != initialValue)
504		{
505			log << TestLog::Message << "    Fail, eglQuerySurface changed value when querying EGL_MIPMAP_LEVEL for non-pbuffer surface. Result: " << value << ". Expected: " << initialValue << TestLog::EndMessage;
506			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "EGL_MIPMAP_LEVEL query modified result for non-pbuffer surface.");
507		}
508
509		egl.surfaceAttrib(display, surface, EGL_MIPMAP_LEVEL, 1);
510
511		{
512			const EGLint	error	= egl.getError();
513
514			if (error != EGL_SUCCESS)
515			{
516				log << TestLog::Message << "    Fail, setting EGL_MIPMAP_LEVEL should not result in an error, received " << eglu::getErrorStr(error) << TestLog::EndMessage;
517
518				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Illegal error condition");
519			}
520		}
521	}
522
523	// Only mipmap level can be set in EGL 1.3 and lower
524	if (version.getMajor() == 1 && version.getMinor() <= 3) return;
525
526	// Multisample resolve
527	{
528		const EGLint	value	= eglu::querySurfaceInt(egl, display, surface, EGL_MULTISAMPLE_RESOLVE);
529
530		logSurfaceAttribute(log, EGL_MULTISAMPLE_RESOLVE, value);
531
532		if (value != EGL_MULTISAMPLE_RESOLVE_DEFAULT)
533		{
534			log << TestLog::Message << "    Fail, initial multisample resolve value should be EGL_MULTISAMPLE_RESOLVE_DEFAULT, is "
535				<< eglu::getSurfaceAttribValueStr(EGL_MULTISAMPLE_RESOLVE, value) << TestLog::EndMessage;
536			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid default multisample resolve");
537		}
538
539		if (info.renderableType & EGL_MULTISAMPLE_RESOLVE_BOX_BIT)
540		{
541			log << TestLog::Message << "    Box filter is supported by surface, trying to set." << TestLog::EndMessage;
542
543			egl.surfaceAttrib(display, surface, EGL_MULTISAMPLE_RESOLVE, EGL_MULTISAMPLE_RESOLVE_BOX);
544
545			if (eglu::querySurfaceInt(egl, display, surface, EGL_MULTISAMPLE_RESOLVE) != EGL_MULTISAMPLE_RESOLVE_BOX)
546			{
547				log << TestLog::Message << "    Fail, tried to enable box filter but value did not change.";
548				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to set multisample resolve");
549			}
550		}
551	}
552
553	// Swap behavior
554	{
555		const EGLint	value	= eglu::querySurfaceInt(egl, display, surface, EGL_SWAP_BEHAVIOR);
556
557		logSurfaceAttribute(log, EGL_SWAP_BEHAVIOR, value);
558
559		if (info.renderableType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)
560		{
561			const EGLint	nextValue	= (value == EGL_BUFFER_DESTROYED) ? EGL_BUFFER_PRESERVED : EGL_BUFFER_DESTROYED;
562
563			egl.surfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, nextValue);
564
565			if (eglu::querySurfaceInt(egl, display, surface, EGL_SWAP_BEHAVIOR) != nextValue)
566			{
567				log << TestLog::Message << "  Fail, tried to set swap behavior to " << eglu::getSurfaceAttribStr(nextValue) << TestLog::EndMessage;
568				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to set swap behavior");
569			}
570		}
571	}
572}
573
574class SurfaceAttribWindowCase : public SurfaceAttribCase
575{
576public:
577	SurfaceAttribWindowCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
578		: SurfaceAttribCase(eglTestCtx, name, description, filters)
579	{
580	}
581
582	void executeForConfig (EGLDisplay display, EGLConfig config)
583	{
584		const Library&						egl				= m_eglTestCtx.getLibrary();
585		tcu::TestLog&						log				= m_testCtx.getLog();
586		const int							width			= 64;
587		const int							height			= 64;
588		const eglu::NativeWindowFactory*	windowFactory	= eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
589		ConfigInfo							info;
590
591		if (!windowFactory)
592			TCU_THROW(NotSupportedError, "Windows not supported");
593
594		eglu::queryConfigInfo(egl, display, config, &info);
595
596		log << TestLog::Message << "Creating window surface with config ID " << info.configId << TestLog::EndMessage;
597		EGLU_CHECK_MSG(egl, "before queries");
598
599		de::UniquePtr<eglu::NativeWindow>	window	(windowFactory->createWindow(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, eglu::WindowParams(width, height, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
600		eglu::UniqueSurface					surface	(egl, display, eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, display, config, DE_NULL));
601
602		testAttributes(display, *surface, EGL_WINDOW_BIT, info);
603	}
604};
605
606class SurfaceAttribPixmapCase : public SurfaceAttribCase
607{
608public:
609	SurfaceAttribPixmapCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
610		: SurfaceAttribCase(eglTestCtx, name, description, filters)
611	{
612	}
613
614	void executeForConfig (EGLDisplay display, EGLConfig config)
615	{
616		const Library&						egl				= m_eglTestCtx.getLibrary();
617		tcu::TestLog&						log				= m_testCtx.getLog();
618		const int							width			= 64;
619		const int							height			= 64;
620		const eglu::NativePixmapFactory*	pixmapFactory	= eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
621		ConfigInfo							info;
622
623		if (!pixmapFactory)
624			TCU_THROW(NotSupportedError, "Pixmaps not supported");
625
626		eglu::queryConfigInfo(egl, display, config, &info);
627
628		log << TestLog::Message << "Creating pixmap surface with config ID " << info.configId << TestLog::EndMessage;
629		EGLU_CHECK_MSG(egl, "before queries");
630
631		de::UniquePtr<eglu::NativePixmap>	pixmap	(pixmapFactory->createPixmap(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, width, height));
632		eglu::UniqueSurface					surface	(egl, display, eglu::createPixmapSurface(m_eglTestCtx.getNativeDisplay(), *pixmap, display, config, DE_NULL));
633
634		testAttributes(display, *surface, EGL_PIXMAP_BIT, info);
635	}
636};
637
638class SurfaceAttribPbufferCase : public SurfaceAttribCase
639{
640public:
641	SurfaceAttribPbufferCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
642		: SurfaceAttribCase(eglTestCtx, name, description, filters)
643	{
644	}
645
646	void executeForConfig (EGLDisplay display, EGLConfig config)
647	{
648		const Library&	egl		= m_eglTestCtx.getLibrary();
649		tcu::TestLog&	log		= m_testCtx.getLog();
650		int				width	= 64;
651		int				height	= 64;
652		ConfigInfo		info;
653
654		eglu::queryConfigInfo(egl, display, config, &info);
655
656		log << TestLog::Message << "Creating pbuffer surface with config ID " << info.configId << TestLog::EndMessage;
657		EGLU_CHECK_MSG(egl, "before queries");
658
659		// Clamp to maximums reported by implementation
660		width	= deMin32(width, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_WIDTH));
661		height	= deMin32(height, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_HEIGHT));
662
663		if (width == 0 || height == 0)
664		{
665			log << TestLog::Message << "    Fail, maximum pbuffer size of " << width << "x" << height << " reported" << TestLog::EndMessage;
666			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid maximum pbuffer size");
667			return;
668		}
669
670		const EGLint attribs[] =
671		{
672			EGL_WIDTH,			width,
673			EGL_HEIGHT,			height,
674			EGL_TEXTURE_FORMAT,	EGL_NO_TEXTURE,
675			EGL_NONE
676		};
677
678		eglu::UniqueSurface surface(egl, display, egl.createPbufferSurface(display, config, attribs));
679
680		testAttributes(display, *surface, EGL_PBUFFER_BIT, info);
681	}
682};
683
684QuerySurfaceTests::QuerySurfaceTests (EglTestContext& eglTestCtx)
685	: TestCaseGroup(eglTestCtx, "query_surface", "Surface Query Tests")
686{
687}
688
689QuerySurfaceTests::~QuerySurfaceTests (void)
690{
691}
692
693template <deUint32 Type>
694static bool surfaceType (const eglu::CandidateConfig& c)
695{
696	return (c.surfaceType() & Type) == Type;
697}
698
699void QuerySurfaceTests::init (void)
700{
701	// Simple queries
702	{
703		tcu::TestCaseGroup* simpleGroup = new tcu::TestCaseGroup(m_testCtx, "simple", "Simple queries");
704		addChild(simpleGroup);
705
706		// Window
707		{
708			tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "window", "Window surfaces");
709			simpleGroup->addChild(windowGroup);
710
711			eglu::FilterList baseFilters;
712			baseFilters << surfaceType<EGL_WINDOW_BIT>;
713
714			std::vector<NamedFilterList> filterLists;
715			getDefaultFilterLists(filterLists, baseFilters);
716
717			for (std::vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
718				windowGroup->addChild(new QuerySurfaceSimpleWindowCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
719		}
720
721		// Pixmap
722		{
723			tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "pixmap", "Pixmap surfaces");
724			simpleGroup->addChild(pixmapGroup);
725
726			eglu::FilterList baseFilters;
727			baseFilters << surfaceType<EGL_PIXMAP_BIT>;
728
729			std::vector<NamedFilterList> filterLists;
730			getDefaultFilterLists(filterLists, baseFilters);
731
732			for (std::vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
733				pixmapGroup->addChild(new QuerySurfaceSimplePixmapCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
734		}
735
736		// Pbuffer
737		{
738			tcu::TestCaseGroup* pbufferGroup = new tcu::TestCaseGroup(m_testCtx, "pbuffer", "Pbuffer surfaces");
739			simpleGroup->addChild(pbufferGroup);
740
741			eglu::FilterList baseFilters;
742			baseFilters << surfaceType<EGL_PBUFFER_BIT>;
743
744			std::vector<NamedFilterList> filterLists;
745			getDefaultFilterLists(filterLists, baseFilters);
746
747			for (std::vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
748				pbufferGroup->addChild(new QuerySurfaceSimplePbufferCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
749		}
750	}
751
752	// Set surface attributes
753	{
754		tcu::TestCaseGroup* setAttributeGroup = new tcu::TestCaseGroup(m_testCtx, "set_attribute", "Setting attributes");
755		addChild(setAttributeGroup);
756
757		// Window
758		{
759			tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "window", "Window surfaces");
760			setAttributeGroup->addChild(windowGroup);
761
762			eglu::FilterList baseFilters;
763			baseFilters << surfaceType<EGL_WINDOW_BIT>;
764
765			std::vector<NamedFilterList> filterLists;
766			getDefaultFilterLists(filterLists, baseFilters);
767
768			for (std::vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
769				windowGroup->addChild(new SurfaceAttribWindowCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
770		}
771
772		// Pixmap
773		{
774			tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "pixmap", "Pixmap surfaces");
775			setAttributeGroup->addChild(pixmapGroup);
776
777			eglu::FilterList baseFilters;
778			baseFilters << surfaceType<EGL_PIXMAP_BIT>;
779
780			std::vector<NamedFilterList> filterLists;
781			getDefaultFilterLists(filterLists, baseFilters);
782
783			for (std::vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
784				pixmapGroup->addChild(new SurfaceAttribPixmapCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
785		}
786
787		// Pbuffer
788		{
789			tcu::TestCaseGroup* pbufferGroup = new tcu::TestCaseGroup(m_testCtx, "pbuffer", "Pbuffer surfaces");
790			setAttributeGroup->addChild(pbufferGroup);
791
792			eglu::FilterList baseFilters;
793			baseFilters << surfaceType<EGL_PBUFFER_BIT>;
794
795			std::vector<NamedFilterList> filterLists;
796			getDefaultFilterLists(filterLists, baseFilters);
797
798			for (std::vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
799				pbufferGroup->addChild(new SurfaceAttribPbufferCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
800		}
801	}
802}
803
804} // egl
805} // deqp
806