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 / 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&)
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                                 return m_eglVersion >= EGL_MAKE_VERSION(1, 4);
262                         case EGL15:
263                                 // With Android Q, EGL 1.5 entry points must have valid
264                                 // GetProcAddress.
265                                 return m_eglVersion >= EGL_MAKE_VERSION(1, 5);
266                         case GLES:
267                         case GLES2:
268                         case GLES3:
269                                 renderableType = RenderableType(m_apiType);
270                                 break;
271                 }
272                 return (eglu::getRenderableAPIsMask(m_eglTestCtx.getLibrary(), m_display) & renderableType) == renderableType;
273         }
274
275         FunctionNames getCoreFunctionNames (EGLint apiType)
276         {
277                 switch (apiType)
278                 {
279                         case EGL14:                             return FunctionNames(DE_LENGTH_OF_ARRAY(s_EGL14),       s_EGL14);
280                         case EGL15:                             return FunctionNames(DE_LENGTH_OF_ARRAY(s_EGL15),       s_EGL15);
281                         case GLES       :                       return FunctionNames(DE_LENGTH_OF_ARRAY(s_GLES10),      s_GLES10);
282                         case GLES2:                             return FunctionNames(DE_LENGTH_OF_ARRAY(s_GLES20),      s_GLES20);
283                         case GLES3:                     return FunctionNames(DE_LENGTH_OF_ARRAY(s_GLES30),      s_GLES30);
284                         default:
285                                 DE_ASSERT(false);
286                 }
287
288                 return FunctionNames(0, DE_NULL);
289         }
290
291         void executeTest (void)
292         {
293                 TestLog&                                log                                     = m_testCtx.getLog();
294                 const bool                              funcPtrSupported        = isSupported("EGL_KHR_get_all_proc_addresses");
295                 const bool                              apiSupported            = isApiSupported();
296                 const FunctionNames             funcNames                       = getCoreFunctionNames(m_apiType);
297
298                 log << TestLog::Message << "EGL_KHR_get_all_proc_addresses: " << (funcPtrSupported ? "supported" : "not supported") << TestLog::EndMessage;
299                 log << TestLog::Message << TestLog::EndMessage;
300
301                 if (!apiSupported)
302                 {
303                         switch (m_apiType)
304                         {
305                                 case EGL14:
306                                         log << TestLog::Message << " EGL not supported by any available configuration." << TestLog::EndMessage;
307                                         break;
308                                 case EGL15:
309                                         log << TestLog::Message << " EGL 1.5 not supported by any available configuration." << TestLog::EndMessage;
310                                         break;
311                                 case GLES:
312                                 case GLES2:
313                                 case GLES3:
314                                         log << TestLog::Message << eglu::getConfigAttribValueStr(EGL_RENDERABLE_TYPE, RenderableType(m_apiType)) << " not supported by any available configuration." << TestLog::EndMessage;
315                                         break;
316                         }
317                         log << TestLog::Message << TestLog::EndMessage;
318                 }
319
320                 for (int funcNdx = 0; funcNdx < funcNames.numFunctions; funcNdx++)
321                 {
322                         const char*     funcName                        = funcNames.functions[funcNdx];
323                         void            (*funcPtr)(void);
324
325                         funcPtr = eglGetProcAddress(funcName);
326                         eglu::checkError(eglGetError(), "eglGetProcAddress()", __FILE__, __LINE__);
327
328                         if (apiSupported && funcPtrSupported && (funcPtr == 0))
329                         {
330                                 log << TestLog::Message << "Fail, received null pointer for supported function: " << funcName << TestLog::EndMessage;
331                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected null pointer");
332                         }
333                         else if (!apiSupported && (funcPtr != 0))
334                         {
335                                 log << TestLog::Message << "Warning, received non-null value for unsupported function: " << funcName << TestLog::EndMessage;
336                                 m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Non-null value for unsupported function");
337                         }
338                 }
339         }
340
341 private:
342         const ApiType   m_apiType;
343 };
344
345 GetProcAddressTests::GetProcAddressTests (EglTestContext& eglTestCtx)
346         : TestCaseGroup(eglTestCtx, "get_proc_address", "eglGetProcAddress() tests")
347 {
348 }
349
350 GetProcAddressTests::~GetProcAddressTests (void)
351 {
352 }
353
354 void GetProcAddressTests::init (void)
355 {
356         // extensions
357         {
358                 tcu::TestCaseGroup* extensionsGroup = new tcu::TestCaseGroup(m_testCtx, "extension", "Test EGL extensions");
359                 addChild(extensionsGroup);
360
361                 for (int extNdx = 0; extNdx < DE_LENGTH_OF_ARRAY(s_extensions); extNdx++)
362                 {
363                         const std::string&              extName         = s_extensions[extNdx].name;
364                         std::string                             testName        (extName);
365
366                         for (size_t ndx = 0; ndx < extName.length(); ndx++)
367                                 testName[ndx] = de::toLower(extName[ndx]);
368
369                         extensionsGroup->addChild(new GetProcAddressExtensionCase(m_eglTestCtx, testName.c_str(), ("Test " + extName).c_str(), extName));
370                 }
371         }
372
373         // core functions
374         {
375                 tcu::TestCaseGroup* coreFuncGroup = new tcu::TestCaseGroup(m_testCtx, "core", "Test core functions");
376                 addChild(coreFuncGroup);
377
378                 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase     (m_eglTestCtx,  "egl",          "Test EGL core functions",                      GetProcAddressCoreFunctionsCase::EGL14));
379
380                 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase     (m_eglTestCtx,  "egl15",        "Test EGL 1.5 functions",                       GetProcAddressCoreFunctionsCase::EGL15));
381                 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase     (m_eglTestCtx,  "gles",         "Test OpenGL ES core functions",        GetProcAddressCoreFunctionsCase::GLES));
382                 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase     (m_eglTestCtx,  "gles2",        "Test OpenGL ES 2 core functions",      GetProcAddressCoreFunctionsCase::GLES2));
383                 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase     (m_eglTestCtx,  "gles3",        "Test OpenGL ES 3 core functions",      GetProcAddressCoreFunctionsCase::GLES3));
384         }
385 }
386
387 } // egl
388 } // deqp