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