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