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 #include "esextcTextureCubeMapArrayColorDepthAttachments.hpp"
25 
26 #include "gluContextInfo.hpp"
27 #include "glwEnums.hpp"
28 #include "glwFunctions.hpp"
29 #include "tcuTestLog.hpp"
30 
31 namespace glcts
32 {
33 /* Shader parts */
34 const glw::GLchar *const TextureCubeMapArrayColorDepthAttachmentsTest::m_fragment_shader_code =
35     "${VERSION}\n"
36     "/* FS */\n"
37     "\n"
38     "precision highp float;\n"
39     "\n"
40     "in flat int fs_in_color;\n"
41     "\n"
42     "layout(location = 0) out int fs_out_color;\n"
43     "\n"
44     "void main()\n"
45     "{\n"
46     "    fs_out_color = fs_in_color;\n"
47     "}\n"
48     "\n";
49 
50 const glw::GLchar *const TextureCubeMapArrayColorDepthAttachmentsTest::m_geometry_shader_code_preamble =
51     "${VERSION}\n"
52     "/* Layered GS */\n"
53     "\n"
54     "${GEOMETRY_SHADER_REQUIRE}\n"
55     "\n"
56     "precision highp float;\n"
57     "\n"
58     "layout(points)                         in;\n"
59     "layout(triangle_strip, max_vertices=4) out;\n"
60     "\n";
61 
62 const glw::GLchar *const TextureCubeMapArrayColorDepthAttachmentsTest::m_geometry_shader_code_layered =
63     "in  flat int vs_out_layer[];\n"
64     "\n"
65     "out flat int fs_in_color;\n"
66     "\n"
67     "void main()\n"
68     "{\n"
69     "    int   layer = vs_out_layer[0];\n";
70 
71 const glw::GLchar *const TextureCubeMapArrayColorDepthAttachmentsTest::m_geometry_shader_code_non_layered =
72     "uniform  int uni_layer;\n"
73     "\n"
74     "out flat int fs_in_color;\n"
75     "\n"
76     "void main()\n"
77     "{\n"
78     "    int   layer = uni_layer;\n";
79 
80 const glw::GLchar *const TextureCubeMapArrayColorDepthAttachmentsTest::m_geometry_shader_code_body =
81     ";\n"
82     "    \n"
83     "    // Left-Bottom\n"
84     "    gl_Position = vec4(-1.0, -1.0, depth, 1);\n"
85     "    gl_Layer    = layer;\n"
86     "    fs_in_color = layer;\n"
87     "    EmitVertex();\n"
88     "    \n"
89     "    // Left-Top\n"
90     "    gl_Position = vec4(-1.0,  1.0, depth, 1);\n"
91     "    gl_Layer    = layer;\n"
92     "    fs_in_color = layer;\n"
93     "    EmitVertex();\n"
94     "    \n"
95     "    // Right-Bottom\n"
96     "    gl_Position = vec4( 1.0, -1.0, depth, 1);\n"
97     "    gl_Layer    = layer;\n"
98     "    fs_in_color = layer;\n"
99     "    EmitVertex();\n"
100     "    \n"
101     "    // Right-Top\n"
102     "    gl_Position = vec4( 1.0,  1.0, depth, 1);\n"
103     "    gl_Layer    = layer;\n"
104     "    fs_in_color = layer;\n"
105     "    EmitVertex();\n"
106     "    EndPrimitive();\n"
107     "}\n"
108     "\n";
109 
110 const glw::GLchar *const TextureCubeMapArrayColorDepthAttachmentsTest::m_vertex_shader_code =
111     "${VERSION}\n"
112     "/* VS */\n"
113     "\n"
114     "precision highp float;\n"
115     "\n"
116     "flat out int vs_out_layer;\n"
117     "\n"
118     "void main()\n"
119     "{\n"
120     "    gl_PointSize = 1.0f;\n"
121     "    vs_out_layer = gl_VertexID;\n"
122     "}\n"
123     "\n";
124 
125 /* Static constants */
126 const glw::GLenum TextureCubeMapArrayColorDepthAttachmentsTest::m_color_internal_format = GL_R32I;
127 const glw::GLenum TextureCubeMapArrayColorDepthAttachmentsTest::m_color_format          = GL_RED_INTEGER;
128 const glw::GLenum TextureCubeMapArrayColorDepthAttachmentsTest::m_color_type            = GL_INT;
129 const glw::GLenum TextureCubeMapArrayColorDepthAttachmentsTest::m_depth_format          = GL_DEPTH_COMPONENT;
130 
131 /** Verifies all texels in user-provided data buffer are equal to user-specified vector value.
132  *
133  * @tparam T            Type of image components
134  * @tparam N_Components Number of image components
135  *
136  * @param  image_width  Width of image
137  * @param  image_height Height of image
138  * @param  components   Amount of components per texel
139  * @param  image        Image data
140  *
141  * @return true if all texels are found valid, false otherwise.
142  **/
143 template <typename T, unsigned int N_Components>
verifyImage(glw::GLuint image_width,glw::GLuint image_height,const T * components,const T * image)144 bool verifyImage(glw::GLuint image_width, glw::GLuint image_height, const T *components, const T *image)
145 {
146     const glw::GLuint line_size = image_width * N_Components;
147 
148     for (glw::GLuint y = 0; y < image_height; ++y)
149     {
150         const glw::GLuint line_offset = y * line_size;
151 
152         for (glw::GLuint x = 0; x < image_width; ++x)
153         {
154             const glw::GLuint pixel_offset = line_offset + x * N_Components;
155 
156             for (glw::GLuint component = 0; component < N_Components; ++component)
157             {
158                 if (image[pixel_offset + component] != components[component])
159                 {
160                     return false;
161                 }
162             } /* for (all components) */
163         }     /* for (all columns) */
164     }         /* for (all rows) */
165 
166     return true;
167 }
168 
169 /** Constructor
170  *
171  * @param size       Size of texture
172  * @param n_cubemaps Number of cube-maps in array
173  **/
_texture_size(glw::GLuint size,glw::GLuint n_cubemaps)174 TextureCubeMapArrayColorDepthAttachmentsTest::_texture_size::_texture_size(glw::GLuint size, glw::GLuint n_cubemaps)
175     : m_size(size)
176     , m_n_cubemaps(n_cubemaps)
177 {
178     /* Nothing to be done here */
179 }
180 
181 /** Constructor
182  *
183  * @param context       Test context
184  * @param name          Test case's name
185  * @param description   Test case's description
186  **/
TextureCubeMapArrayColorDepthAttachmentsTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)187 TextureCubeMapArrayColorDepthAttachmentsTest::TextureCubeMapArrayColorDepthAttachmentsTest(
188     Context &context, const ExtParameters &extParams, const char *name, const char *description)
189     : TestCaseBase(context, extParams, name, description)
190     , m_vao_id(0)
191     , m_color_texture_id(0)
192     , m_depth_texture_id(0)
193     , m_fragment_shader_id(0)
194     , m_framebuffer_object_id(0)
195     , m_layered_geometry_shader_id(0)
196     , m_layered_program_id(0)
197     , m_non_layered_geometry_shader_id(0)
198     , m_non_layered_program_id(0)
199     , m_non_layered_program_id_uni_layer_uniform_location(0)
200     , m_vertex_shader_id(0)
201     , m_depth_internal_format(0)
202     , m_depth_type(0)
203     , m_n_invalid_color_checks(0)
204     , m_n_invalid_depth_checks(0)
205 {
206     /* Define tested resolutions */
207     m_resolutions.push_back(_texture_size(8, 8));
208     m_resolutions.push_back(_texture_size(64, 3));
209     m_resolutions.push_back(_texture_size(117, 1));
210     m_resolutions.push_back(_texture_size(256, 1));
211     m_resolutions.push_back(_texture_size(173, 3));
212 }
213 
214 /** Attaches an user-specified texture object to zeroth color attachment OR depth attachment of
215  *  test-maintained FBO in a layered manner.
216  *
217  * @param texture_id                     Texture object's ID.
218  * @param should_use_as_color_attachment true to attach the texture object to GL_COLOR_ATTACHMENT0 of
219  *                                       the test-maintained FBO; false to use GL_DEPTH_ATTACHMENT
220  *                                       binding point.
221  **/
configureLayeredFramebufferAttachment(glw::GLuint texture_id,bool should_use_as_color_attachment)222 void TextureCubeMapArrayColorDepthAttachmentsTest::configureLayeredFramebufferAttachment(
223     glw::GLuint texture_id, bool should_use_as_color_attachment)
224 {
225     glw::GLenum attachment   = GL_NONE;
226     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
227 
228     /* Determine which attachment should be used */
229     if (true == should_use_as_color_attachment)
230     {
231         attachment = GL_COLOR_ATTACHMENT0;
232     }
233     else
234     {
235         attachment = GL_DEPTH_ATTACHMENT;
236     }
237 
238     /* Re-bind the draw framebuffer, just in case. */
239     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer_object_id);
240     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
241 
242     /* Update the FBO's attachment  */
243     gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, attachment, texture_id, 0 /* level */);
244     GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureEXT() call failed.");
245 }
246 
247 /** Attaches an user-specified texture object to zeroth color attachment OR depth attachment of
248  *  test-maintained FBO in a non-layered manner.
249  *
250  * @param texture_id                     Texture object's ID.
251  * @param n_layer                        Layer of the texture to attach.
252  * @param should_use_as_color_attachment true to attach the texture object to GL_COLOR_ATTACHMENT0 of
253  *                                       the test-maintained FBO; false to use GL_DEPTH_ATTACHMENT
254  *                                       binding point.
255  * @param should_update_draw_framebuffer true to bind the test-maintained FBO to GL_DRAW_FRAMEBUFFER
256  *                                       binding point first, false to use GL_READ_FRAMEBUFFER binding
257  *                                       point.
258  **/
configureNonLayeredFramebufferAttachment(glw::GLuint texture_id,glw::GLuint n_layer,bool should_use_as_color_attachment,bool should_update_draw_framebuffer)259 void TextureCubeMapArrayColorDepthAttachmentsTest::configureNonLayeredFramebufferAttachment(
260     glw::GLuint texture_id, glw::GLuint n_layer, bool should_use_as_color_attachment,
261     bool should_update_draw_framebuffer)
262 {
263     glw::GLenum attachment_type    = GL_NONE;
264     glw::GLenum framebuffer_target = GL_NONE;
265     const glw::Functions &gl       = m_context.getRenderContext().getFunctions();
266 
267     /* Determine which attachment should be used */
268     if (true == should_use_as_color_attachment)
269     {
270         attachment_type = GL_COLOR_ATTACHMENT0;
271     }
272     else
273     {
274         attachment_type = GL_DEPTH_ATTACHMENT;
275     }
276 
277     /* Determine which framebuffer target should be used */
278     if (true == should_update_draw_framebuffer)
279     {
280         framebuffer_target = GL_DRAW_FRAMEBUFFER;
281     }
282     else
283     {
284         framebuffer_target = GL_READ_FRAMEBUFFER;
285     }
286 
287     /* Re-bind the framebuffer, just in case. */
288     gl.bindFramebuffer(framebuffer_target, m_framebuffer_object_id);
289     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
290 
291     /* Use the specified texture layer as attachment */
292     gl.framebufferTextureLayer(framebuffer_target, attachment_type, texture_id, 0 /* level */, n_layer);
293     GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() call failed.");
294 }
295 
296 /* Deinitializes GLES objects created during the test. */
deinit()297 void TextureCubeMapArrayColorDepthAttachmentsTest::deinit()
298 {
299     /* Deinitialize base class */
300     TestCaseBase::deinit();
301 
302     if (true != m_is_texture_cube_map_array_supported)
303     {
304         return;
305     }
306     if (true != m_is_geometry_shader_extension_supported)
307     {
308         return;
309     }
310 
311     /* GL functions */
312     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
313 
314     /* Release texture objects */
315     releaseAndDetachTextureObject(m_color_texture_id, true /* is_color_attachment */);
316     releaseAndDetachTextureObject(m_depth_texture_id, false /* is_color_attachment */);
317 
318     /* Restore default state */
319     gl.useProgram(0);
320     gl.bindVertexArray(0);
321 
322     /* Delete all remaining ES objects the test may have created. */
323     if (0 != m_fragment_shader_id)
324     {
325         gl.deleteShader(m_fragment_shader_id);
326 
327         m_fragment_shader_id = 0;
328     }
329 
330     if (0 != m_framebuffer_object_id)
331     {
332         gl.deleteFramebuffers(1, &m_framebuffer_object_id);
333 
334         m_framebuffer_object_id = 0;
335     }
336 
337     if (0 != m_layered_geometry_shader_id)
338     {
339         gl.deleteShader(m_layered_geometry_shader_id);
340 
341         m_layered_geometry_shader_id = 0;
342     }
343 
344     if (0 != m_layered_program_id)
345     {
346         gl.deleteProgram(m_layered_program_id);
347 
348         m_layered_program_id = 0;
349     }
350 
351     if (0 != m_non_layered_geometry_shader_id)
352     {
353         gl.deleteShader(m_non_layered_geometry_shader_id);
354 
355         m_non_layered_geometry_shader_id = 0;
356     }
357 
358     if (0 != m_non_layered_program_id)
359     {
360         gl.deleteProgram(m_non_layered_program_id);
361 
362         m_non_layered_program_id = 0;
363     }
364 
365     if (0 != m_vertex_shader_id)
366     {
367         gl.deleteShader(m_vertex_shader_id);
368 
369         m_vertex_shader_id = 0;
370     }
371 
372     if (m_vao_id != 0)
373     {
374         gl.deleteVertexArrays(1, &m_vao_id);
375 
376         m_vao_id = 0;
377     }
378 }
379 
380 /* Determines depth internalformat that can be used for a draw framebuffer.
381  * The result is stored in m_depth_internal_format and m_depth_type.
382  **/
determineSupportedDepthFormat()383 void TextureCubeMapArrayColorDepthAttachmentsTest::determineSupportedDepthFormat()
384 {
385     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
386 
387     /* Start with 16-bit depth internalformat */
388     m_depth_internal_format = GL_DEPTH_COMPONENT16;
389     m_depth_type            = GL_UNSIGNED_SHORT;
390 
391     while (true)
392     {
393         /* Create color and depth texture objectss */
394         generateAndConfigureTextureObjects(8,      /* texture_width */
395                                            1,      /* n_cubemaps */
396                                            false); /* should_generate_mutable_textures */
397 
398         /* Set framebuffer attachments up */
399         configureNonLayeredFramebufferAttachment(m_color_texture_id, 0 /* layer */, true /* is_color_attachment */,
400                                                  true /* should_update_draw_framebuffer */);
401         configureNonLayeredFramebufferAttachment(m_depth_texture_id, 0 /* layer */, false /* is_color_attachment */,
402                                                  true /* should_update_draw_framebuffer */);
403 
404         /* Check framebuffer status */
405         const glw::GLenum framebuffer_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
406 
407         if (GL_FRAMEBUFFER_COMPLETE == framebuffer_status)
408         {
409             return;
410         }
411 
412         /* Current format does not work too well, try another one */
413         switch (m_depth_internal_format)
414         {
415         case GL_DEPTH_COMPONENT16:
416         {
417             m_depth_internal_format = GL_DEPTH_COMPONENT24;
418             m_depth_type            = GL_UNSIGNED_INT;
419 
420             break;
421         }
422 
423         case GL_DEPTH_COMPONENT24:
424         {
425             m_depth_internal_format = GL_DEPTH_COMPONENT32F;
426             m_depth_type            = GL_FLOAT;
427 
428             break;
429         }
430 
431         case GL_DEPTH_COMPONENT32F:
432         {
433             throw tcu::NotSupportedError("Implementation does not support any known depth format");
434         }
435 
436         default:
437         {
438             TCU_FAIL("Unrecognized depth internalformat");
439         }
440         } /* switch (m_depth_internal_format) */
441     }     /* while (true) */
442 }
443 
444 /** Execute a draw call that renders (texture_size.m_n_cubemaps * 6) points.
445  *  First, the viewport is configured to match the texture resolution and
446  *  both color & depth buffers are cleared.
447  *
448  *  @param texture_size Render-target resolution.
449  *
450  **/
draw(const _texture_size & texture_size)451 void TextureCubeMapArrayColorDepthAttachmentsTest::draw(const _texture_size &texture_size)
452 {
453     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
454 
455     /* Set up the viewport */
456     gl.viewport(0, /* x */
457                 0, /* y */
458                 texture_size.m_size, texture_size.m_size);
459     GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed.");
460 
461     /* Clear color & depth buffers */
462     gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
463     GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");
464 
465     gl.drawArrays(GL_POINTS, 0 /* first */, texture_size.m_n_cubemaps * 6 /* layer-faces per cube-map */);
466     GLU_EXPECT_NO_ERROR(gl.getError(), "drawArrays");
467 }
468 
469 /** Releases existing color & depth cube-map texture array objects, generates new
470  *  ones and configures them as per user-specified properties.
471  *
472  *  @param texture_width                    Size to use for each layer-face's width and height.
473  *  @param n_cubemaps                       Number of cube-maps to initialize for the cube-map texture arrays.
474  *  @param should_generate_mutable_textures true if the texture should be initialized as mutable, false otherwise.
475  **/
generateAndConfigureTextureObjects(glw::GLuint texture_width,glw::GLuint n_cubemaps,bool should_generate_mutable_textures)476 void TextureCubeMapArrayColorDepthAttachmentsTest::generateAndConfigureTextureObjects(
477     glw::GLuint texture_width, glw::GLuint n_cubemaps, bool should_generate_mutable_textures)
478 {
479     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
480 
481     /* Release any texture objects that may have already been initialized */
482     releaseAndDetachTextureObject(m_color_texture_id, true /* is_color_attachment */);
483     releaseAndDetachTextureObject(m_depth_texture_id, false /* is_color_attachment */);
484 
485     /* Generate texture objects */
486     gl.genTextures(1, &m_color_texture_id);
487     gl.genTextures(1, &m_depth_texture_id);
488 
489     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed");
490 
491     /* Configure new textures' storage */
492     if (true == should_generate_mutable_textures)
493     {
494         prepareMutableTextureObject(m_color_texture_id, texture_width, n_cubemaps,
495                                     true /* should_take_color_texture_properties */);
496         prepareMutableTextureObject(m_depth_texture_id, texture_width, n_cubemaps,
497                                     false /* should_take_color_texture_properties */);
498     }
499     else
500     {
501         prepareImmutableTextureObject(m_color_texture_id, texture_width, n_cubemaps,
502                                       true /* should_take_color_texture_properties */);
503         prepareImmutableTextureObject(m_depth_texture_id, texture_width, n_cubemaps,
504                                       false /* should_take_color_texture_properties */);
505     }
506 }
507 
508 /* Initializes all ES objects needed to run the test */
initTest()509 void TextureCubeMapArrayColorDepthAttachmentsTest::initTest()
510 {
511     const glw::GLchar *depth_calculation_code = DE_NULL;
512     const glw::Functions &gl                  = m_context.getRenderContext().getFunctions();
513 
514     /* Check if EXT_texture_cube_map_array extension is supported */
515     if (true != m_is_texture_cube_map_array_supported)
516     {
517         throw tcu::NotSupportedError(TEXTURE_CUBE_MAP_ARRAY_EXTENSION_NOT_SUPPORTED);
518     }
519 
520     /* This test should only run if EXT_geometry_shader is supported */
521     if (true != m_is_geometry_shader_extension_supported)
522     {
523         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED);
524     }
525 
526     /* Generate and bind VAO */
527     gl.genVertexArrays(1, &m_vao_id);
528     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate vertex array object");
529 
530     gl.bindVertexArray(m_vao_id);
531     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding vertex array object!");
532 
533     /* Create a framebuffer object */
534     gl.genFramebuffers(1, &m_framebuffer_object_id);
535     GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers");
536 
537     /* Determine which depth format can be used as a depth attachment without
538      * making the FBO incomplete */
539     determineSupportedDepthFormat();
540 
541     /* Decide which code snippet to use for depth value calculation */
542     switch (m_depth_internal_format)
543     {
544     case GL_DEPTH_COMPONENT16:
545     {
546         depth_calculation_code = "-1.0 + float(2 * layer) / float(0xffff)";
547 
548         break;
549     }
550 
551     case GL_DEPTH_COMPONENT24:
552     {
553         depth_calculation_code = "-1.0 + float(2 * layer) / float(0xffffff)";
554 
555         break;
556     }
557 
558     case GL_DEPTH_COMPONENT32F:
559     {
560         depth_calculation_code = "-1.0 + float(2 * layer) / 256.0";
561 
562         break;
563     }
564 
565     default:
566     {
567         TCU_FAIL("Unrecognized depth internal format");
568     }
569     } /* switch (m_depth_internal_format) */
570 
571     /* Create shader objects */
572     m_fragment_shader_id             = gl.createShader(GL_FRAGMENT_SHADER);
573     m_layered_geometry_shader_id     = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
574     m_non_layered_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
575     m_vertex_shader_id               = gl.createShader(GL_VERTEX_SHADER);
576 
577     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
578 
579     /* Create program objects */
580     m_layered_program_id     = gl.createProgram();
581     m_non_layered_program_id = gl.createProgram();
582 
583     GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed");
584 
585     /* Build up an array of snippets making up bodies of two geometry shaders
586      * we'll be using for the test.
587      */
588     const glw::GLchar *const layered_geometry_shader_parts[] = {
589         m_geometry_shader_code_preamble, m_geometry_shader_code_layered, "    float depth = ", depth_calculation_code,
590         m_geometry_shader_code_body};
591 
592     const glw::GLchar *const non_layered_geometry_shader_parts[] = {
593         m_geometry_shader_code_preamble, m_geometry_shader_code_non_layered,
594         "    float depth = ", depth_calculation_code, m_geometry_shader_code_body};
595 
596     const glw::GLuint n_layered_geometry_shader_parts =
597         sizeof(layered_geometry_shader_parts) / sizeof(layered_geometry_shader_parts[0]);
598     const glw::GLuint n_non_layered_geometry_shader_parts =
599         sizeof(non_layered_geometry_shader_parts) / sizeof(non_layered_geometry_shader_parts[0]);
600 
601     /* Build both programs */
602     if (!buildProgram(m_layered_program_id, m_fragment_shader_id, 1, &m_fragment_shader_code,
603                       m_layered_geometry_shader_id, n_layered_geometry_shader_parts, layered_geometry_shader_parts,
604                       m_vertex_shader_id, 1, &m_vertex_shader_code))
605     {
606         TCU_FAIL("Could not build layered-case program object");
607     }
608 
609     if (!buildProgram(m_non_layered_program_id, m_fragment_shader_id, 1, &m_fragment_shader_code,
610                       m_non_layered_geometry_shader_id, n_non_layered_geometry_shader_parts,
611                       non_layered_geometry_shader_parts, m_vertex_shader_id, 1, &m_vertex_shader_code))
612     {
613         TCU_FAIL("Could not build non-layered-case program object");
614     }
615 
616     /* Get location of "uni_layer" uniform */
617     m_non_layered_program_id_uni_layer_uniform_location = gl.getUniformLocation(m_non_layered_program_id, "uni_layer");
618 
619     if ((-1 == m_non_layered_program_id_uni_layer_uniform_location) || (GL_NO_ERROR != gl.getError()))
620     {
621         TCU_FAIL("Could not retrieve location of uni_layer uniform for non-layered program");
622     }
623 }
624 
625 /** Executes the test.
626  *
627  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
628  *  Note the function throws exception should an error occur!
629  *
630  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
631  **/
iterate()632 tcu::TestCase::IterateResult TextureCubeMapArrayColorDepthAttachmentsTest::iterate()
633 {
634     /* GL functions */
635     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
636 
637     /* Initialize all ES objects needed to run the test */
638     initTest();
639 
640     /* Setup clear values */
641     gl.clearColor(0.0f /* red */, 0.0f /* green */, 0.0f /* blue */, 0.0f /* alpha */);
642     GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor() call failed.");
643 
644     gl.clearDepthf(1.0f /* d */);
645     GLU_EXPECT_NO_ERROR(gl.getError(), "glClearDepthf() call failed.");
646 
647     /* Enable depth test */
648     gl.enable(GL_DEPTH_TEST);
649     GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call failed");
650 
651     /* Execute tests for each resolution */
652     for (_texture_size_vector::iterator texture_size_iterator = m_resolutions.begin(),
653                                         end_iterator          = m_resolutions.end();
654          end_iterator != texture_size_iterator; ++texture_size_iterator)
655     {
656         testNonLayeredRendering(*texture_size_iterator, false);
657         testNonLayeredRendering(*texture_size_iterator, true);
658         testLayeredRendering(*texture_size_iterator, false);
659         testLayeredRendering(*texture_size_iterator, true);
660     }
661 
662     /* Test passes if there were no errors */
663     if ((0 != m_n_invalid_color_checks) || (0 != m_n_invalid_depth_checks))
664     {
665         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
666     }
667     else
668     {
669         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
670     }
671 
672     /* Done */
673     return STOP;
674 }
675 
676 /** Takes a texture ID, binds it to GL_TEXTURE_CUBE_MAP_ARRAY texture target and
677  *  initializes an immutable texture storage of @param texture_size x @param texture_size
678  *  x (@param n_elements * 6) resolution.
679  *
680  * @param texture_id                           ID to use for the initialization.
681  * @param texture_size                         Width & height to use for each layer-face.
682  * @param n_cubemaps                           Amount of cube-maps to initialize.
683  * @param should_take_color_texture_properties true if m_color_internal_format, m_color_format,
684  *                                             m_color_type should be used for texture storage
685  *                                             initialization, false to use relevant m_depth_*
686  *                                             fields.
687  **/
prepareImmutableTextureObject(glw::GLuint texture_id,glw::GLuint texture_size,glw::GLuint n_cubemaps,bool should_take_color_texture_properties)688 void TextureCubeMapArrayColorDepthAttachmentsTest::prepareImmutableTextureObject(
689     glw::GLuint texture_id, glw::GLuint texture_size, glw::GLuint n_cubemaps, bool should_take_color_texture_properties)
690 {
691     const glw::Functions &gl    = m_context.getRenderContext().getFunctions();
692     glw::GLenum internal_format = GL_NONE;
693 
694     /* Set internal_format accordingly to requested texture type */
695     if (true == should_take_color_texture_properties)
696     {
697         internal_format = m_color_internal_format;
698     }
699     else
700     {
701         internal_format = m_depth_internal_format;
702     }
703 
704     /* Bind the texture object to GL_TEXTURE_CUBE_MAP_ARRAY texture target. */
705     gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, texture_id);
706     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
707 
708     /* Initialize immutable texture storage as per description */
709     gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, /* n_mipmap_levels */
710                     internal_format, texture_size, texture_size, n_cubemaps * 6 /* layer-faces per cube-map */);
711 
712     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed.");
713 }
714 
715 /** Takes a texture ID, binds it to GL_TEXTURE_CUBE_MAP_ARRAY texture target and
716  *  initializes a mutable texture storage of @param texture_size x @param texture_size
717  *  x (@param n_elements * 6) resolution. Finally,the function sets GL_TEXTURE_MAX_LEVEL
718  *  of the texture object to 0.
719  *
720  * @param texture_id                           ID to use for the initialization.
721  * @param texture_size                         Width & height to use for each layer-face.
722  * @param n_cubemaps                           Amount of cube-maps to initialize.
723  * @param should_take_color_texture_properties true if m_color_internal_format, m_color_format,
724  *                                             m_color_type should be used for texture storage
725  *                                             initialization, false to use relevant m_depth_*
726  *                                             fields.
727  **/
prepareMutableTextureObject(glw::GLuint texture_id,glw::GLuint texture_size,glw::GLuint n_cubemaps,bool should_take_color_texture_properties)728 void TextureCubeMapArrayColorDepthAttachmentsTest::prepareMutableTextureObject(
729     glw::GLuint texture_id, glw::GLuint texture_size, glw::GLuint n_cubemaps, bool should_take_color_texture_properties)
730 {
731     const glw::Functions &gl    = m_context.getRenderContext().getFunctions();
732     glw::GLenum format          = GL_NONE;
733     glw::GLenum internal_format = GL_NONE;
734     glw::GLenum type            = GL_NONE;
735 
736     /* Set internal_format, format and type accordingly to requested texture type */
737     if (true == should_take_color_texture_properties)
738     {
739         internal_format = m_color_internal_format;
740         format          = m_color_format;
741         type            = m_color_type;
742     }
743     else
744     {
745         internal_format = m_depth_internal_format;
746         format          = m_depth_format;
747         type            = m_depth_type;
748     }
749 
750     /* Bind the texture object to GL_TEXTURE_CUBE_MAP_ARRAY texture target. */
751     gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, texture_id);
752     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
753 
754     /* Initialize mutable texture storage as per description */
755     gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0 /* mipmap_level */, internal_format, texture_size, texture_size,
756                   n_cubemaps * 6 /* layer-faces per cube-map */, 0 /* border */, format, type,
757                   DE_NULL); /* initial data */
758     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D() call failed");
759 
760     /* Update GL_TEXTURE_MAX_LEVEL so that the texture is considered complete */
761     gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, 0 /* param */);
762 
763     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call failed");
764 }
765 
766 /** Releases a texture object and detaches it from test-maintained draw framebuffer.
767  *
768  * @param texture_id          Id of the texture object;
769  * @param is_color_attachment true if the texture object described by id @param texture_id
770  *                            is current draw framebuffer's color attachment, false if it's
771  *                            a depth attachment.
772  **/
releaseAndDetachTextureObject(glw::GLuint texture_id,bool is_color_attachment)773 void TextureCubeMapArrayColorDepthAttachmentsTest::releaseAndDetachTextureObject(glw::GLuint texture_id,
774                                                                                  bool is_color_attachment)
775 {
776     glw::GLenum attachment   = GL_NONE;
777     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
778 
779     if (true == is_color_attachment)
780     {
781         attachment = GL_COLOR_ATTACHMENT0;
782     }
783     else
784     {
785         attachment = GL_DEPTH_ATTACHMENT;
786     }
787 
788     /* Update draw framewbuffer binding just in case. */
789     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer_object_id);
790     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
791 
792     /* Clean framebuffer's attachment */
793     gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, 0, /* texture */
794                             0);                                                /* level */
795     GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
796 
797     /* Unbind the texture object from GL_TEXTURE_CUBE_MAP_ARRAY binding point */
798     gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
799     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
800 
801     /* Finally delete the texture object */
802     gl.deleteTextures(1, &texture_id);
803     GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
804 }
805 
806 /** Verifies layered rendering works correctly.
807  *
808  * @param texture_size                Resolution of texture;
809  * @param should_use_mutable_textures true if mutable textures should be used for the test,
810  *                                    false to use immutable textures.
811  **/
testLayeredRendering(const _texture_size & texture_size,bool should_use_mutable_textures)812 void TextureCubeMapArrayColorDepthAttachmentsTest::testLayeredRendering(const _texture_size &texture_size,
813                                                                         bool should_use_mutable_textures)
814 {
815     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
816 
817     /* Generate texture objects for the test */
818     generateAndConfigureTextureObjects(texture_size.m_size, texture_size.m_n_cubemaps, should_use_mutable_textures);
819 
820     /* Setup layered framebuffer */
821     configureLayeredFramebufferAttachment(m_color_texture_id, true /* should_use_as_color_attachment */);
822     configureLayeredFramebufferAttachment(m_depth_texture_id, false /* should_use_as_color_attachment */);
823 
824     /* Activate the program object that performs layered rendering */
825     gl.useProgram(m_layered_program_id);
826 
827     GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
828 
829     /* Issue the draw call. */
830     draw(texture_size);
831 
832     /* Restore default framebuffer attachments */
833     configureLayeredFramebufferAttachment(0 /* texture_id */, true /* should_use_as_color_attachment */);
834     configureLayeredFramebufferAttachment(0 /* texture_id */, false /* should_use_as_color_attachment */);
835 
836     /* Restore draw framebuffer binding */
837     gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
838 
839     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
840 
841     /* Time to verify the results - update read framebuffer binding first. */
842     gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_framebuffer_object_id);
843 
844     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
845 
846     /* Iterate through all layer-faces */
847     for (glw::GLuint n_layer_face = 0; n_layer_face < texture_size.m_n_cubemaps * 6 /* layer-faces per cube-map */;
848          ++n_layer_face)
849     {
850         /* Configure read framebuffer attachments to point to the layer of our current interest */
851         configureNonLayeredFramebufferAttachment(m_color_texture_id, n_layer_face,
852                                                  true,   /* should_use_as_color_attachment */
853                                                  false); /* should_update_draw_framebuffer */
854         configureNonLayeredFramebufferAttachment(m_depth_texture_id, n_layer_face,
855                                                  false,  /* should_use_as_color_attachment */
856                                                  false); /* should_update_draw_framebuffer */
857 
858         /* Verify contents of color and depth attachments */
859         bool is_color_data_ok = verifyColorData(texture_size, n_layer_face);
860         bool is_depth_data_ok = false;
861 
862         if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
863         {
864             switch (m_depth_internal_format)
865             {
866             case GL_DEPTH_COMPONENT16:
867             {
868                 is_depth_data_ok = verifyDepth16Data(texture_size, n_layer_face);
869 
870                 break;
871             }
872 
873             case GL_DEPTH_COMPONENT24:
874             {
875                 is_depth_data_ok = verifyDepth24Data(texture_size, n_layer_face);
876 
877                 break;
878             }
879 
880             case GL_DEPTH_COMPONENT32F:
881             {
882                 is_depth_data_ok = verifyDepth32FData(texture_size, n_layer_face);
883 
884                 break;
885             }
886 
887             default:
888             {
889                 TCU_FAIL("Unrecognized depth internalformat");
890             }
891             } /* switch (m_depth_internal_format) */
892         }
893         else
894         {
895             is_depth_data_ok = true;
896         }
897 
898         /* Any errors? Increment relevant counters */
899         if (false == is_color_data_ok)
900         {
901             m_n_invalid_color_checks++;
902         }
903 
904         if (false == is_depth_data_ok)
905         {
906             m_n_invalid_depth_checks++;
907         }
908     } /* for (all layer-faces) */
909 }
910 
911 /** Verifies layered rendering works correctly.
912  *
913  * @param texture_size               Resolution of texture
914  * @param should_use_mutable_texture true if an immutable texture should be used for
915  *                                   the invocation; false if mutable.
916  **/
testNonLayeredRendering(const _texture_size & texture_size,bool should_use_mutable_texture)917 void TextureCubeMapArrayColorDepthAttachmentsTest::testNonLayeredRendering(const _texture_size &texture_size,
918                                                                            bool should_use_mutable_texture)
919 {
920     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
921 
922     /* Activate a program object that renders in a non-layered fashion */
923     gl.useProgram(m_non_layered_program_id);
924 
925     GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
926 
927     /* Create relevant textures */
928     generateAndConfigureTextureObjects(texture_size.m_size, texture_size.m_n_cubemaps, should_use_mutable_texture);
929 
930     /* Iterate over all layer-faces */
931     for (glw::GLuint n_layer_face = 0; n_layer_face < texture_size.m_n_cubemaps * 6 /* layer-faces per cube-map */;
932          ++n_layer_face)
933     {
934         /* Set up non-layered framebuffer attachments */
935         configureNonLayeredFramebufferAttachment(m_color_texture_id, n_layer_face, true /* is_color_attachment */);
936         configureNonLayeredFramebufferAttachment(m_depth_texture_id, n_layer_face, false /* is_color_attachment */);
937 
938         /* Update value assigned to "uni_layer" uniform */
939         gl.uniform1i(m_non_layered_program_id_uni_layer_uniform_location, n_layer_face);
940         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
941 
942         /* Execute a draw call */
943         draw(texture_size);
944 
945         /* Restore default framebuffer attachments */
946         configureNonLayeredFramebufferAttachment(0 /* texture_id */, 0 /* n_layer */,
947                                                  true /* should_use_as_color_attachment */);
948         configureNonLayeredFramebufferAttachment(0 /* texture_id */, 0 /* n_layer */,
949                                                  false /* should_use_as_color_attachment */);
950 
951         /* Remove draw framebuffer binding */
952         gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
953         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
954 
955         /* Verify the results. First, make sure the read framebuffer binding is configured
956          * accordingly.
957          */
958         gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_framebuffer_object_id);
959         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
960 
961         /* Configure read framebuffer attachments to point to the layer of our current interest */
962         configureNonLayeredFramebufferAttachment(m_color_texture_id, n_layer_face,
963                                                  true,   /* should_use_as_color_attachment */
964                                                  false); /* should_update_draw_framebuffer */
965         configureNonLayeredFramebufferAttachment(m_depth_texture_id, n_layer_face,
966                                                  false,  /* should_use_as_color_attachment */
967                                                  false); /* should_update_draw_framebuffer */
968 
969         /* Verify contents of color and depth attachments */
970         bool is_color_data_ok = verifyColorData(texture_size, n_layer_face);
971         bool is_depth_data_ok = false;
972 
973         if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
974         {
975             switch (m_depth_internal_format)
976             {
977             case GL_DEPTH_COMPONENT16:
978             {
979                 is_depth_data_ok = verifyDepth16Data(texture_size, n_layer_face);
980 
981                 break;
982             }
983 
984             case GL_DEPTH_COMPONENT24:
985             {
986                 is_depth_data_ok = verifyDepth24Data(texture_size, n_layer_face);
987 
988                 break;
989             }
990 
991             case GL_DEPTH_COMPONENT32F:
992             {
993                 is_depth_data_ok = verifyDepth32FData(texture_size, n_layer_face);
994 
995                 break;
996             }
997 
998             default:
999             {
1000                 TCU_FAIL("Unrecognized depth internalformat");
1001             }
1002             } /* switch (m_depth_internal_format) */
1003         }
1004         else
1005         {
1006             is_depth_data_ok = true;
1007         }
1008 
1009         /* Any errors? Increment relevant counters */
1010         if (false == is_color_data_ok)
1011         {
1012             m_n_invalid_color_checks++;
1013         }
1014 
1015         if (false == is_depth_data_ok)
1016         {
1017             m_n_invalid_depth_checks++;
1018         }
1019     } /* for (all layer-faces) */
1020 }
1021 
1022 /** Reads read buffer's color data and verifies its correctness.
1023  *
1024  *  @param texture_size Texture size
1025  *  @param n_layer      Index of the layer to verify.
1026  *
1027  *  @return true if the retrieved data was found correct, false otherwise.
1028  **/
verifyColorData(const _texture_size & texture_size,glw::GLuint n_layer)1029 bool TextureCubeMapArrayColorDepthAttachmentsTest::verifyColorData(const _texture_size &texture_size,
1030                                                                    glw::GLuint n_layer)
1031 {
1032     /* Allocate buffer for the data we will retrieve from the implementation */
1033     const glw::Functions &gl           = m_context.getRenderContext().getFunctions();
1034     bool result                        = false;
1035     const glw::GLuint result_data_size = texture_size.m_size * texture_size.m_size * 4;
1036     glw::GLuint *result_data           = new glw::GLuint[result_data_size];
1037 
1038     DE_ASSERT(result_data != NULL);
1039 
1040     /* Read the data */
1041     gl.readPixels(0, /* x */
1042                   0, /* y */
1043                   texture_size.m_size, texture_size.m_size, GL_RGBA_INTEGER, m_color_type, result_data);
1044     GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed");
1045 
1046     glw::GLuint expected[4] = {n_layer, 0, 0, 1};
1047 
1048     /* Verify image, expected value is layer index */
1049     result = verifyImage<glw::GLuint, 4>(texture_size.m_size, texture_size.m_size, expected, result_data);
1050 
1051     /* Release the buffer */
1052     if (result_data != NULL)
1053     {
1054         delete[] result_data;
1055 
1056         result_data = NULL;
1057     }
1058 
1059     return result;
1060 }
1061 
1062 /** Reads read buffer's depth data (assuming it's of 16-bit resolution)
1063  *  and verifies its correctness.
1064  *
1065  *  @param texture_size Texture size
1066  *  @param n_layer      Index of the layer to verify.
1067  *
1068  *  @return true if the retrieved data was found correct, false otherwise.
1069  **/
verifyDepth16Data(const _texture_size & texture_size,glw::GLuint n_layer)1070 bool TextureCubeMapArrayColorDepthAttachmentsTest::verifyDepth16Data(const _texture_size &texture_size,
1071                                                                      glw::GLuint n_layer)
1072 {
1073     /* Allocate buffer for the data we will retrieve from the implementation */
1074     glw::GLushort expected_value       = (glw::GLushort)n_layer;
1075     const glw::Functions &gl           = m_context.getRenderContext().getFunctions();
1076     bool result                        = false;
1077     const glw::GLuint result_data_size = texture_size.m_size * texture_size.m_size;
1078     glw::GLushort *result_data         = new glw::GLushort[result_data_size];
1079 
1080     DE_ASSERT(result_data != NULL);
1081 
1082     gl.pixelStorei(GL_PACK_ALIGNMENT, 2);
1083 
1084     /* Read the data */
1085     gl.readPixels(0, /* x */
1086                   0, /* y */
1087                   texture_size.m_size, texture_size.m_size, m_depth_format, m_depth_type, result_data);
1088     GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed");
1089 
1090     /* Verify image, expected value is layer index */
1091     result = verifyImage<glw::GLushort, 1>(texture_size.m_size, texture_size.m_size, &expected_value, result_data);
1092 
1093     /* Release the buffer */
1094     if (result_data != NULL)
1095     {
1096         delete[] result_data;
1097 
1098         result_data = NULL;
1099     }
1100 
1101     gl.pixelStorei(GL_PACK_ALIGNMENT, 4);
1102 
1103     return result;
1104 }
1105 
1106 /** Reads read buffer's depth data (assuming it's of 24-bit resolution)
1107  *  and verifies its correctness.
1108  *
1109  *  @param texture_size Texture size
1110  *  @param n_layer      Index of the layer to verify.
1111  *
1112  *  @return true if the retrieved data was found correct, false otherwise.
1113  **/
verifyDepth24Data(const _texture_size & texture_size,glw::GLuint n_layer)1114 bool TextureCubeMapArrayColorDepthAttachmentsTest::verifyDepth24Data(const _texture_size &texture_size,
1115                                                                      glw::GLuint n_layer)
1116 {
1117     /* Allocate buffer for the data we will retrieve from the implementation */
1118     glw::GLuint expected_value         = n_layer << 8;
1119     const glw::Functions &gl           = m_context.getRenderContext().getFunctions();
1120     bool result                        = false;
1121     const glw::GLuint result_data_size = texture_size.m_size * texture_size.m_size;
1122     glw::GLuint *result_data           = new glw::GLuint[result_data_size];
1123 
1124     DE_ASSERT(result_data != NULL);
1125 
1126     /* Read the data */
1127     gl.readPixels(0, /* x */
1128                   0, /* y */
1129                   texture_size.m_size, texture_size.m_size, m_depth_format, m_depth_type, result_data);
1130     GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed");
1131 
1132     /* Verify image, expected value is layer index */
1133     result = verifyImage<glw::GLuint, 1>(texture_size.m_size, texture_size.m_size, &expected_value, result_data);
1134 
1135     /* Release the buffer */
1136     if (result_data != NULL)
1137     {
1138         delete[] result_data;
1139 
1140         result_data = NULL;
1141     }
1142 
1143     return result;
1144 }
1145 
1146 /** Reads read buffer's depth data (assuming it's of 32-bit FP resolution)
1147  *  and verifies its correctness.
1148  *
1149  *  @param texture_size Texture size
1150  *  @param n_layer      Index of the layer to verify.
1151  *
1152  *  @return true if the retrieved data was found correct, false otherwise.
1153  **/
verifyDepth32FData(const _texture_size & texture_size,glw::GLuint n_layer)1154 bool TextureCubeMapArrayColorDepthAttachmentsTest::verifyDepth32FData(const _texture_size &texture_size,
1155                                                                       glw::GLuint n_layer)
1156 {
1157     /* Allocate buffer for the data we will retrieve from the implementation */
1158     glw::GLfloat expected_value        = (glw::GLfloat)n_layer / 256.0f;
1159     const glw::Functions &gl           = m_context.getRenderContext().getFunctions();
1160     bool result                        = false;
1161     const glw::GLuint result_data_size = texture_size.m_size * texture_size.m_size;
1162     glw::GLfloat *result_data          = new glw::GLfloat[result_data_size];
1163 
1164     DE_ASSERT(result_data != NULL);
1165 
1166     /* Read the data */
1167     gl.readPixels(0, /* x */
1168                   0, /* y */
1169                   texture_size.m_size, texture_size.m_size, m_depth_format, m_depth_type, result_data);
1170     GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed");
1171 
1172     /* Verify image, expected value is layer index */
1173     result = verifyImage<glw::GLfloat, 1>(texture_size.m_size, texture_size.m_size, &expected_value, result_data);
1174 
1175     /* Release the buffer */
1176     if (result_data != NULL)
1177     {
1178         delete[] result_data;
1179 
1180         result_data = NULL;
1181     }
1182 
1183     return result;
1184 }
1185 
1186 } // namespace glcts
1187