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
38namespace glcts
39{
40
41/* Buffer size for uniform variable name */
42const glw::GLuint TextureBufferActiveUniformValidation::m_param_value_size = 100;
43
44/** Constructor
45 *
46 **/
47TextureParameters::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 **/
58TextureParameters::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 **/
73TextureBufferActiveUniformValidation::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 */
89void 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 */
100void 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 */
150const 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 */
196const 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 **/
216tcu::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 */
372void 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 **/
421TextureBufferActiveUniformValidationVSFS::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 **/
434void 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 **/
466const 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 **/
493const 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 **/
512void 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 **/
523void 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 */
551void 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 **/
580TextureBufferActiveUniformValidationCS::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 */
592void 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 */
618const 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 **/
647void 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 **/
657void 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 */
681void 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