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 "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