• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
56 /* Location of dimension in array with texture resolutions */
57 enum Dimensions_Location
58 {
59 	DL_WIDTH  = 0,
60 	DL_HEIGHT = 1,
61 	DL_DEPTH  = 2
62 };
63 
64 /** Constructor
65  *
66  *  @param context              Test context
67  *  @param name                 Test case's name
68  *  @param description          Test case's description
69  */
TextureCubeMapArraySubImage3D(Context & context,const ExtParameters & extParams,const char * name,const char * description)70 TextureCubeMapArraySubImage3D::TextureCubeMapArraySubImage3D(Context& context, const ExtParameters& extParams,
71 															 const char* name, const char* description)
72 	: TestCaseBase(context, extParams, name, description)
73 	, m_read_fbo_id(0)
74 	, m_pixel_buffer_id(0)
75 	, m_tex_cube_map_array_id(0)
76 	, m_tex_2d_id(0)
77 {
78 	/* Nothing to be done here */
79 }
80 
81 /** Initialize test case */
initTest(void)82 void TextureCubeMapArraySubImage3D::initTest(void)
83 {
84 	/* Check if texture_cube_map_array extension is supported */
85 	if (!m_is_texture_cube_map_array_supported)
86 	{
87 		throw tcu::NotSupportedError(TEXTURE_CUBE_MAP_ARRAY_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
88 	}
89 
90 	/* Get GL entry points */
91 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
92 
93 	gl.genFramebuffers(1, &m_read_fbo_id);
94 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating frame buffer object!");
95 
96 	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_read_fbo_id);
97 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding frame buffer object!");
98 }
99 
100 /** Deinitialize test case */
deinit(void)101 void TextureCubeMapArraySubImage3D::deinit(void)
102 {
103 	/* Get GL entry points */
104 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
105 
106 	/* Reset GLES configuration */
107 	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
108 
109 	/* Delete GLES objects */
110 	if (m_read_fbo_id != 0)
111 	{
112 		gl.deleteFramebuffers(1, &m_read_fbo_id);
113 		m_read_fbo_id = 0;
114 	}
115 
116 	/* Delete pixel unpack buffer */
117 	deletePixelUnpackBuffer();
118 
119 	/* Delete cube map array texture */
120 	deleteCubeMapArrayTexture();
121 
122 	/* Delete 2D texture */
123 	delete2DTexture();
124 
125 	/* Deinitialize base class */
126 	TestCaseBase::deinit();
127 }
128 
129 /** Executes the test.
130  *
131  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
132  *
133  *  Note the function throws exception should an error occur!
134  *
135  *  @return STOP if the test has finished, CONTINUE to indicate iterate() should be called once again.
136  */
iterate()137 tcu::TestCase::IterateResult TextureCubeMapArraySubImage3D::iterate()
138 {
139 	initTest();
140 
141 	glw::GLboolean test_passed = true;
142 
143 	/* Execute test throught all storage types */
144 	for (glw::GLuint storage_index = 0; storage_index < m_n_storage_type; ++storage_index)
145 	{
146 		/* Execute test throught all texture resolutions */
147 		for (glw::GLuint resolution_index = 0; resolution_index < m_n_resolutions; ++resolution_index)
148 		{
149 			glw::GLuint width  = resolutions[resolution_index][DL_WIDTH];
150 			glw::GLuint height = resolutions[resolution_index][DL_HEIGHT];
151 			glw::GLuint depth  = resolutions[resolution_index][DL_DEPTH];
152 
153 			configureCubeMapArrayTexture(width, height, depth, static_cast<STORAGE_TYPE>(storage_index), 0);
154 
155 			/* A single whole layer-face at index 0 should be replaced (both functions) */
156 			SubImage3DCopyParams copy_params;
157 			copy_params.init(0, 0, 0, width, height, 1);
158 
159 			configureDataBuffer(width, height, depth, copy_params, 0);
160 			configurePixelUnpackBuffer(copy_params);
161 			configure2DTexture(copy_params);
162 			testTexSubImage3D(width, height, depth, copy_params, test_passed);
163 			testCopyTexSubImage3D(width, height, depth, copy_params, test_passed);
164 			deletePixelUnpackBuffer();
165 			delete2DTexture();
166 
167 			/* A region of a layer-face at index 0 should be replaced (both functions) */
168 			copy_params.init(width / 2, height / 2, 0, width / 2, height / 2, 1);
169 
170 			configureDataBuffer(width, height, depth, copy_params, 0);
171 			configurePixelUnpackBuffer(copy_params);
172 			configure2DTexture(copy_params);
173 			testTexSubImage3D(width, height, depth, copy_params, test_passed);
174 			testCopyTexSubImage3D(width, height, depth, copy_params, test_passed);
175 			deletePixelUnpackBuffer();
176 			delete2DTexture();
177 
178 			/* 6 layer-faces, making up a single layer, should be replaced (glTexSubImage3D() only) */
179 			copy_params.init(0, 0, 0, width, height, 6);
180 
181 			configureDataBuffer(width, height, depth, copy_params, 0);
182 			configurePixelUnpackBuffer(copy_params);
183 			testTexSubImage3D(width, height, depth, copy_params, test_passed);
184 			deletePixelUnpackBuffer();
185 
186 			/* 6 layer-faces, making up two different layers (for instance: three last layer-faces of
187 			 layer 1 and three first layer-faces of layer 2) should be replaced (glTexSubImage3D() only) */
188 			copy_params.init(0, 0, 3, width, height, 6);
189 
190 			configureDataBuffer(width, height, depth, copy_params, 0);
191 			configurePixelUnpackBuffer(copy_params);
192 			testTexSubImage3D(width, height, depth, copy_params, test_passed);
193 			deletePixelUnpackBuffer();
194 
195 			/* 6 layer-faces, making up a single layer, should be replaced (glTexSubImage3D() only),
196 			 but limited to a quad */
197 			copy_params.init(width / 2, height / 2, 0, width / 2, height / 2, 6);
198 
199 			configureDataBuffer(width, height, depth, copy_params, 0);
200 			configurePixelUnpackBuffer(copy_params);
201 			testTexSubImage3D(width, height, depth, copy_params, test_passed);
202 			deletePixelUnpackBuffer();
203 
204 			/* 6 layer-faces, making up two different layers (for instance: three last layer-faces of
205 			 layer 1 and three first layer-faces of layer 2) should be replaced (glTexSubImage3D() only),
206 			 but limited to a quad */
207 			copy_params.init(width / 2, height / 2, 3, width / 2, height / 2, 6);
208 
209 			configureDataBuffer(width, height, depth, copy_params, 0);
210 			configurePixelUnpackBuffer(copy_params);
211 			testTexSubImage3D(width, height, depth, copy_params, test_passed);
212 			deletePixelUnpackBuffer();
213 
214 			deleteCubeMapArrayTexture();
215 		}
216 	}
217 
218 	if (test_passed)
219 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
220 	else
221 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
222 
223 	return STOP;
224 }
225 
226 /** Resizes data buffer and fills it with values
227  * @param width       - width of the texture
228  * @param height      - height of the texture
229  * @param depth       - depth of the texture
230  * @param copy_params - data structure specifying which region of the data store to replace
231  * @param clear_value - value with which to fill the data buffer outside of region specified by copy_params
232  */
configureDataBuffer(glw::GLuint width,glw::GLuint height,glw::GLuint depth,const SubImage3DCopyParams & copy_params,glw::GLuint clear_value)233 void TextureCubeMapArraySubImage3D::configureDataBuffer(glw::GLuint width, glw::GLuint height, glw::GLuint depth,
234 														const SubImage3DCopyParams& copy_params,
235 														glw::GLuint					clear_value)
236 {
237 	glw::GLuint index = 0;
238 
239 	m_copy_data_buffer.assign(copy_params.m_width * copy_params.m_height * copy_params.m_depth * m_n_components,
240 							  clear_value);
241 	for (glw::GLuint zoffset = copy_params.m_zoffset; zoffset < copy_params.m_zoffset + copy_params.m_depth; ++zoffset)
242 	{
243 		for (glw::GLuint yoffset = copy_params.m_yoffset; yoffset < copy_params.m_yoffset + copy_params.m_height;
244 			 ++yoffset)
245 		{
246 			for (glw::GLuint xoffset = copy_params.m_xoffset; xoffset < copy_params.m_xoffset + copy_params.m_width;
247 				 ++xoffset)
248 			{
249 				for (glw::GLuint component = 0; component < m_n_components; ++component)
250 				{
251 					m_copy_data_buffer[index++] =
252 						(zoffset * width * height + yoffset * width + xoffset) * m_n_components + component;
253 				}
254 			}
255 		}
256 	}
257 
258 	m_expected_data_buffer.assign(width * height * depth * m_n_components, clear_value);
259 	for (glw::GLuint zoffset = copy_params.m_zoffset; zoffset < copy_params.m_zoffset + copy_params.m_depth; ++zoffset)
260 	{
261 		for (glw::GLuint yoffset = copy_params.m_yoffset; yoffset < copy_params.m_yoffset + copy_params.m_height;
262 			 ++yoffset)
263 		{
264 			for (glw::GLuint xoffset = copy_params.m_xoffset; xoffset < copy_params.m_xoffset + copy_params.m_width;
265 				 ++xoffset)
266 			{
267 				glw::GLuint* data_pointer =
268 					&m_expected_data_buffer[(zoffset * width * height + yoffset * width + xoffset) * m_n_components];
269 				for (glw::GLuint component = 0; component < m_n_components; ++component)
270 				{
271 					data_pointer[component] =
272 						(zoffset * width * height + yoffset * width + xoffset) * m_n_components + component;
273 				}
274 			}
275 		}
276 	}
277 }
278 
279 /** Creates a pixel unpack buffer that will be used as data source for filling a region of cube map array texture with data
280  * @param copy_params - data structure specifying which region of the data store to replace
281  */
configurePixelUnpackBuffer(const SubImage3DCopyParams & copy_params)282 void TextureCubeMapArraySubImage3D::configurePixelUnpackBuffer(const SubImage3DCopyParams& copy_params)
283 {
284 	/* Get GL entry points */
285 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
286 
287 	/* generate buffer for pixel unpack buffer */
288 	gl.genBuffers(1, &m_pixel_buffer_id);
289 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate buffer object!");
290 
291 	/* bind buffer to PIXEL_UNPACK_BUFFER binding point */
292 	gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pixel_buffer_id);
293 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind buffer object!");
294 
295 	/* fill buffer with data */
296 	gl.bufferData(GL_PIXEL_UNPACK_BUFFER,
297 				  copy_params.m_width * copy_params.m_height * copy_params.m_depth * m_n_components *
298 					  sizeof(glw::GLuint),
299 				  &m_copy_data_buffer[0], GL_STATIC_READ);
300 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not fill buffer object's data store with data!");
301 
302 	gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
303 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind buffer object!");
304 }
305 
306 /** Creates cube map array texture and fills it with data
307  * @param width       - width of the texture
308  * @param height      - height of the texture
309  * @param depth       - depth of the texture
310  * @param storType    - mutable or immutable storage type
311  * @param clear_value - value with which to initialize the texture's data store
312  */
configureCubeMapArrayTexture(glw::GLuint width,glw::GLuint height,glw::GLuint depth,STORAGE_TYPE storType,glw::GLuint clear_value)313 void TextureCubeMapArraySubImage3D::configureCubeMapArrayTexture(glw::GLuint width, glw::GLuint height,
314 																 glw::GLuint depth, STORAGE_TYPE storType,
315 																 glw::GLuint clear_value)
316 {
317 	/* Get GL entry points */
318 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
319 
320 	gl.genTextures(1, &m_tex_cube_map_array_id);
321 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!");
322 
323 	gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_tex_cube_map_array_id);
324 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
325 
326 	/* used glTexImage3D() method if texture should be MUTABLE */
327 	if (storType == ST_MUTABLE)
328 	{
329 		gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
330 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture parameter.");
331 		gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
332 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture parameter.");
333 
334 		DataBufferVec data_buffer(width * height * depth * m_n_components, clear_value);
335 
336 		gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA32UI, width, height, depth, 0, GL_RGBA_INTEGER,
337 					  GL_UNSIGNED_INT, &data_buffer[0]);
338 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object's data store");
339 	}
340 	/* used glTexStorage3D() method if texture should be IMMUTABLE */
341 	else
342 	{
343 		gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA32UI, width, height, depth);
344 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object's data store");
345 
346 		clearCubeMapArrayTexture(width, height, depth, clear_value);
347 	}
348 }
349 
350 /** Fills cube map array texture's data store with data
351  * @param width       - width of the texture
352  * @param height      - height of the texture
353  * @param depth       - depth of the texture
354  * @param clear_value - value with which to fill the texture's data store
355  */
clearCubeMapArrayTexture(glw::GLuint width,glw::GLuint height,glw::GLuint depth,glw::GLuint clear_value)356 void TextureCubeMapArraySubImage3D::clearCubeMapArrayTexture(glw::GLuint width, glw::GLuint height, glw::GLuint depth,
357 															 glw::GLuint clear_value)
358 {
359 	/* Get GL entry points */
360 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
361 
362 	DataBufferVec data_buffer(width * height * depth * m_n_components, clear_value);
363 
364 	gl.texSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, width, height, depth, GL_RGBA_INTEGER, GL_UNSIGNED_INT,
365 					 &data_buffer[0]);
366 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture object's data store with data");
367 }
368 
369 /** Creates 2D texture that will be used as data source by the glCopyTexSubImage3D call
370  * @param copy_params - data structure specifying which region of the data store to replace
371  */
configure2DTexture(const SubImage3DCopyParams & copy_params)372 void TextureCubeMapArraySubImage3D::configure2DTexture(const SubImage3DCopyParams& copy_params)
373 {
374 	/* Get GL entry points */
375 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
376 
377 	gl.genTextures(1, &m_tex_2d_id);
378 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate texture object!");
379 
380 	gl.bindTexture(GL_TEXTURE_2D, m_tex_2d_id);
381 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind texture object!");
382 
383 	gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32UI, copy_params.m_width, copy_params.m_height);
384 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object's data store");
385 
386 	gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, copy_params.m_width, copy_params.m_height, GL_RGBA_INTEGER,
387 					 GL_UNSIGNED_INT, &m_copy_data_buffer[0]);
388 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture object's data store with data");
389 }
390 
391 /** Replaces region of cube map array texture's data store using texSubImage3D function
392  * @param copy_params    - data structure specifying which region of the data store to replace
393  * @param data_pointer   - pointer to the data that should end up in the specified region of the data store
394  */
texSubImage3D(const SubImage3DCopyParams & copy_params,const glw::GLuint * data_pointer)395 void TextureCubeMapArraySubImage3D::texSubImage3D(const SubImage3DCopyParams& copy_params,
396 												  const glw::GLuint*		  data_pointer)
397 {
398 	/* Get GL entry points */
399 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
400 
401 	gl.texSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, copy_params.m_xoffset, copy_params.m_yoffset, copy_params.m_zoffset,
402 					 copy_params.m_width, copy_params.m_height, copy_params.m_depth, GL_RGBA_INTEGER, GL_UNSIGNED_INT,
403 					 data_pointer);
404 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture object's data store with data");
405 }
406 
407 /** Replaces region of cube map array texture's data store using copyTexSubImage3D function
408  * @param copy_params    - data structure specifying which region of the data store to replace
409  */
copyTexSubImage3D(const SubImage3DCopyParams & copy_params)410 void TextureCubeMapArraySubImage3D::copyTexSubImage3D(const SubImage3DCopyParams& copy_params)
411 {
412 	/* Get GL entry points */
413 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
414 
415 	gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_tex_2d_id, 0);
416 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not attach texture object to framebuffer's attachment");
417 
418 	checkFramebufferStatus(GL_READ_FRAMEBUFFER);
419 
420 	gl.copyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, copy_params.m_xoffset, copy_params.m_yoffset,
421 						 copy_params.m_zoffset, 0, 0, copy_params.m_width, copy_params.m_height);
422 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture object's data store with data");
423 }
424 
425 /** Compares the region of data specified by copy_params taken from the cube map array texture's data store with
426  *  the reference data stored in m_data_buffer.
427  * @param width       - width of the texture
428  * @param height      - height of the texture
429  * @param depth       - depth of the texture
430  * @return            - true if the result of comparison is that the regions contain the same data, false otherwise
431  */
checkResults(glw::GLuint width,glw::GLuint height,glw::GLuint depth)432 bool TextureCubeMapArraySubImage3D::checkResults(glw::GLuint width, glw::GLuint height, glw::GLuint depth)
433 {
434 	/* Get GL entry points */
435 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
436 
437 	glw::GLuint   n_elements = width * height * depth * m_n_components;
438 	DataBufferVec result_data_buffer(n_elements, 0);
439 
440 	for (glw::GLuint layer_nr = 0; layer_nr < depth; ++layer_nr)
441 	{
442 		/* attach one layer to framebuffer's attachment */
443 		gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_tex_cube_map_array_id, 0, layer_nr);
444 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not attach texture object to framebuffer's attachment");
445 
446 		/* check framebuffer status */
447 		checkFramebufferStatus(GL_READ_FRAMEBUFFER);
448 
449 		/* read data from the texture */
450 		gl.readPixels(0, 0, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT,
451 					  &result_data_buffer[layer_nr * width * height * m_n_components]);
452 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read pixels from framebuffer's attachment!");
453 	}
454 
455 	return memcmp(&result_data_buffer[0], &m_expected_data_buffer[0], n_elements * sizeof(glw::GLuint)) == 0;
456 }
457 
458 /** Perform a full test of testTexSubImage3D function on cube map array texture, both with client pointer and pixel unpack buffer
459  * @param width          - width of the texture
460  * @param height         - height of the texture
461  * @param depth          - depth of the texture
462  * @param copy_params    - data structure specifying which region of the cube map array to test
463  * @param test_passed    - a boolean variable set to false if at any stage of the test we experience wrong result
464  */
testTexSubImage3D(glw::GLuint width,glw::GLuint height,glw::GLuint depth,const SubImage3DCopyParams & copy_params,glw::GLboolean & test_passed)465 void TextureCubeMapArraySubImage3D::testTexSubImage3D(glw::GLuint width, glw::GLuint height, glw::GLuint depth,
466 													  const SubImage3DCopyParams& copy_params,
467 													  glw::GLboolean&			  test_passed)
468 {
469 	/* Get GL entry points */
470 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
471 
472 	clearCubeMapArrayTexture(width, height, depth, 0);
473 
474 	texSubImage3D(copy_params, &m_copy_data_buffer[0]);
475 
476 	if (!checkResults(width, height, depth))
477 	{
478 		m_testCtx.getLog()
479 			<< tcu::TestLog::Message
480 			<< "glTexSubImage3D failed to copy data to texture cube map array's data store from client's memory\n"
481 			<< "Texture Cube Map Array Dimensions (width, height, depth) "
482 			<< "(" << width << "," << height << "," << depth << ")\n"
483 			<< "Texture Cube Map Array Offsets (xoffset, yoffset, zoffset) "
484 			<< "(" << copy_params.m_xoffset << "," << copy_params.m_yoffset << "," << copy_params.m_zoffset << ")\n"
485 			<< "Texture Cube Map Array Copy Size (width, height, depth) "
486 			<< "(" << copy_params.m_width << "," << copy_params.m_height << "," << copy_params.m_depth << ")\n"
487 			<< tcu::TestLog::EndMessage;
488 
489 		test_passed = false;
490 	}
491 
492 	clearCubeMapArrayTexture(width, height, depth, 0);
493 
494 	gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pixel_buffer_id);
495 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!");
496 
497 	texSubImage3D(copy_params, 0);
498 
499 	if (!checkResults(width, height, depth))
500 	{
501 		m_testCtx.getLog() << tcu::TestLog::Message << "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