1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */ /*!
20  * \file
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23 
24 /*!
25  * \file  esextcTextureCubeMapArraySubImage3D.cpp
26  * \brief Texture Cube Map Array SubImage3D (Test 5)
27  */ /*-------------------------------------------------------------------*/
28 
29 #include "esextcTextureCubeMapArraySubImage3D.hpp"
30 #include "gluContextInfo.hpp"
31 #include "gluDefs.hpp"
32 #include "glwEnums.hpp"
33 #include "glwFunctions.hpp"
34 #include "tcuTestLog.hpp"
35 #include <string.h>
36 
37 namespace glcts
38 {
39 const glw::GLuint TextureCubeMapArraySubImage3D::m_n_components   = 4;
40 const glw::GLuint TextureCubeMapArraySubImage3D::m_n_dimensions   = 3;
41 const glw::GLuint TextureCubeMapArraySubImage3D::m_n_resolutions  = 4;
42 const glw::GLuint TextureCubeMapArraySubImage3D::m_n_storage_type = 2;
43 
44 /* Helper arrays for tests configuration */
45 
46 /* Different texture resolutions */
47 const glw::GLuint resolutions[TextureCubeMapArraySubImage3D::m_n_resolutions]
48                              [TextureCubeMapArraySubImage3D::m_n_dimensions] = {
49                                  /* Width , Height, Depth */
50                                  {32, 32, 12},
51                                  {64, 64, 12},
52                                  {16, 16, 18},
53                                  {16, 16, 24}};
54 
55 /* Location of dimension in array with texture resolutions */
56 enum Dimensions_Location
57 {
58     DL_WIDTH  = 0,
59     DL_HEIGHT = 1,
60     DL_DEPTH  = 2
61 };
62 
63 /** Constructor
64  *
65  *  @param context              Test context
66  *  @param name                 Test case's name
67  *  @param description          Test case's description
68  */
TextureCubeMapArraySubImage3D(Context & context,const ExtParameters & extParams,const char * name,const char * description)69 TextureCubeMapArraySubImage3D::TextureCubeMapArraySubImage3D(Context &context, const ExtParameters &extParams,
70                                                              const char *name, const char *description)
71     : TestCaseBase(context, extParams, name, description)
72     , m_read_fbo_id(0)
73     , m_pixel_buffer_id(0)
74     , m_tex_cube_map_array_id(0)
75     , m_tex_2d_id(0)
76 {
77     /* Nothing to be done here */
78 }
79 
80 /** Initialize test case */
initTest(void)81 void TextureCubeMapArraySubImage3D::initTest(void)
82 {
83     /* Check if texture_cube_map_array extension is supported */
84     if (!m_is_texture_cube_map_array_supported)
85     {
86         throw tcu::NotSupportedError(TEXTURE_CUBE_MAP_ARRAY_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
87     }
88 
89     /* Get GL entry points */
90     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
91 
92     gl.genFramebuffers(1, &m_read_fbo_id);
93     GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating frame buffer object!");
94 
95     gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_read_fbo_id);
96     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding frame buffer object!");
97 }
98 
99 /** Deinitialize test case */
deinit(void)100 void TextureCubeMapArraySubImage3D::deinit(void)
101 {
102     /* Get GL entry points */
103     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
104 
105     /* Reset GLES configuration */
106     gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
107 
108     /* Delete GLES objects */
109     if (m_read_fbo_id != 0)
110     {
111         gl.deleteFramebuffers(1, &m_read_fbo_id);
112         m_read_fbo_id = 0;
113     }
114 
115     /* Delete pixel unpack buffer */
116     deletePixelUnpackBuffer();
117 
118     /* Delete cube map array texture */
119     deleteCubeMapArrayTexture();
120 
121     /* Delete 2D texture */
122     delete2DTexture();
123 
124     /* Deinitialize base class */
125     TestCaseBase::deinit();
126 }
127 
128 /** Executes the test.
129  *
130  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
131  *
132  *  Note the function throws exception should an error occur!
133  *
134  *  @return STOP if the test has finished, CONTINUE to indicate iterate() should be called once again.
135  */
iterate()136 tcu::TestCase::IterateResult TextureCubeMapArraySubImage3D::iterate()
137 {
138     initTest();
139 
140     glw::GLboolean test_passed = true;
141 
142     /* Execute test throught all storage types */
143     for (glw::GLuint storage_index = 0; storage_index < m_n_storage_type; ++storage_index)
144     {
145         /* Execute test throught all texture resolutions */
146         for (glw::GLuint resolution_index = 0; resolution_index < m_n_resolutions; ++resolution_index)
147         {
148             glw::GLuint width  = resolutions[resolution_index][DL_WIDTH];
149             glw::GLuint height = resolutions[resolution_index][DL_HEIGHT];
150             glw::GLuint depth  = resolutions[resolution_index][DL_DEPTH];
151 
152             configureCubeMapArrayTexture(width, height, depth, static_cast<STORAGE_TYPE>(storage_index), 0);
153 
154             /* A single whole layer-face at index 0 should be replaced (both functions) */
155             SubImage3DCopyParams copy_params;
156             copy_params.init(0, 0, 0, width, height, 1);
157 
158             configureDataBuffer(width, height, depth, copy_params, 0);
159             configurePixelUnpackBuffer(copy_params);
160             configure2DTexture(copy_params);
161             testTexSubImage3D(width, height, depth, copy_params, test_passed);
162             testCopyTexSubImage3D(width, height, depth, copy_params, test_passed);
163             deletePixelUnpackBuffer();
164             delete2DTexture();
165 
166             /* A region of a layer-face at index 0 should be replaced (both functions) */
167             copy_params.init(width / 2, height / 2, 0, width / 2, height / 2, 1);
168 
169             configureDataBuffer(width, height, depth, copy_params, 0);
170             configurePixelUnpackBuffer(copy_params);
171             configure2DTexture(copy_params);
172             testTexSubImage3D(width, height, depth, copy_params, test_passed);
173             testCopyTexSubImage3D(width, height, depth, copy_params, test_passed);
174             deletePixelUnpackBuffer();
175             delete2DTexture();
176 
177             /* 6 layer-faces, making up a single layer, should be replaced (glTexSubImage3D() only) */
178             copy_params.init(0, 0, 0, width, height, 6);
179 
180             configureDataBuffer(width, height, depth, copy_params, 0);
181             configurePixelUnpackBuffer(copy_params);
182             testTexSubImage3D(width, height, depth, copy_params, test_passed);
183             deletePixelUnpackBuffer();
184 
185             /* 6 layer-faces, making up two different layers (for instance: three last layer-faces of
186              layer 1 and three first layer-faces of layer 2) should be replaced (glTexSubImage3D() only) */
187             copy_params.init(0, 0, 3, width, height, 6);
188 
189             configureDataBuffer(width, height, depth, copy_params, 0);
190             configurePixelUnpackBuffer(copy_params);
191             testTexSubImage3D(width, height, depth, copy_params, test_passed);
192             deletePixelUnpackBuffer();
193 
194             /* 6 layer-faces, making up a single layer, should be replaced (glTexSubImage3D() only),
195              but limited to a quad */
196             copy_params.init(width / 2, height / 2, 0, width / 2, height / 2, 6);
197 
198             configureDataBuffer(width, height, depth, copy_params, 0);
199             configurePixelUnpackBuffer(copy_params);
200             testTexSubImage3D(width, height, depth, copy_params, test_passed);
201             deletePixelUnpackBuffer();
202 
203             /* 6 layer-faces, making up two different layers (for instance: three last layer-faces of
204              layer 1 and three first layer-faces of layer 2) should be replaced (glTexSubImage3D() only),
205              but limited to a quad */
206             copy_params.init(width / 2, height / 2, 3, width / 2, height / 2, 6);
207 
208             configureDataBuffer(width, height, depth, copy_params, 0);
209             configurePixelUnpackBuffer(copy_params);
210             testTexSubImage3D(width, height, depth, copy_params, test_passed);
211             deletePixelUnpackBuffer();
212 
213             deleteCubeMapArrayTexture();
214         }
215     }
216 
217     if (test_passed)
218         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
219     else
220         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
221 
222     return STOP;
223 }
224 
225 /** Resizes data buffer and fills it with values
226  * @param width       - width of the texture
227  * @param height      - height of the texture
228  * @param depth       - depth of the texture
229  * @param copy_params - data structure specifying which region of the data store to replace
230  * @param clear_value - value with which to fill the data buffer outside of region specified by copy_params
231  */
configureDataBuffer(glw::GLuint width,glw::GLuint height,glw::GLuint depth,const SubImage3DCopyParams & copy_params,glw::GLuint clear_value)232 void TextureCubeMapArraySubImage3D::configureDataBuffer(glw::GLuint width, glw::GLuint height, glw::GLuint depth,
233                                                         const SubImage3DCopyParams &copy_params,
234                                                         glw::GLuint clear_value)
235 {
236     glw::GLuint index = 0;
237 
238     m_copy_data_buffer.assign(copy_params.m_width * copy_params.m_height * copy_params.m_depth * m_n_components,
239                               clear_value);
240     for (glw::GLuint zoffset = copy_params.m_zoffset; zoffset < copy_params.m_zoffset + copy_params.m_depth; ++zoffset)
241     {
242         for (glw::GLuint yoffset = copy_params.m_yoffset; yoffset < copy_params.m_yoffset + copy_params.m_height;
243              ++yoffset)
244         {
245             for (glw::GLuint xoffset = copy_params.m_xoffset; xoffset < copy_params.m_xoffset + copy_params.m_width;
246                  ++xoffset)
247             {
248                 for (glw::GLuint component = 0; component < m_n_components; ++component)
249                 {
250                     m_copy_data_buffer[index++] =
251                         (zoffset * width * height + yoffset * width + xoffset) * m_n_components + component;
252                 }
253             }
254         }
255     }
256 
257     m_expected_data_buffer.assign(width * height * depth * m_n_components, clear_value);
258     for (glw::GLuint zoffset = copy_params.m_zoffset; zoffset < copy_params.m_zoffset + copy_params.m_depth; ++zoffset)
259     {
260         for (glw::GLuint yoffset = copy_params.m_yoffset; yoffset < copy_params.m_yoffset + copy_params.m_height;
261              ++yoffset)
262         {
263             for (glw::GLuint xoffset = copy_params.m_xoffset; xoffset < copy_params.m_xoffset + copy_params.m_width;
264                  ++xoffset)
265             {
266                 glw::GLuint *data_pointer =
267                     &m_expected_data_buffer[(zoffset * width * height + yoffset * width + xoffset) * m_n_components];
268                 for (glw::GLuint component = 0; component < m_n_components; ++component)
269                 {
270                     data_pointer[component] =
271                         (zoffset * width * height + yoffset * width + xoffset) * m_n_components + component;
272                 }
273             }
274         }
275     }
276 }
277 
278 /** Creates a pixel unpack buffer that will be used as data source for filling a region of cube map array texture with data
279  * @param copy_params - data structure specifying which region of the data store to replace
280  */
configurePixelUnpackBuffer(const SubImage3DCopyParams & copy_params)281 void TextureCubeMapArraySubImage3D::configurePixelUnpackBuffer(const SubImage3DCopyParams &copy_params)
282 {
283     /* Get GL entry points */
284     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
285 
286     /* generate buffer for pixel unpack buffer */
287     gl.genBuffers(1, &m_pixel_buffer_id);
288     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate buffer object!");
289 
290     /* bind buffer to PIXEL_UNPACK_BUFFER binding point */
291     gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pixel_buffer_id);
292     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind buffer object!");
293 
294     /* fill buffer with data */
295     gl.bufferData(GL_PIXEL_UNPACK_BUFFER,
296                   copy_params.m_width * copy_params.m_height * copy_params.m_depth * m_n_components *
297                       sizeof(glw::GLuint),
298                   &m_copy_data_buffer[0], GL_STATIC_READ);
299     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not fill buffer object's data store with data!");
300 
301     gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
302     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind buffer object!");
303 }
304 
305 /** Creates cube map array texture and fills it with data
306  * @param width       - width of the texture
307  * @param height      - height of the texture
308  * @param depth       - depth of the texture
309  * @param storType    - mutable or immutable storage type
310  * @param clear_value - value with which to initialize the texture's data store
311  */
configureCubeMapArrayTexture(glw::GLuint width,glw::GLuint height,glw::GLuint depth,STORAGE_TYPE storType,glw::GLuint clear_value)312 void TextureCubeMapArraySubImage3D::configureCubeMapArrayTexture(glw::GLuint width, glw::GLuint height,
313                                                                  glw::GLuint depth, STORAGE_TYPE storType,
314                                                                  glw::GLuint clear_value)
315 {
316     /* Get GL entry points */
317     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
318 
319     gl.genTextures(1, &m_tex_cube_map_array_id);
320     GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!");
321 
322     gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_tex_cube_map_array_id);
323     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
324 
325     /* used glTexImage3D() method if texture should be MUTABLE */
326     if (storType == ST_MUTABLE)
327     {
328         gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
329         GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture parameter.");
330         gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
331         GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture parameter.");
332 
333         DataBufferVec data_buffer(width * height * depth * m_n_components, clear_value);
334 
335         gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA32UI, width, height, depth, 0, GL_RGBA_INTEGER,
336                       GL_UNSIGNED_INT, &data_buffer[0]);
337         GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object's data store");
338     }
339     /* used glTexStorage3D() method if texture should be IMMUTABLE */
340     else
341     {
342         gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA32UI, width, height, depth);
343         GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object's data store");
344 
345         clearCubeMapArrayTexture(width, height, depth, clear_value);
346     }
347 }
348 
349 /** Fills cube map array texture's data store with data
350  * @param width       - width of the texture
351  * @param height      - height of the texture
352  * @param depth       - depth of the texture
353  * @param clear_value - value with which to fill the texture's data store
354  */
clearCubeMapArrayTexture(glw::GLuint width,glw::GLuint height,glw::GLuint depth,glw::GLuint clear_value)355 void TextureCubeMapArraySubImage3D::clearCubeMapArrayTexture(glw::GLuint width, glw::GLuint height, glw::GLuint depth,
356                                                              glw::GLuint clear_value)
357 {
358     /* Get GL entry points */
359     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
360 
361     DataBufferVec data_buffer(width * height * depth * m_n_components, clear_value);
362 
363     gl.texSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, width, height, depth, GL_RGBA_INTEGER, GL_UNSIGNED_INT,
364                      &data_buffer[0]);
365     GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture object's data store with data");
366 }
367 
368 /** Creates 2D texture that will be used as data source by the glCopyTexSubImage3D call
369  * @param copy_params - data structure specifying which region of the data store to replace
370  */
configure2DTexture(const SubImage3DCopyParams & copy_params)371 void TextureCubeMapArraySubImage3D::configure2DTexture(const SubImage3DCopyParams &copy_params)
372 {
373     /* Get GL entry points */
374     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
375 
376     gl.genTextures(1, &m_tex_2d_id);
377     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate texture object!");
378 
379     gl.bindTexture(GL_TEXTURE_2D, m_tex_2d_id);
380     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind texture object!");
381 
382     gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32UI, copy_params.m_width, copy_params.m_height);
383     GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object's data store");
384 
385     gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, copy_params.m_width, copy_params.m_height, GL_RGBA_INTEGER,
386                      GL_UNSIGNED_INT, &m_copy_data_buffer[0]);
387     GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture object's data store with data");
388 }
389 
390 /** Replaces region of cube map array texture's data store using texSubImage3D function
391  * @param copy_params    - data structure specifying which region of the data store to replace
392  * @param data_pointer   - pointer to the data that should end up in the specified region of the data store
393  */
texSubImage3D(const SubImage3DCopyParams & copy_params,const glw::GLuint * data_pointer)394 void TextureCubeMapArraySubImage3D::texSubImage3D(const SubImage3DCopyParams &copy_params,
395                                                   const glw::GLuint *data_pointer)
396 {
397     /* Get GL entry points */
398     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
399 
400     gl.texSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, copy_params.m_xoffset, copy_params.m_yoffset, copy_params.m_zoffset,
401                      copy_params.m_width, copy_params.m_height, copy_params.m_depth, GL_RGBA_INTEGER, GL_UNSIGNED_INT,
402                      data_pointer);
403     GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture object's data store with data");
404 }
405 
406 /** Replaces region of cube map array texture's data store using copyTexSubImage3D function
407  * @param copy_params    - data structure specifying which region of the data store to replace
408  */
copyTexSubImage3D(const SubImage3DCopyParams & copy_params)409 void TextureCubeMapArraySubImage3D::copyTexSubImage3D(const SubImage3DCopyParams &copy_params)
410 {
411     /* Get GL entry points */
412     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
413 
414     gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_tex_2d_id, 0);
415     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not attach texture object to framebuffer's attachment");
416 
417     checkFramebufferStatus(GL_READ_FRAMEBUFFER);
418 
419     gl.copyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, copy_params.m_xoffset, copy_params.m_yoffset,
420                          copy_params.m_zoffset, 0, 0, copy_params.m_width, copy_params.m_height);
421     GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture object's data store with data");
422 }
423 
424 /** Compares the region of data specified by copy_params taken from the cube map array texture's data store with
425  *  the reference data stored in m_data_buffer.
426  * @param width       - width of the texture
427  * @param height      - height of the texture
428  * @param depth       - depth of the texture
429  * @return            - true if the result of comparison is that the regions contain the same data, false otherwise
430  */
checkResults(glw::GLuint width,glw::GLuint height,glw::GLuint depth)431 bool TextureCubeMapArraySubImage3D::checkResults(glw::GLuint width, glw::GLuint height, glw::GLuint depth)
432 {
433     /* Get GL entry points */
434     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
435 
436     glw::GLuint n_elements = width * height * depth * m_n_components;
437     DataBufferVec result_data_buffer(n_elements, 0);
438 
439     for (glw::GLuint layer_nr = 0; layer_nr < depth; ++layer_nr)
440     {
441         /* attach one layer to framebuffer's attachment */
442         gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_tex_cube_map_array_id, 0, layer_nr);
443         GLU_EXPECT_NO_ERROR(gl.getError(), "Could not attach texture object to framebuffer's attachment");
444 
445         /* check framebuffer status */
446         checkFramebufferStatus(GL_READ_FRAMEBUFFER);
447 
448         /* read data from the texture */
449         gl.readPixels(0, 0, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT,
450                       &result_data_buffer[layer_nr * width * height * m_n_components]);
451         GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read pixels from framebuffer's attachment!");
452     }
453 
454     return memcmp(&result_data_buffer[0], &m_expected_data_buffer[0], n_elements * sizeof(glw::GLuint)) == 0;
455 }
456 
457 /** Perform a full test of testTexSubImage3D function on cube map array texture, both with client pointer and pixel unpack buffer
458  * @param width          - width of the texture
459  * @param height         - height of the texture
460  * @param depth          - depth of the texture
461  * @param copy_params    - data structure specifying which region of the cube map array to test
462  * @param test_passed    - a boolean variable set to false if at any stage of the test we experience wrong result
463  */
testTexSubImage3D(glw::GLuint width,glw::GLuint height,glw::GLuint depth,const SubImage3DCopyParams & copy_params,glw::GLboolean & test_passed)464 void TextureCubeMapArraySubImage3D::testTexSubImage3D(glw::GLuint width, glw::GLuint height, glw::GLuint depth,
465                                                       const SubImage3DCopyParams &copy_params,
466                                                       glw::GLboolean &test_passed)
467 {
468     /* Get GL entry points */
469     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
470 
471     clearCubeMapArrayTexture(width, height, depth, 0);
472 
473     texSubImage3D(copy_params, &m_copy_data_buffer[0]);
474 
475     if (!checkResults(width, height, depth))
476     {
477         m_testCtx.getLog()
478             << tcu::TestLog::Message
479             << "glTexSubImage3D failed to copy data to texture cube map array's data store from client's memory\n"
480             << "Texture Cube Map Array Dimensions (width, height, depth) "
481             << "(" << width << "," << height << "," << depth << ")\n"
482             << "Texture Cube Map Array Offsets (xoffset, yoffset, zoffset) "
483             << "(" << copy_params.m_xoffset << "," << copy_params.m_yoffset << "," << copy_params.m_zoffset << ")\n"
484             << "Texture Cube Map Array Copy Size (width, height, depth) "
485             << "(" << copy_params.m_width << "," << copy_params.m_height << "," << copy_params.m_depth << ")\n"
486             << tcu::TestLog::EndMessage;
487 
488         test_passed = false;
489     }
490 
491     clearCubeMapArrayTexture(width, height, depth, 0);
492 
493     gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pixel_buffer_id);
494     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!");
495 
496     texSubImage3D(copy_params, 0);
497 
498     if (!checkResults(width, height, depth))
499     {
500         m_testCtx.getLog() << tcu::TestLog::Message
501                            << "glTexSubImage3D failed to copy data to texture cube map "
502                               "array's data store from GL_PIXEL_UNPACK_BUFFER\n"
503                            << "Texture Cube Map Array Dimensions (width, height, depth) "
504                            << "(" << width << "," << height << "," << depth << ")\n"
505                            << "Texture Cube Map Array Offsets (xoffset, yoffset, zoffset) "
506                            << "(" << copy_params.m_xoffset << "," << copy_params.m_yoffset << ","
507                            << copy_params.m_zoffset << ")\n"
508                            << "Texture Cube Map Array Copy Size (width, height, depth) "
509                            << "(" << copy_params.m_width << "," << copy_params.m_height << "," << copy_params.m_depth
510                            << ")\n"
511                            << tcu::TestLog::EndMessage;
512 
513         test_passed = false;
514     }
515 
516     gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
517     GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!");
518 }
519 
520 /** Perform a full test of copyTexSubImage3D function on cube map array texture
521  * @param width          - width of the texture
522  * @param height         - height of the texture
523  * @param depth          - depth of the texture
524  * @param copy_params    - data structure specifying which region of the cube map array to test
525  * @param test_passed    - a boolean variable set to false if at any stage of the test we experience wrong result
526  */
testCopyTexSubImage3D(glw::GLuint width,glw::GLuint height,glw::GLuint depth,const SubImage3DCopyParams & copy_params,glw::GLboolean & test_passed)527 void TextureCubeMapArraySubImage3D::testCopyTexSubImage3D(glw::GLuint width, glw::GLuint height, glw::GLuint depth,
528                                                           const SubImage3DCopyParams &copy_params,
529                                                           glw::GLboolean &test_passed)
530 {
531     clearCubeMapArrayTexture(width, height, depth, 0);
532 
533     copyTexSubImage3D(copy_params);
534 
535     if (!checkResults(width, height, depth))
536     {
537         m_testCtx.getLog() << tcu::TestLog::Message
538                            << "glCopyTexSubImage3D failed to copy data to texture cube map array's data store\n"
539                            << "Texture Cube Map Array Dimensions (width, height, depth) "
540                            << "(" << width << "," << height << "," << depth << ")\n"
541                            << "Texture Cube Map Array Offsets (xoffset, yoffset, zoffset) "
542                            << "(" << copy_params.m_xoffset << "," << copy_params.m_yoffset << ","
543                            << copy_params.m_zoffset << ")\n"
544                            << "Texture Cube Map Array Copy Size (width, height, depth) "
545                            << "(" << copy_params.m_width << "," << copy_params.m_height << "," << copy_params.m_depth
546                            << ")\n"
547                            << tcu::TestLog::EndMessage;
548 
549         test_passed = false;
550     }
551 }
552 
553 /** Delete pixel unpack buffer */
deletePixelUnpackBuffer()554 void TextureCubeMapArraySubImage3D::deletePixelUnpackBuffer()
555 {
556     /* Get GL entry points */
557     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
558 
559     /* Reset GLES configuration */
560     gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
561 
562     /* Delete buffer object */
563     if (m_pixel_buffer_id != 0)
564     {
565         gl.deleteBuffers(1, &m_pixel_buffer_id);
566         m_pixel_buffer_id = 0;
567     }
568 }
569 
570 /** Delete cube map array texture */
deleteCubeMapArrayTexture()571 void TextureCubeMapArraySubImage3D::deleteCubeMapArrayTexture()
572 {
573     /* Get GL entry points */
574     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
575 
576     /* Reset GLES configuration */
577     gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
578 
579     /* Delete texture object */
580     if (m_tex_cube_map_array_id != 0)
581     {
582         gl.deleteTextures(1, &m_tex_cube_map_array_id);
583         m_tex_cube_map_array_id = 0;
584     }
585 }
586 
587 /* Delete 2D texture that had been used as data source by the glCopyTexSubImage3D call */
delete2DTexture()588 void TextureCubeMapArraySubImage3D::delete2DTexture()
589 {
590     /* Get GL entry points */
591     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
592 
593     /* Reset GLES configuration */
594     gl.bindTexture(GL_TEXTURE_2D, 0);
595 
596     /* Delete texture object */
597     if (m_tex_2d_id != 0)
598     {
599         gl.deleteTextures(1, &m_tex_2d_id);
600         m_tex_2d_id = 0;
601     }
602 }
603 
604 } // namespace glcts
605