Correct robust buffer access behavior tests
[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 "deSTLUtil.hpp"
41 #include "deUniquePtr.hpp"
42
43 #include <memory>
44
45 namespace deqp
46 {
47 namespace egl
48 {
49
50 using std::vector;
51 using tcu::TestLog;
52 using namespace eglw;
53
54 namespace
55 {
56
57 void checkEGLPlatformSupport (const Library& egl, const char* platformExt)
58 {
59         std::vector<std::string> extensions = eglu::getClientExtensions(egl);
60
61         if (!de::contains(extensions.begin(), extensions.end(), platformExt))
62                 throw tcu::NotSupportedError((std::string("Platform extension '") + platformExt + "' not supported").c_str(), "", __FILE__, __LINE__);
63 }
64
65 EGLSurface createWindowSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativeWindow& window, bool useLegacyCreate)
66 {
67         const Library&  egl             = nativeDisplay.getLibrary();
68         EGLSurface              surface = EGL_NO_SURFACE;
69
70         if (useLegacyCreate)
71         {
72                 surface = egl.createWindowSurface(display, config, window.getLegacyNative(), DE_NULL);
73                 EGLU_CHECK_MSG(egl, "eglCreateWindowSurface() failed");
74         }
75         else
76         {
77                 checkEGLPlatformSupport(egl, nativeDisplay.getPlatformExtensionName());
78
79                 surface = egl.createPlatformWindowSurfaceEXT(display, config, window.getPlatformNative(), DE_NULL);
80                 EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurfaceEXT() failed");
81         }
82
83         return surface;
84 }
85
86 EGLSurface createPixmapSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativePixmap& pixmap, bool useLegacyCreate)
87 {
88         const Library&  egl             = nativeDisplay.getLibrary();
89         EGLSurface              surface = EGL_NO_SURFACE;
90
91         if (useLegacyCreate)
92         {
93                 surface = egl.createPixmapSurface(display, config, pixmap.getLegacyNative(), DE_NULL);
94                 EGLU_CHECK_MSG(egl, "eglCreatePixmapSurface() failed");
95         }
96         else
97         {
98                 checkEGLPlatformSupport(egl, nativeDisplay.getPlatformExtensionName());
99
100                 surface = egl.createPlatformPixmapSurfaceEXT(display, config, pixmap.getPlatformNative(), DE_NULL);
101                 EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurfaceEXT() failed");
102         }
103
104         return surface;
105 }
106
107 class CreateWindowSurfaceCase : public SimpleConfigCase
108 {
109 public:
110         CreateWindowSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, bool useLegacyCreate, const eglu::FilterList& filters)
111                 : SimpleConfigCase      (eglTestCtx, name, description, filters)
112                 , m_useLegacyCreate     (useLegacyCreate)
113         {
114         }
115
116         void executeForConfig (EGLDisplay display, EGLConfig config)
117         {
118                 const Library&                                          egl                             = m_eglTestCtx.getLibrary();
119                 TestLog&                                                        log                             = m_testCtx.getLog();
120                 EGLint                                                          id                              = eglu::getConfigID(egl, display, config);
121                 const eglu::NativeWindowFactory&        windowFactory   = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
122
123                 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
124
125                 if (m_useLegacyCreate)
126                 {
127                         if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
128                                 TCU_THROW(NotSupportedError, "Native window doesn't support legacy eglCreateWindowSurface()");
129                 }
130                 else
131                 {
132                         if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
133                                 TCU_THROW(NotSupportedError, "Native window doesn't support eglCreatePlatformWindowSurfaceEXT()");
134                 }
135
136                 log << TestLog::Message << "Creating window surface with config ID " << id << TestLog::EndMessage;
137                 EGLU_CHECK_MSG(egl, "init");
138
139                 {
140                         const int                                                       width                   = 64;
141                         const int                                                       height                  = 64;
142                         de::UniquePtr<eglu::NativeWindow>       window                  (windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, eglu::WindowParams(width, height, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
143                         eglu::UniqueSurface                                     surface                 (egl, display, createWindowSurface(display, config, m_eglTestCtx.getNativeDisplay(), *window, m_useLegacyCreate));
144
145                         EGLint                                                          windowWidth             = 0;
146                         EGLint                                                          windowHeight    = 0;
147
148                         EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH,         &windowWidth));
149                         EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT,        &windowHeight));
150
151                         if (windowWidth <= 0 || windowHeight <= 0)
152                         {
153                                 log << TestLog::Message << "  Fail, invalid surface size " << windowWidth << "x" << windowHeight << TestLog::EndMessage;
154                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
155                         }
156                         else
157                                 log << TestLog::Message << "  Pass" << TestLog::EndMessage;
158                 }
159         }
160
161 private:
162         bool    m_useLegacyCreate;
163 };
164
165 class CreatePixmapSurfaceCase : public SimpleConfigCase
166 {
167 public:
168         CreatePixmapSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, bool useLegacyCreate, const eglu::FilterList& filters)
169                 : SimpleConfigCase(eglTestCtx, name, description, filters)
170                 , m_useLegacyCreate     (useLegacyCreate)
171         {
172         }
173
174         void executeForConfig (EGLDisplay display, EGLConfig config)
175         {
176                 const Library&                                          egl                             = m_eglTestCtx.getLibrary();
177                 TestLog&                                                        log                             = m_testCtx.getLog();
178                 EGLint                                                          id                              = eglu::getConfigID(egl, display, config);
179                 const eglu::NativePixmapFactory&        pixmapFactory   = eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
180
181                 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
182
183                 if (m_useLegacyCreate)
184                 {
185                         if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
186                                 TCU_THROW(NotSupportedError, "Native pixmap doesn't support legacy eglCreatePixmapSurface()");
187                 }
188                 else
189                 {
190                         if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
191                                 TCU_THROW(NotSupportedError, "Native pixmap doesn't support eglCreatePlatformPixmapSurfaceEXT()");
192                 }
193
194                 log << TestLog::Message << "Creating pixmap surface with config ID " << id << TestLog::EndMessage;
195                 EGLU_CHECK_MSG(egl, "init");
196
197                 {
198                         const int                                                       width                   = 64;
199                         const int                                                       height                  = 64;
200                         de::UniquePtr<eglu::NativePixmap>       pixmap                  (pixmapFactory.createPixmap(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, width, height));
201                         eglu::UniqueSurface                                     surface                 (egl, display, createPixmapSurface(display, config, m_eglTestCtx.getNativeDisplay(), *pixmap, m_useLegacyCreate));
202                         EGLint                                                          pixmapWidth             = 0;
203                         EGLint                                                          pixmapHeight    = 0;
204
205                         EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH,         &pixmapWidth));
206                         EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT,        &pixmapHeight));
207
208                         if (pixmapWidth <= 0 || pixmapHeight <= 0)
209                         {
210                                 log << TestLog::Message << "  Fail, invalid surface size " << pixmapWidth << "x" << pixmapHeight << TestLog::EndMessage;
211                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
212                         }
213                         else
214                                 log << TestLog::Message << "  Pass" << TestLog::EndMessage;
215                 }
216         }
217
218 private:
219         bool    m_useLegacyCreate;
220 };
221
222 class CreatePbufferSurfaceCase : public SimpleConfigCase
223 {
224 public:
225         CreatePbufferSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
226                 : SimpleConfigCase(eglTestCtx, name, description, filters)
227         {
228         }
229
230         void executeForConfig (EGLDisplay display, EGLConfig config)
231         {
232                 const Library&  egl             = m_eglTestCtx.getLibrary();
233                 TestLog&                log             = m_testCtx.getLog();
234                 EGLint                  id              = eglu::getConfigID(egl, display, config);
235                 int                             width   = 64;
236                 int                             height  = 64;
237
238                 // \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT
239
240                 log << TestLog::Message << "Creating pbuffer surface with config ID " << id << TestLog::EndMessage;
241                 EGLU_CHECK_MSG(egl, "init");
242
243                 // Clamp to maximums reported by implementation
244                 width   = deMin32(width, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_WIDTH));
245                 height  = deMin32(height, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_HEIGHT));
246
247                 if (width == 0 || height == 0)
248                 {
249                         log << TestLog::Message << "  Fail, maximum pbuffer size of " << width << "x" << height << " reported" << TestLog::EndMessage;
250                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid maximum pbuffer size");
251                         return;
252                 }
253
254                 // \todo [2011-03-23 pyry] Texture-backed variants!
255
256                 const EGLint attribs[] =
257                 {
258                         EGL_WIDTH,                      width,
259                         EGL_HEIGHT,                     height,
260                         EGL_TEXTURE_FORMAT,     EGL_NO_TEXTURE,
261                         EGL_NONE
262                 };
263
264                 EGLSurface surface = egl.createPbufferSurface(display, config, attribs);
265                 EGLU_CHECK_MSG(egl, "Failed to create pbuffer");
266                 TCU_CHECK(surface != EGL_NO_SURFACE);
267                 egl.destroySurface(display, surface);
268
269                 log << TestLog::Message << "  Pass" << TestLog::EndMessage;
270         }
271 };
272
273 } // anonymous
274
275 CreateSurfaceTests::CreateSurfaceTests (EglTestContext& eglTestCtx)
276         : TestCaseGroup(eglTestCtx, "create_surface", "Basic surface construction tests")
277 {
278 }
279
280 CreateSurfaceTests::~CreateSurfaceTests (void)
281 {
282 }
283
284 template <deUint32 Type>
285 static bool surfaceType (const eglu::CandidateConfig& c)
286 {
287         return (c.surfaceType() & Type) == Type;
288 }
289
290 void CreateSurfaceTests::init (void)
291 {
292         // Window surfaces
293         {
294                 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "window", "Window surfaces");
295                 addChild(windowGroup);
296
297                 eglu::FilterList baseFilters;
298                 baseFilters << surfaceType<EGL_WINDOW_BIT>;
299
300                 vector<NamedFilterList> filterLists;
301                 getDefaultFilterLists(filterLists, baseFilters);
302
303                 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
304                         windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), true, *i));
305         }
306
307         // Pixmap surfaces
308         {
309                 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "pixmap", "Pixmap surfaces");
310                 addChild(pixmapGroup);
311
312                 eglu::FilterList baseFilters;
313                 baseFilters << surfaceType<EGL_PIXMAP_BIT>;
314
315                 vector<NamedFilterList> filterLists;
316                 getDefaultFilterLists(filterLists, baseFilters);
317
318                 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
319                         pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), true, *i));
320         }
321
322         // Pbuffer surfaces
323         {
324                 tcu::TestCaseGroup* pbufferGroup = new tcu::TestCaseGroup(m_testCtx, "pbuffer", "Pbuffer surfaces");
325                 addChild(pbufferGroup);
326
327                 eglu::FilterList baseFilters;
328                 baseFilters << surfaceType<EGL_PBUFFER_BIT>;
329
330                 vector<NamedFilterList> filterLists;
331                 getDefaultFilterLists(filterLists, baseFilters);
332
333                 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
334                         pbufferGroup->addChild(new CreatePbufferSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
335         }
336
337         // Window surfaces with new platform extension
338         {
339                 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_window", "Window surfaces with platform extension");
340                 addChild(windowGroup);
341
342                 eglu::FilterList baseFilters;
343                 baseFilters << surfaceType<EGL_WINDOW_BIT>;
344
345                 vector<NamedFilterList> filterLists;
346                 getDefaultFilterLists(filterLists, baseFilters);
347
348                 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
349                         windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), false, *i));
350         }
351
352         // Pixmap surfaces with new platform extension
353         {
354                 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_pixmap", "Pixmap surfaces with platform extension");
355                 addChild(pixmapGroup);
356
357                 eglu::FilterList baseFilters;
358                 baseFilters << surfaceType<EGL_PIXMAP_BIT>;
359
360                 vector<NamedFilterList> filterLists;
361                 getDefaultFilterLists(filterLists, baseFilters);
362
363                 for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
364                         pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), false, *i));
365         }
366 }
367
368 } // egl
369 } // deqp