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