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