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
logSurfaceAttribute(tcu::TestLog & log,EGLint attribute,EGLint value)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
logSurfaceAttributes(tcu::TestLog & log,const Library & egl,EGLDisplay display,EGLSurface surface,const EGLint * attributes,int numAttribs)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
logCommonSurfaceAttributes(tcu::TestLog & log,const Library & egl,EGLDisplay display,EGLSurface surface)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
logPbufferSurfaceAttributes(tcu::TestLog & log,const Library & egl,EGLDisplay display,EGLSurface surface)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
QuerySurfaceCase(EglTestContext & eglTestCtx,const char * name,const char * description,const eglu::FilterList & filters)113 QuerySurfaceCase::QuerySurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
114 : SimpleConfigCase(eglTestCtx, name, description, filters)
115 {
116 }
117
checkCommonAttributes(EGLDisplay display,EGLSurface surface,const ConfigInfo & info)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
checkNonPbufferAttributes(EGLDisplay display,EGLSurface surface)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:
QuerySurfaceSimpleWindowCase(EglTestContext & eglTestCtx,const char * name,const char * description,const eglu::FilterList & filters)298 QuerySurfaceSimpleWindowCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
299 : QuerySurfaceCase(eglTestCtx, name, description, filters)
300 {
301 }
302
executeForConfig(EGLDisplay display,EGLConfig config)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::queryConfigInfo(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:
QuerySurfaceSimplePixmapCase(EglTestContext & eglTestCtx,const char * name,const char * description,const eglu::FilterList & filters)329 QuerySurfaceSimplePixmapCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
330 : QuerySurfaceCase(eglTestCtx, name, description, filters)
331 {
332 }
333
executeForConfig(EGLDisplay display,EGLConfig config)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::queryConfigInfo(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:
QuerySurfaceSimplePbufferCase(EglTestContext & eglTestCtx,const char * name,const char * description,const eglu::FilterList & filters)360 QuerySurfaceSimplePbufferCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
361 : QuerySurfaceCase(eglTestCtx, name, description, filters)
362 {
363 }
364
executeForConfig(EGLDisplay display,EGLConfig config)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::queryConfigInfo(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);
~SurfaceAttribCase(void)457 virtual ~SurfaceAttribCase (void) {}
458
459 void testAttributes (EGLDisplay display, EGLSurface surface, EGLint surfaceType, const ConfigInfo& info);
460 };
461
SurfaceAttribCase(EglTestContext & eglTestCtx,const char * name,const char * description,const eglu::FilterList & filters)462 SurfaceAttribCase::SurfaceAttribCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
463 : SimpleConfigCase(eglTestCtx, name, description, filters)
464 {
465 }
466
testAttributes(EGLDisplay display,EGLSurface surface,EGLint surfaceType,const ConfigInfo & info)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:
SurfaceAttribWindowCase(EglTestContext & eglTestCtx,const char * name,const char * description,const eglu::FilterList & filters)571 SurfaceAttribWindowCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
572 : SurfaceAttribCase(eglTestCtx, name, description, filters)
573 {
574 }
575
executeForConfig(EGLDisplay display,EGLConfig config)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::queryConfigInfo(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:
SurfaceAttribPixmapCase(EglTestContext & eglTestCtx,const char * name,const char * description,const eglu::FilterList & filters)600 SurfaceAttribPixmapCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
601 : SurfaceAttribCase(eglTestCtx, name, description, filters)
602 {
603 }
604
executeForConfig(EGLDisplay display,EGLConfig config)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::queryConfigInfo(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:
SurfaceAttribPbufferCase(EglTestContext & eglTestCtx,const char * name,const char * description,const eglu::FilterList & filters)629 SurfaceAttribPbufferCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
630 : SurfaceAttribCase(eglTestCtx, name, description, filters)
631 {
632 }
633
executeForConfig(EGLDisplay display,EGLConfig config)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::queryConfigInfo(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
QuerySurfaceTests(EglTestContext & eglTestCtx)672 QuerySurfaceTests::QuerySurfaceTests (EglTestContext& eglTestCtx)
673 : TestCaseGroup(eglTestCtx, "query_surface", "Surface Query Tests")
674 {
675 }
676
~QuerySurfaceTests(void)677 QuerySurfaceTests::~QuerySurfaceTests (void)
678 {
679 }
680
681 template <deUint32 Type>
surfaceType(const eglu::CandidateConfig & c)682 static bool surfaceType (const eglu::CandidateConfig& c)
683 {
684 return (c.surfaceType() & Type) == Type;
685 }
686
init(void)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