Merge vulkan-cts-1.0 to master
[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 using tcu::TestLog;
44 using namespace eglw;
45
46 // Function name strings generated from API headers
47
48 #include "teglGetProcAddressTests.inl"
49
50 struct FunctionNames
51 {
52         int                                     numFunctions;
53         const char* const*      functions;
54
55         FunctionNames (int numFunctions_, const char* const* functions_)
56                 : numFunctions  (numFunctions_)
57                 , functions             (functions_)
58         {
59         }
60 };
61
62 FunctionNames getExtFunctionNames (const std::string& extName)
63 {
64         for (int ndx = 0; ndx <= DE_LENGTH_OF_ARRAY(s_extensions); ndx++)
65         {
66                 if (extName == s_extensions[ndx].name)
67                         return FunctionNames(s_extensions[ndx].numFunctions, s_extensions[ndx].functions);
68         }
69
70         DE_ASSERT(false);
71         return FunctionNames(0, DE_NULL);
72 }
73
74 FunctionNames getCoreFunctionNames (EGLint apiBit)
75 {
76         switch (apiBit)
77         {
78                 case 0:                                                 return FunctionNames(DE_LENGTH_OF_ARRAY(s_EGL14),       s_EGL14);
79                 case EGL_OPENGL_ES_BIT:                 return FunctionNames(DE_LENGTH_OF_ARRAY(s_GLES10),      s_GLES10);
80                 case EGL_OPENGL_ES2_BIT:                return FunctionNames(DE_LENGTH_OF_ARRAY(s_GLES20),      s_GLES20);
81                 case EGL_OPENGL_ES3_BIT_KHR:    return FunctionNames(DE_LENGTH_OF_ARRAY(s_GLES30),      s_GLES30);
82                 default:
83                         DE_ASSERT(false);
84         }
85
86         return FunctionNames(0, DE_NULL);
87 }
88
89 } // anonymous
90
91 // Base class for eglGetProcAddress() test cases
92
93 class GetProcAddressCase : public TestCase, protected eglu::CallLogWrapper
94 {
95 public:
96                                                                 GetProcAddressCase              (EglTestContext& eglTestCtx, const char* name, const char* description);
97         virtual                                         ~GetProcAddressCase             (void);
98
99         void                                            init                                    (void);
100         void                                            deinit                                  (void);
101         IterateResult                           iterate                                 (void);
102
103         bool                                            isSupported                             (const std::string& extName);
104
105         virtual void                            executeTest                             (void) = 0;
106
107 protected:
108         EGLDisplay                                      m_display;
109
110 private:
111         std::vector<std::string>        m_supported;
112 };
113
114 GetProcAddressCase::GetProcAddressCase (EglTestContext& eglTestCtx, const char* name, const char* description)
115         : TestCase                      (eglTestCtx, name, description)
116         , CallLogWrapper        (eglTestCtx.getLibrary(), eglTestCtx.getTestContext().getLog())
117         , m_display                     (EGL_NO_DISPLAY)
118 {
119 }
120
121 GetProcAddressCase::~GetProcAddressCase (void)
122 {
123 }
124
125 void GetProcAddressCase::init (void)
126 {
127         try
128         {
129                 m_supported = eglu::getClientExtensions(m_eglTestCtx.getLibrary());
130         }
131         catch (const eglu::Error& error)
132         {
133                 // EGL_BAD_DISPLAY is generated if client extensions are not supported.
134                 if (error.getError() != EGL_BAD_DISPLAY)
135                         throw;
136         }
137
138         DE_ASSERT(m_display == EGL_NO_DISPLAY);
139
140         m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
141
142         {
143                 const std::vector<std::string> displayExtensios = eglu::getDisplayExtensions(m_eglTestCtx.getLibrary(), m_display);
144                 m_supported.insert(m_supported.end(), displayExtensios.begin(), displayExtensios.end());
145         }
146
147         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
148 }
149
150 void GetProcAddressCase::deinit (void)
151 {
152         m_eglTestCtx.getLibrary().terminate(m_display);
153         m_display = EGL_NO_DISPLAY;
154 }
155
156 tcu::TestNode::IterateResult GetProcAddressCase::iterate (void)
157 {
158         enableLogging(true);
159
160         executeTest();
161
162         enableLogging(false);
163
164         return STOP;
165 }
166
167 bool GetProcAddressCase::isSupported (const std::string& extName)
168 {
169         return de::contains(m_supported.begin(), m_supported.end(), extName);
170 }
171
172 // Test by extension
173
174 class GetProcAddressExtensionCase : public GetProcAddressCase
175 {
176 public:
177         GetProcAddressExtensionCase (EglTestContext& eglTestCtx, const char* name, const char* description, const std::string& extName)
178                 : GetProcAddressCase    (eglTestCtx, name, description)
179                 , m_extName                             (extName)
180         {
181         }
182
183         virtual ~GetProcAddressExtensionCase (void)
184         {
185         }
186
187         void executeTest (void)
188         {
189                 TestLog&                                log                     = m_testCtx.getLog();
190                 bool                                    supported       = isSupported(m_extName);
191                 const FunctionNames             funcNames       = getExtFunctionNames(m_extName);
192
193                 DE_ASSERT(funcNames.numFunctions > 0);
194
195                 log << TestLog::Message << m_extName << ": " << (supported ? "supported" : "not supported") << TestLog::EndMessage;
196                 log << TestLog::Message << TestLog::EndMessage;
197
198                 for (int funcNdx = 0; funcNdx < funcNames.numFunctions; funcNdx++)
199                 {
200                         const char*     funcName                = funcNames.functions[funcNdx];
201                         void            (*funcPtr)(void);
202
203                         funcPtr = eglGetProcAddress(funcName);
204                         eglu::checkError(eglGetError(), "eglGetProcAddress()", __FILE__, __LINE__);
205
206                         if (supported && funcPtr == 0)
207                         {
208                                 log << TestLog::Message << "Fail, received null pointer for supported extension function: " << funcName << TestLog::EndMessage;
209                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected null pointer");
210                         }
211                 }
212         }
213
214 private:
215         std::string     m_extName;
216 };
217
218 // Test core functions
219
220 class GetProcAddressCoreFunctionsCase : public GetProcAddressCase
221 {
222 public:
223         GetProcAddressCoreFunctionsCase (EglTestContext& eglTestCtx, const char* name, const char* description, const EGLint apiBit)
224                 : GetProcAddressCase    (eglTestCtx, name, description)
225                 , m_apiBit                              (apiBit)
226         {
227         }
228
229         virtual ~GetProcAddressCoreFunctionsCase (void)
230         {
231         }
232
233         void executeTest (void)
234         {
235                 TestLog&                                log                                     = m_testCtx.getLog();
236                 const bool                              funcPtrSupported        = isSupported("EGL_KHR_get_all_proc_addresses");
237                 const bool                              apiSupported            = (eglu::getRenderableAPIsMask(m_eglTestCtx.getLibrary(), m_display) & m_apiBit) == m_apiBit;
238                 const FunctionNames             funcNames                       = getCoreFunctionNames(m_apiBit);
239
240                 log << TestLog::Message << "EGL_KHR_get_all_proc_addresses: " << (funcPtrSupported ? "supported" : "not supported") << TestLog::EndMessage;
241                 log << TestLog::Message << TestLog::EndMessage;
242
243                 if (!apiSupported)
244                 {
245                         log << TestLog::Message << eglu::getConfigAttribValueStr(EGL_RENDERABLE_TYPE, m_apiBit) << " not supported by any available configuration." << TestLog::EndMessage;
246                         log << TestLog::Message << TestLog::EndMessage;
247                 }
248
249                 for (int funcNdx = 0; funcNdx < funcNames.numFunctions; funcNdx++)
250                 {
251                         const char*     funcName                        = funcNames.functions[funcNdx];
252                         void            (*funcPtr)(void);
253
254                         funcPtr = eglGetProcAddress(funcName);
255                         eglu::checkError(eglGetError(), "eglGetProcAddress()", __FILE__, __LINE__);
256
257                         if (apiSupported && funcPtrSupported && (funcPtr == 0))
258                         {
259                                 log << TestLog::Message << "Fail, received null pointer for supported function: " << funcName << TestLog::EndMessage;
260                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected null pointer");
261                         }
262                         else if (!apiSupported && (funcPtr != 0))
263                         {
264                                 log << TestLog::Message << "Warning, received non-null value for unsupported function: " << funcName << TestLog::EndMessage;
265                                 m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Non-null value for unsupported function");
266                         }
267                 }
268         }
269
270 private:
271         const EGLint    m_apiBit;
272 };
273
274 GetProcAddressTests::GetProcAddressTests (EglTestContext& eglTestCtx)
275         : TestCaseGroup(eglTestCtx, "get_proc_address", "eglGetProcAddress() tests")
276 {
277 }
278
279 GetProcAddressTests::~GetProcAddressTests (void)
280 {
281 }
282
283 void GetProcAddressTests::init (void)
284 {
285         // extensions
286         {
287                 tcu::TestCaseGroup* extensionsGroup = new tcu::TestCaseGroup(m_testCtx, "extension", "Test EGL extensions");
288                 addChild(extensionsGroup);
289
290                 for (int extNdx = 0; extNdx < DE_LENGTH_OF_ARRAY(s_extensions); extNdx++)
291                 {
292                         const std::string&              extName         = s_extensions[extNdx].name;
293                         std::string                             testName        (extName);
294
295                         for (size_t ndx = 0; ndx < extName.length(); ndx++)
296                                 testName[ndx] = de::toLower(extName[ndx]);
297
298                         extensionsGroup->addChild(new GetProcAddressExtensionCase(m_eglTestCtx, testName.c_str(), ("Test " + extName).c_str(), extName));
299                 }
300         }
301
302         // core functions
303         {
304                 tcu::TestCaseGroup* coreFuncGroup = new tcu::TestCaseGroup(m_testCtx, "core", "Test core functions");
305                 addChild(coreFuncGroup);
306
307                 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase     (m_eglTestCtx,  "egl",          "Test EGL core functions",                      0));
308                 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase     (m_eglTestCtx,  "gles",         "Test OpenGL ES core functions",        EGL_OPENGL_ES_BIT));
309                 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase     (m_eglTestCtx,  "gles2",        "Test OpenGL ES 2 core functions",      EGL_OPENGL_ES2_BIT));
310                 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase     (m_eglTestCtx,  "gles3",        "Test OpenGL ES 3 core functions",      EGL_OPENGL_ES3_BIT_KHR));
311         }
312 }
313
314 } // egl
315 } // deqp