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 DE_ASSERT(m_display == EGL_NO_DISPLAY); 128 129 m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay()); 130 m_supported = eglu::getClientExtensions(m_eglTestCtx.getLibrary(), m_display); 131 132 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 133 } 134 135 void GetProcAddressCase::deinit (void) 136 { 137 m_eglTestCtx.getLibrary().terminate(m_display); 138 m_display = EGL_NO_DISPLAY; 139 } 140 141 tcu::TestNode::IterateResult GetProcAddressCase::iterate (void) 142 { 143 enableLogging(true); 144 145 executeTest(); 146 147 enableLogging(false); 148 149 return STOP; 150 } 151 152 bool GetProcAddressCase::isSupported (const std::string& extName) 153 { 154 return de::contains(m_supported.begin(), m_supported.end(), extName); 155 } 156 157 // Test by extension 158 159 class GetProcAddressExtensionCase : public GetProcAddressCase 160 { 161 public: 162 GetProcAddressExtensionCase (EglTestContext& eglTestCtx, const char* name, const char* description, const std::string& extName) 163 : GetProcAddressCase (eglTestCtx, name, description) 164 , m_extName (extName) 165 { 166 } 167 168 virtual ~GetProcAddressExtensionCase (void) 169 { 170 } 171 172 void executeTest (void) 173 { 174 TestLog& log = m_testCtx.getLog(); 175 bool supported = isSupported(m_extName); 176 const FunctionNames funcNames = getExtFunctionNames(m_extName); 177 178 DE_ASSERT(funcNames.numFunctions > 0); 179 180 log << TestLog::Message << m_extName << ": " << (supported ? "supported" : "not supported") << TestLog::EndMessage; 181 log << TestLog::Message << TestLog::EndMessage; 182 183 for (int funcNdx = 0; funcNdx < funcNames.numFunctions; funcNdx++) 184 { 185 const char* funcName = funcNames.functions[funcNdx]; 186 void (*funcPtr)(void); 187 188 funcPtr = eglGetProcAddress(funcName); 189 eglu::checkError(eglGetError(), "eglGetProcAddress()", __FILE__, __LINE__); 190 191 if (supported && funcPtr == 0) 192 { 193 log << TestLog::Message << "Fail, received null pointer for supported extension function: " << funcName << TestLog::EndMessage; 194 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected null pointer"); 195 } 196 } 197 } 198 199 private: 200 std::string m_extName; 201 }; 202 203 // Test core functions 204 205 class GetProcAddressCoreFunctionsCase : public GetProcAddressCase 206 { 207 public: 208 GetProcAddressCoreFunctionsCase (EglTestContext& eglTestCtx, const char* name, const char* description, const EGLint apiBit) 209 : GetProcAddressCase (eglTestCtx, name, description) 210 , m_apiBit (apiBit) 211 { 212 } 213 214 virtual ~GetProcAddressCoreFunctionsCase (void) 215 { 216 } 217 218 void executeTest (void) 219 { 220 TestLog& log = m_testCtx.getLog(); 221 const bool funcPtrSupported = isSupported("EGL_KHR_get_all_proc_addresses"); 222 const bool apiSupported = (eglu::getRenderableAPIsMask(m_eglTestCtx.getLibrary(), m_display) & m_apiBit) == m_apiBit; 223 const FunctionNames funcNames = getCoreFunctionNames(m_apiBit); 224 225 log << TestLog::Message << "EGL_KHR_get_all_proc_addresses: " << (funcPtrSupported ? "supported" : "not supported") << TestLog::EndMessage; 226 log << TestLog::Message << TestLog::EndMessage; 227 228 if (!apiSupported) 229 { 230 log << TestLog::Message << eglu::getConfigAttribValueStr(EGL_RENDERABLE_TYPE, m_apiBit) << " not supported by any available configuration." << TestLog::EndMessage; 231 log << TestLog::Message << TestLog::EndMessage; 232 } 233 234 for (int funcNdx = 0; funcNdx < funcNames.numFunctions; funcNdx++) 235 { 236 const char* funcName = funcNames.functions[funcNdx]; 237 void (*funcPtr)(void); 238 239 funcPtr = eglGetProcAddress(funcName); 240 eglu::checkError(eglGetError(), "eglGetProcAddress()", __FILE__, __LINE__); 241 242 if (apiSupported && funcPtrSupported && (funcPtr == 0)) 243 { 244 log << TestLog::Message << "Fail, received null pointer for supported function: " << funcName << TestLog::EndMessage; 245 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected null pointer"); 246 } 247 else if (!apiSupported && (funcPtr != 0)) 248 { 249 log << TestLog::Message << "Warning, received non-null value for unsupported function: " << funcName << TestLog::EndMessage; 250 m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Non-null value for unsupported function"); 251 } 252 } 253 } 254 255 private: 256 const EGLint m_apiBit; 257 }; 258 259 GetProcAddressTests::GetProcAddressTests (EglTestContext& eglTestCtx) 260 : TestCaseGroup(eglTestCtx, "get_proc_address", "eglGetProcAddress() tests") 261 { 262 } 263 264 GetProcAddressTests::~GetProcAddressTests (void) 265 { 266 } 267 268 void GetProcAddressTests::init (void) 269 { 270 // extensions 271 { 272 tcu::TestCaseGroup* extensionsGroup = new tcu::TestCaseGroup(m_testCtx, "extension", "Test EGL extensions"); 273 addChild(extensionsGroup); 274 275 for (int extNdx = 0; extNdx < DE_LENGTH_OF_ARRAY(s_extensions); extNdx++) 276 { 277 const std::string& extName = s_extensions[extNdx].name; 278 std::string testName (extName); 279 280 for (size_t ndx = 0; ndx < extName.length(); ndx++) 281 testName[ndx] = de::toLower(extName[ndx]); 282 283 extensionsGroup->addChild(new GetProcAddressExtensionCase(m_eglTestCtx, testName.c_str(), ("Test " + extName).c_str(), extName)); 284 } 285 } 286 287 // core functions 288 { 289 tcu::TestCaseGroup* coreFuncGroup = new tcu::TestCaseGroup(m_testCtx, "core", "Test core functions"); 290 addChild(coreFuncGroup); 291 292 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase (m_eglTestCtx, "egl", "Test EGL core functions", 0)); 293 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase (m_eglTestCtx, "gles", "Test OpenGL ES core functions", EGL_OPENGL_ES_BIT)); 294 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase (m_eglTestCtx, "gles2", "Test OpenGL ES 2 core functions", EGL_OPENGL_ES2_BIT)); 295 coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase (m_eglTestCtx, "gles3", "Test OpenGL ES 3 core functions", EGL_OPENGL_ES3_BIT_KHR)); 296 } 297 } 298 299 } // egl 300 } // deqp 301