Home | History | Annotate | Download | only in texture_buffer
      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  **/
     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  **/
     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  **/
     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  */
     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  */
    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  */
    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  */
    196 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  **/
    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  */
    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  **/
    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  **/
    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  **/
    466 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  **/
    493 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  **/
    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  **/
    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  */
    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  **/
    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  */
    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  */
    618 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  **/
    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  **/
    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  */
    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