xref: /aosp_15_r20/external/deqp/modules/egl/teglQuerySurfaceTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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