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