1/*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.0 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 String Query tests.
22 *//*--------------------------------------------------------------------*/
23
24#include "es3fStringQueryTests.hpp"
25#include "es3fApiCase.hpp"
26#include "gluRenderContext.hpp"
27#include "glwEnums.hpp"
28#include "glwFunctions.hpp"
29#include "deString.h"
30
31#include <algorithm>
32#include <sstream>
33#include <string>
34
35using namespace glw; // GLint and other GL types
36
37namespace deqp
38{
39namespace gles3
40{
41namespace Functional
42{
43
44StringQueryTests::StringQueryTests (Context& context)
45	: TestCaseGroup (context, "string", "String Query tests")
46{
47}
48
49StringQueryTests::~StringQueryTests (void)
50{
51}
52
53void StringQueryTests::init (void)
54{
55	using tcu::TestLog;
56
57	ES3F_ADD_API_CASE(renderer, "RENDERER",
58	{
59		const GLubyte* string = glGetString(GL_RENDERER);
60		if (string == NULL)
61			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid string");
62	});
63	ES3F_ADD_API_CASE(vendor, "VENDOR",
64	{
65		const GLubyte* string = glGetString(GL_VENDOR);
66		if (string == NULL)
67			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid string");
68	});
69	ES3F_ADD_API_CASE(version, "VERSION",
70	{
71		const char* string				= (const char*)glGetString(GL_VERSION);
72		const char	referenceString[]	= "OpenGL ES 3.";
73
74		if (string == NULL)
75			TCU_FAIL("Got invalid string");
76
77		if (!deStringBeginsWith(string, referenceString))
78			TCU_FAIL("Got invalid string prefix");
79
80		{
81			std::string tmpString;
82			char		versionDelimiter;
83			int			glMajor				= 0;
84			int			glMinor				= 0;
85			GLint		stateVersionMinor	= 0;
86
87			std::istringstream versionStream(string);
88			versionStream >> tmpString;			// OpenGL
89			versionStream >> tmpString;			// ES
90			versionStream >> glMajor;			// 3
91			versionStream >> std::noskipws;
92			versionStream >> versionDelimiter;	// .
93			versionStream >> glMinor;			// x
94
95			if (!versionStream)
96				TCU_FAIL("Got invalid string format");
97
98			glGetIntegerv(GL_MINOR_VERSION, &stateVersionMinor);
99			if (glMinor != stateVersionMinor)
100			{
101				m_testCtx.getLog() << TestLog::Message << "// ERROR: MINOR_VERSION is " << stateVersionMinor << TestLog::EndMessage;
102				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid version.");
103				return;
104			}
105		}
106	});
107	ES3F_ADD_API_CASE(shading_language_version, "SHADING_LANGUAGE_VERSION",
108	{
109		const char* string				= (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
110		const char	referenceString[]	= "OpenGL ES GLSL ES ";
111
112		if (string == NULL)
113			TCU_FAIL("Got invalid string");
114
115		if (!deStringBeginsWith(string, referenceString))
116			TCU_FAIL("Got invalid string prefix");
117
118		{
119			std::string tmpString;
120			char		versionDelimiter;
121			int			glslMajor			= 0;
122			char		glslMinorDigit1		= 0;
123			char		glslMinorDigit2		= 0;
124			bool		digitsAreValid;
125
126			std::istringstream versionStream(string);
127			versionStream >> tmpString;			// OpenGL
128			versionStream >> tmpString;			// ES
129			versionStream >> tmpString;			// GLSL
130			versionStream >> tmpString;			// ES
131			versionStream >> glslMajor;			// x
132			versionStream >> std::noskipws;
133			versionStream >> versionDelimiter;	// .
134			versionStream >> glslMinorDigit1;	// x
135			versionStream >> glslMinorDigit2;	// x
136
137			digitsAreValid =	glslMinorDigit1 >= '0' && glslMinorDigit1 <= '9' &&
138								glslMinorDigit2 >= '0' && glslMinorDigit2 <= '9';
139
140			if (!versionStream || !digitsAreValid)
141				TCU_FAIL("Got invalid string format");
142		}
143	});
144	ES3F_ADD_API_CASE(extensions, "EXTENSIONS",
145	{
146		const char* extensions_cstring = (const char*)glGetString(GL_EXTENSIONS);
147		if (extensions_cstring == NULL)
148			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid string");
149
150		// split extensions_string at ' '
151
152		std::istringstream extensionStream((std::string)(extensions_cstring));
153		std::vector<std::string> extensions;
154
155		for (;;)
156		{
157			std::string extension;
158			if (std::getline(extensionStream, extension, ' '))
159				extensions.push_back(extension);
160			else
161				break;
162		}
163
164		GLint numExtensions = 0;
165		glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
166		expectError(GL_NO_ERROR);
167
168		if (extensions.size() != (size_t)numExtensions)
169		{
170			m_testCtx.getLog() << TestLog::Message << "// ERROR:  NUM_EXTENSIONS is " << numExtensions << "; got " << extensions.size() << " extensions" << TestLog::EndMessage;
171			if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
172				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got non-consistent number of extensions");
173		}
174
175		// all in glGetStringi(GL_EXTENSIONS) in must be in glGetString
176
177		for (int i = 0; i < numExtensions; ++i)
178		{
179			std::string extension((const char*)glGetStringi(GL_EXTENSIONS, i));
180
181			if (std::find(extensions.begin(), extensions.end(), extension) == extensions.end())
182			{
183				m_testCtx.getLog() << TestLog::Message << "// ERROR: extension " << extension << " found with GetStringi was not found in glGetString(GL_EXTENSIONS)" << TestLog::EndMessage;
184				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
185					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Extension query methods are not consistent.");
186			}
187		}
188
189		// only elements in glGetStringi(GL_EXTENSIONS) can be in glGetString
190
191		for (int i = 0; i < numExtensions; ++i)
192		{
193			std::string extension((const char*)glGetStringi(GL_EXTENSIONS, i));
194
195			std::vector<std::string>::iterator it = std::find(extensions.begin(), extensions.end(), extension);
196			if (it != extensions.end())
197				extensions.erase(it);
198		}
199
200		if (!extensions.empty())
201		{
202			for (size_t ndx = 0; ndx < extensions.size(); ++ndx)
203				m_testCtx.getLog() << TestLog::Message << "// ERROR: extension \"" << extensions[ndx] << "\" found with GetString was not found with GetStringi(GL_EXTENSIONS, ind)" << TestLog::EndMessage;
204
205			if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
206				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Extension query methods are not consistent.");
207		}
208
209	});
210}
211
212} // Functional
213} // gles3
214} // deqp
215