• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
makeStringVector(const char ** cStrArray)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 
getExtensionNames(void)65 std::vector<std::string> getExtensionNames (void)
66 {
67 	return makeStringVector(getExtensionStrs());
68 }
69 
getExtFunctionNames(const std::string & extName)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 
getCoreFunctionNames(EGLint apiBit)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 
GetProcAddressCase(EglTestContext & eglTestCtx,const char * name,const char * description)113 GetProcAddressCase::GetProcAddressCase (EglTestContext& eglTestCtx, const char* name, const char* description)
114 	: TestCase			(eglTestCtx, name, description)
115 	, CallLogWrapper	(eglTestCtx.getTestContext().getLog())
116 {
117 }
118 
~GetProcAddressCase(void)119 GetProcAddressCase::~GetProcAddressCase (void)
120 {
121 }
122 
init(void)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 
iterate(void)131 tcu::TestNode::IterateResult GetProcAddressCase::iterate (void)
132 {
133 	enableLogging(true);
134 
135 	executeTest();
136 
137 	enableLogging(false);
138 
139 	return STOP;
140 }
141 
isSupported(const std::string & extName)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:
GetProcAddressExtensionCase(EglTestContext & eglTestCtx,const char * name,const char * description,const std::string & extName)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 
~GetProcAddressExtensionCase(void)158 	virtual ~GetProcAddressExtensionCase (void)
159 	{
160 	}
161 
executeTest(void)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:
GetProcAddressCoreFunctionsCase(EglTestContext & eglTestCtx,const char * name,const char * description,const EGLint apiBit=0)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 
~GetProcAddressCoreFunctionsCase(void)205 	virtual ~GetProcAddressCoreFunctionsCase (void)
206 	{
207 	}
208 
isApiSupported(void)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 
executeTest(void)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 
GetProcAddressTests(EglTestContext & eglTestCtx)268 GetProcAddressTests::GetProcAddressTests (EglTestContext& eglTestCtx)
269 	: TestCaseGroup(eglTestCtx, "get_proc_address", "eglGetProcAddress() tests")
270 {
271 }
272 
~GetProcAddressTests(void)273 GetProcAddressTests::~GetProcAddressTests (void)
274 {
275 }
276 
init(void)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