Merge vk-gl-cts/vulkan-cts-1.1.3 into vk-gl-cts/vulkan-cts-1.1.4
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglGetProcAddressTests.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 Extension function pointer query tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "teglGetProcAddressTests.hpp"
25 #include "teglTestCase.hpp"
26 #include "egluCallLogWrapper.hpp"
27 #include "egluStrUtil.hpp"
28 #include "egluUtil.hpp"
29 #include "eglwLibrary.hpp"
30 #include "eglwEnums.hpp"
31 #include "tcuTestLog.hpp"
32 #include "deSTLUtil.hpp"
33 #include "deStringUtil.hpp"
34
35 namespace deqp
36 {
37 namespace egl
38 {
39
40 namespace
41 {
42
43 #define EGL_MAKE_VERSION(major, minor) (((major) << 12) | (minor))
44
45 using tcu::TestLog;
46 using namespace eglw;
47
48 // Function name strings generated from API headers
49
50 #include "teglGetProcAddressTests.inl"
51
52 struct FunctionNames
53 {
54         int                                     numFunctions;
55         const char* const*      functions;
56
57         FunctionNames (int numFunctions_, const char* const* functions_)
58                 : numFunctions  (numFunctions_)
59                 , functions             (functions_)
60         {
61         }
62 };
63
64 FunctionNames getExtFunctionNames (const std::string& extName)
65 {
66         for (int ndx = 0; ndx <= DE_LENGTH_OF_ARRAY(s_extensions); ndx++)
67         {
68                 if (extName == s_extensions[ndx].name)
69                         return FunctionNames(s_extensions[ndx].numFunctions, s_extensions[ndx].functions);
70         }
71
72         DE_ASSERT(false);
73         return FunctionNames(0, DE_NULL);
74 }
75
76 } // anonymous
77
78 // Base class for eglGetProcAddress() test cases
79
80 class GetProcAddressCase : public TestCase, protected eglu::CallLogWrapper
81 {
82 public:
83                                                                 GetProcAddressCase              (EglTestContext& eglTestCtx, const char* name, const char* description);
84         virtual                                         ~GetProcAddressCase             (void);
85
86         void                                            init                                    (void);
87         void                                            deinit                                  (void);
88         IterateResult                           iterate                                 (void);
89
90         bool                                            isSupported                             (const std::string& extName);
91
92         virtual void                            executeTest                             (void) = 0;
93
94 protected:
95         EGLDisplay                                      m_display;
96         int                                                     m_eglVersion;
97
98 private:
99         std::vector<std::string>        m_supported;
100 };
101
102 GetProcAddressCase::GetProcAddressCase (EglTestContext& eglTestCtx, const char* name, const char* description)
103         : TestCase                      (eglTestCtx, name, description)
104         , CallLogWrapper        (eglTestCtx.getLibrary(), eglTestCtx.getTestContext().getLog())
105         , m_display                     (EGL_NO_DISPLAY)
106 {
107 }
108
109 GetProcAddressCase::~GetProcAddressCase (void)
110 {
111 }
112
113 void GetProcAddressCase::init (void)
114 {
115         try
116         {
117                 m_supported = eglu::getClientExtensions(m_eglTestCtx.getLibrary());
118         }
119         catch (const tcu::NotSupportedError& error)
120         {
121                 // Ignore case where EGL client extensions are not supported
122                 // that's okay for these tests.
123         }
124
125         DE_ASSERT(m_display == EGL_NO_DISPLAY);
126
127         m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
128
129         // The EGL_VERSION string is laid out as follows:
130         // major_version.minor_version space vendor_specific_info
131         // Split version from vendor_specific_info
132         std::vector<std::string> tokens = de::splitString(eglQueryString(m_display, EGL_VERSION), ' ');
133         // split version into major & minor
134         std::vector<std::string> values = de::splitString(tokens[0], '.');
135         m_eglVersion = EGL_MAKE_VERSION(atoi(values[0].c_str()), atoi(values[1].c_str()));
136
137         {
138                 const std::vector<std::string> displayExtensios = eglu::getDisplayExtensions(m_eglTestCtx.getLibrary(), m_display);
139                 m_supported.insert(m_supported.end(), displayExtensios.begin(), displayExtensios.end());
140         }
141
142         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
143 }
144
145 void GetProcAddressCase::deinit (void)
146 {
147         m_eglTestCtx.getLibrary().terminate(m_display);
148         m_display = EGL_NO_DISPLAY;
149 }
150
151 tcu::TestNode::IterateResult GetProcAddressCase::iterate (void)
152 {
153         enableLogging(true);
154
155         executeTest();
156
157         enableLogging(false);
158
159         return STOP;
160 }
161
162 bool GetProcAddressCase::isSupported (const std::string& extName)
163 {
164         return de::contains(m_supported.begin(), m_supported.end(), extName);
165 }
166
167 // Test by extension
168
169 class GetProcAddressExtensionCase : public GetProcAddressCase
170 {
171 public:
172         GetProcAddressExtensionCase (EglTestContext& eglTestCtx, const char* name, const char* description, const std::string& extName)
173                 : GetProcAddressCase    (eglTestCtx, name, description)
174                 , m_extName                             (extName)
175         {
176         }
177
178         virtual ~GetProcAddressExtensionCase (void)
179         {
180         }
181
182         void executeTest (void)
183         {
184                 TestLog&                                log                     = m_testCtx.getLog();
185                 bool                                    supported       = isSupported(m_extName);
186                 const FunctionNames             funcNames       = getExtFunctionNames(m_extName);
187
188                 DE_ASSERT(funcNames.numFunctions > 0);
189
190                 log << TestLog::Message << m_extName << ": " << (supported ? "supported" : "not supported") << TestLog::EndMessage;
191                 log << TestLog::Message << TestLog::EndMessage;
192
193                 for (int funcNdx = 0; funcNdx < funcNames.numFunctions; funcNdx++)
194                 {
195                         const char*     funcName                = funcNames.functions[funcNdx];
196                         void            (*funcPtr)(void);
197
198                         funcPtr = eglGetProcAddress(funcName);
199                         eglu::checkError(eglGetError(), "eglGetProcAddress()", __FILE__, __LINE__);
200
201                         if (supported && funcPtr == 0)
202                         {
203                                 log << TestLog::Message << "Fail, received null pointer for supported extension function: " << funcName << TestLog::EndMessage;
204                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected null pointer");
205                         }
206                 }
207         }
208
209 private:
210         std::string     m_extName;
211 };
212
213 // Test core functions
214
215 class GetProcAddressCoreFunctionsCase : public GetProcAddressCase
216 {
217 public:
218         enum ApiType
219         {
220                 EGL14,
221                 EGL15,
222                 GLES,
223                 GLES2,
224                 GLES3
225         };
226
227         GetProcAddressCoreFunctionsCase (EglTestContext& eglTestCtx, const char* name, const char* description, const ApiType apiType)
228                 : GetProcAddressCase    (eglTestCtx, name, description)
229                 , m_apiType                             (apiType)
230         {
231         }
232
233         virtual ~GetProcAddressCoreFunctionsCase (void)
234         {
235         }
236
237         EGLint RenderableType (ApiType type)
238         {
239                 EGLint  renderableType = EGL_OPENGL_ES_BIT;
240                 switch (type) {
241                         case EGL14:
242                         case EGL15:
243                         case GLES:
244                                 renderableType = EGL_OPENGL_ES_BIT;
245                                 break;
246                         case GLES2:
247                                 renderableType = EGL_OPENGL_ES2_BIT;
248                                 break;
249                         case GLES3:
250                                 renderableType = EGL_OPENGL_ES3_BIT_KHR;
251                                 break;
252                 }
253                 return renderableType;
254         }
255
256         bool isApiSupported (void)
257         {
258                 EGLint  renderableType = EGL_OPENGL_ES_BIT;
259                 switch (m_apiType) {
260                         case EGL14:
261                                 if (m_eglVersion >= EGL_MAKE_VERSION(1, 4)) return true;
262                                 return false;
263                                 break;
264                         case EGL15:
265                                 // With Android Q, EGL 1.5 entry points must have valid
266                                 // GetProcAddress.
267                                 if (m_eglVersion >= EGL_MAKE_VERSION(1, 5)) return true;
268                                 return false;
269                                 break;
270                         case GLES:
271                         case GLES2:
272                         case GLES3:
273                                 renderableType = RenderableType(m_apiType);
274                                 break;
275                 }
276                 return (eglu::getRenderableAPIsMask(m_eglTestCtx.getLibrary(), m_display) & renderableType) == renderableType;
277         }
278
279         FunctionNames getCoreFunctionNames (EGLint apiType)
280         {
281                 switch (apiType)
282                 {
283                         case EGL14:                             return FunctionNames(DE_LENGTH_OF_ARRAY(s_EGL14),       s_EGL14);
284                         case EGL15:                             return FunctionNames(DE_LENGTH_OF_ARRAY(s_EGL15),       s_EGL15);
285                         case GLES       :                       return FunctionNames(DE_LENGTH_OF_ARRAY(s_GLES10),      s_GLES10);
286                         case GLES2:                             return FunctionNames(DE_LENGTH_OF_ARRAY(s_GLES20),      s_GLES20);
287                         case GLES3:                     return FunctionNames(DE_LENGTH_OF_ARRAY(s_GLES30),      s_GLES30);
288                         default:
289                                 DE_ASSERT(false);
290                 }
291
292                 return FunctionNames(0, DE_NULL);
293         }
294
295         void executeTest (void)
296         {
297                 TestLog&                                log                                     = m_testCtx.getLog();
298                 const bool                              funcPtrSupported        = isSupported("EGL_KHR_get_all_proc_addresses");
299                 const bool                              apiSupported            = isApiSupported();
300                 const FunctionNames             funcNames                       = getCoreFunctionNames(m_apiType);
301
302                 log << TestLog::Message << "EGL_KHR_get_all_proc_addresses: " << (funcPtrSupported ? "supported" : "not supported") << TestLog::EndMessage;
303                 log << TestLog::Message << TestLog::EndMessage;
304
305                 if (!apiSupported)
306                 {
307                         switch (m_apiType)
308                         {
309                                 case EGL14:
310                                         log << TestLog::Message << " EGL not supported by any available configuration." << TestLog::EndMessage;
311                                         break;
312                                 case EGL15:
313                                         log << TestLog::Message << " EGL 1.5 not supported by any available configuration." << TestLog::EndMessage;
314                                         break;
315                                 case GLES:
316                                 case GLES2:
317                                 case GLES3:
318                                         log << TestLog::Message << eglu::getConfigAttribValueStr(EGL_RENDERABLE_TYPE, RenderableType(m_apiType)) << " not supported by any available configuration." << TestLog::EndMessage;
319                                         break;
320                         }
321                         log << TestLog::Message << TestLog::EndMessage;
322                 }
323
324                 for (int funcNdx = 0; funcNdx < funcNames.numFunctions; funcNdx++)
325                 {
326                         const char*     funcName                        = funcNames.functions[funcNdx];
327                         void            (*funcPtr)(void);
328
329                         funcPtr = eglGetProcAddress(funcName);
330                         eglu::checkError(eglGetError(), "eglGetProcAddress()", __FILE__, __LINE__);
331
332                         if (apiSupported && funcPtrSupported && (funcPtr == 0))
333                         {
334                                 log << TestLog::Message << "Fail, received null pointer for supported function: " << funcName << TestLog::EndMessage;
335                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected null pointer");
336                         }
337                         else if (!apiSupported && (funcPtr != 0))
338                         {
339                                 log << TestLog::Message << "Warning, received non-null value for unsupported function: " << funcName << TestLog::EndMessage;
340                                 m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Non-null value for unsupported function");
341                         }
342                 }
343         }
344
345 private:
346         const ApiType   m_apiType;
347 };
348
349 GetProcAddressTests::GetProcAddressTests (EglTestContext& eglTestCtx)
350         : TestCaseGroup(eglTestCtx, "get_proc_address", "eglGetProcAddress() tests")
351 {
352 }
353
354 GetProcAddressTests::~GetProcAddressTests (void)
355 {
356 }
357
358 void GetProcAddressTests::init (void)
359 {
360         // extensions
361         {
362                 tcu::TestCaseGroup* extensionsGroup = new tcu::TestCaseGroup(m_testCtx, "extension", "Test EGL extensions");
363                 addChild(extensionsGroup);
364
365                 for (int extNdx = 0; extNdx < DE_LENGTH_OF_ARRAY(s_extensions); extNdx++)
366                 {
367                         const std::string&              extName         = s_extensions[extNdx].name;
368                         std::string                             testName        (extName);
369
370                         for (size_t ndx = 0; ndx < extName.length(); ndx++)
371                                 testName[ndx] = de::toLower(extName[ndx]);
372
373                         extensionsGroup->addChild(new GetProcAddressExtensionCase(m_eglTestCtx, testName.c_str(), ("Test " + extName).c_str(), extName));
374                 }
375         }
376
377         // core functions
378         {
379                 tcu::TestCaseGroup* coreFuncGroup = new tcu::TestCaseGroup(m_testCtx, "core", "Test core functions");
380                 addChild(coreFuncGroup);
381
382                 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase     (m_eglTestCtx,  "egl",          "Test EGL core functions",                      GetProcAddressCoreFunctionsCase::EGL14));
383
384                 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase     (m_eglTestCtx,  "egl15",        "Test EGL 1.5 functions",                       GetProcAddressCoreFunctionsCase::EGL15));
385                 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase     (m_eglTestCtx,  "gles",         "Test OpenGL ES core functions",        GetProcAddressCoreFunctionsCase::GLES));
386                 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase     (m_eglTestCtx,  "gles2",        "Test OpenGL ES 2 core functions",      GetProcAddressCoreFunctionsCase::GLES2));
387                 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase     (m_eglTestCtx,  "gles3",        "Test OpenGL ES 3 core functions",      GetProcAddressCoreFunctionsCase::GLES3));
388         }
389 }
390
391 } // egl
392 } // deqp