• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  esextcTextureBufferActiveUniformValidation.cpp
26  * \brief Texture Buffer - Active Uniform Value Validation (Test 8)
27  */ /*-------------------------------------------------------------------*/
28 
29 #include "esextcTextureBufferActiveUniformValidation.hpp"
30 #include "gluContextInfo.hpp"
31 #include "gluDefs.hpp"
32 #include "glwEnums.hpp"
33 #include "glwFunctions.hpp"
34 #include "tcuTestLog.hpp"
35 #include <cstring>
36 #include <map>
37 
38 namespace glcts
39 {
40 
41 /* Buffer size for uniform variable name */
42 const glw::GLuint TextureBufferActiveUniformValidation::m_param_value_size = 100;
43 
44 /** Constructor
45  *
46  **/
TextureParameters()47 TextureParameters::TextureParameters() : m_texture_buffer_size(0), m_texture_format(0), m_texture_uniform_type(0)
48 {
49 }
50 
51 /** Constructor
52  *
53  *  @param textureBufferSize  size of buffer object
54  *  @param textureFormat      texture format
55  *  @param textureUniforType  texture uniform type
56  *  @param uniformName        pointer to literal containing uniform name
57  **/
TextureParameters(glw::GLuint textureBufferSize,glw::GLenum textureFormat,glw::GLenum textureUniforType,const char * uniformName)58 TextureParameters::TextureParameters(glw::GLuint textureBufferSize, glw::GLenum textureFormat,
59 									 glw::GLenum textureUniforType, const char* uniformName)
60 {
61 	m_texture_buffer_size  = textureBufferSize;
62 	m_texture_format	   = textureFormat;
63 	m_texture_uniform_type = textureUniforType;
64 	m_uniform_name		   = uniformName;
65 }
66 
67 /** Constructor
68  *
69  *  @param context     Test context
70  *  @param name        Test case's name
71  *  @param description Test case's description
72  **/
TextureBufferActiveUniformValidation(Context & context,const ExtParameters & extParams,const char * name,const char * description)73 TextureBufferActiveUniformValidation::TextureBufferActiveUniformValidation(Context&				context,
74 																		   const ExtParameters& extParams,
75 																		   const char* name, const char* description)
76 	: TestCaseBase(context, extParams, name, description), m_po_id(0), m_tbo_ids(0), m_tbo_tex_ids(0)
77 {
78 	/* Nothing to be done here */
79 }
80 
81 /** Add parameters to the vector of texture parameters
82  *
83  * @param uniformType enum with type of uniform
84  * @param format      enum with texture format
85  * @param size        texture size
86  * @param name        uniform name
87  * @param params      pointer to vector where parameters will be added
88  */
addTextureParam(glw::GLenum uniformType,glw::GLenum format,glw::GLuint size,const char * name,std::vector<TextureParameters> * params)89 void TextureBufferActiveUniformValidation::addTextureParam(glw::GLenum uniformType, glw::GLenum format,
90 														   glw::GLuint size, const char* name,
91 														   std::vector<TextureParameters>* params)
92 {
93 	TextureParameters texParam(size, format, uniformType, name);
94 	params->push_back(texParam);
95 }
96 
97 /** Initializes GLES objects used during the test.
98  *
99  */
initTest(void)100 void TextureBufferActiveUniformValidation::initTest(void)
101 {
102 	/* Check if required extensions are supported */
103 	if (!m_is_texture_buffer_supported)
104 	{
105 		throw tcu::NotSupportedError(TEXTURE_BUFFER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
106 	}
107 
108 	/* Call specific implementation to configure texture params */
109 	configureParams(&m_texture_params);
110 
111 	m_tbo_tex_ids = new glw::GLuint[m_texture_params.size()];
112 	m_tbo_ids	 = new glw::GLuint[m_texture_params.size()];
113 
114 	memset(m_tbo_tex_ids, 0, m_texture_params.size() * sizeof(glw::GLuint));
115 	memset(m_tbo_ids, 0, m_texture_params.size() * sizeof(glw::GLuint));
116 
117 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
118 
119 	/* Create buffers and textures */
120 	for (glw::GLuint i = 0; i < m_texture_params.size(); ++i)
121 	{
122 		/* Create buffer object*/
123 		gl.genBuffers(1, &m_tbo_ids[i]);
124 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!");
125 		gl.bindBuffer(m_glExtTokens.TEXTURE_BUFFER, m_tbo_ids[i]);
126 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object !");
127 		gl.bufferData(m_glExtTokens.TEXTURE_BUFFER, m_texture_params[i].get_texture_buffer_size(), 0, GL_DYNAMIC_DRAW);
128 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating buffer object's data store!");
129 
130 		/* Create texture buffer */
131 		gl.genTextures(1, &m_tbo_tex_ids[i]);
132 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!");
133 		gl.activeTexture(GL_TEXTURE0 + i);
134 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error activating texture unit!");
135 		gl.bindTexture(m_glExtTokens.TEXTURE_BUFFER, m_tbo_tex_ids[i]);
136 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
137 		gl.texBuffer(m_glExtTokens.TEXTURE_BUFFER, m_texture_params[i].get_texture_format(), m_tbo_ids[i]);
138 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting buffer object as data store for texture buffer!");
139 	}
140 
141 	/* Create program */
142 	createProgram();
143 }
144 
145 /** Returns uniform type name
146  *
147  * @param  uniformType enum value of uniform type
148  * @return             pointer to literal with uniform type name
149  */
getUniformTypeName(glw::GLenum uniformType)150 const char* TextureBufferActiveUniformValidation::getUniformTypeName(glw::GLenum uniformType)
151 {
152 	static const char* str_GL_SAMPLER_BUFFER_EXT			  = "GL_SAMPLER_BUFFER_EXT";
153 	static const char* str_GL_INT_SAMPLER_BUFFER_EXT		  = "GL_INT_SAMPLER_BUFFER_EXT";
154 	static const char* str_GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT = "GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT";
155 	static const char* str_GL_IMAGE_BUFFER_EXT				  = "GL_IMAGE_BUFFER_EXT";
156 	static const char* str_GL_INT_IMAGE_BUFFER_EXT			  = "GL_INT_IMAGE_BUFFER_EXT";
157 	static const char* str_GL_UNSIGNED_INT_IMAGE_BUFFER_EXT   = "GL_UNSIGNED_INT_IMAGE_BUFFER_EXT";
158 	static const char* str_UNKNOWN							  = "UNKNOWN";
159 
160 	if (uniformType == m_glExtTokens.SAMPLER_BUFFER)
161 	{
162 		return str_GL_SAMPLER_BUFFER_EXT;
163 	}
164 	else if (uniformType == m_glExtTokens.INT_SAMPLER_BUFFER)
165 	{
166 		return str_GL_INT_SAMPLER_BUFFER_EXT;
167 	}
168 	else if (uniformType == m_glExtTokens.UNSIGNED_INT_SAMPLER_BUFFER)
169 	{
170 		return str_GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT;
171 	}
172 	else if (uniformType == m_glExtTokens.IMAGE_BUFFER)
173 	{
174 		return str_GL_IMAGE_BUFFER_EXT;
175 	}
176 	else if (uniformType == m_glExtTokens.INT_IMAGE_BUFFER)
177 	{
178 		return str_GL_INT_IMAGE_BUFFER_EXT;
179 	}
180 	else if (uniformType == m_glExtTokens.UNSIGNED_INT_IMAGE_BUFFER)
181 	{
182 		return str_GL_UNSIGNED_INT_IMAGE_BUFFER_EXT;
183 	}
184 	else
185 	{
186 		return str_UNKNOWN;
187 	}
188 }
189 
190 /** Returns pointer to texture parameters for specific uniform type
191  *
192  * @param uniformType  enum specifying unform type
193  *
194  * @return             if TextureParameters for specific uniformType was found returns pointer to the element, otherwise return NULL
195  */
getParamsForType(glw::GLenum uniformType) const196 const TextureParameters* TextureBufferActiveUniformValidation::getParamsForType(glw::GLenum uniformType) const
197 {
198 	for (glw::GLuint i = 0; i < m_texture_params.size(); ++i)
199 	{
200 		if (m_texture_params[i].get_texture_uniform_type() == uniformType)
201 		{
202 			return &m_texture_params[i];
203 		}
204 	}
205 	return DE_NULL;
206 }
207 
208 /** Executes the test.
209  *
210  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
211  *
212  *  Note the function throws exception should an error occur!
213  *
214  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
215  **/
iterate(void)216 tcu::TestNode::IterateResult TextureBufferActiveUniformValidation::iterate(void)
217 {
218 	/* Initialize */
219 	initTest();
220 
221 	/* Get GL entry points */
222 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
223 
224 	bool testResult = true;
225 
226 	gl.useProgram(m_po_id);
227 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active program object!");
228 
229 	/* Configure Program */
230 	configureProgram(&m_texture_params, m_tbo_tex_ids);
231 
232 	/* Get number of active uniforms for current program */
233 	glw::GLint n_active_uniforms;
234 
235 	gl.getProgramiv(m_po_id, GL_ACTIVE_UNIFORMS, &n_active_uniforms);
236 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting value of GL_ACTIVE_UNIFORMS!");
237 
238 	if ((glw::GLuint)n_active_uniforms != m_texture_params.size())
239 	{
240 		/* Log error if number of active uniforms different than expected */
241 		m_testCtx.getLog() << tcu::TestLog::Message << "Result is different than expected!\n"
242 						   << "Expected number of active uniforms: " << m_texture_params.size() << "\n"
243 						   << "Result   number of active uniforms: " << n_active_uniforms << "\n"
244 						   << tcu::TestLog::EndMessage;
245 
246 		testResult = false;
247 	}
248 
249 	/* Retrieve parameters for specific indices */
250 	std::vector<glw::GLchar> nameValue(m_param_value_size);
251 	glw::GLsizei			 paramLength = 0;
252 	glw::GLsizei			 uniformSize = 0;
253 	glw::GLenum				 uniformType;
254 
255 	/* store map of indices and uniform types */
256 	std::map<glw::GLuint, glw::GLenum> resultTypes;
257 
258 	for (glw::GLuint i = 0; i < (glw::GLuint)n_active_uniforms; ++i)
259 	{
260 		gl.getActiveUniform(m_po_id, i /* index */, (glw::GLsizei)(m_param_value_size - 1), &paramLength, &uniformSize,
261 							&uniformType, &nameValue[0]);
262 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting information about active uniform variable!");
263 
264 		/*Check if returned uniform type is one of types defined in current program*/
265 		const TextureParameters* param = getParamsForType(uniformType);
266 
267 		if (0 == param)
268 		{
269 			m_testCtx.getLog() << tcu::TestLog::Message
270 							   << "Following uniform type was not expected to be defined in current program : \n"
271 							   << getUniformTypeName(uniformType) << "\n"
272 							   << tcu::TestLog::EndMessage;
273 			testResult = false;
274 		}
275 		else if (strncmp(&nameValue[0], param->get_uniform_name().c_str(), m_param_value_size))
276 		{
277 			m_testCtx.getLog() << tcu::TestLog::Message << "For :" << getUniformTypeName(uniformType) << " type name \n"
278 							   << "expected  uniform name is: " << param->get_uniform_name().c_str() << "\n"
279 							   << "result    uniform name is: " << &nameValue[0] << "\n"
280 							   << tcu::TestLog::EndMessage;
281 			testResult = false;
282 		}
283 
284 		resultTypes[i] = uniformType;
285 	}
286 
287 	/* Check if all uniform types defined in program were returned */
288 	for (glw::GLuint i = 0; i < (glw::GLuint)n_active_uniforms; ++i)
289 	{
290 		/* Log error if expected uniform type is missing */
291 		std::map<glw::GLuint, glw::GLenum>::iterator it = resultTypes.begin();
292 		for (; it != resultTypes.end(); ++it)
293 		{
294 			if (it->second == m_texture_params[i].get_texture_uniform_type())
295 			{
296 				break;
297 			}
298 		}
299 
300 		/* Log if there is some missing uniform type */
301 		if (it == resultTypes.end())
302 		{
303 			m_testCtx.getLog() << tcu::TestLog::Message
304 							   << "Following uniform type is missing from active uniforms list: "
305 							   << getUniformTypeName(m_texture_params[i].get_texture_uniform_type()) << "\n"
306 							   << tcu::TestLog::EndMessage;
307 
308 			testResult = false;
309 		}
310 	}
311 
312 	/* Get all active uniform types using glGetActiveUniformsiv and compare with results from glGetActiveUniform function */
313 	std::vector<glw::GLuint> indicies(n_active_uniforms);
314 	std::vector<glw::GLint>  types(n_active_uniforms);
315 
316 	for (glw::GLuint i = 0; i < (glw::GLuint)n_active_uniforms; ++i)
317 	{
318 		indicies[i] = i;
319 	}
320 
321 	gl.getActiveUniformsiv(m_po_id, n_active_uniforms, &indicies[0], GL_UNIFORM_TYPE, &types[0]);
322 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting information about active uniform variables!");
323 
324 	for (glw::GLuint i = 0; i < (glw::GLuint)n_active_uniforms; ++i)
325 	{
326 		/* Log error if expected result is different from expected*/
327 		if (resultTypes[i] != (glw::GLuint)types[i])
328 		{
329 			m_testCtx.getLog() << tcu::TestLog::Message << "Wrong uniform type for index(" << i << ")\n"
330 							   << "expected uniform type: " << getUniformTypeName(resultTypes[i]) << "\n"
331 							   << "result   uniform type: " << getUniformTypeName(types[i]) << "\n"
332 							   << tcu::TestLog::EndMessage;
333 
334 			testResult = false;
335 		}
336 	}
337 
338 	glw::GLenum paramVal = GL_TYPE;
339 	glw::GLint  type	 = -1;
340 
341 	for (glw::GLuint i = 0; i < (glw::GLuint)n_active_uniforms; ++i)
342 	{
343 		gl.getProgramResourceiv(m_po_id, GL_UNIFORM, i /*index */, 1 /* parameters count */,
344 								&paramVal /* parameter enum */, 1 /* buffer size */, 0, &type);
345 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting information about one of program resources!");
346 
347 		if (resultTypes[i] != (glw::GLuint)type)
348 		{
349 			m_testCtx.getLog() << tcu::TestLog::Message << "Wrong uniform type for index(" << i << ")\n"
350 							   << "expected uniform type: " << getUniformTypeName(resultTypes[i]) << "\n"
351 							   << "result   uniform type: " << getUniformTypeName(type) << "\n"
352 							   << tcu::TestLog::EndMessage;
353 			testResult = false;
354 		}
355 	}
356 
357 	if (testResult)
358 	{
359 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
360 	}
361 	else
362 	{
363 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
364 	}
365 
366 	return STOP;
367 }
368 
369 /** Deinitializes GLES objects created during the test.
370  *
371  */
deinit(void)372 void TextureBufferActiveUniformValidation::deinit(void)
373 {
374 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
375 
376 	/* Reset GLES state */
377 	gl.useProgram(0);
378 	gl.bindBuffer(GL_ARRAY_BUFFER, 0);
379 	gl.bindBuffer(m_glExtTokens.TEXTURE_BUFFER, 0);
380 
381 	for (glw::GLuint i = 0; i < m_texture_params.size(); ++i)
382 	{
383 		gl.activeTexture(GL_TEXTURE0 + i);
384 		gl.bindTexture(m_glExtTokens.TEXTURE_BUFFER, 0);
385 	}
386 	gl.activeTexture(GL_TEXTURE0);
387 
388 	/* Delete GLES objects */
389 	if (0 != m_po_id)
390 	{
391 		gl.deleteProgram(m_po_id);
392 		m_po_id = 0;
393 	}
394 
395 	if (0 != m_tbo_tex_ids)
396 	{
397 		gl.deleteTextures((glw::GLsizei)m_texture_params.size(), m_tbo_tex_ids);
398 		delete[] m_tbo_tex_ids;
399 		m_tbo_tex_ids = 0;
400 	}
401 
402 	if (0 != m_tbo_ids)
403 	{
404 		gl.deleteBuffers((glw::GLsizei)m_texture_params.size(), m_tbo_ids);
405 		delete[] m_tbo_ids;
406 		m_tbo_ids = 0;
407 	}
408 
409 	m_texture_params.clear();
410 
411 	/* Call base class' deinit() */
412 	TestCaseBase::deinit();
413 }
414 
415 /** Constructor
416  *
417  *  @param context     Test context
418  *  @param name        Test case's name
419  *  @param description Test case's description
420  **/
TextureBufferActiveUniformValidationVSFS(Context & context,const ExtParameters & extParams,const char * name,const char * description)421 TextureBufferActiveUniformValidationVSFS::TextureBufferActiveUniformValidationVSFS(Context&				context,
422 																				   const ExtParameters& extParams,
423 																				   const char*			name,
424 																				   const char*			description)
425 	: TextureBufferActiveUniformValidation(context, extParams, name, description), m_fs_id(0), m_vs_id(0)
426 {
427 
428 	/* Nothing to be done here */
429 }
430 
431 /** Deinitializes GLES objects created during the test.
432  *
433  **/
deinit(void)434 void TextureBufferActiveUniformValidationVSFS::deinit(void)
435 {
436 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
437 
438 	gl.useProgram(0);
439 
440 	if (0 != m_po_id)
441 	{
442 		gl.deleteProgram(m_po_id);
443 		m_po_id = 0;
444 	}
445 
446 	if (0 != m_fs_id)
447 	{
448 		gl.deleteShader(m_fs_id);
449 		m_fs_id = 0;
450 	}
451 
452 	if (0 != m_vs_id)
453 	{
454 		gl.deleteShader(m_vs_id);
455 		m_vs_id = 0;
456 	}
457 
458 	/* Call base class' deinit() */
459 	TextureBufferActiveUniformValidation::deinit();
460 }
461 
462 /** Returns Fragment shader Code
463  *
464  * @return pointer to literal with Fragment Shader Code
465  **/
getFragmentShaderCode() const466 const char* TextureBufferActiveUniformValidationVSFS::getFragmentShaderCode() const
467 {
468 	const char* result = "${VERSION}\n"
469 						 "\n"
470 						 "${TEXTURE_BUFFER_REQUIRE}\n"
471 						 "\n"
472 						 "precision highp float;\n"
473 						 "\n"
474 						 "uniform highp samplerBuffer  sampler_buffer;\n"
475 						 "uniform highp isamplerBuffer isampler_buffer;\n"
476 						 "uniform highp usamplerBuffer usampler_buffer;\n"
477 						 "\n"
478 						 "layout(location = 0) out vec4 outColor;\n"
479 						 "void main(void)\n"
480 						 "{\n"
481 						 "    outColor =  texelFetch(sampler_buffer, 0);\n"
482 						 "    outColor += vec4(texelFetch(isampler_buffer, 0));\n"
483 						 "    outColor += vec4(texelFetch(usampler_buffer, 0));\n"
484 						 "}\n";
485 
486 	return result;
487 }
488 
489 /** Returns Vertex shader Code
490  *
491  * @return pointer to literal with Vertex Shader Code
492  **/
getVertexShaderCode() const493 const char* TextureBufferActiveUniformValidationVSFS::getVertexShaderCode() const
494 {
495 	const char* result = "${VERSION}\n"
496 						 "\n"
497 						 "precision highp float;\n"
498 						 "\n"
499 						 "void main(void)\n"
500 						 "{\n"
501 						 "    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);\n"
502 						 "}\n";
503 
504 	return result;
505 }
506 
507 /** Configure Texture parameters for test
508  *
509  * @param params  pointer to the buffer where parameters will be added
510  *
511  **/
configureParams(std::vector<TextureParameters> * params)512 void TextureBufferActiveUniformValidationVSFS::configureParams(std::vector<TextureParameters>* params)
513 {
514 	addTextureParam(m_glExtTokens.SAMPLER_BUFFER, GL_R32F, sizeof(glw::GLfloat), "sampler_buffer", params);
515 	addTextureParam(m_glExtTokens.INT_SAMPLER_BUFFER, GL_R32I, sizeof(glw::GLint), "isampler_buffer", params);
516 	addTextureParam(m_glExtTokens.UNSIGNED_INT_SAMPLER_BUFFER, GL_R32UI, sizeof(glw::GLuint), "usampler_buffer",
517 					params);
518 }
519 
520 /** Create program used for test
521  *
522  **/
createProgram(void)523 void TextureBufferActiveUniformValidationVSFS::createProgram(void)
524 {
525 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
526 
527 	m_po_id = gl.createProgram();
528 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program object!");
529 
530 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
531 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating shader object!");
532 
533 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
534 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating shader object!");
535 
536 	const char* fsCode = getFragmentShaderCode();
537 	const char* vsCode = getVertexShaderCode();
538 
539 	if (!buildProgram(m_po_id, m_fs_id, 1, &fsCode, m_vs_id, 1, &vsCode))
540 	{
541 		TCU_FAIL("Error building a program!");
542 	}
543 }
544 
545 /** Configure Program elements
546  *
547  * @param params pointer to buffer with texture parameters
548  * @param params pointer to textures' ids
549  *
550  */
configureProgram(std::vector<TextureParameters> * params,glw::GLuint * texIds)551 void TextureBufferActiveUniformValidationVSFS::configureProgram(std::vector<TextureParameters>* params,
552 																glw::GLuint*					texIds)
553 {
554 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
555 
556 	for (glw::GLuint i = 0; i < params->size(); ++i)
557 	{
558 		glw::GLint location = gl.getUniformLocation(m_po_id, (*params)[i].get_uniform_name().c_str());
559 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting uniform location!");
560 		if (location == -1)
561 		{
562 			TCU_FAIL("Could not get uniform location for active uniform variable");
563 		}
564 
565 		gl.activeTexture(GL_TEXTURE0 + i);
566 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error activating texture unit!");
567 		gl.bindTexture(m_glExtTokens.TEXTURE_BUFFER, texIds[i]);
568 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
569 		gl.uniform1i(location, i);
570 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting value for uniform location!");
571 	}
572 }
573 
574 /** Constructor
575  *
576  *  @param context     Test context
577  *  @param name        Test case's name
578  *  @param description Test case's description
579  **/
TextureBufferActiveUniformValidationCS(Context & context,const ExtParameters & extParams,const char * name,const char * description)580 TextureBufferActiveUniformValidationCS::TextureBufferActiveUniformValidationCS(Context&				context,
581 																			   const ExtParameters& extParams,
582 																			   const char*			name,
583 																			   const char*			description)
584 	: TextureBufferActiveUniformValidation(context, extParams, name, description), m_cs_id(0)
585 {
586 	/* Nothing to be done here */
587 }
588 
589 /** Deinitializes GLES objects created during the test.
590  *
591  */
deinit(void)592 void TextureBufferActiveUniformValidationCS::deinit(void)
593 {
594 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
595 
596 	gl.useProgram(0);
597 
598 	if (0 != m_po_id)
599 	{
600 		gl.deleteProgram(m_po_id);
601 		m_po_id = 0;
602 	}
603 
604 	if (0 != m_cs_id)
605 	{
606 		gl.deleteShader(m_cs_id);
607 		m_cs_id = 0;
608 	}
609 
610 	/* Call base class' deinit() */
611 	TextureBufferActiveUniformValidation::deinit();
612 }
613 
614 /** Returns Compute shader Code
615  *
616  * @return pointer to literal with Compute Shader Code
617  */
getComputeShaderCode() const618 const char* TextureBufferActiveUniformValidationCS::getComputeShaderCode() const
619 {
620 	const char* result = "${VERSION}\n"
621 						 "\n"
622 						 "${TEXTURE_BUFFER_REQUIRE}\n"
623 						 "\n"
624 						 "precision highp float;\n"
625 						 "\n"
626 						 "layout(r32f)  uniform highp imageBuffer    image_buffer;\n"
627 						 "layout(r32i)  uniform highp iimageBuffer   iimage_buffer;\n"
628 						 "layout(r32ui) uniform highp uimageBuffer   uimage_buffer;\n"
629 						 "\n"
630 						 "layout (local_size_x = 1) in;\n"
631 						 "\n"
632 						 "void main(void)\n"
633 						 "{\n"
634 						 "    imageStore(image_buffer,  0, vec4 (1.0, 1.0, 1.0, 1.0));\n"
635 						 "    imageStore(iimage_buffer, 0, ivec4(1,   1,   1,   1)  );\n"
636 						 "    imageStore(uimage_buffer, 0, uvec4(1,   1,   1,   1)  );\n"
637 						 "}\n";
638 
639 	return result;
640 }
641 
642 /** Configure Texture parameters for test
643  *
644  * @param params  pointer to the buffer where parameters will be added
645  *
646  **/
configureParams(std::vector<TextureParameters> * params)647 void TextureBufferActiveUniformValidationCS::configureParams(std::vector<TextureParameters>* params)
648 {
649 	addTextureParam(m_glExtTokens.IMAGE_BUFFER, GL_R32F, sizeof(glw::GLfloat), "image_buffer", params);
650 	addTextureParam(m_glExtTokens.INT_IMAGE_BUFFER, GL_R32I, sizeof(glw::GLint), "iimage_buffer", params);
651 	addTextureParam(m_glExtTokens.UNSIGNED_INT_IMAGE_BUFFER, GL_R32UI, sizeof(glw::GLuint), "uimage_buffer", params);
652 }
653 
654 /** Create program used for test
655  *
656  **/
createProgram(void)657 void TextureBufferActiveUniformValidationCS::createProgram(void)
658 {
659 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
660 
661 	m_po_id = gl.createProgram();
662 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program object!");
663 
664 	m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
665 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating shader object!");
666 
667 	const char* csCode = getComputeShaderCode();
668 
669 	if (!buildProgram(m_po_id, m_cs_id, 1, &csCode))
670 	{
671 		TCU_FAIL("Error building a program!");
672 	}
673 }
674 
675 /** Configure Program elements
676  *
677  * @param params pointer to buffer with texture parameters
678  * @param params pointer to textures' ids
679  *
680  */
configureProgram(std::vector<TextureParameters> * params,glw::GLuint * texIds)681 void TextureBufferActiveUniformValidationCS::configureProgram(std::vector<TextureParameters>* params,
682 															  glw::GLuint*					  texIds)
683 {
684 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
685 
686 	for (glw::GLuint i = 0; i < params->size(); ++i)
687 	{
688 		gl.bindImageTexture(i, texIds[i], 0, GL_FALSE, 0, GL_WRITE_ONLY, (*params)[i].get_texture_format());
689 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture to image unit!");
690 	}
691 }
692 
693 } // namespace glcts
694