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  esextcTextureCubeMapArrayImageTextureSize.cpp
26  * \brief texture_cube_map_array extension - Image Texture Size (Test 10)
27  */ /*-------------------------------------------------------------------*/
28 
29 #include "esextcTextureCubeMapArrayImageTextureSize.hpp"
30 
31 #include "gluContextInfo.hpp"
32 #include "gluStrUtil.hpp"
33 #include "glwEnums.hpp"
34 #include "glwFunctions.hpp"
35 #include "tcuTestLog.hpp"
36 #include <cmath>
37 #include <iostream>
38 
39 namespace glcts
40 {
41 /* Static const variables used for configuring tests */
42 const glw::GLuint TextureCubeMapArrayTextureSizeBase::m_n_dimensions         = 3;
43 const glw::GLuint TextureCubeMapArrayTextureSizeBase::m_n_resolutions        = 4;
44 const glw::GLuint TextureCubeMapArrayTextureSizeBase::m_n_layers_per_cube    = 6;
45 const glw::GLuint TextureCubeMapArrayTextureSizeBase::m_n_storage_types      = 2;
46 const glw::GLuint TextureCubeMapArrayTextureSizeBase::m_n_texture_components = 4;
47 
48 /* Array with resolutions */
49 glw::GLuint resolutionArray[TextureCubeMapArrayTextureSizeBase::m_n_resolutions]
50                            [TextureCubeMapArrayTextureSizeBase::m_n_dimensions] = {{32, 32, 18},
51                                                                                    {64, 64, 6},
52                                                                                    {128, 128, 12},
53                                                                                    {256, 256, 12}};
54 
55 /* Names of storage types */
56 static const char *mutableStorage   = "MUTABLE";
57 static const char *imMutableStorage = "IMMUTABLE";
58 
59 /** Constructor
60  *
61  *  @param context       Test context
62  *  @param name          Test case's name
63  *  @param description   Test case's description
64  **/
TextureCubeMapArrayTextureSizeBase(Context & context,const ExtParameters & extParams,const char * name,const char * description)65 TextureCubeMapArrayTextureSizeBase::TextureCubeMapArrayTextureSizeBase(Context &context, const ExtParameters &extParams,
66                                                                        const char *name, const char *description)
67     : TestCaseBase(context, extParams, name, description)
68     , m_po_id(0)
69     , m_to_std_id(0)
70     , m_to_shw_id(0)
71     , m_vao_id(0)
72 {
73     /* Nothing to be done here */
74 }
75 
76 /** Initialize test case */
initTest(void)77 void TextureCubeMapArrayTextureSizeBase::initTest(void)
78 {
79     /* Check if texture_cube_map_array extension is supported */
80     if (!m_is_texture_cube_map_array_supported)
81     {
82         throw tcu::NotSupportedError(TEXTURE_CUBE_MAP_ARRAY_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
83     }
84 
85     /* Get GL entry points */
86     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
87 
88     /* Generate and bind VAO */
89     gl.genVertexArrays(1, &m_vao_id);
90     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate vertex array object");
91 
92     gl.bindVertexArray(m_vao_id);
93     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding vertex array object!");
94 
95     /* Create program object */
96     m_po_id = gl.createProgram();
97     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create program object.");
98 
99     /* Create program object */
100     configureProgram();
101 
102     /* Create GLES objects specific for the test */
103     configureTestSpecificObjects();
104 }
105 
106 /** Deinitialize test case */
deinit(void)107 void TextureCubeMapArrayTextureSizeBase::deinit(void)
108 {
109     /* Get GL entry points */
110     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
111 
112     /* Reset Opengl ES configuration */
113     gl.useProgram(0);
114     gl.bindVertexArray(0);
115 
116     /* Delete GLES objects specific for the test */
117     deleteTestSpecificObjects();
118 
119     /* Delete shader objects */
120     deleteProgram();
121 
122     if (m_po_id != 0)
123     {
124         gl.deleteProgram(m_po_id);
125         m_po_id = 0;
126     }
127 
128     if (m_vao_id != 0)
129     {
130         gl.deleteVertexArrays(1, &m_vao_id);
131         m_vao_id = 0;
132     }
133 
134     /* Delete texture objects */
135     deleteTextures();
136 
137     /* Deinitialize base class */
138     TestCaseBase::deinit();
139 }
140 
141 /** Executes the test.
142  *
143  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
144  *
145  *  Note the function throws exception should an error occur!
146  *
147  *  @return STOP if the test has finished, CONTINUE to indicate iterate() should be called once again.
148  **/
iterate(void)149 tcu::TestCase::IterateResult TextureCubeMapArrayTextureSizeBase::iterate(void)
150 {
151     /* Initialize test case */
152     initTest();
153 
154     /* Get GL entry points */
155     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
156 
157     glw::GLboolean test_passed = true;
158 
159     /* Use program object */
160     gl.useProgram(m_po_id);
161     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set active program object.");
162 
163     glw::GLuint width  = 0;
164     glw::GLuint height = 0;
165     glw::GLuint depth  = 0;
166 
167     /* Go through IMMUTABLE AND MUTABLE storages */
168     for (glw::GLuint i = 0; i < m_n_storage_types; ++i)
169     {
170         if (!isMutableTextureTestable() && (STORAGE_TYPE)i == ST_MUTABLE)
171         {
172             continue;
173         }
174 
175         /* Go through all resolutions */
176         for (glw::GLuint j = 0; j < m_n_resolutions; ++j)
177         {
178             width  = resolutionArray[j][0];
179             height = resolutionArray[j][1];
180             depth  = resolutionArray[j][2];
181 
182             /* Configure texture objects */
183             configureTextures(width, height, depth, (STORAGE_TYPE)i);
184 
185             /* Configure uniforms */
186             configureUniforms();
187 
188             /* Run shaders to get texture size */
189             runShaders();
190 
191             /* Check if results are as expected */
192             if (!checkResults(width, height, depth, (STORAGE_TYPE)i))
193             {
194                 test_passed = false;
195             }
196 
197             /* Delete texture objects used for this iteration */
198             deleteTextures();
199         }
200     }
201 
202     /* Set proper test result */
203     if (test_passed)
204         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
205     else
206         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
207 
208     return STOP;
209 }
210 
211 /** Method to check if the test supports mutable textures.
212  *
213  *  @return return true if mutable textures work with the test
214  **/
isMutableTextureTestable(void)215 glw::GLboolean TextureCubeMapArrayTextureSizeBase::isMutableTextureTestable(void)
216 {
217     return true;
218 }
219 
220 /** Method to create texture cube map array with proper configuration
221  @param texId    pointer to variable where texture id will be stored
222  @param width    texture width
223  @param height   texture height
224  @param depth    texture depth
225  @param storType inform if texture should be mutable or immutable
226  @param shadow   inform if texture should be shadow texture or not
227  */
createCubeMapArrayTexture(glw::GLuint & texId,glw::GLuint width,glw::GLuint height,glw::GLuint depth,STORAGE_TYPE storType,glw::GLboolean shadow)228 void TextureCubeMapArrayTextureSizeBase::createCubeMapArrayTexture(glw::GLuint &texId, glw::GLuint width,
229                                                                    glw::GLuint height, glw::GLuint depth,
230                                                                    STORAGE_TYPE storType, glw::GLboolean shadow)
231 {
232     /* Get Gl entry points */
233     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
234 
235     /* Save the current binding */
236     glw::GLuint savedTexId = 0;
237     gl.getIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARRAY, (glw::GLint *)&savedTexId);
238 
239     /* Generate Texture object */
240     gl.genTextures(1, &texId);
241     GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object.");
242 
243     /* Bind texture object */
244     gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, texId);
245     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object.");
246 
247     /* Create immutable texture storage */
248     if (storType == ST_IMMUTABLE)
249     {
250         /* Create shadow texture object */
251         if (shadow)
252         {
253             gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
254             gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
255             gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
256             gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
257             GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture parameter.");
258 
259             gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_DEPTH_COMPONENT32F, width, height, depth);
260             GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating immutable texture storage.");
261         }
262         /* Create texture object */
263         else
264         {
265             gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
266             gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
267             GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture parameter.");
268 
269             gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA32F, width, height, depth);
270             GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating immutable texture storage.");
271         }
272     }
273     /* Create mutable texture storage */
274     else
275     {
276         std::vector<glw::GLfloat> data(width * height * depth * m_n_texture_components, 0);
277 
278         /* Create shadow texture object */
279         if (shadow)
280         {
281             gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
282             gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
283             gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
284             gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
285             gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
286             gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
287             GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture parameter.");
288 
289             gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_DEPTH_COMPONENT32F, width, height, depth, 0,
290                           GL_DEPTH_COMPONENT, GL_FLOAT, &data[0]);
291             GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating mutable texture storage.");
292         }
293         /* Create texture object */
294         else
295         {
296             gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
297             gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
298             gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
299             gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
300             GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture parameter.");
301 
302             gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA32F, width, height, depth, 0, GL_RGBA, GL_FLOAT,
303                           &data[0]);
304             GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating mutable texture storage.");
305         }
306     }
307 
308     /* Restore the original texture binding */
309     gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, savedTexId);
310     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object.");
311 }
312 
313 /** Configure textures used in the test for textureSize() and imageSize() calls
314  @param width    texture width
315  @param height   texture height
316  @param depth    texture depth
317  @param storType inform if texture should be mutable or immutable
318  */
configureTextures(glw::GLuint width,glw::GLuint height,glw::GLuint depth,STORAGE_TYPE storType)319 void TextureCubeMapArrayTextureSizeBase::configureTextures(glw::GLuint width, glw::GLuint height, glw::GLuint depth,
320                                                            STORAGE_TYPE storType)
321 {
322     /* Get Gl entry points */
323     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
324 
325     /* Create texture objects which will be tested */
326     createCubeMapArrayTexture(m_to_std_id, width, height, depth, storType, false);
327     createCubeMapArrayTexture(m_to_shw_id, width, height, depth, storType, true);
328 
329     /* Binding texture object to texture unit */
330     gl.activeTexture(GL_TEXTURE0);
331     gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_to_std_id);
332     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
333 
334     /* Binding texture object to texture unit */
335     gl.activeTexture(GL_TEXTURE1);
336     gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_to_shw_id);
337     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
338 }
339 
340 /** Delete textures used in the test for textureSize() and imageSize() calls */
deleteTextures(void)341 void TextureCubeMapArrayTextureSizeBase::deleteTextures(void)
342 {
343     /* Get Gl entry points */
344     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
345 
346     /* Reset GLES state */
347     gl.activeTexture(GL_TEXTURE0);
348     gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
349     gl.activeTexture(GL_TEXTURE1);
350     gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
351     gl.activeTexture(GL_TEXTURE0);
352 
353     /* Delete GLES objects */
354     if (m_to_std_id != 0)
355     {
356         gl.deleteTextures(1, &m_to_std_id);
357         m_to_std_id = 0;
358     }
359 
360     if (m_to_shw_id != 0)
361     {
362         gl.deleteTextures(1, &m_to_shw_id);
363         m_to_shw_id = 0;
364     }
365 }
366 
367 /** Configure uniform variables */
configureUniforms(void)368 void TextureCubeMapArrayTextureSizeBase::configureUniforms(void)
369 {
370     /* Get Gl entry points */
371     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
372 
373     /* Bind uniform samplers to texture units */
374     glw::GLint texture_std_location = gl.getUniformLocation(m_po_id, "texture_std_sampler");
375     GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting sampler location!");
376 
377     gl.uniform1i(texture_std_location, 0);
378     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding sampler to texture unit!");
379 
380     glw::GLint texture_shw_location = gl.getUniformLocation(m_po_id, "texture_shw_sampler");
381     GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting sampler location!");
382 
383     gl.uniform1i(texture_shw_location, 1);
384     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding sampler to texture unit!");
385 }
386 
387 /* Static const variables used for configuring tests */
388 const glw::GLsizei TextureCubeMapArrayTextureSizeTFBase::m_n_varyings     = 2;
389 const glw::GLuint TextureCubeMapArrayTextureSizeTFBase::m_n_tf_components = 3;
390 
391 /** Constructor
392  *
393  *  @param context       Test context
394  *  @param name          Test case's name
395  *  @param description   Test case's description
396  **/
TextureCubeMapArrayTextureSizeTFBase(Context & context,const ExtParameters & extParams,const char * name,const char * description)397 TextureCubeMapArrayTextureSizeTFBase::TextureCubeMapArrayTextureSizeTFBase(Context &context,
398                                                                            const ExtParameters &extParams,
399                                                                            const char *name, const char *description)
400     : TextureCubeMapArrayTextureSizeBase(context, extParams, name, description)
401     , m_tf_bo_id(0)
402 {
403     /* Nothing to be done here */
404 }
405 
406 /** Configure GLES objects specific for the test configuration */
configureTestSpecificObjects(void)407 void TextureCubeMapArrayTextureSizeTFBase::configureTestSpecificObjects(void)
408 {
409     /* Get GL entry points */
410     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
411 
412     gl.genBuffers(1, &m_tf_bo_id);
413     GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object.");
414 
415     gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_tf_bo_id);
416     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object.");
417 
418     std::vector<glw::GLint> buffer_data(m_n_varyings * m_n_tf_components, 0);
419 
420     gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, m_n_varyings * m_n_tf_components * sizeof(glw::GLint), &buffer_data[0],
421                   GL_DYNAMIC_COPY);
422     GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating buffer object's data store.");
423 
424     gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_tf_bo_id);
425     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object to transform feedback binding point.");
426 }
427 
428 /** Delete GLES objects specific for the test configuration */
deleteTestSpecificObjects(void)429 void TextureCubeMapArrayTextureSizeTFBase::deleteTestSpecificObjects(void)
430 {
431     /* Get GL entry points */
432     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
433 
434     gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
435     gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
436 
437     /* Delete transform feedback buffer */
438     if (m_tf_bo_id != 0)
439     {
440         gl.deleteBuffers(1, &m_tf_bo_id);
441         m_tf_bo_id = 0;
442     }
443 }
444 
445 /** Configure textures used in the test for textureSize() and imageSize() calls
446  @param width    texture width
447  @param height   texture height
448  @param depth    texture depth
449  @param storType inform if texture should be mutable or immutable
450  */
configureTextures(glw::GLuint width,glw::GLuint height,glw::GLuint depth,STORAGE_TYPE storType)451 void TextureCubeMapArrayTextureSizeTFBase::configureTextures(glw::GLuint width, glw::GLuint height, glw::GLuint depth,
452                                                              STORAGE_TYPE storType)
453 {
454     TextureCubeMapArrayTextureSizeBase::configureTextures(width, height, depth, storType);
455 
456     /* Get Gl entry points */
457     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
458 
459     std::vector<glw::GLint> buffer_data(m_n_varyings * m_n_tf_components, 0);
460 
461     gl.bufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_n_varyings * m_n_tf_components * sizeof(glw::GLint),
462                      &buffer_data[0]);
463     GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling buffer object's data store with data.");
464 }
465 
466 /** Check textureSize() and imageSize() methods returned proper values
467  * @param  width    texture width
468  * @param  height   texture height
469  * @param  depth    texture depth
470  * @param  storType inform if texture is mutable or immutable
471  * @return          return true if result data is as expected
472  */
checkResults(glw::GLuint width,glw::GLuint height,glw::GLuint depth,STORAGE_TYPE storType)473 glw::GLboolean TextureCubeMapArrayTextureSizeTFBase::checkResults(glw::GLuint width, glw::GLuint height,
474                                                                   glw::GLuint depth, STORAGE_TYPE storType)
475 {
476     /* Get GL entry points */
477     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
478 
479     /* Read results from transform feedback */
480     glw::GLuint *temp_buff = (glw::GLuint *)gl.mapBufferRange(
481         GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_n_varyings * m_n_tf_components * sizeof(glw::GLuint), GL_MAP_READ_BIT);
482     GLU_EXPECT_NO_ERROR(gl.getError(), "Error mapping buffer object's data store to client's address space.");
483 
484     /* Copy results to helper buffer */
485     glw::GLuint read_size[m_n_varyings * m_n_tf_components];
486     memcpy(read_size, temp_buff, m_n_varyings * m_n_tf_components * sizeof(glw::GLint));
487 
488     gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
489     GLU_EXPECT_NO_ERROR(gl.getError(), "Error ummapping transform feedback buffer.");
490 
491     glw::GLboolean test_passed = true;
492 
493     /* Elements under index 0-2 contain result of textureSize called for samplerCubeArray sampler */
494     if (read_size[0] != width || read_size[1] != height || read_size[2] != (depth / m_n_layers_per_cube))
495     {
496         getTestContext().getLog()
497             << tcu::TestLog::Message
498             << "Storage Type: " << ((storType == ST_MUTABLE) ? mutableStorage : imMutableStorage) << "\n"
499             << "textureSize() for samplerCubeArray returned wrong values. [width][height][layers]. They are equal "
500             << "[" << read_size[0] << "][" << read_size[1] << "][" << read_size[2] << "] but should be "
501             << "[" << width << "][" << height << "][" << depth / m_n_layers_per_cube << "]."
502             << tcu::TestLog::EndMessage;
503         test_passed = false;
504     }
505 
506     /* Elements under index 3-5 contain result of textureSize called for samplerCubeArrayShadow sampler */
507     if (read_size[3] != width || read_size[4] != height || read_size[5] != (depth / m_n_layers_per_cube))
508     {
509         getTestContext().getLog() << tcu::TestLog::Message
510                                   << "Storage Type: " << ((storType == ST_MUTABLE) ? mutableStorage : imMutableStorage)
511                                   << "\n"
512                                   << "textureSize() for samplerCubeArrayShadow returned wrong values. "
513                                      "[width][height][layers]. They are equal "
514                                   << "[" << read_size[3] << "][" << read_size[4] << "][" << read_size[5]
515                                   << "] but should be "
516                                   << "[" << width << "][" << height << "][" << depth / m_n_layers_per_cube << "]."
517                                   << tcu::TestLog::EndMessage;
518         test_passed = false;
519     }
520 
521     return test_passed;
522 }
523 
524 /** Constructor
525  *
526  *  @param context       Test context
527  *  @param name          Test case's name
528  *  @param description   Test case's description
529  **/
TextureCubeMapArrayTextureSizeTFVertexShader(Context & context,const ExtParameters & extParams,const char * name,const char * description)530 TextureCubeMapArrayTextureSizeTFVertexShader::TextureCubeMapArrayTextureSizeTFVertexShader(
531     Context &context, const ExtParameters &extParams, const char *name, const char *description)
532     : TextureCubeMapArrayTextureSizeTFBase(context, extParams, name, description)
533     , m_vs_id(0)
534     , m_fs_id(0)
535 {
536     /* Nothing to be done here */
537 }
538 
539 /* Configure program object */
configureProgram(void)540 void TextureCubeMapArrayTextureSizeTFVertexShader::configureProgram(void)
541 {
542     /* Get GL entry points */
543     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
544 
545     /* Set transform feedback varyings */
546     const char *varyings[] = {"texture_std_size", "texture_shw_size"};
547     gl.transformFeedbackVaryings(m_po_id, m_n_varyings, varyings, GL_INTERLEAVED_ATTRIBS);
548     GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting transform feedback varyings.");
549 
550     const char *vsCode = getVertexShaderCode();
551     const char *fsCode = getFragmentShaderCode();
552 
553     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
554     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object.");
555     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
556     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object.");
557 
558     if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fsCode, m_vs_id, 1 /* part */, &vsCode))
559     {
560         TCU_FAIL("Could not compile/link program object from valid shader code.");
561     }
562 }
563 
564 /** Delete program object */
deleteProgram(void)565 void TextureCubeMapArrayTextureSizeTFVertexShader::deleteProgram(void)
566 {
567     /* Get GL entry points */
568     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
569 
570     /* Delete shader objects */
571     if (m_vs_id != 0)
572     {
573         gl.deleteShader(m_vs_id);
574         m_vs_id = 0;
575     }
576 
577     if (m_fs_id != 0)
578     {
579         gl.deleteShader(m_fs_id);
580         m_fs_id = 0;
581     }
582 }
583 
584 /** Render or dispatch compute */
runShaders(void)585 void TextureCubeMapArrayTextureSizeTFVertexShader::runShaders(void)
586 {
587     /* Get GL entry points */
588     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
589 
590     gl.beginTransformFeedback(GL_POINTS);
591     GLU_EXPECT_NO_ERROR(gl.getError(), "Error beginning transform feedback.");
592 
593     gl.drawArrays(GL_POINTS, 0, 1);
594     GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!");
595 
596     gl.endTransformFeedback();
597     GLU_EXPECT_NO_ERROR(gl.getError(), "Error ending transform feedback.");
598 }
599 
600 /** Returns code for Vertex Shader
601  *  @return pointer to literal with Vertex Shader code
602  **/
getVertexShaderCode(void)603 const char *TextureCubeMapArrayTextureSizeTFVertexShader::getVertexShaderCode(void)
604 {
605     static const char *result = "${VERSION}\n"
606                                 "\n"
607                                 "${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
608                                 "\n"
609                                 "precision highp float;\n"
610                                 "\n"
611                                 "uniform highp samplerCubeArray       texture_std_sampler;\n"
612                                 "uniform highp samplerCubeArrayShadow texture_shw_sampler;\n"
613                                 "\n"
614                                 "layout (location = 0) out flat uvec3 texture_std_size;\n"
615                                 "layout (location = 1) out flat uvec3 texture_shw_size;\n"
616                                 "\n"
617                                 "void main()\n"
618                                 "{\n"
619                                 "    gl_PointSize = 1.0f;\n"
620                                 "\n"
621                                 "    texture_std_size = uvec3( textureSize(texture_std_sampler, 0) );\n"
622                                 "    texture_shw_size = uvec3( textureSize(texture_shw_sampler, 0) );\n"
623                                 "    gl_Position      = vec4(0.0f,0.0f,0.0f,0.0f);\n"
624                                 "}\n";
625     return result;
626 }
627 
628 /** Return code for Fragment Shader
629  *  @return pointer to literal with Fragment Shader code
630  **/
getFragmentShaderCode(void)631 const char *TextureCubeMapArrayTextureSizeTFVertexShader::getFragmentShaderCode(void)
632 {
633     static const char *result = "${VERSION}\n"
634                                 "\n"
635                                 "precision highp float;\n"
636                                 "\n"
637                                 "void main()\n"
638                                 "{\n"
639                                 "}\n";
640     return result;
641 }
642 
643 /** Constructor
644  *
645  *  @param context       Test context
646  *  @param name          Test case's name
647  *  @param description   Test case's description
648  **/
TextureCubeMapArrayTextureSizeTFGeometryShader(Context & context,const ExtParameters & extParams,const char * name,const char * description)649 TextureCubeMapArrayTextureSizeTFGeometryShader::TextureCubeMapArrayTextureSizeTFGeometryShader(
650     Context &context, const ExtParameters &extParams, const char *name, const char *description)
651     : TextureCubeMapArrayTextureSizeTFBase(context, extParams, name, description)
652     , m_vs_id(0)
653     , m_gs_id(0)
654     , m_fs_id(0)
655 {
656     /* Nothing to be done here */
657 }
658 
659 /* Configure program object */
configureProgram(void)660 void TextureCubeMapArrayTextureSizeTFGeometryShader::configureProgram(void)
661 {
662     /* Check if geometry_shader extension is supported */
663     if (!m_is_geometry_shader_extension_supported)
664     {
665         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
666     }
667 
668     /* Get GL entry points */
669     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
670 
671     /* Set transform feedback varyings */
672     const char *varyings[] = {"texture_std_size", "texture_shw_size"};
673     gl.transformFeedbackVaryings(m_po_id, m_n_varyings, varyings, GL_INTERLEAVED_ATTRIBS);
674     GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting transform feedback varyings.");
675 
676     const char *vsCode = getVertexShaderCode();
677     const char *gsCode = getGeometryShaderCode();
678     const char *fsCode = getFragmentShaderCode();
679 
680     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
681     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object.");
682     m_gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
683     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object.");
684     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
685     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object.");
686 
687     if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fsCode, m_gs_id, 1 /* part */, &gsCode, m_vs_id, 1 /* part */,
688                       &vsCode))
689     {
690         TCU_FAIL("Could not compile/link program object from valid shader code.");
691     }
692 }
693 
694 /** Delete program object */
deleteProgram(void)695 void TextureCubeMapArrayTextureSizeTFGeometryShader::deleteProgram(void)
696 {
697     /* Get GL entry points */
698     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
699 
700     /* Delete shader objects */
701     if (m_vs_id != 0)
702     {
703         gl.deleteShader(m_vs_id);
704         m_vs_id = 0;
705     }
706 
707     if (m_gs_id != 0)
708     {
709         gl.deleteShader(m_gs_id);
710         m_gs_id = 0;
711     }
712 
713     if (m_fs_id != 0)
714     {
715         gl.deleteShader(m_fs_id);
716         m_fs_id = 0;
717     }
718 }
719 
runShaders(void)720 void TextureCubeMapArrayTextureSizeTFGeometryShader::runShaders(void)
721 {
722     /* Get GL entry points */
723     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
724 
725     gl.beginTransformFeedback(GL_POINTS);
726     GLU_EXPECT_NO_ERROR(gl.getError(), "Error beginning transform feedback.");
727 
728     gl.drawArrays(GL_POINTS, 0, 1);
729     GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!");
730 
731     gl.endTransformFeedback();
732     GLU_EXPECT_NO_ERROR(gl.getError(), "Error ending transform feedback.");
733 }
734 
735 /** Returns code for Vertex Shader
736  *  @return pointer to literal with Vertex Shader code
737  **/
getVertexShaderCode(void)738 const char *TextureCubeMapArrayTextureSizeTFGeometryShader::getVertexShaderCode(void)
739 {
740     static const char *result = "${VERSION}\n"
741                                 "\n"
742                                 "precision highp float;\n"
743                                 "\n"
744                                 "void main()\n"
745                                 "{\n"
746                                 "    gl_Position      = vec4(0.0f,0.0f,0.0f,0.0f);\n"
747                                 "}\n";
748     return result;
749 }
750 
751 /** Return code for Geometry Shader
752  *  @return pointer to literal with Geometry Shader code
753  **/
getGeometryShaderCode(void)754 const char *TextureCubeMapArrayTextureSizeTFGeometryShader::getGeometryShaderCode(void)
755 {
756     static const char *result = "${VERSION}\n"
757                                 "\n"
758                                 "${GEOMETRY_SHADER_ENABLE}\n"
759                                 "${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
760                                 "\n"
761                                 "precision highp float;\n"
762                                 "\n"
763                                 "uniform highp samplerCubeArray       texture_std_sampler;\n"
764                                 "uniform highp samplerCubeArrayShadow texture_shw_sampler;\n"
765                                 "\n"
766                                 "layout (location = 0) out flat uvec3 texture_std_size;\n"
767                                 "layout (location = 1) out flat uvec3 texture_shw_size;\n"
768                                 "\n"
769                                 "layout(points)                 in;\n"
770                                 "layout(points, max_vertices=1) out;\n"
771                                 "\n"
772                                 "void main()\n"
773                                 "{\n"
774                                 "    texture_std_size = uvec3( textureSize(texture_std_sampler, 0) );\n"
775                                 "    texture_shw_size = uvec3( textureSize(texture_shw_sampler, 0) );\n"
776                                 "    gl_Position      = vec4(0.0f,0.0f,0.0f,0.0f);\n"
777                                 "    EmitVertex();\n"
778                                 "    EndPrimitive();\n"
779                                 "}\n";
780     return result;
781 }
782 
783 /** Return code for Fragment Shader
784  *  @return pointer to literal with Fragment Shader code
785  **/
getFragmentShaderCode(void)786 const char *TextureCubeMapArrayTextureSizeTFGeometryShader::getFragmentShaderCode(void)
787 {
788     static const char *result = "${VERSION}\n"
789                                 "\n"
790                                 "precision highp float;\n"
791                                 "\n"
792                                 "void main()\n"
793                                 "{\n"
794                                 "}\n";
795     return result;
796 }
797 
798 /** Constructor
799  *
800  *  @param context       Test context
801  *  @param name          Test case's name
802  *  @param description   Test case's description
803  **/
TextureCubeMapArrayTextureSizeTFTessControlShader(Context & context,const ExtParameters & extParams,const char * name,const char * description)804 TextureCubeMapArrayTextureSizeTFTessControlShader::TextureCubeMapArrayTextureSizeTFTessControlShader(
805     Context &context, const ExtParameters &extParams, const char *name, const char *description)
806     : TextureCubeMapArrayTextureSizeTFBase(context, extParams, name, description)
807     , m_vs_id(0)
808     , m_tcs_id(0)
809     , m_tes_id(0)
810     , m_fs_id(0)
811 {
812     /* Nothing to be done here */
813 }
814 
815 /* Configure program object */
configureProgram(void)816 void TextureCubeMapArrayTextureSizeTFTessControlShader::configureProgram(void)
817 {
818     /* Check if tessellation_shader extension is supported */
819     if (!m_is_tessellation_shader_supported)
820     {
821         throw tcu::NotSupportedError(TESSELLATION_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
822     }
823 
824     /* Get GL entry points */
825     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
826 
827     /* Set transform feedback varyings */
828     const char *varyings[] = {"texture_std_size", "texture_shw_size"};
829     gl.transformFeedbackVaryings(m_po_id, m_n_varyings, varyings, GL_INTERLEAVED_ATTRIBS);
830     GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting transform feedback varyings.");
831 
832     const char *vsCode  = getVertexShaderCode();
833     const char *tcsCode = getTessellationControlShaderCode();
834     const char *tesCode = getTessellationEvaluationShaderCode();
835     const char *fsCode  = getFragmentShaderCode();
836 
837     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
838     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object.");
839     m_tcs_id = gl.createShader(m_glExtTokens.TESS_CONTROL_SHADER);
840     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object.");
841     m_tes_id = gl.createShader(m_glExtTokens.TESS_EVALUATION_SHADER);
842     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object.");
843     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
844     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object.");
845 
846     if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fsCode, m_tcs_id, 1 /* part */, &tcsCode, m_tes_id, 1 /* part */,
847                       &tesCode, m_vs_id, 1 /* part */, &vsCode))
848     {
849         TCU_FAIL("Could not compile/link program object from valid shader code.");
850     }
851 }
852 
853 /** Delete program object */
deleteProgram(void)854 void TextureCubeMapArrayTextureSizeTFTessControlShader::deleteProgram(void)
855 {
856     /* Get GL entry points */
857     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
858 
859     /* Delete shader objects */
860     if (m_vs_id != 0)
861     {
862         gl.deleteShader(m_vs_id);
863         m_vs_id = 0;
864     }
865 
866     if (m_tcs_id != 0)
867     {
868         gl.deleteShader(m_tcs_id);
869         m_tcs_id = 0;
870     }
871 
872     if (m_tes_id != 0)
873     {
874         gl.deleteShader(m_tes_id);
875         m_tes_id = 0;
876     }
877 
878     if (m_fs_id != 0)
879     {
880         gl.deleteShader(m_fs_id);
881         m_fs_id = 0;
882     }
883 }
884 
885 /** Render or dispatch compute */
runShaders(void)886 void TextureCubeMapArrayTextureSizeTFTessControlShader::runShaders(void)
887 {
888     /* Get GL entry points */
889     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
890 
891     gl.beginTransformFeedback(GL_POINTS);
892     GLU_EXPECT_NO_ERROR(gl.getError(), "Error beginning transform feedback.");
893 
894     gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 1);
895     GLU_EXPECT_NO_ERROR(gl.getError(), "Setting number of vertices per patch failed");
896 
897     gl.drawArrays(m_glExtTokens.PATCHES, 0, 1);
898     GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!");
899 
900     gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 3);
901     GLU_EXPECT_NO_ERROR(gl.getError(), "Setting number of vertices per patch failed");
902 
903     gl.endTransformFeedback();
904     GLU_EXPECT_NO_ERROR(gl.getError(), "Error ending transform feedback.");
905 }
906 
907 /** Returns code for Vertex Shader
908  *  @return pointer to literal with Vertex Shader code
909  **/
getVertexShaderCode(void)910 const char *TextureCubeMapArrayTextureSizeTFTessControlShader::getVertexShaderCode(void)
911 {
912     static const char *result = "${VERSION}\n"
913                                 "\n"
914                                 "precision highp float;\n"
915                                 "\n"
916                                 "void main()\n"
917                                 "{\n"
918                                 "    gl_Position      = vec4(0.0f,0.0f,0.0f,0.0f);\n"
919                                 "}\n";
920     return result;
921 }
922 
923 /** Return code for Tessellation Control Shader
924  *  @return pointer to literal with Tessellation Control Shader code
925  **/
getTessellationControlShaderCode(void)926 const char *TextureCubeMapArrayTextureSizeTFTessControlShader::getTessellationControlShaderCode(void)
927 {
928     static const char *result =
929         "${VERSION}\n"
930         "\n"
931         "${TESSELLATION_SHADER_ENABLE}\n"
932         "${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
933         "\n"
934         "precision highp float;\n"
935         "\n"
936         "uniform highp samplerCubeArray       texture_std_sampler;\n"
937         "uniform highp samplerCubeArrayShadow texture_shw_sampler;\n"
938         "\n"
939         "layout (location = 0) out flat uvec3 texture_std_size_array[];\n"
940         "layout (location = 1) out flat uvec3 texture_shw_size_array[];\n"
941         "\n"
942         "layout (vertices = 1) out;\n"
943         "\n"
944         "void main()\n"
945         "{\n"
946         "    gl_TessLevelInner[0] = 1.0;\n"
947         "    gl_TessLevelInner[1] = 1.0;\n"
948         "    gl_TessLevelOuter[0] = 1.0;\n"
949         "    gl_TessLevelOuter[1] = 1.0;\n"
950         "    gl_TessLevelOuter[2] = 1.0;\n"
951         "    gl_TessLevelOuter[3] = 1.0;\n"
952         "    texture_std_size_array[gl_InvocationID]    = uvec3( textureSize(texture_std_sampler, 0) );\n"
953         "    texture_shw_size_array[gl_InvocationID]    = uvec3( textureSize(texture_shw_sampler, 0) );\n"
954         "    gl_out[gl_InvocationID].gl_Position        = vec4(0.0f,0.0f,0.0f,0.0f);\n"
955         "}\n";
956     return result;
957 }
958 
959 /** Returns code for Tessellation Evaluation Shader
960  * @return pointer to literal with Tessellation Evaluation code
961  **/
getTessellationEvaluationShaderCode(void)962 const char *TextureCubeMapArrayTextureSizeTFTessControlShader::getTessellationEvaluationShaderCode(void)
963 {
964     static const char *result = "${VERSION}\n"
965                                 "\n"
966                                 "${TESSELLATION_SHADER_REQUIRE}\n"
967                                 "\n"
968                                 "layout(isolines, point_mode) in;\n"
969                                 "\n"
970                                 "in layout(location = 0) flat uvec3 texture_std_size_array[];\n"
971                                 "in layout(location = 1) flat uvec3 texture_shw_size_array[];\n"
972                                 "\n"
973                                 "out flat uvec3 texture_std_size;\n"
974                                 "out flat uvec3 texture_shw_size;\n"
975                                 "\n"
976                                 "void main()\n"
977                                 "{\n"
978                                 "    texture_std_size = texture_std_size_array[0];\n"
979                                 "    texture_shw_size = texture_shw_size_array[0];\n"
980                                 "    gl_Position      = vec4(0.0f,0.0f,0.0f,0.0f);\n"
981                                 "}\n";
982     return result;
983 }
984 
985 /** Return code for Fragment Shader
986  *  @return pointer to literal with Fragment Shader code
987  **/
getFragmentShaderCode(void)988 const char *TextureCubeMapArrayTextureSizeTFTessControlShader::getFragmentShaderCode(void)
989 {
990     static const char *result = "${VERSION}\n"
991                                 "\n"
992                                 "precision highp float;\n"
993                                 "\n"
994                                 "void main()\n"
995                                 "{\n"
996                                 "}\n";
997     return result;
998 }
999 
1000 /** Constructor
1001  *
1002  *  @param context       Test context
1003  *  @param name          Test case's name
1004  *  @param description   Test case's description
1005  **/
TextureCubeMapArrayTextureSizeTFTessEvaluationShader(Context & context,const ExtParameters & extParams,const char * name,const char * description)1006 TextureCubeMapArrayTextureSizeTFTessEvaluationShader::TextureCubeMapArrayTextureSizeTFTessEvaluationShader(
1007     Context &context, const ExtParameters &extParams, const char *name, const char *description)
1008     : TextureCubeMapArrayTextureSizeTFTessControlShader(context, extParams, name, description)
1009 {
1010     /* Nothing to be done here */
1011 }
1012 
1013 /** Return code for Tessellation Control Shader
1014  *  @return pointer to literal with Tessellation Control Shader code
1015  **/
getTessellationControlShaderCode(void)1016 const char *TextureCubeMapArrayTextureSizeTFTessEvaluationShader::getTessellationControlShaderCode(void)
1017 {
1018     static const char *result = "${VERSION}\n"
1019                                 "\n"
1020                                 "${TESSELLATION_SHADER_ENABLE}\n"
1021                                 "\n"
1022                                 "precision highp float;\n"
1023                                 "\n"
1024                                 "layout (vertices = 1) out;\n"
1025                                 "\n"
1026                                 "void main()\n"
1027                                 "{\n"
1028                                 "    gl_TessLevelInner[0] = 1.0;\n"
1029                                 "    gl_TessLevelInner[1] = 1.0;\n"
1030                                 "    gl_TessLevelOuter[0] = 1.0;\n"
1031                                 "    gl_TessLevelOuter[1] = 1.0;\n"
1032                                 "    gl_TessLevelOuter[2] = 1.0;\n"
1033                                 "    gl_TessLevelOuter[3] = 1.0;\n"
1034                                 "    gl_out[gl_InvocationID].gl_Position = vec4(0.0f,0.0f,0.0f,0.0f);\n"
1035                                 "}\n";
1036     return result;
1037 }
1038 
1039 /** Returns code for Tessellation Evaluation Shader
1040  * @return pointer to literal with Tessellation Evaluation code
1041  **/
getTessellationEvaluationShaderCode(void)1042 const char *TextureCubeMapArrayTextureSizeTFTessEvaluationShader::getTessellationEvaluationShaderCode(void)
1043 {
1044     static const char *result = "${VERSION}\n"
1045                                 "\n"
1046                                 "${TESSELLATION_SHADER_REQUIRE}\n"
1047                                 "${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
1048                                 "\n"
1049                                 "layout(isolines, point_mode) in;\n"
1050                                 "\n"
1051                                 "uniform highp samplerCubeArray       texture_std_sampler;\n"
1052                                 "uniform highp samplerCubeArrayShadow texture_shw_sampler;\n"
1053                                 "\n"
1054                                 "layout (location = 0) out flat uvec3 texture_std_size;\n"
1055                                 "layout (location = 1) out flat uvec3 texture_shw_size;\n"
1056                                 "\n"
1057                                 "void main()\n"
1058                                 "{\n"
1059                                 "    texture_std_size   = uvec3( textureSize(texture_std_sampler, 0) );\n"
1060                                 "    texture_shw_size   = uvec3( textureSize(texture_shw_sampler, 0) );\n"
1061                                 "    gl_Position        = vec4(0.0f,0.0f,0.0f,0.0f);\n"
1062                                 "}\n";
1063     return result;
1064 }
1065 
1066 const glw::GLuint TextureCubeMapArrayTextureSizeRTBase::m_n_rt_components = 4;
1067 
1068 /** Constructor
1069  *
1070  *  @param context       Test context
1071  *  @param name          Test case's name
1072  *  @param description   Test case's description
1073  **/
TextureCubeMapArrayTextureSizeRTBase(Context & context,const ExtParameters & extParams,const char * name,const char * description)1074 TextureCubeMapArrayTextureSizeRTBase::TextureCubeMapArrayTextureSizeRTBase(Context &context,
1075                                                                            const ExtParameters &extParams,
1076                                                                            const char *name, const char *description)
1077     : TextureCubeMapArrayTextureSizeBase(context, extParams, name, description)
1078     , m_read_fbo_id(0)
1079     , m_rt_std_id(0)
1080     , m_rt_shw_id(0)
1081 {
1082     /* Nothing to be done here */
1083 }
1084 
1085 /** Configure GLES objects specific for the test configuration */
configureTestSpecificObjects(void)1086 void TextureCubeMapArrayTextureSizeRTBase::configureTestSpecificObjects(void)
1087 {
1088     /* Get GL entry points */
1089     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1090 
1091     glw::GLint rt_data[m_n_rt_components];
1092     memset(rt_data, 0, m_n_rt_components * sizeof(glw::GLuint));
1093 
1094     /* Create texture which will store result of textureSize() for samplerCubeArray sampler */
1095     gl.genTextures(1, &m_rt_std_id);
1096     GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!");
1097 
1098     gl.activeTexture(GL_TEXTURE0);
1099     gl.bindTexture(GL_TEXTURE_2D, m_rt_std_id);
1100     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
1101 
1102     gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32UI, 1, 1);
1103     GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating storage for texture object!");
1104 
1105     gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, rt_data);
1106     GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture object's data store with data!");
1107 
1108     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1109     GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!");
1110     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1111     GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!");
1112 
1113     /* Create texture which will store result of textureSize() for samplerCubeArrayShadow sampler */
1114     gl.genTextures(1, &m_rt_shw_id);
1115     GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!");
1116 
1117     gl.activeTexture(GL_TEXTURE1);
1118     gl.bindTexture(GL_TEXTURE_2D, m_rt_shw_id);
1119     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
1120 
1121     gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32UI, 1, 1);
1122     GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating storage for texture object!");
1123 
1124     gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, rt_data);
1125     GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture object's data store with data!");
1126 
1127     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1128     GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!");
1129     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1130     GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!");
1131 
1132     /* Generate frame buffer object */
1133     gl.genFramebuffers(1, &m_read_fbo_id);
1134     GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating frame buffer object!");
1135 }
1136 
1137 /** Delete GLES objects specific for the test configuration */
deleteTestSpecificObjects(void)1138 void TextureCubeMapArrayTextureSizeRTBase::deleteTestSpecificObjects(void)
1139 {
1140     /* Get GL entry points */
1141     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1142 
1143     /* Reset GL state */
1144     gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1145     gl.activeTexture(GL_TEXTURE0);
1146     gl.bindTexture(GL_TEXTURE_2D, 0);
1147     gl.activeTexture(GL_TEXTURE1);
1148     gl.bindTexture(GL_TEXTURE_2D, 0);
1149     gl.activeTexture(GL_TEXTURE0);
1150 
1151     /* Delete GL objects */
1152     if (m_read_fbo_id != 0)
1153     {
1154         gl.deleteFramebuffers(1, &m_read_fbo_id);
1155         m_read_fbo_id = 0;
1156     }
1157 
1158     if (m_rt_std_id != 0)
1159     {
1160         gl.deleteTextures(1, &m_rt_std_id);
1161         m_rt_std_id = 0;
1162     }
1163 
1164     if (m_rt_shw_id != 0)
1165     {
1166         gl.deleteTextures(1, &m_rt_shw_id);
1167         m_rt_shw_id = 0;
1168     }
1169 }
1170 
1171 /** Check textureSize() and imageSize() methods returned proper values
1172  * @param  width    texture width
1173  * @param  height   texture height
1174  * @param  depth    texture depth
1175  * @param  storType inform if texture is mutable or immutable
1176  * @return          return true if result data is as expected
1177  */
checkResults(glw::GLuint width,glw::GLuint height,glw::GLuint depth,STORAGE_TYPE storType)1178 glw::GLboolean TextureCubeMapArrayTextureSizeRTBase::checkResults(glw::GLuint width, glw::GLuint height,
1179                                                                   glw::GLuint depth, STORAGE_TYPE storType)
1180 {
1181     /* Get GL entry points */
1182     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1183 
1184     glw::GLboolean test_passed = true;
1185 
1186     glw::GLuint read_size[m_n_rt_components];
1187     memset(read_size, 0, m_n_rt_components * sizeof(glw::GLuint));
1188 
1189     gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_read_fbo_id);
1190 
1191     /* Compare returned results of textureSize() called for samplerCubeArray sampler*/
1192     gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt_std_id, 0);
1193     GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to frame buffer");
1194 
1195     /* Check framebuffer status */
1196     checkFramebufferStatus(GL_READ_FRAMEBUFFER);
1197 
1198     gl.readPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, read_size);
1199     GLU_EXPECT_NO_ERROR(gl.getError(), "Error reading pixles from frame buffer!");
1200 
1201     if (read_size[0] != width || read_size[1] != height || read_size[2] != (depth / m_n_layers_per_cube))
1202     {
1203         getTestContext().getLog()
1204             << tcu::TestLog::Message
1205             << "Storage Type: " << ((storType == ST_MUTABLE) ? mutableStorage : imMutableStorage) << "\n"
1206             << "textureSize() for samplerCubeArray returned wrong values of [width][height][layers]. They are equal to"
1207             << "[" << read_size[0] << "][" << read_size[1] << "][" << read_size[2] << "] but should be "
1208             << "[" << width << "][" << height << "][" << depth / m_n_layers_per_cube << "]."
1209             << tcu::TestLog::EndMessage;
1210         test_passed = false;
1211     }
1212 
1213     /* Compare returned results of textureSize() for samplerCubeArrayShadow sampler*/
1214     gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt_shw_id, 0);
1215     GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to frame buffer");
1216 
1217     /* Check framebuffer status */
1218     checkFramebufferStatus(GL_READ_FRAMEBUFFER);
1219 
1220     gl.readPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, read_size);
1221     GLU_EXPECT_NO_ERROR(gl.getError(), "Error reading pixles from frame buffer!");
1222 
1223     if (read_size[0] != width || read_size[1] != height || read_size[2] != (depth / m_n_layers_per_cube))
1224     {
1225         getTestContext().getLog() << tcu::TestLog::Message
1226                                   << "Storage Type: " << ((storType == ST_MUTABLE) ? mutableStorage : imMutableStorage)
1227                                   << "\n"
1228                                   << "textureSize() for samplerCubeArrayShadow returned wrong values of "
1229                                      "[width][height][layers]. They are equal to"
1230                                   << "[" << read_size[0] << "][" << read_size[1] << "][" << read_size[2]
1231                                   << "] but should be "
1232                                   << "[" << width << "][" << height << "][" << depth / m_n_layers_per_cube << "]."
1233                                   << tcu::TestLog::EndMessage;
1234         test_passed = false;
1235     }
1236 
1237     return test_passed;
1238 }
1239 
1240 /** Check Framebuffer Status. Throws a TestError exception, should the framebuffer status
1241  *  be found incomplete.
1242  *
1243  *  @param framebuffer - GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER or GL_FRAMEBUFFER
1244  *
1245  */
checkFramebufferStatus(glw::GLenum framebuffer)1246 void TextureCubeMapArrayTextureSizeRTBase::checkFramebufferStatus(glw::GLenum framebuffer)
1247 {
1248     /* Get GL entry points */
1249     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1250 
1251     glw::GLenum framebuffer_status = gl.checkFramebufferStatus(framebuffer);
1252     GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting framebuffer status!");
1253 
1254     if (GL_FRAMEBUFFER_COMPLETE != framebuffer_status)
1255     {
1256         switch (framebuffer_status)
1257         {
1258         case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
1259         {
1260             TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
1261         }
1262 
1263         case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
1264         {
1265             TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
1266         }
1267 
1268         case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
1269         {
1270             TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
1271         }
1272 
1273         case GL_FRAMEBUFFER_UNSUPPORTED:
1274         {
1275             TCU_FAIL("Framebuffer incomplete, status: Error: GL_FRAMEBUFFER_UNSUPPORTED");
1276         }
1277 
1278         default:
1279         {
1280             TCU_FAIL("Framebuffer incomplete, status not recognized");
1281         }
1282         } /* switch (framebuffer_status) */
1283     }     /* if (GL_FRAMEBUFFER_COMPLETE != framebuffer_status) */
1284 }
1285 
1286 /** Constructor
1287  *
1288  *  @param context       Test context
1289  *  @param name          Test case's name
1290  *  @param description   Test case's description
1291  **/
TextureCubeMapArrayTextureSizeRTFragmentShader(Context & context,const ExtParameters & extParams,const char * name,const char * description)1292 TextureCubeMapArrayTextureSizeRTFragmentShader::TextureCubeMapArrayTextureSizeRTFragmentShader(
1293     Context &context, const ExtParameters &extParams, const char *name, const char *description)
1294     : TextureCubeMapArrayTextureSizeRTBase(context, extParams, name, description)
1295     , m_draw_fbo_id(0)
1296     , m_vs_id(0)
1297     , m_fs_id(0)
1298 {
1299     /* Nothing to be done here */
1300 }
1301 
1302 /** Configure GLES objects specific for the test configuration */
configureTestSpecificObjects(void)1303 void TextureCubeMapArrayTextureSizeRTFragmentShader::configureTestSpecificObjects(void)
1304 {
1305     /* Get GL entry points */
1306     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1307 
1308     TextureCubeMapArrayTextureSizeRTBase::configureTestSpecificObjects();
1309 
1310     /* Generate frame buffer object */
1311     gl.genFramebuffers(1, &m_draw_fbo_id);
1312     GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating frame buffer object!");
1313 }
1314 
1315 /** Delete GLES objects specific for the test configuration */
deleteTestSpecificObjects(void)1316 void TextureCubeMapArrayTextureSizeRTFragmentShader::deleteTestSpecificObjects(void)
1317 {
1318     /* Get GL entry points */
1319     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1320 
1321     /* Reset GLES state */
1322     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1323 
1324     /* Delete GLEs objects */
1325     if (m_draw_fbo_id != 0)
1326     {
1327         gl.deleteFramebuffers(1, &m_draw_fbo_id);
1328         m_draw_fbo_id = 0;
1329     }
1330 
1331     TextureCubeMapArrayTextureSizeRTBase::deleteTestSpecificObjects();
1332 }
1333 
1334 /* Configure program object */
configureProgram(void)1335 void TextureCubeMapArrayTextureSizeRTFragmentShader::configureProgram(void)
1336 {
1337     /* Get GL entry points */
1338     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1339 
1340     const char *vsCode = getVertexShaderCode();
1341     const char *fsCode = getFragmentShaderCode();
1342 
1343     m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1344     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object.");
1345     m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1346     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object.");
1347 
1348     if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fsCode, m_vs_id, 1 /* part */, &vsCode))
1349     {
1350         TCU_FAIL("Could not compile/link program object from valid shader code.");
1351     }
1352 }
1353 
1354 /** Delete program object */
deleteProgram(void)1355 void TextureCubeMapArrayTextureSizeRTFragmentShader::deleteProgram(void)
1356 {
1357     /* Get GL entry points */
1358     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1359 
1360     /* Delete shader objects */
1361     if (m_vs_id != 0)
1362     {
1363         gl.deleteShader(m_vs_id);
1364         m_vs_id = 0;
1365     }
1366 
1367     if (m_fs_id != 0)
1368     {
1369         gl.deleteShader(m_fs_id);
1370         m_fs_id = 0;
1371     }
1372 }
1373 
1374 /** Return code for bolierPlate Vertex Shader
1375  * @return pointer to literal with Vertex Shader code
1376  **/
getVertexShaderCode(void)1377 const char *TextureCubeMapArrayTextureSizeRTFragmentShader::getVertexShaderCode(void)
1378 {
1379     static const char *result = "${VERSION}\n"
1380                                 "\n"
1381                                 "precision highp float;\n"
1382                                 "\n"
1383                                 "void main()\n"
1384                                 "{\n"
1385                                 "    gl_PointSize = 1.0f;\n"
1386                                 "    gl_Position = vec4(0, 0, 0, 1.0f);\n"
1387                                 "}\n";
1388 
1389     return result;
1390 }
1391 
1392 /** Return code for Fragment Shader
1393  * @return pointer to literal with Fragment Shader code
1394  **/
getFragmentShaderCode(void)1395 const char *TextureCubeMapArrayTextureSizeRTFragmentShader::getFragmentShaderCode(void)
1396 {
1397     static const char *result = "${VERSION}\n"
1398                                 "\n"
1399                                 "${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
1400                                 "\n"
1401                                 "precision highp float;\n"
1402                                 "\n"
1403                                 "uniform highp samplerCubeArray       texture_std_sampler;\n"
1404                                 "uniform highp samplerCubeArrayShadow texture_shw_sampler;\n"
1405                                 "\n"
1406                                 "layout (location = 0) out uvec4 texture_std_size;\n"
1407                                 "layout (location = 1) out uvec4 texture_shw_size;\n"
1408                                 "\n"
1409                                 "void main()\n"
1410                                 "{\n"
1411                                 "    texture_std_size = uvec4( textureSize(texture_std_sampler, 0), 0 );\n"
1412                                 "    texture_shw_size = uvec4( textureSize(texture_shw_sampler, 0), 0 );\n"
1413                                 "}\n";
1414 
1415     return result;
1416 }
1417 
runShaders(void)1418 void TextureCubeMapArrayTextureSizeRTFragmentShader::runShaders(void)
1419 {
1420     /* Get GL entry points */
1421     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1422 
1423     /* Configure draw framebuffer */
1424     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_draw_fbo_id);
1425     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding framebuffer object");
1426 
1427     gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt_std_id, 0);
1428     GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to GL_COLOR_ATTACHMENT0");
1429     gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, m_rt_shw_id, 0);
1430     GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to GL_COLOR_ATTACHMENT0");
1431 
1432     /* Check framebuffer status */
1433     checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
1434 
1435     /* Configure draw buffers for fragment shader */
1436     const glw::GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
1437     gl.drawBuffers(2, drawBuffers);
1438     GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting draw buffers");
1439 
1440     glw::GLint viewport_size[4];
1441     gl.getIntegerv(GL_VIEWPORT, viewport_size);
1442 
1443     gl.viewport(0, 0, 1, 1);
1444     GLU_EXPECT_NO_ERROR(gl.getError(), "Setting viewport");
1445 
1446     gl.drawArrays(GL_POINTS, 0, 1);
1447     GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!");
1448 
1449     gl.viewport(viewport_size[0], viewport_size[1], viewport_size[2], viewport_size[3]);
1450     GLU_EXPECT_NO_ERROR(gl.getError(), "Setting viewport");
1451 }
1452 
1453 /** Constructor
1454  *
1455  *  @param context       Test context
1456  *  @param name          Test case's name
1457  *  @param description   Test case's description
1458  **/
TextureCubeMapArrayTextureSizeRTComputeShader(Context & context,const ExtParameters & extParams,const char * name,const char * description)1459 TextureCubeMapArrayTextureSizeRTComputeShader::TextureCubeMapArrayTextureSizeRTComputeShader(
1460     Context &context, const ExtParameters &extParams, const char *name, const char *description)
1461     : TextureCubeMapArrayTextureSizeRTBase(context, extParams, name, description)
1462     , m_cs_id(0)
1463     , m_to_img_id(0)
1464     , m_rt_img_id(0)
1465 {
1466     /* Nothing to be done here */
1467 }
1468 
1469 /** Configure program object */
configureProgram(void)1470 void TextureCubeMapArrayTextureSizeRTComputeShader::configureProgram(void)
1471 {
1472     /* Get GL entry points */
1473     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1474 
1475     const char *csCode = getComputeShaderCode();
1476 
1477     m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
1478     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object.");
1479 
1480     /* Build program */
1481     if (!buildProgram(m_po_id, m_cs_id, 1 /* part */, &csCode))
1482     {
1483         TCU_FAIL("Could not compile/link program object from valid shader code.");
1484     }
1485 }
1486 
1487 /** Delete program object */
deleteProgram(void)1488 void TextureCubeMapArrayTextureSizeRTComputeShader::deleteProgram(void)
1489 {
1490     /* Get GL entry points */
1491     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1492 
1493     /* Delete shader objects */
1494     if (m_cs_id != 0)
1495     {
1496         gl.deleteShader(m_cs_id);
1497         m_cs_id = 0;
1498     }
1499 }
1500 
1501 /** Returns code for Compute Shader
1502  * @return pointer to literal with Compute Shader code
1503  **/
getComputeShaderCode(void)1504 const char *TextureCubeMapArrayTextureSizeRTComputeShader::getComputeShaderCode(void)
1505 {
1506     static const char *result =
1507         "${VERSION}\n"
1508         "\n"
1509         "${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
1510         "\n"
1511         "precision highp float;\n"
1512         "\n"
1513         "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1514         "\n"
1515         "                               uniform highp samplerCubeArray       texture_std_sampler;\n"
1516         "                               uniform highp samplerCubeArrayShadow texture_shw_sampler;\n"
1517         "layout(rgba32f,  binding = 0)  writeonly uniform highp imageCubeArray         texture_img_sampler;\n"
1518         "\n"
1519         "layout (rgba32ui, binding = 1) uniform highp writeonly uimage2D image_std_size;\n"
1520         "layout (rgba32ui, binding = 2) uniform highp writeonly uimage2D image_shw_size;\n"
1521         "layout (rgba32ui, binding = 3) uniform highp writeonly uimage2D image_img_size;\n"
1522         "\n"
1523         "void main(void)\n"
1524         "{\n"
1525         "    imageStore(image_std_size, ivec2(0,0),  uvec4(uvec3( textureSize(texture_std_sampler, 0)), 0) );\n"
1526         "    imageStore(image_shw_size, ivec2(0,0),  uvec4(uvec3( textureSize(texture_shw_sampler, 0)), 0) );\n"
1527         "    imageStore(image_img_size, ivec2(0,0),  uvec4(uvec3( imageSize  (texture_img_sampler)), 0) );\n"
1528         "}\n";
1529 
1530     return result;
1531 }
1532 
1533 /** Configure GLES objects specific for the test configuration */
configureTestSpecificObjects(void)1534 void TextureCubeMapArrayTextureSizeRTComputeShader::configureTestSpecificObjects(void)
1535 {
1536     TextureCubeMapArrayTextureSizeRTBase::configureTestSpecificObjects();
1537 
1538     /* Get GL entry points */
1539     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1540 
1541     glw::GLuint rt_data[m_n_rt_components];
1542     memset(rt_data, 0, m_n_rt_components * sizeof(glw::GLuint));
1543 
1544     /* Create texture which will store result of imageSize() for imageCubeArray image */
1545     gl.genTextures(1, &m_rt_img_id);
1546     GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!");
1547 
1548     gl.activeTexture(GL_TEXTURE2);
1549     gl.bindTexture(GL_TEXTURE_2D, m_rt_img_id);
1550     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
1551 
1552     gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32UI, 1, 1);
1553     GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating storage for texture object!");
1554 
1555     gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, rt_data);
1556     GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture object's data store with data!");
1557 
1558     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1559     GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!");
1560     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1561     GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!");
1562 
1563     /* Image unit binding start from index 1 for compute shader results */
1564     gl.bindImageTexture(1, m_rt_std_id, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI);
1565     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit");
1566     gl.bindImageTexture(2, m_rt_shw_id, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI);
1567     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit");
1568     gl.bindImageTexture(3, m_rt_img_id, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI);
1569     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit");
1570 }
1571 
1572 /** Delete GLES objects specific for the test configuration */
deleteTestSpecificObjects(void)1573 void TextureCubeMapArrayTextureSizeRTComputeShader::deleteTestSpecificObjects(void)
1574 {
1575     /* Get GL entry points */
1576     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1577 
1578     /* Reset GL state */
1579     gl.activeTexture(GL_TEXTURE2);
1580     gl.bindTexture(GL_TEXTURE_2D, 0);
1581 
1582     /* Delete GL objects */
1583     if (m_rt_img_id != 0)
1584     {
1585         gl.deleteTextures(1, &m_rt_img_id);
1586         m_rt_img_id = 0;
1587     }
1588 
1589     TextureCubeMapArrayTextureSizeRTBase::deleteTestSpecificObjects();
1590 }
1591 
1592 /** Configure textures used in the test for textureSize() and imageSize() calls
1593  @param width    texture width
1594  @param height   texture height
1595  @param depth    texture depth
1596  @param storType inform if texture should be mutable or immutable
1597  */
configureTextures(glw::GLuint width,glw::GLuint height,glw::GLuint depth,STORAGE_TYPE storType)1598 void TextureCubeMapArrayTextureSizeRTComputeShader::configureTextures(glw::GLuint width, glw::GLuint height,
1599                                                                       glw::GLuint depth, STORAGE_TYPE storType)
1600 {
1601     TextureCubeMapArrayTextureSizeRTBase::configureTextures(width, height, depth, storType);
1602 
1603     /* Get GL entry points */
1604     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1605 
1606     createCubeMapArrayTexture(m_to_img_id, width, height, depth, storType, false);
1607 
1608     /* Binding texture object to texture unit */
1609     gl.activeTexture(GL_TEXTURE2);
1610     gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_to_img_id);
1611     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
1612 
1613     gl.bindImageTexture(0, m_to_img_id, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32F);
1614     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit");
1615 }
1616 
1617 /** Delete textures used in the test for textureSize() and imageSize() calls */
deleteTextures(void)1618 void TextureCubeMapArrayTextureSizeRTComputeShader::deleteTextures(void)
1619 {
1620     /* Get Gl entry points */
1621     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1622 
1623     /* Reset GLES state */
1624     gl.activeTexture(GL_TEXTURE2);
1625     gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
1626 
1627     /* Delete GLES objects */
1628     if (m_to_img_id != 0)
1629     {
1630         gl.deleteTextures(1, &m_to_img_id);
1631         m_to_img_id = 0;
1632     }
1633 
1634     TextureCubeMapArrayTextureSizeRTBase::deleteTextures();
1635 }
1636 
1637 /** Render or dispatch compute */
runShaders(void)1638 void TextureCubeMapArrayTextureSizeRTComputeShader::runShaders(void)
1639 {
1640     /* Get GL entry points */
1641     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1642 
1643     gl.dispatchCompute(1, 1, 1);
1644     GLU_EXPECT_NO_ERROR(gl.getError(), "Error executing compute shader");
1645     gl.memoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
1646     GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting memory barrier!");
1647 }
1648 
1649 /** Check textureSize() and imageSize() methods returned proper values
1650  * @param  width    texture width
1651  * @param  height   texture height
1652  * @param  depth    texture depth
1653  * @param  storType inform if texture is mutable or immutable
1654  * @return          return true if result data is as expected
1655  */
checkResults(glw::GLuint width,glw::GLuint height,glw::GLuint depth,STORAGE_TYPE storType)1656 glw::GLboolean TextureCubeMapArrayTextureSizeRTComputeShader::checkResults(glw::GLuint width, glw::GLuint height,
1657                                                                            glw::GLuint depth, STORAGE_TYPE storType)
1658 {
1659     glw::GLboolean test_passed = TextureCubeMapArrayTextureSizeRTBase::checkResults(width, height, depth, storType);
1660 
1661     /* Get GL entry points */
1662     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1663 
1664     glw::GLuint read_size[m_n_rt_components];
1665     memset(read_size, 0, m_n_rt_components * sizeof(glw::GLuint));
1666 
1667     /* Compare returned results of imageSize() for imageCubeArray image */
1668     gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt_img_id, 0);
1669     GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to frame buffer");
1670 
1671     /* Check framebuffer status */
1672     checkFramebufferStatus(GL_READ_FRAMEBUFFER);
1673 
1674     gl.readPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, read_size);
1675     GLU_EXPECT_NO_ERROR(gl.getError(), "Error reading pixles from frame buffer!");
1676 
1677     if (read_size[0] != width || read_size[1] != height || read_size[2] != (depth / m_n_layers_per_cube))
1678     {
1679         getTestContext().getLog()
1680             << tcu::TestLog::Message
1681             << "Storage Type: " << ((storType == ST_MUTABLE) ? mutableStorage : imMutableStorage) << "\n"
1682             << "imageSize() for imageCubeArray returned wrong values of [width][height][layers]. They are equal to"
1683             << "[" << read_size[0] << "][" << read_size[1] << "][" << read_size[2] << "] but should be "
1684             << "[" << width << "][" << height << "][" << depth / m_n_layers_per_cube << "]."
1685             << tcu::TestLog::EndMessage;
1686         test_passed = false;
1687     }
1688 
1689     return test_passed;
1690 }
1691 
1692 /** Method to check if the test supports mutable textures.
1693  *
1694  *  @return return true if mutable textures work with the test
1695  */
isMutableTextureTestable(void)1696 glw::GLboolean TextureCubeMapArrayTextureSizeRTComputeShader::isMutableTextureTestable(void)
1697 {
1698     /**
1699      * Mutable textures cannot be bound as image textures on ES, but can be on
1700      * desktop GL. This check enables/disables testing of mutable image textures.
1701      */
1702     if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
1703     {
1704         return true;
1705     }
1706     else
1707     {
1708         return false;
1709     }
1710 }
1711 
1712 } // namespace glcts
1713