Merge vk-gl-cts/vulkan-cts-1.3.4 into vk-gl-cts/vulkan-cts-1.3.5
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglQueryContextTests.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 Config query tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "teglQueryContextTests.hpp"
25 #include "teglRenderCase.hpp"
26 #include "teglRenderCase.hpp"
27 #include "egluCallLogWrapper.hpp"
28 #include "egluStrUtil.hpp"
29 #include "tcuCommandLine.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuTestContext.hpp"
32
33 #include "egluUtil.hpp"
34 #include "egluNativeDisplay.hpp"
35 #include "egluNativeWindow.hpp"
36 #include "egluNativePixmap.hpp"
37
38 #include "eglwLibrary.hpp"
39 #include "eglwEnums.hpp"
40
41 #include "deUniquePtr.hpp"
42 #include "deSTLUtil.hpp"
43
44 #include <vector>
45
46 namespace deqp
47 {
48 namespace egl
49 {
50
51 using std::vector;
52 using eglu::ConfigInfo;
53 using tcu::TestLog;
54 using namespace eglw;
55
56 static EGLint getClientTypeFromAPIBit (EGLint apiBit)
57 {
58         switch (apiBit)
59         {
60                 case EGL_OPENGL_BIT:            return EGL_OPENGL_API;
61                 case EGL_OPENGL_ES_BIT:         return EGL_OPENGL_ES_API;
62                 case EGL_OPENGL_ES2_BIT:        return EGL_OPENGL_ES_API;
63                 case EGL_OPENGL_ES3_BIT:        return EGL_OPENGL_ES_API;
64                 case EGL_OPENVG_BIT:            return EGL_OPENVG_API;
65                 default:
66                         DE_ASSERT(false);
67                         return 0;
68         }
69 }
70
71 static EGLint getMinClientMajorVersion (EGLint apiBit)
72 {
73         switch (apiBit)
74         {
75                 case EGL_OPENGL_BIT:            return 1;
76                 case EGL_OPENGL_ES_BIT:         return 1;
77                 case EGL_OPENGL_ES2_BIT:        return 2;
78                 case EGL_OPENGL_ES3_BIT:        return 3;
79                 case EGL_OPENVG_BIT:            return 1;
80                 default:
81                         DE_ASSERT(false);
82                         return 0;
83         }
84 }
85
86 class GetCurrentContextCase : public SingleContextRenderCase, private eglu::CallLogWrapper
87 {
88 public:
89         GetCurrentContextCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters, EGLint surfaceTypeMask)
90                 : SingleContextRenderCase       (eglTestCtx, name, description, getBuildClientAPIMask(), surfaceTypeMask, filters)
91                 , eglu::CallLogWrapper          (eglTestCtx.getLibrary(), m_testCtx.getLog())
92         {
93         }
94
95         void executeForContext (EGLDisplay display, EGLContext context, EGLSurface surface, const Config& config)
96         {
97                 const Library&  egl     = m_eglTestCtx.getLibrary();
98                 TestLog&                log     = m_testCtx.getLog();
99
100                 DE_UNREF(display);
101                 DE_UNREF(surface);
102                 DE_UNREF(config);
103
104                 enableLogging(true);
105
106                 const EGLContext        gotContext      = eglGetCurrentContext();
107                 EGLU_CHECK_MSG(egl, "eglGetCurrentContext");
108
109                 if (gotContext == context)
110                 {
111                         log << TestLog::Message << "  Pass" << TestLog::EndMessage;
112                 }
113                 else if (gotContext == EGL_NO_CONTEXT)
114                 {
115                         log << TestLog::Message << "  Fail, got EGL_NO_CONTEXT" << TestLog::EndMessage;
116                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected EGL_NO_CONTEXT");
117                 }
118                 else if (gotContext != context)
119                 {
120                         log << TestLog::Message << "  Fail, call returned the wrong context. Expected: " << tcu::toHex(context) << ", got: " << tcu::toHex(gotContext) << TestLog::EndMessage;
121                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid context");
122                 }
123
124                 enableLogging(false);
125         }
126 };
127
128 class GetCurrentSurfaceCase : public SingleContextRenderCase, private eglu::CallLogWrapper
129 {
130 public:
131         GetCurrentSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters, EGLint surfaceTypeMask)
132                 : SingleContextRenderCase       (eglTestCtx, name, description, getBuildClientAPIMask(), surfaceTypeMask, filters)
133                 , eglu::CallLogWrapper          (eglTestCtx.getLibrary(), m_testCtx.getLog())
134         {
135         }
136
137         void executeForContext (EGLDisplay display, EGLContext context, EGLSurface surface, const Config& config)
138         {
139                 const Library&  egl     = m_eglTestCtx.getLibrary();
140                 TestLog&                log     = m_testCtx.getLog();
141
142                 DE_UNREF(display);
143                 DE_UNREF(context);
144                 DE_UNREF(config);
145
146                 enableLogging(true);
147
148                 const EGLContext        gotReadSurface  = eglGetCurrentSurface(EGL_READ);
149                 EGLU_CHECK_MSG(egl, "eglGetCurrentSurface(EGL_READ)");
150
151                 const EGLContext        gotDrawSurface  = eglGetCurrentSurface(EGL_DRAW);
152                 EGLU_CHECK_MSG(egl, "eglGetCurrentSurface(EGL_DRAW)");
153
154                 if (gotReadSurface == surface && gotDrawSurface == surface)
155                 {
156                         log << TestLog::Message << "  Pass" << TestLog::EndMessage;
157                 }
158                 else
159                 {
160                         log << TestLog::Message << "  Fail, read surface: " << tcu::toHex(gotReadSurface)
161                                                                         << ", draw surface: " << tcu::toHex(gotDrawSurface)
162                                                                         << ", expected: " << tcu::toHex(surface) << TestLog::EndMessage;
163                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface");
164                 }
165
166                 enableLogging(false);
167         }
168 };
169
170 class GetCurrentDisplayCase : public SingleContextRenderCase, private eglu::CallLogWrapper
171 {
172 public:
173         GetCurrentDisplayCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters, EGLint surfaceTypeMask)
174                 : SingleContextRenderCase       (eglTestCtx, name, description, getBuildClientAPIMask(), surfaceTypeMask, filters)
175                 , eglu::CallLogWrapper          (eglTestCtx.getLibrary(), m_testCtx.getLog())
176         {
177         }
178
179         void executeForContext (EGLDisplay display, EGLContext context, EGLSurface surface, const Config& config)
180         {
181                 const Library&  egl     = m_eglTestCtx.getLibrary();
182                 TestLog&                log     = m_testCtx.getLog();
183
184                 DE_UNREF(surface && context);
185                 DE_UNREF(config);
186
187                 enableLogging(true);
188
189                 const EGLDisplay        gotDisplay      = eglGetCurrentDisplay();
190                 EGLU_CHECK_MSG(egl, "eglGetCurrentDisplay");
191
192                 if (gotDisplay == display)
193                 {
194                         log << TestLog::Message << "  Pass" << TestLog::EndMessage;
195                 }
196                 else if (gotDisplay == EGL_NO_DISPLAY)
197                 {
198                         log << TestLog::Message << "  Fail, got EGL_NO_DISPLAY" << TestLog::EndMessage;
199                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected EGL_NO_DISPLAY");
200                 }
201                 else if (gotDisplay != display)
202                 {
203                         log << TestLog::Message << "  Fail, call returned the wrong display. Expected: " << tcu::toHex(display) << ", got: " << tcu::toHex(gotDisplay) << TestLog::EndMessage;
204                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid display");
205                 }
206
207                 enableLogging(false);
208         }
209 };
210
211 class QueryContextCase : public SingleContextRenderCase, private eglu::CallLogWrapper
212 {
213 public:
214         QueryContextCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters, EGLint surfaceTypeMask)
215                 : SingleContextRenderCase       (eglTestCtx, name, description, getBuildClientAPIMask(), surfaceTypeMask, filters)
216                 , eglu::CallLogWrapper          (eglTestCtx.getLibrary(), m_testCtx.getLog())
217         {
218         }
219
220         EGLint getContextAttrib (EGLDisplay display, EGLContext context, EGLint attrib)
221         {
222                 const Library&  egl     = m_eglTestCtx.getLibrary();
223                 EGLint                  value;
224                 EGLU_CHECK_CALL(egl, queryContext(display, context, attrib, &value));
225
226                 return value;
227         }
228
229         void executeForContext (EGLDisplay display, EGLContext context, EGLSurface surface, const Config& config)
230         {
231                 const Library&          egl             = m_eglTestCtx.getLibrary();
232                 TestLog&                        log             = m_testCtx.getLog();
233                 const eglu::Version     version = eglu::getVersion(egl, display);
234
235                 DE_UNREF(surface);
236                 enableLogging(true);
237
238                 // Config ID
239                 {
240                         const EGLint    configID                = getContextAttrib(display, context, EGL_CONFIG_ID);
241                         const EGLint    surfaceConfigID = eglu::getConfigAttribInt(egl, display, config.config, EGL_CONFIG_ID);
242
243                         if (configID != surfaceConfigID)
244                         {
245                                 log << TestLog::Message << "  Fail, config ID doesn't match the one used to create the context." << TestLog::EndMessage;
246                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid config ID");
247                         }
248                 }
249
250                 // Client API type
251                 if (version >= eglu::Version(1, 2))
252                 {
253                         const EGLint    clientType              = getContextAttrib(display, context, EGL_CONTEXT_CLIENT_TYPE);
254
255                         if (clientType != getClientTypeFromAPIBit(config.apiBits))
256                         {
257                                 log << TestLog::Message << "  Fail, client API type doesn't match." << TestLog::EndMessage;
258                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid client API type");
259                         }
260                 }
261
262                 // Client API version
263                 if (version >= eglu::Version(1, 3))
264                 {
265                         const EGLint    clientVersion   = getContextAttrib(display, context, EGL_CONTEXT_CLIENT_VERSION);
266
267                         // \todo [2014-10-21 mika] Query actual supported api version from client api to make this check stricter.
268                         if (clientVersion < getMinClientMajorVersion(config.apiBits))
269                         {
270                                 log << TestLog::Message << "  Fail, client API version doesn't match." << TestLog::EndMessage;
271                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid client API version");
272                         }
273                 }
274
275                 // Render buffer
276                 if (version >= eglu::Version(1, 2))
277                 {
278                         const EGLint    renderBuffer    = getContextAttrib(display, context, EGL_RENDER_BUFFER);
279
280                         if (config.surfaceTypeBit == EGL_PIXMAP_BIT && renderBuffer != EGL_SINGLE_BUFFER)
281                         {
282                                 log << TestLog::Message << "  Fail, render buffer should be EGL_SINGLE_BUFFER for a pixmap surface." << TestLog::EndMessage;
283                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid render buffer");
284                         }
285                         else if (config.surfaceTypeBit == EGL_PBUFFER_BIT && renderBuffer != EGL_BACK_BUFFER)
286                         {
287                                 log << TestLog::Message << "  Fail, render buffer should be EGL_BACK_BUFFER for a pbuffer surface." << TestLog::EndMessage;
288                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid render buffer");
289                         }
290                         else if (config.surfaceTypeBit == EGL_WINDOW_BIT && renderBuffer != EGL_SINGLE_BUFFER && renderBuffer != EGL_BACK_BUFFER)
291                         {
292                                 log << TestLog::Message << "  Fail, render buffer should be either EGL_SINGLE_BUFFER or EGL_BACK_BUFFER for a window surface." << TestLog::EndMessage;
293                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid render buffer");
294                         }
295                 }
296
297                 enableLogging(false);
298
299                 log << TestLog::Message << "  Pass" << TestLog::EndMessage;
300         }
301 };
302
303 class QueryAPICase : public TestCase, private eglu::CallLogWrapper
304 {
305 public:
306         QueryAPICase (EglTestContext& eglTestCtx, const char* name, const char* description)
307                 : TestCase              (eglTestCtx, name, description)
308                 , CallLogWrapper(eglTestCtx.getLibrary(), eglTestCtx.getTestContext().getLog())
309         {
310         }
311
312         void init (void)
313         {
314                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
315         }
316
317         IterateResult iterate (void)
318         {
319                 const Library&                  egl                             = m_eglTestCtx.getLibrary();
320                 EGLDisplay                              display                 = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
321                 tcu::TestLog&                   log                             = m_testCtx.getLog();
322                 const EGLenum                   apis[]                  = { EGL_OPENGL_API, EGL_OPENGL_ES_API, EGL_OPENVG_API };
323                 const vector<EGLenum>   supportedAPIs   = eglu::getClientAPIs(egl, display);
324
325                 enableLogging(true);
326
327                 {
328                         const EGLenum   api     = eglQueryAPI();
329
330                         if (api != EGL_OPENGL_ES_API && (de::contains(supportedAPIs.begin(), supportedAPIs.end(), EGL_OPENGL_ES_API)))
331                         {
332                                 log << TestLog::Message << "  Fail, initial value should be EGL_OPENGL_ES_API if OpenGL ES is supported." << TestLog::EndMessage;
333                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid default value");
334                         }
335                         else if (api != EGL_NONE && !(de::contains(supportedAPIs.begin(), supportedAPIs.end(), EGL_OPENGL_ES_API)))
336                         {
337                                 log << TestLog::Message << "  Fail, initial value should be EGL_NONE if OpenGL ES is not supported." << TestLog::EndMessage;
338                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid default value");
339                         }
340                 }
341
342                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(apis); ndx++)
343                 {
344                         const EGLenum   api     = apis[ndx];
345
346                         log << TestLog::Message << TestLog::EndMessage;
347
348                         if (de::contains(supportedAPIs.begin(), supportedAPIs.end(), api))
349                         {
350                                 egl.bindAPI(api);
351
352                                 if (api != egl.queryAPI())
353                                 {
354                                         log << TestLog::Message << "  Fail, return value does not match previously bound API." << TestLog::EndMessage;
355                                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid return value");
356                                 }
357                         }
358                         else
359                         {
360                                 log << TestLog::Message << eglu::getAPIStr(api) << " not supported." << TestLog::EndMessage;
361                         }
362                 }
363
364                 enableLogging(false);
365                 eglTerminate(display);
366                 return STOP;
367         }
368 };
369
370 QueryContextTests::QueryContextTests (EglTestContext& eglTestCtx)
371         : TestCaseGroup(eglTestCtx, "query_context", "Rendering context query tests")
372 {
373 }
374
375 QueryContextTests::~QueryContextTests (void)
376 {
377 }
378
379 template<class QueryContextClass>
380 void createQueryContextGroups (EglTestContext& eglTestCtx, tcu::TestCaseGroup* group)
381 {
382         std::vector<RenderFilterList> filterLists;
383
384         getDefaultRenderFilterLists(filterLists, eglu::FilterList());
385
386         for (std::vector<RenderFilterList>::const_iterator listIter = filterLists.begin(); listIter != filterLists.end(); listIter++)
387                 group->addChild(new QueryContextClass(eglTestCtx, listIter->getName(), "", *listIter, listIter->getSurfaceTypeMask()));
388 }
389
390 void QueryContextTests::init (void)
391 {
392         {
393                 tcu::TestCaseGroup* simpleGroup = new tcu::TestCaseGroup(m_testCtx, "simple", "Simple API tests");
394                 addChild(simpleGroup);
395
396                 simpleGroup->addChild(new QueryAPICase(m_eglTestCtx, "query_api", "eglQueryAPI() test"));
397         }
398
399         // eglGetCurrentContext
400         {
401                 tcu::TestCaseGroup* getCurrentContextGroup = new tcu::TestCaseGroup(m_testCtx, "get_current_context", "eglGetCurrentContext() tests");
402                 addChild(getCurrentContextGroup);
403
404                 createQueryContextGroups<GetCurrentContextCase>(m_eglTestCtx, getCurrentContextGroup);
405         }
406
407         // eglGetCurrentSurface
408         {
409                 tcu::TestCaseGroup* getCurrentSurfaceGroup = new tcu::TestCaseGroup(m_testCtx, "get_current_surface", "eglGetCurrentSurface() tests");
410                 addChild(getCurrentSurfaceGroup);
411
412                 createQueryContextGroups<GetCurrentSurfaceCase>(m_eglTestCtx, getCurrentSurfaceGroup);
413         }
414
415         // eglGetCurrentDisplay
416         {
417                 tcu::TestCaseGroup* getCurrentDisplayGroup = new tcu::TestCaseGroup(m_testCtx, "get_current_display", "eglGetCurrentDisplay() tests");
418                 addChild(getCurrentDisplayGroup);
419
420                 createQueryContextGroups<GetCurrentDisplayCase>(m_eglTestCtx, getCurrentDisplayGroup);
421         }
422
423         // eglQueryContext
424         {
425                 tcu::TestCaseGroup* queryContextGroup = new tcu::TestCaseGroup(m_testCtx, "query_context", "eglQueryContext() tests");
426                 addChild(queryContextGroup);
427
428                 createQueryContextGroups<QueryContextCase>(m_eglTestCtx, queryContextGroup);
429         }
430 }
431
432 } // egl
433 } // deqp