Merge vk-gl-cts/vulkan-cts-1.1.3 into vk-gl-cts/master
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglCreateSurfaceTests.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 Simple surface construction test.
22  *//*--------------------------------------------------------------------*/
23
24 #include "teglCreateSurfaceTests.hpp"
25
26 #include "egluNativeDisplay.hpp"
27 #include "egluNativeWindow.hpp"
28 #include "egluNativePixmap.hpp"
29 #include "egluUtil.hpp"
30 #include "egluUnique.hpp"
31
32 #include "eglwLibrary.hpp"
33 #include "eglwEnums.hpp"
34
35 #include "teglSimpleConfigCase.hpp"
36 #include "tcuTestContext.hpp"
37 #include "tcuCommandLine.hpp"
38 #include "tcuTestLog.hpp"
39
40 #include "deStringUtil.hpp"
41 #include "deSTLUtil.hpp"
42 #include "deUniquePtr.hpp"
43
44 #include <memory>
45
46 namespace deqp
47 {
48 namespace egl
49 {
50
51 using std::vector;
52 using tcu::TestLog;
53 using namespace eglw;
54
55 namespace
56 {
57
58 #define EGL_MAKE_VERSION(major, minor) (((major) << 12) | (minor))
59
60 enum ApiType
61 {
62         LEGACY,
63         EXTENSION,
64         EGL15
65 };
66
67 void checkEGLPlatformSupport (const Library& egl)
68 {
69         const vector<std::string>       extensions      = eglu::getClientExtensions(egl);
70         if (!de::contains(extensions.begin(), extensions.end(), "EGL_EXT_platform_base"))
71                 throw tcu::NotSupportedError("Platform extension 'EGL_EXT_platform_base' not supported", "", __FILE__, __LINE__);
72 }
73
74 void checkEGL15Support (const Library& egl, EGLDisplay display)
75 {
76         // The EGL_VERSION string is laid out as follows:
77         // major_version.minor_version space vendor_specific_info
78         // Split version from vendor_specific_info
79         std::vector<std::string> tokens = de::splitString(egl.queryString(display, EGL_VERSION), ' ');
80         // split version into major & minor
81         std::vector<std::string> values = de::splitString(tokens[0], '.');
82         EGLint eglVersion = EGL_MAKE_VERSION(atoi(values[0].c_str()), atoi(values[1].c_str()));
83         if (eglVersion < EGL_MAKE_VERSION(1, 5))
84                 throw tcu::NotSupportedError("EGL 1.5 not supported", "", __FILE__, __LINE__);
85 }
86
87 EGLSurface createWindowSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativeWindow& window, ApiType createType)
88 {
89         const Library&  egl             = nativeDisplay.getLibrary();
90         EGLSurface              surface = EGL_NO_SURFACE;
91
92         switch (createType)
93         {
94                 case LEGACY:
95                 {
96                         surface = egl.createWindowSurface(display, config, window.getLegacyNative(), DE_NULL);
97                         EGLU_CHECK_MSG(egl, "eglCreateWindowSurface() failed");
98                 }
99                 break;
100                 case EXTENSION:
101                 {
102                         checkEGLPlatformSupport(egl);
103                         void *nativeWindow = window.getPlatformExtension();
104                         surface = egl.createPlatformWindowSurfaceEXT(display, config, nativeWindow, DE_NULL);
105                         EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurfaceEXT() failed");
106                 }
107                 break;
108                 case EGL15:
109                 {
110                         checkEGL15Support(egl, display);
111                         surface = egl.createPlatformWindowSurface(display, config, window.getPlatformNative(), DE_NULL);
112                         EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurface() failed");
113                 }
114         }
115
116         return surface;
117 }
118
119 EGLSurface createPixmapSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativePixmap& pixmap, ApiType createType)
120 {
121         const Library&  egl             = nativeDisplay.getLibrary();
122         EGLSurface              surface = EGL_NO_SURFACE;
123
124         switch (createType)
125         {
126                 case LEGACY:
127                         surface = egl.createPixmapSurface(display, config, pixmap.getLegacyNative(), DE_NULL);
128                         EGLU_CHECK_MSG(egl, "eglCreatePixmapSurface() failed");
129                 break;
130                 case EXTENSION:
131                         checkEGLPlatformSupport(egl);
132                         surface = egl.createPlatformPixmapSurfaceEXT(display, config, pixmap.getPlatformExtension(), DE_NULL);
133                         EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurfaceEXT() failed");
134                 break;
135                 case EGL15:
136                         surface = egl.createPlatformPixmapSurface(display, config, pixmap.getPlatformNative(), DE_NULL);
137                         EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurface() failed");
138                 break;
139         }
140
141         return surface;
142 }
143
144 class CreateWindowSurfaceCase : public SimpleConfigCase
145 {
146 public:
147         CreateWindowSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, ApiType createType, const eglu::FilterList& filters)
148                 : SimpleConfigCase      (eglTestCtx, name, description, filters)
149                 , m_createType  (createType)
150         {
151         }
152
153         void executeForConfig (EGLDisplay display, EGLConfig config)
154         {
155                 const Library&                                          egl                             = m_eglTestCtx.getLibrary();
156                 TestLog&                                                        log                             = m_testCtx.getLog();
157                 EGLint                                                          id                              = eglu::getConfigID(egl, display, config);
158                 const eglu::NativeWindowFactory&        windowFactory   = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
159
160                 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
161
162                 switch (m_createType)
163                 {
164                         case LEGACY:
165                         {
166                                 if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
167                                         TCU_THROW(NotSupportedError, "Native window doesn't support legacy eglCreateWindowSurface()");
168                         }
169                         break;
170                         case EXTENSION:
171                         {
172                                 if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) == 0)
173                                         TCU_THROW(NotSupportedError, "Native window doesn't support eglCreatePlatformWindowSurfaceEXT()");
174                         }
175                         break;
176                         case EGL15:
177                         {
178                                 if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
179                                         TCU_THROW(NotSupportedError, "Native window doesn't support eglCreatePlatformWindowSurface()");
180                         }
181                         break;
182                 }
183
184                 log << TestLog::Message << "Creating window surface with config ID " << id << TestLog::EndMessage;
185                 EGLU_CHECK_MSG(egl, "init");
186
187                 {
188                         const int                                                       width                   = 64;
189                         const int                                                       height                  = 64;
190                         de::UniquePtr<eglu::NativeWindow>       window                  (windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, eglu::WindowParams(width, height, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
191                         eglu::UniqueSurface                                     surface                 (egl, display, createWindowSurface(display, config, m_eglTestCtx.getNativeDisplay(), *window, m_createType));
192
193                         EGLint                                                          windowWidth             = 0;
194                         EGLint                                                          windowHeight    = 0;
195
196                         EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH,         &windowWidth));
197                         EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT,        &windowHeight));
198
199                         if (windowWidth <= 0 || windowHeight <= 0)
200                         {
201                                 log << TestLog::Message << "  Fail, invalid surface size " << windowWidth << "x" << windowHeight << TestLog::EndMessage;
202                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
203                         }
204                         else
205                                 log << TestLog::Message << "  Pass" << TestLog::EndMessage;
206                 }
207         }
208
209 private:
210         ApiType         m_createType;
211 };
212
213 class CreatePixmapSurfaceCase : public SimpleConfigCase
214 {
215 public:
216         CreatePixmapSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, ApiType createType, const eglu::FilterList& filters)
217                 : SimpleConfigCase(eglTestCtx, name, description, filters)
218                 , m_createType  (createType)
219         {
220         }
221
222         void executeForConfig (EGLDisplay display, EGLConfig config)
223         {
224                 const Library&                                          egl                             = m_eglTestCtx.getLibrary();
225                 TestLog&                                                        log                             = m_testCtx.getLog();
226                 EGLint                                                          id                              = eglu::getConfigID(egl, display, config);
227                 const eglu::NativePixmapFactory&        pixmapFactory   = eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
228
229                 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
230
231                 switch (m_createType)
232                 {
233                         case LEGACY:
234                         {
235                                 if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
236                                         TCU_THROW(NotSupportedError, "Native pixmap doesn't support legacy eglCreatePixmapSurface()");
237                         }
238                         break;
239                         case EXTENSION:
240                         {
241                                 if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) == 0)
242                                         TCU_THROW(NotSupportedError, "Native pixmap doesn't support eglCreatePlatformPixmapSurfaceEXT()");
243                         }
244                         break;
245                         case EGL15:
246                         {
247                                 if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
248                                         TCU_THROW(NotSupportedError, "Native pixmap doesn't support eglCreatePlatformPixmapSurface()");
249                         }
250                         break;
251                 };
252
253                 log << TestLog::Message << "Creating pixmap surface with config ID " << id << TestLog::EndMessage;
254                 EGLU_CHECK_MSG(egl, "init");
255
256                 {
257                         const int                                                       width                   = 64;
258                         const int                                                       height                  = 64;
259                         de::UniquePtr<eglu::NativePixmap>       pixmap                  (pixmapFactory.createPixmap(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, width, height));
260                         eglu::UniqueSurface                                     surface                 (egl, display, createPixmapSurface(display, config, m_eglTestCtx.getNativeDisplay(), *pixmap, m_createType));
261                         EGLint                                                          pixmapWidth             = 0;
262                         EGLint                                                          pixmapHeight    = 0;
263
264                         EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH,         &pixmapWidth));
265                         EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT,        &pixmapHeight));
266
267                         if (pixmapWidth <= 0 || pixmapHeight <= 0)
268                         {
269                                 log << TestLog::Message << "  Fail, invalid surface size " << pixmapWidth << "x" << pixmapHeight << TestLog::EndMessage;
270                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
271                         }
272                         else
273                                 log << TestLog::Message << "  Pass" << TestLog::EndMessage;
274                 }
275         }
276
277 private:
278         ApiType         m_createType;
279 };
280
281 class CreatePbufferSurfaceCase : public SimpleConfigCase
282 {
283 public:
284         CreatePbufferSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
285                 : SimpleConfigCase(eglTestCtx, name, description, filters)
286         {
287         }
288
289         void executeForConfig (EGLDisplay display, EGLConfig config)
290         {
291                 const Library&  egl             = m_eglTestCtx.getLibrary();
292                 TestLog&                log             = m_testCtx.getLog();
293                 EGLint                  id              = eglu::getConfigID(egl, display, config);
294                 int                             width   = 64;
295                 int                             height  = 64;
296
297                 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
298
299                 log << TestLog::Message << "Creating pbuffer surface with config ID " << id << TestLog::EndMessage;
300                 EGLU_CHECK_MSG(egl, "init");
301
302                 // Clamp to maximums reported by implementation
303                 width   = deMin32(width, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_WIDTH));
304                 height  = deMin32(height, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_HEIGHT));
305
306                 if (width == 0 || height == 0)
307                 {
308                         log << TestLog::Message << "  Fail, maximum pbuffer size of " << width << "x" << height << " reported" << TestLog::EndMessage;
309                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid maximum pbuffer size");
310                         return;
311                 }
312
313                 // \todo [2011-03-23 pyry] Texture-backed variants!
314
315                 const EGLint attribs[] =
316                 {
317                         EGL_WIDTH,                      width,
318                         EGL_HEIGHT,                     height,
319                         EGL_TEXTURE_FORMAT,     EGL_NO_TEXTURE,
320                         EGL_NONE
321                 };
322
323                 EGLSurface surface = egl.createPbufferSurface(display, config, attribs);
324                 EGLU_CHECK_MSG(egl, "Failed to create pbuffer");
325                 TCU_CHECK(surface != EGL_NO_SURFACE);
326                 egl.destroySurface(display, surface);
327
328                 log << TestLog::Message << "  Pass" << TestLog::EndMessage;
329         }
330 };
331
332 } // anonymous
333
334 CreateSurfaceTests::CreateSurfaceTests (EglTestContext& eglTestCtx)
335         : TestCaseGroup(eglTestCtx, "create_surface", "Basic surface construction tests")
336 {
337 }
338
339 CreateSurfaceTests::~CreateSurfaceTests (void)
340 {
341 }
342
343 template <deUint32 Type>
344 static bool surfaceType (const eglu::CandidateConfig& c)
345 {
346         return (c.surfaceType() & Type) == Type;
347 }
348
349 void CreateSurfaceTests::init (void)
350 {
351         // Window surfaces
352         {
353                 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "window", "Window surfaces");
354                 addChild(windowGroup);
355
356                 eglu::FilterList baseFilters;
357                 baseFilters << surfaceType<EGL_WINDOW_BIT>;
358
359                 vector<NamedFilterList> filterLists;
360                 getDefaultFilterLists(filterLists, baseFilters);
361
362                 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
363                         windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), LEGACY, *i));
364         }
365
366         // Pixmap surfaces
367         {
368                 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "pixmap", "Pixmap surfaces");
369                 addChild(pixmapGroup);
370
371                 eglu::FilterList baseFilters;
372                 baseFilters << surfaceType<EGL_PIXMAP_BIT>;
373
374                 vector<NamedFilterList> filterLists;
375                 getDefaultFilterLists(filterLists, baseFilters);
376
377                 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
378                         pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), LEGACY, *i));
379         }
380
381         // Pbuffer surfaces
382         {
383                 tcu::TestCaseGroup* pbufferGroup = new tcu::TestCaseGroup(m_testCtx, "pbuffer", "Pbuffer surfaces");
384                 addChild(pbufferGroup);
385
386                 eglu::FilterList baseFilters;
387                 baseFilters << surfaceType<EGL_PBUFFER_BIT>;
388
389                 vector<NamedFilterList> filterLists;
390                 getDefaultFilterLists(filterLists, baseFilters);
391
392                 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
393                         pbufferGroup->addChild(new CreatePbufferSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
394         }
395
396         // Window surfaces with new platform extension
397         {
398                 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_ext_window", "Window surfaces with platform extension");
399                 addChild(windowGroup);
400
401                 eglu::FilterList baseFilters;
402                 baseFilters << surfaceType<EGL_WINDOW_BIT>;
403
404                 vector<NamedFilterList> filterLists;
405                 getDefaultFilterLists(filterLists, baseFilters);
406
407                 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
408                         windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EXTENSION, *i));
409         }
410
411         // Pixmap surfaces with new platform extension
412         {
413                 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_ext_pixmap", "Pixmap surfaces with platform extension");
414                 addChild(pixmapGroup);
415
416                 eglu::FilterList baseFilters;
417                 baseFilters << surfaceType<EGL_PIXMAP_BIT>;
418
419                 vector<NamedFilterList> filterLists;
420                 getDefaultFilterLists(filterLists, baseFilters);
421
422                 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
423                         pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EXTENSION, *i));
424         }
425         //
426         // Window surfaces with EGL 1.5 CreateWindowSurface
427         {
428                 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_window", "Window surfaces with EGL 1.5");
429                 addChild(windowGroup);
430
431                 eglu::FilterList baseFilters;
432                 baseFilters << surfaceType<EGL_WINDOW_BIT>;
433
434                 vector<NamedFilterList> filterLists;
435                 getDefaultFilterLists(filterLists, baseFilters);
436
437                 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
438                         windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EGL15, *i));
439         }
440
441         // Pixmap surfaces with EGL 1.5 CreateWindowSurface
442         {
443                 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_pixmap", "Pixmap surfaces with EGL 1.5");
444                 addChild(pixmapGroup);
445
446                 eglu::FilterList baseFilters;
447                 baseFilters << surfaceType<EGL_PIXMAP_BIT>;
448
449                 vector<NamedFilterList> filterLists;
450                 getDefaultFilterLists(filterLists, baseFilters);
451
452                 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
453                         pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EGL15, *i));
454         }
455 }
456
457 } // egl
458 } // deqp