1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2016 The Khronos Group Inc.
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
22  */ /*-------------------------------------------------------------------*/
23 
24 /*!
25  * \file  esextcTextureBufferParameters.cpp
26  * \brief Texture Buffer GetTexLevelParameter and GetIntegerv test (Test 6)
27  */ /*-------------------------------------------------------------------*/
28 
29 #include "esextcTextureBufferParameters.hpp"
30 #include "gluContextInfo.hpp"
31 #include "gluDefs.hpp"
32 #include "glwEnums.hpp"
33 #include "glwFunctions.hpp"
34 #include "tcuTestLog.hpp"
35 #include <stddef.h>
36 
37 namespace glcts
38 {
39 
40 const glw::GLuint TextureBufferParameters::m_n_texels_phase_one = 128;
41 const glw::GLuint TextureBufferParameters::m_n_texels_phase_two = 256;
42 
43 /** Constructor
44  *
45  * @param context     Test context
46  * @param name        Test case's name
47  * @param description Test case's description
48  **/
TextureBufferParameters(Context & context,const ExtParameters & extParams,const char * name,const char * description)49 TextureBufferParameters::TextureBufferParameters(Context& context, const ExtParameters& extParams, const char* name,
50 												 const char* description)
51 	: TestCaseBase(context, extParams, name, description), m_tbo_id(0), m_to_id(0)
52 {
53 }
54 
55 /** Initializes all GLES objects and reference values for the test. */
initTest(void)56 void TextureBufferParameters::initTest(void)
57 {
58 	/* Skip if required extensions are not supported. */
59 	if (!m_is_texture_buffer_supported)
60 	{
61 		throw tcu::NotSupportedError(TEXTURE_BUFFER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
62 	}
63 
64 	m_internal_formats[GL_R8]		= sizeof(glw::GLubyte) * 1 /* components */;
65 	m_internal_formats[GL_R16F]		= sizeof(glw::GLhalf) * 1 /* components */;
66 	m_internal_formats[GL_R32F]		= sizeof(glw::GLfloat) * 1 /* components */;
67 	m_internal_formats[GL_R8I]		= sizeof(glw::GLbyte) * 1 /* components */;
68 	m_internal_formats[GL_R16I]		= sizeof(glw::GLshort) * 1 /* components */;
69 	m_internal_formats[GL_R32I]		= sizeof(glw::GLint) * 1 /* components */;
70 	m_internal_formats[GL_R8UI]		= sizeof(glw::GLubyte) * 1 /* components */;
71 	m_internal_formats[GL_R16UI]	= sizeof(glw::GLushort) * 1 /* components */;
72 	m_internal_formats[GL_R32UI]	= sizeof(glw::GLuint) * 1 /* components */;
73 	m_internal_formats[GL_RG8]		= sizeof(glw::GLubyte) * 2 /* components */;
74 	m_internal_formats[GL_RG16F]	= sizeof(glw::GLhalf) * 2 /* components */;
75 	m_internal_formats[GL_RG32F]	= sizeof(glw::GLfloat) * 2 /* components */;
76 	m_internal_formats[GL_RG8I]		= sizeof(glw::GLbyte) * 2 /* components */;
77 	m_internal_formats[GL_RG16I]	= sizeof(glw::GLshort) * 2 /* components */;
78 	m_internal_formats[GL_RG32I]	= sizeof(glw::GLint) * 2 /* components */;
79 	m_internal_formats[GL_RG8UI]	= sizeof(glw::GLubyte) * 2 /* components */;
80 	m_internal_formats[GL_RG16UI]   = sizeof(glw::GLushort) * 2 /* components */;
81 	m_internal_formats[GL_RG32UI]   = sizeof(glw::GLuint) * 2 /* components */;
82 	m_internal_formats[GL_RGB32F]   = sizeof(glw::GLfloat) * 3 /* components */;
83 	m_internal_formats[GL_RGB32I]   = sizeof(glw::GLint) * 3 /* components */;
84 	m_internal_formats[GL_RGB32UI]  = sizeof(glw::GLuint) * 3 /* components */;
85 	m_internal_formats[GL_RGBA8]	= sizeof(glw::GLubyte) * 4 /* components */;
86 	m_internal_formats[GL_RGBA16F]  = sizeof(glw::GLhalf) * 4 /* components */;
87 	m_internal_formats[GL_RGBA32F]  = sizeof(glw::GLfloat) * 4 /* components */;
88 	m_internal_formats[GL_RGBA8I]   = sizeof(glw::GLbyte) * 4 /* components */;
89 	m_internal_formats[GL_RGBA16I]  = sizeof(glw::GLshort) * 4 /* components */;
90 	m_internal_formats[GL_RGBA32I]  = sizeof(glw::GLint) * 4 /* components */;
91 	m_internal_formats[GL_RGBA8UI]  = sizeof(glw::GLubyte) * 4 /* components */;
92 	m_internal_formats[GL_RGBA16UI] = sizeof(glw::GLushort) * 4 /* components */;
93 	m_internal_formats[GL_RGBA32UI] = sizeof(glw::GLuint) * 4 /* components */;
94 
95 	/* Retrieve GLES entry points. */
96 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
97 
98 	gl.genTextures(1, &m_to_id);
99 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate texture object!");
100 
101 	gl.bindTexture(m_glExtTokens.TEXTURE_BUFFER, m_to_id);
102 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind texture object!");
103 
104 	gl.genBuffers(1, &m_tbo_id);
105 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate buffer object!");
106 
107 	gl.bindBuffer(m_glExtTokens.TEXTURE_BUFFER, m_tbo_id);
108 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind buffer object!");
109 }
110 
111 /** Deinitializes GLES objects created during the test */
deinit(void)112 void TextureBufferParameters::deinit(void)
113 {
114 	/* Retrieve GLES entry points. */
115 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
116 
117 	/* Reset GLES state */
118 	gl.bindTexture(m_glExtTokens.TEXTURE_BUFFER, 0);
119 	gl.bindBuffer(m_glExtTokens.TEXTURE_BUFFER, 0);
120 
121 	/* Delete GLEs objects */
122 	if (m_to_id != 0)
123 	{
124 		gl.deleteTextures(1, &m_to_id);
125 		m_to_id = 0;
126 	}
127 
128 	if (m_tbo_id != 0)
129 	{
130 		gl.deleteBuffers(1, &m_tbo_id);
131 		m_tbo_id = 0;
132 	}
133 
134 	/* Deinitialize base class */
135 	TestCaseBase::deinit();
136 }
137 
138 /** Executes the test.
139  *
140  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
141  *
142  *  Note the function throws exception should an error occur!
143  *
144  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
145  **/
iterate(void)146 tcu::TestNode::IterateResult TextureBufferParameters::iterate(void)
147 {
148 	/* Initialization */
149 	initTest();
150 
151 	/* Retrieve GLEs entry points. */
152 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
153 
154 	glw::GLboolean test_passed = true;
155 
156 	/* Check GL_TEXTURE_BINDING_BUFFER_EXT */
157 	test_passed = test_passed && queryTextureBufferBinding(m_to_id);
158 
159 	/* Check GL_TEXTURE_BUFFER_BINDING_EXT */
160 	test_passed = test_passed && queryTextureBindingBuffer(m_tbo_id);
161 
162 	/* For each GL_TEXTURE_INTERNAL_FORMAT */
163 	for (InternalFormatsMap::iterator iter = m_internal_formats.begin(); iter != m_internal_formats.end(); ++iter)
164 	{
165 		std::vector<glw::GLubyte> data_phase_one(m_n_texels_phase_one * iter->second, 0);
166 		gl.bufferData(m_glExtTokens.TEXTURE_BUFFER, m_n_texels_phase_one * iter->second, &data_phase_one[0],
167 					  GL_STATIC_READ);
168 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not allocate buffer object's data store!");
169 
170 		gl.texBuffer(m_glExtTokens.TEXTURE_BUFFER, iter->first, m_tbo_id);
171 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set buffer object as data source for texture buffer!");
172 
173 		/* Check GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT */
174 		test_passed = test_passed && queryTextureBufferDataStoreBinding(m_tbo_id);
175 
176 		/* Check GL_TEXTURE_INTERNAL_FORMAT */
177 		test_passed = test_passed && queryTextureInternalFormat(iter->first);
178 
179 		/* Check GL_TEXTURE_BUFFER_OFFSET_EXT */
180 		test_passed = test_passed && queryTextureBufferOffset(0);
181 
182 		/* Ckeck GL_TEXTURE_BUFFER_SIZE_EXT */
183 		test_passed = test_passed && queryTextureBufferSize(m_n_texels_phase_one * iter->second);
184 
185 		/* Ckeck wrong lod level */
186 		test_passed = test_passed && queryTextureInvalidLevel();
187 
188 		/* Get texture buffer offset alignment */
189 		glw::GLint offset_alignment = 0;
190 		gl.getIntegerv(m_glExtTokens.TEXTURE_BUFFER_OFFSET_ALIGNMENT, &offset_alignment);
191 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not get texture buffer offset alignment!");
192 
193 		/* Resize buffer object */
194 		std::vector<glw::GLubyte> data_phase_two(m_n_texels_phase_two * iter->second + offset_alignment, 0);
195 		gl.bufferData(m_glExtTokens.TEXTURE_BUFFER, m_n_texels_phase_two * iter->second + offset_alignment,
196 					  &data_phase_two[0], GL_STATIC_READ);
197 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not allocate buffer object's data store!");
198 
199 		/* Check GL_TEXTURE_BUFFER_OFFSET_EXT */
200 		test_passed = test_passed && queryTextureBufferOffset(0);
201 
202 		/* Check GL_TEXTURE_BUFFER_SIZE_EXT */
203 		test_passed = test_passed && queryTextureBufferSize(m_n_texels_phase_two * iter->second + offset_alignment);
204 
205 		gl.texBufferRange(m_glExtTokens.TEXTURE_BUFFER, iter->first, m_tbo_id, offset_alignment,
206 						  m_n_texels_phase_two * iter->second);
207 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set buffer object as data source for texture buffer!");
208 
209 		/* Check GL_TEXTURE_BUFFER_OFFSET_EXT */
210 		test_passed = test_passed && queryTextureBufferOffset(offset_alignment);
211 
212 		/* Check GL_TEXTURE_BUFFER_SIZE_EXT */
213 		test_passed = test_passed && queryTextureBufferSize(m_n_texels_phase_two * iter->second);
214 
215 		gl.texBuffer(m_glExtTokens.TEXTURE_BUFFER, iter->first, 0);
216 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not reset buffer object binding!");
217 	}
218 
219 	if (test_passed)
220 	{
221 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
222 	}
223 	else
224 	{
225 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
226 	}
227 
228 	return STOP;
229 }
230 
231 /** Query GL_TEXTURE_BUFFER_BINDING_EXT and compare with the expected value.
232  *
233  *  Note - the function throws exception should an error occur!
234  *
235  *  @param expected     Expected value used for comparison.
236  *
237  *  @return true  if the comparison has passed,
238  *          false if the comparison has failed.
239  **/
queryTextureBindingBuffer(glw::GLint expected)240 glw::GLboolean TextureBufferParameters::queryTextureBindingBuffer(glw::GLint expected)
241 {
242 	/* Retrieve GLES entry points. */
243 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
244 
245 	glw::GLint	 result	  = -1;
246 	glw::GLboolean test_passed = true;
247 
248 	gl.getIntegerv(m_glExtTokens.TEXTURE_BUFFER_BINDING, &result);
249 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not query value of GL_TEXTURE_BUFFER_BINDING_EXT");
250 
251 	if (result != expected)
252 	{
253 		test_passed = false;
254 
255 		m_testCtx.getLog() << tcu::TestLog::Message << "glGetIntegerv(GL_TEXTURE_BINDING_BUFFER_EXT) returned "
256 						   << result << " which is not equal to expected buffer object id == " << expected << ".\n"
257 						   << tcu::TestLog::EndMessage;
258 	}
259 
260 	return test_passed;
261 }
262 
263 /** Query GL_TEXTURE_BINDING_BUFFER_EXT and compare with the expected value.
264  *
265  *  Note - the function throws exception should an error occur!
266  *
267  *  @param expected     Expected value used for comparison.
268  *
269  *  @return true  if the comparison has passed,
270  *          false if the comparison has failed.
271  **/
queryTextureBufferBinding(glw::GLint expected)272 glw::GLboolean TextureBufferParameters::queryTextureBufferBinding(glw::GLint expected)
273 {
274 	/* Retrieve GLES entry points. */
275 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
276 
277 	glw::GLint	 result	  = -1;
278 	glw::GLboolean test_passed = true;
279 
280 	gl.getIntegerv(m_glExtTokens.TEXTURE_BINDING_BUFFER, &result);
281 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not query value of GL_TEXTURE_BINDING_BUFFER_EXT");
282 
283 	if (result != expected)
284 	{
285 		test_passed = false;
286 
287 		m_testCtx.getLog() << tcu::TestLog::Message << "glGetIntegerv(GL_TEXTURE_BUFFER_BINDING_EXT) returned "
288 						   << result << " which is not equal to expected texture object id == " << expected << ".\n"
289 						   << tcu::TestLog::EndMessage;
290 	}
291 
292 	return test_passed;
293 }
294 
295 /** Query GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT and compare with the expected value.
296  *
297  *  Note - the function throws exception should an error occur!
298  *
299  *  @param expected     Expected value used for comparison.
300  *
301  *  @return true  if the comparison has passed,
302  *          false if the comparison has failed.
303  **/
queryTextureBufferDataStoreBinding(glw::GLint expected)304 glw::GLboolean TextureBufferParameters::queryTextureBufferDataStoreBinding(glw::GLint expected)
305 {
306 	/* Retrieve GLES entry points. */
307 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
308 
309 	glw::GLint	 result	  = -1;
310 	glw::GLboolean test_passed = true;
311 
312 	gl.getTexLevelParameteriv(m_glExtTokens.TEXTURE_BUFFER, 0, m_glExtTokens.TEXTURE_BUFFER_DATA_STORE_BINDING,
313 							  &result);
314 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not query value of GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT");
315 
316 	if (result != expected)
317 	{
318 		test_passed = false;
319 
320 		m_testCtx.getLog() << tcu::TestLog::Message
321 						   << "glGetTexLevelParameteriv(GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT) returned " << result
322 						   << " which is not equal to expected buffer object id == " << expected << ".\n"
323 						   << tcu::TestLog::EndMessage;
324 	}
325 
326 	return test_passed;
327 }
328 
329 /** Query GL_TEXTURE_BUFFER_OFFSET_EXT and compare with the expected value.
330  *
331  *  Note - the function throws exception should an error occur!
332  *
333  *  @param expected     Expected value used for comparison.
334  *
335  *  @return true  if the comparison has passed,
336  *          false if the comparison has failed.
337  **/
queryTextureBufferOffset(glw::GLint expected)338 glw::GLboolean TextureBufferParameters::queryTextureBufferOffset(glw::GLint expected)
339 {
340 	/* Retrieve GLES entry points. */
341 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
342 
343 	glw::GLint	 result	  = -1;
344 	glw::GLboolean test_passed = true;
345 
346 	gl.getTexLevelParameteriv(m_glExtTokens.TEXTURE_BUFFER, 0, m_glExtTokens.TEXTURE_BUFFER_OFFSET, &result);
347 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not query value of GL_TEXTURE_BUFFER_OFFSET_EXT");
348 
349 	if (result != expected)
350 	{
351 		test_passed = false;
352 
353 		m_testCtx.getLog() << tcu::TestLog::Message
354 						   << "glGetTexLevelParameteriv(GL_TEXTURE_BUFFER_OFFSET_EXT) returned " << result
355 						   << " which is not equal to expected offset " << expected << ".\n"
356 						   << tcu::TestLog::EndMessage;
357 	}
358 
359 	return test_passed;
360 }
361 
362 /** Query GL_TEXTURE_BUFFER_SIZE_EXT and compare with the expected value.
363  *
364  *  Note - the function throws exception should an error occur!
365  *
366  *  @param expected     Expected value used for comparison.
367  *
368  *  @return true  if the comparison has passed,
369  *          false if the comparison has failed.
370  **/
queryTextureBufferSize(glw::GLint expected)371 glw::GLboolean TextureBufferParameters::queryTextureBufferSize(glw::GLint expected)
372 {
373 	/* Retrieve GLES entry points. */
374 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
375 
376 	glw::GLint	 result	  = -1;
377 	glw::GLboolean test_passed = true;
378 
379 	gl.getTexLevelParameteriv(m_glExtTokens.TEXTURE_BUFFER, 0, m_glExtTokens.TEXTURE_BUFFER_SIZE, &result);
380 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not query value of GL_TEXTURE_BUFFER_SIZE_EXT");
381 
382 	if (result != expected)
383 	{
384 		test_passed = false;
385 
386 		m_testCtx.getLog() << tcu::TestLog::Message << "glGetTexLevelParameteriv(GL_TEXTURE_BUFFER_SIZE_EXT) returned "
387 						   << result << " which is not equal to expected size " << expected << ".\n"
388 						   << tcu::TestLog::EndMessage;
389 	}
390 
391 	return test_passed;
392 }
393 
394 /** Query GL_TEXTURE_INTERNAL_FORMAT and compare with the expected value.
395  *
396  *  Note - the function throws exception should an error occur!
397  *
398  *  @param expected     Expected value used for comparison.
399  *
400  *  @return true  if the comparison has passed,
401  *          false if the comparison has failed.
402  **/
queryTextureInternalFormat(glw::GLint expected)403 glw::GLboolean TextureBufferParameters::queryTextureInternalFormat(glw::GLint expected)
404 {
405 	/* Retrieve GLES entry points. */
406 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
407 
408 	glw::GLint	 result	  = -1;
409 	glw::GLboolean test_passed = true;
410 
411 	gl.getTexLevelParameteriv(m_glExtTokens.TEXTURE_BUFFER, 0, GL_TEXTURE_INTERNAL_FORMAT, &result);
412 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not query value of GL_TEXTURE_INTERNAL_FORMAT");
413 
414 	if (result != expected)
415 	{
416 		test_passed = false;
417 
418 		m_testCtx.getLog() << tcu::TestLog::Message << "glGetTexLevelParameteriv(GL_TEXTURE_INTERNAL_FORMAT) returned "
419 						   << result << " which is not equal to expected internal format " << expected
420 						   << tcu::TestLog::EndMessage;
421 	}
422 
423 	return test_passed;
424 }
425 
426 /** Query GL_TEXTURE_BUFFER_SIZE_EXT with invalid texture level
427  *   and checks for GL_INVALID_VALUE error.
428  *
429  *  Note - the function throws exception should an error occur!
430  *
431  *  @return true  if the GL_INVALID_VALUE error was generated,
432  *          false if the GL_INVALID_VALUE error was not generated.
433  **/
queryTextureInvalidLevel()434 glw::GLboolean TextureBufferParameters::queryTextureInvalidLevel()
435 {
436 	/* Retrieve GLES entry points. */
437 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
438 
439 	glw::GLint	 result	  = -1;
440 	glw::GLboolean test_passed = true;
441 
442 	gl.getTexLevelParameteriv(m_glExtTokens.TEXTURE_BUFFER, 1, m_glExtTokens.TEXTURE_BUFFER_SIZE, &result);
443 	glw::GLenum error_code = gl.getError();
444 
445 	if (error_code != GL_INVALID_VALUE)
446 	{
447 		test_passed = false;
448 
449 		m_testCtx.getLog() << tcu::TestLog::Message
450 						   << "glGetTexLevelParameteriv() called for GL_TEXTURE_BUFFER_EXT texture target "
451 						   << "with lod level different than 0 did not generate an GL_INVALID_VALUE error.\n"
452 						   << tcu::TestLog::EndMessage;
453 	}
454 
455 	return test_passed;
456 }
457 
458 } /* namespace glcts */
459