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 35namespace deqp 36{ 37namespace egl 38{ 39 40namespace 41{ 42 43using tcu::TestLog; 44using namespace eglw; 45 46// Function name strings generated from API headers 47 48#include "teglGetProcAddressTests.inl" 49 50struct 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 62FunctionNames 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 74FunctionNames 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 93class GetProcAddressCase : public TestCase, protected eglu::CallLogWrapper 94{ 95public: 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 107protected: 108 EGLDisplay m_display; 109 110private: 111 std::vector<std::string> m_supported; 112}; 113 114GetProcAddressCase::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 121GetProcAddressCase::~GetProcAddressCase (void) 122{ 123} 124 125void 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 135void GetProcAddressCase::deinit (void) 136{ 137 m_eglTestCtx.getLibrary().terminate(m_display); 138 m_display = EGL_NO_DISPLAY; 139} 140 141tcu::TestNode::IterateResult GetProcAddressCase::iterate (void) 142{ 143 enableLogging(true); 144 145 executeTest(); 146 147 enableLogging(false); 148 149 return STOP; 150} 151 152bool 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 159class GetProcAddressExtensionCase : public GetProcAddressCase 160{ 161public: 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 199private: 200 std::string m_extName; 201}; 202 203// Test core functions 204 205class GetProcAddressCoreFunctionsCase : public GetProcAddressCase 206{ 207public: 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 255private: 256 const EGLint m_apiBit; 257}; 258 259GetProcAddressTests::GetProcAddressTests (EglTestContext& eglTestCtx) 260 : TestCaseGroup(eglTestCtx, "get_proc_address", "eglGetProcAddress() tests") 261{ 262} 263 264GetProcAddressTests::~GetProcAddressTests (void) 265{ 266} 267 268void 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