Home | History | Annotate | Download | only in egl
      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 "tcuTestLog.hpp"
     29 
     30 #include <vector>
     31 #include <string>
     32 #include <algorithm>
     33 #include <cctype>
     34 
     35 #if !defined(EGL_OPENGL_ES3_BIT_KHR)
     36 #	define EGL_OPENGL_ES3_BIT_KHR	0x0040
     37 #endif
     38 
     39 using tcu::TestLog;
     40 
     41 namespace deqp
     42 {
     43 namespace egl
     44 {
     45 
     46 namespace
     47 {
     48 
     49 // Function name strings generated from API headers
     50 
     51 #include "teglGetProcAddressTests.inl"
     52 
     53 std::vector<std::string> makeStringVector (const char** cStrArray)
     54 {
     55 	std::vector<std::string>	out;
     56 
     57 	for (int ndx = 0; cStrArray[ndx] != DE_NULL; ndx++)
     58 	{
     59 		out.push_back(std::string(cStrArray[ndx]));
     60 	}
     61 
     62 	return out;
     63 }
     64 
     65 std::vector<std::string> getExtensionNames (void)
     66 {
     67 	return makeStringVector(getExtensionStrs());
     68 }
     69 
     70 std::vector<std::string> getExtFunctionNames (const std::string& extName)
     71 {
     72 	const char** names_raw = getExtensionFuncStrs(extName);
     73 
     74 	return (names_raw != 0) ? makeStringVector(names_raw) : std::vector<std::string>();
     75 }
     76 
     77 std::vector<std::string> getCoreFunctionNames (EGLint apiBit)
     78 {
     79 	switch (apiBit)
     80 	{
     81 		case 0:							return makeStringVector(getCoreFunctionStrs());
     82 		case EGL_OPENGL_ES_BIT:			return makeStringVector(getGlesFunctionStrs());
     83 		case EGL_OPENGL_ES2_BIT:		return makeStringVector(getGles2FunctionStrs());
     84 		case EGL_OPENGL_ES3_BIT_KHR:	return makeStringVector(getGles3FunctionStrs());
     85 		default:
     86 			DE_ASSERT(DE_FALSE);
     87 	}
     88 
     89 	return std::vector<std::string>();
     90 }
     91 
     92 } // anonymous
     93 
     94 // Base class for eglGetProcAddress() test cases
     95 
     96 class GetProcAddressCase : public TestCase, protected eglu::CallLogWrapper
     97 {
     98 public:
     99 								GetProcAddressCase		(EglTestContext& eglTestCtx, const char* name, const char* description);
    100 	virtual						~GetProcAddressCase		(void);
    101 
    102 	void						init					(void);
    103 	IterateResult				iterate					(void);
    104 
    105 	bool						isSupported				(const std::string& extName);
    106 
    107 	virtual void				executeTest				(void) = 0;
    108 
    109 private:
    110 	std::vector<std::string>	m_supported;
    111 };
    112 
    113 GetProcAddressCase::GetProcAddressCase (EglTestContext& eglTestCtx, const char* name, const char* description)
    114 	: TestCase			(eglTestCtx, name, description)
    115 	, CallLogWrapper	(eglTestCtx.getTestContext().getLog())
    116 {
    117 }
    118 
    119 GetProcAddressCase::~GetProcAddressCase (void)
    120 {
    121 }
    122 
    123 void GetProcAddressCase::init (void)
    124 {
    125 	const tcu::egl::Display&	display		= m_eglTestCtx.getDisplay();
    126 	display.getExtensions(m_supported);
    127 
    128 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    129 }
    130 
    131 tcu::TestNode::IterateResult GetProcAddressCase::iterate (void)
    132 {
    133 	enableLogging(true);
    134 
    135 	executeTest();
    136 
    137 	enableLogging(false);
    138 
    139 	return STOP;
    140 }
    141 
    142 bool GetProcAddressCase::isSupported (const std::string& extName)
    143 {
    144 	return std::find(m_supported.begin(), m_supported.end(), extName) != m_supported.end();
    145 }
    146 
    147 // Test by extension
    148 
    149 class GetProcAddressExtensionCase : public GetProcAddressCase
    150 {
    151 public:
    152 	GetProcAddressExtensionCase (EglTestContext& eglTestCtx, const char* name, const char* description, const std::string& extName)
    153 		: GetProcAddressCase	(eglTestCtx, name, description)
    154 		, m_extName				(extName)
    155 	{
    156 	}
    157 
    158 	virtual ~GetProcAddressExtensionCase (void)
    159 	{
    160 	}
    161 
    162 	void executeTest (void)
    163 	{
    164 		TestLog&						log			= m_testCtx.getLog();
    165 		bool							supported	= isSupported(m_extName);
    166 		const std::vector<std::string>	funcNames	= getExtFunctionNames(m_extName);
    167 
    168 		DE_ASSERT(!funcNames.empty());
    169 
    170 		log << TestLog::Message << m_extName << ": " << (supported ? "supported" : "not supported") << TestLog::EndMessage;
    171 		log << TestLog::Message << TestLog::EndMessage;
    172 
    173 		for (std::vector<std::string>::const_iterator funcIter = funcNames.begin(); funcIter != funcNames.end(); funcIter++)
    174 		{
    175 			const std::string&	funcName			= *funcIter;
    176 			void				(*funcPtr)(void);
    177 
    178 			funcPtr = eglGetProcAddress(funcName.c_str());
    179 			TCU_CHECK_EGL();
    180 
    181 			if (supported && funcPtr == 0)
    182 			{
    183 				log << TestLog::Message << "Fail, received null pointer for supported extension function: " << funcName << TestLog::EndMessage;
    184 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected null pointer");
    185 			}
    186 		}
    187 	}
    188 
    189 private:
    190 	std::string	m_extName;
    191 };
    192 
    193 // Test core functions
    194 
    195 class GetProcAddressCoreFunctionsCase : public GetProcAddressCase
    196 {
    197 public:
    198 	GetProcAddressCoreFunctionsCase (EglTestContext& eglTestCtx, const char* name, const char* description, const EGLint apiBit = 0)
    199 		: GetProcAddressCase	(eglTestCtx, name, description)
    200 		, m_funcNames			(getCoreFunctionNames(apiBit))
    201 		, m_apiBit				(apiBit)
    202 	{
    203 	}
    204 
    205 	virtual ~GetProcAddressCoreFunctionsCase (void)
    206 	{
    207 	}
    208 
    209 	bool isApiSupported (void)
    210 	{
    211 		const std::vector<eglu::ConfigInfo>	configs	= m_eglTestCtx.getConfigs();
    212 
    213 		if (m_apiBit == 0)
    214 			return true;
    215 
    216 		for (std::vector<eglu::ConfigInfo>::const_iterator configIter = configs.begin(); configIter != configs.end(); configIter++)
    217 		{
    218 			const eglu::ConfigInfo&	config	= *configIter;
    219 
    220 			if ((config.renderableType & m_apiBit) != 0)
    221 				return true;
    222 		}
    223 
    224 		return false;
    225 	}
    226 
    227 	void executeTest (void)
    228 	{
    229 		TestLog&	log					= m_testCtx.getLog();
    230 		const bool	funcPtrSupported	= isSupported("EGL_KHR_get_all_proc_addresses");
    231 		const bool	apiSupported		= isApiSupported();
    232 
    233 		log << TestLog::Message << "EGL_KHR_get_all_proc_addresses: " << (funcPtrSupported ? "supported" : "not supported") << TestLog::EndMessage;
    234 		log << TestLog::Message << TestLog::EndMessage;
    235 
    236 		if (!apiSupported)
    237 		{
    238 			log << TestLog::Message << eglu::getConfigAttribValueStr(EGL_RENDERABLE_TYPE, m_apiBit) << " not supported by any available configuration." << TestLog::EndMessage;
    239 			log << TestLog::Message << TestLog::EndMessage;
    240 		}
    241 
    242 		for (std::vector<std::string>::const_iterator funcIter = m_funcNames.begin(); funcIter != m_funcNames.end(); funcIter++)
    243 		{
    244 			const std::string&	funcName			= *funcIter;
    245 			void				(*funcPtr)(void);
    246 
    247 			funcPtr = eglGetProcAddress(funcName.c_str());
    248 			TCU_CHECK_EGL();
    249 
    250 			if (apiSupported && funcPtrSupported && (funcPtr == 0))
    251 			{
    252 				log << TestLog::Message << "Fail, received null pointer for supported function: " << funcName << TestLog::EndMessage;
    253 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected null pointer");
    254 			}
    255 			else if (!apiSupported && (funcPtr != 0))
    256 			{
    257 				log << TestLog::Message << "Warning, received non-null value for unsupported function: " << funcName << TestLog::EndMessage;
    258 				m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Non-null value for unsupported function");
    259 			}
    260 		}
    261 	}
    262 
    263 private:
    264 	const std::vector<std::string>	m_funcNames;
    265 	const EGLint					m_apiBit;
    266 };
    267 
    268 GetProcAddressTests::GetProcAddressTests (EglTestContext& eglTestCtx)
    269 	: TestCaseGroup(eglTestCtx, "get_proc_address", "eglGetProcAddress() tests")
    270 {
    271 }
    272 
    273 GetProcAddressTests::~GetProcAddressTests (void)
    274 {
    275 }
    276 
    277 void GetProcAddressTests::init (void)
    278 {
    279 	// extensions
    280 	{
    281 		tcu::TestCaseGroup* extensionsGroup = new tcu::TestCaseGroup(m_testCtx, "extension", "Test EGL extensions");
    282 		addChild(extensionsGroup);
    283 
    284 		const std::vector<std::string>	extNames	= getExtensionNames();
    285 
    286 		for (std::vector<std::string>::const_iterator extIter = extNames.begin(); extIter != extNames.end(); extIter++)
    287 		{
    288 			const std::string&				extName		= *extIter;
    289 			const std::vector<std::string>	funcNames	= getExtFunctionNames(extName);
    290 
    291 			std::string						testName	(extName);
    292 
    293 			if (funcNames.empty())
    294 				continue;
    295 
    296 			for (size_t ndx = 0; ndx < extName.length(); ndx++)
    297 				testName[ndx] = std::tolower(extName[ndx]);
    298 
    299 			extensionsGroup->addChild(new GetProcAddressExtensionCase(m_eglTestCtx, testName.c_str(), ("Test " + extName).c_str(), extName));
    300 		}
    301 	}
    302 
    303 	// core functions
    304 	{
    305 		tcu::TestCaseGroup* coreFuncGroup = new tcu::TestCaseGroup(m_testCtx, "core", "Test core functions");
    306 		addChild(coreFuncGroup);
    307 
    308 		coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase	(m_eglTestCtx,	"egl",		"Test EGL core functions"));
    309 		coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase	(m_eglTestCtx,	"gles",		"Test OpenGL ES core functions",	EGL_OPENGL_ES_BIT));
    310 		coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase	(m_eglTestCtx,	"gles2",	"Test OpenGL ES 2 core functions",	EGL_OPENGL_ES2_BIT));
    311 		coreFuncGroup->addChild(new GetProcAddressCoreFunctionsCase	(m_eglTestCtx,	"gles3",	"Test OpenGL ES 3 core functions",	EGL_OPENGL_ES3_BIT_KHR));
    312 	}
    313 }
    314 
    315 } // egl
    316 } // deqp
    317