• 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  esextcTextureCubeMapArrayImageOperations.cpp
26  * \brief texture_cube_map_array extension - Image Operations (Test 8)
27  */ /*-------------------------------------------------------------------*/
28 
29 #include "esextcTextureCubeMapArrayImageOperations.hpp"
30 #include "gluContextInfo.hpp"
31 #include "gluStrUtil.hpp"
32 #include "glwEnums.hpp"
33 #include "glwFunctions.hpp"
34 #include "tcuTestLog.hpp"
35 #include <cmath>
36 #include <cstring>
37 #include <vector>
38 
39 namespace glcts
40 {
41 
42 /* Set constant values for tests */
43 const glw::GLfloat TextureCubeMapArrayImageOpCompute::m_f_base  = 1.5f;
44 const glw::GLint   TextureCubeMapArrayImageOpCompute::m_i_base  = -1;
45 const glw::GLuint  TextureCubeMapArrayImageOpCompute::m_ui_base = 1;
46 
47 const glw::GLuint TextureCubeMapArrayImageOpCompute::m_n_components	= 4;
48 const glw::GLuint TextureCubeMapArrayImageOpCompute::m_n_dimensions	= 3;
49 const glw::GLuint TextureCubeMapArrayImageOpCompute::m_n_image_formats = 3;
50 const glw::GLuint TextureCubeMapArrayImageOpCompute::m_n_resolutions   = 4;
51 const glw::GLuint TextureCubeMapArrayImageOpCompute::m_n_storage_type  = 2;
52 
53 const char* TextureCubeMapArrayImageOpCompute::m_mutable_storage   = "MUTABLE";
54 const char* TextureCubeMapArrayImageOpCompute::m_immutable_storage = "IMMUTABLE";
55 
56 /* Helper arrays for tests configuration */
57 
58 /* Different texture resolutions */
59 const int m_resolutions[TextureCubeMapArrayImageOpCompute::m_n_resolutions]
60 					   [TextureCubeMapArrayImageOpCompute::m_n_dimensions] = {
61 						   /* Width , Height, Depth */
62 						   { 16, 16, 12 },
63 						   { 32, 32, 6 },
64 						   { 4, 4, 18 },
65 						   { 8, 8, 6 }
66 					   };
67 
68 /** Check if buffers contains the same values
69  * @param a      buffer with data to compare
70  * @param b      buffer with data to compare
71  * @param length buffers length
72  * @return       true if both buffers are equal, otherwise false
73  */
74 template <typename T>
areBuffersEqual(const T * a,const T * b,glw::GLuint length)75 glw::GLboolean areBuffersEqual(const T* a, const T* b, glw::GLuint length)
76 {
77 	return (memcmp(a, b, length * sizeof(T))) ? false : true;
78 }
79 
80 /** Check if buffers contains the same values (float type)
81  * @param a      buffer with data to compare
82  * @param b      buffer with data to compare
83  * @param length buffers length
84  * @return       true if both buffers are equal, otherwise false
85  */
86 template <>
areBuffersEqual(const glw::GLfloat * a,const glw::GLfloat * b,glw::GLuint length)87 glw::GLboolean areBuffersEqual(const glw::GLfloat* a, const glw::GLfloat* b, glw::GLuint length)
88 {
89 	for (glw::GLuint i = 0; i < length; ++i)
90 	{
91 		if (de::abs(a[i] - b[i]) > TestCaseBase::m_epsilon_float)
92 		{
93 			return false;
94 		}
95 	}
96 	return true;
97 }
98 
99 /** Fill buffer with test data
100  * @param data       buffer where values will be stored
101  * @param width      buffer/texture width
102  * @param height     buffer/texture height
103  * @param depth      buffer/texture depth
104  * @param components buffer/texture components number
105  * @param base       base value used to fill array
106  **/
107 template <typename T>
fillData(T * data,glw::GLuint width,glw::GLuint height,glw::GLuint depth,glw::GLuint components,T base)108 void fillData(T* data, glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLuint components, T base)
109 {
110 	for (glw::GLuint i = 0; i < depth; ++i)
111 	{
112 		for (glw::GLuint j = 0; j < width; ++j)
113 		{
114 			for (glw::GLuint k = 0; k < height; ++k)
115 			{
116 				for (glw::GLuint l = 0; l < components; ++l)
117 				{
118 					data[i * width * height * components + j * height * components + k * components + l] = base + (T)i;
119 				}
120 			}
121 		}
122 	}
123 }
124 
125 /** Check if results are es expected and log error if not
126  * @param context      application context
127  * @param id           id of texture
128  * @param width        texture width
129  * @param height       texture height
130  * @param depth        texture depth
131  * @param components   number of components per texel
132  * @param format       texture data format
133  * @param type         texture data type
134  * @param storType     storageType
135  * @param expectedData buffer with expected data
136  * @return             return true if data read from the texture is the same as expected
137  */
138 template <typename T>
checkResults(Context & context,glw::GLuint copy_po_id,glw::GLuint id,glw::GLuint width,glw::GLuint height,glw::GLuint depth,glw::GLuint components,glw::GLenum format,glw::GLenum type,STORAGE_TYPE storType,T * expectedData)139 bool checkResults(Context& context, glw::GLuint copy_po_id, glw::GLuint id, glw::GLuint width, glw::GLuint height,
140 				  glw::GLuint depth, glw::GLuint components, glw::GLenum format, glw::GLenum type,
141 				  STORAGE_TYPE storType, T* expectedData)
142 {
143 	/* Get GL entry points */
144 	const glw::Functions& gl = context.getRenderContext().getFunctions();
145 
146 	/* prepare buffers for result data */
147 	std::vector<T> resultData(width * height * components);
148 
149 	glw::GLint  old_program = 0;
150 	glw::GLuint uint_tex_id = 0;
151 
152 	/* Floating point textures are not renderable, so we will need to copy their bits to a temporary unsigned integer texture */
153 	if (type == GL_FLOAT)
154 	{
155 		/* Generate a new texture name */
156 		gl.genTextures(1, &uint_tex_id);
157 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating temporary texture object!");
158 
159 		/* Allocate unsigned integer storage */
160 		gl.bindTexture(GL_TEXTURE_2D, uint_tex_id);
161 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding temporary texture object!");
162 		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32UI, width, height);
163 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating temporary texture object!");
164 
165 		/* Set the filter mode */
166 		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
167 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!");
168 		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
169 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!");
170 
171 		/* Attach it to the framebuffer */
172 		gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, uint_tex_id, 0);
173 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to frame buffer");
174 
175 		/* And bind it to an image unit for writing */
176 		gl.bindImageTexture(1, uint_tex_id, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI);
177 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding integer texture for copy destination");
178 
179 		/* Finally, bind the copy compute shader */
180 		gl.getIntegerv(GL_CURRENT_PROGRAM, &old_program);
181 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error querying old program!");
182 		gl.useProgram(copy_po_id);
183 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active program object!");
184 
185 		gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
186 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting memory barrier!");
187 	}
188 	else
189 	{
190 		gl.memoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
191 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting memory barrier!");
192 	}
193 
194 	bool result = true;
195 
196 	for (glw::GLuint i = 0; i < depth; ++i)
197 	{
198 		/* Floating point textures are not renderable */
199 		if (type == GL_FLOAT)
200 		{
201 			/* Use a compute shader to store the float bits as unsigned integers */
202 			gl.bindImageTexture(0, id, 0, GL_FALSE, i, GL_READ_ONLY, GL_RGBA32F);
203 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding floating point texture for copy source");
204 			gl.dispatchCompute(width, height, 1);
205 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error dispatching float-to-integer compute shader");
206 
207 			gl.memoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
208 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting memory barrier!");
209 
210 			/* Read data as unsigned ints */
211 			gl.readPixels(0, 0, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &resultData[0]);
212 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error reading pixels from frame buffer!");
213 		}
214 		else
215 		{
216 			/* Attach proper 2D texture to frame buffer and read pixels */
217 			gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, id, 0, i);
218 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to frame buffer");
219 
220 			/* Read data */
221 			gl.readPixels(0, 0, width, height, format, type, &resultData[0]);
222 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error reading pixels from frame buffer!");
223 		}
224 
225 		/* Prepare correct pointer for expected data layer */
226 		T* pointer = &expectedData[0] + (i * width * height * components);
227 
228 		/* If compared data are not equal log error and return false */
229 		if (!areBuffersEqual<T>(&resultData[0], pointer, width * height * components))
230 		{
231 			context.getTestContext().getLog()
232 				<< tcu::TestLog::Message << "Wrong value in result texture for "
233 				<< ((type == GL_FLOAT) ? "imageCubeArray" : ((type == GL_INT) ? "iimageCubeArray" : "uimageCubeArray"))
234 				<< " for resolution[w,h,d] = [" << width << "," << height << "," << depth << "] for layer[" << i
235 				<< "] and " << ((storType == ST_MUTABLE) ? TextureCubeMapArrayImageOpCompute::m_mutable_storage :
236 														   TextureCubeMapArrayImageOpCompute::m_immutable_storage)
237 				<< " storage!" << tcu::TestLog::EndMessage;
238 			result = false;
239 			break;
240 		}
241 	}
242 
243 	/* Clean up the floating point stuff */
244 	if (type == GL_FLOAT)
245 	{
246 		/* Restore the program */
247 		gl.useProgram(old_program);
248 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active program object!");
249 
250 		/* Delete the temporary texture */
251 		gl.deleteTextures(1, &uint_tex_id);
252 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error deleting temporary texture!");
253 	}
254 
255 	return result;
256 }
257 
258 /** Configure texture object
259  * @param context        application context
260  * @param id             pointer where texture id will be stored
261  * @param width          texture width
262  * @param height         texture height
263  * @param depth          texture depth
264  * @param storType       storageType
265  * @param internalFormat texture internal format
266  * @param format         texture data format
267  * @param type           texture data type
268  * @param data           initialization data for texture
269  */
270 template <typename T>
configureTexture(glcts::Context & context,glw::GLuint * id,glw::GLuint width,glw::GLuint height,glw::GLuint depth,STORAGE_TYPE storType,glw::GLenum internalFormat,glw::GLenum format,glw::GLenum type,const T * data)271 void configureTexture(glcts::Context& context, glw::GLuint* id, glw::GLuint width, glw::GLuint height,
272 					  glw::GLuint depth, STORAGE_TYPE storType, glw::GLenum internalFormat, glw::GLenum format,
273 					  glw::GLenum type, const T* data)
274 {
275 	/* Get GL entry points */
276 	const glw::Functions& gl = context.getRenderContext().getFunctions();
277 
278 	/* Generate texture object */
279 	gl.activeTexture(GL_TEXTURE0);
280 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active texture unit!");
281 
282 	gl.genTextures(1, id);
283 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!");
284 
285 	gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, *id);
286 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
287 
288 	gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
289 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!");
290 	gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
291 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!");
292 
293 	/* used glTexImage3D() method if texture should be MUTABLE */
294 	if (storType == ST_MUTABLE)
295 	{
296 		gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
297 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture parameter.");
298 		gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
299 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture parameter.");
300 
301 		gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, internalFormat, width, height, depth, 0, format, type, data);
302 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object's data store");
303 	}
304 	/* used glTexStorage3D() method if texture should be IMMUTABLE */
305 	else
306 	{
307 		gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, internalFormat, width, height, depth);
308 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object's data store");
309 
310 		gl.texSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, width, height, depth, format, type, data);
311 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture object's data store with data");
312 	}
313 }
314 
315 /** Constructor
316  *
317  *  @param context       Test context
318  *  @param name          Test case's name
319  *  @param description   Test case's description
320  **/
TextureCubeMapArrayImageOpCompute(Context & context,const ExtParameters & extParams,const char * name,const char * description,SHADER_TO_CHECK shaderToCheck)321 TextureCubeMapArrayImageOpCompute::TextureCubeMapArrayImageOpCompute(Context& context, const ExtParameters& extParams,
322 																	 const char* name, const char* description,
323 																	 SHADER_TO_CHECK shaderToCheck)
324 	: TestCaseBase(context, extParams, name, description)
325 	, m_shader_to_check(shaderToCheck)
326 	, m_cs_id(0)
327 	, m_fbo_id(0)
328 	, m_fs_id(0)
329 	, m_gs_id(0)
330 	, m_po_id(0)
331 	, m_tc_id(0)
332 	, m_te_id(0)
333 	, m_vao_id(0)
334 	, m_vs_id(0)
335 	, m_copy_po_id(0)
336 	, m_copy_cs_id(0)
337 	, m_iimage_read_to_id(0)
338 	, m_iimage_write_to_id(0)
339 	, m_image_read_to_id(0)
340 	, m_image_write_to_id(0)
341 	, m_uimage_read_to_id(0)
342 	, m_uimage_write_to_id(0)
343 {
344 	/* Nothing to be done here */
345 }
346 
getQueryPname(SHADER_TO_CHECK stage)347 glw::GLenum getQueryPname(SHADER_TO_CHECK stage) {
348 	switch (stage) {
349 		case STC_COMPUTE_SHADER:					return GL_MAX_COMPUTE_IMAGE_UNIFORMS;
350 		case STC_VERTEX_SHADER:						return GL_MAX_VERTEX_IMAGE_UNIFORMS;
351 		case STC_FRAGMENT_SHADER:					return GL_MAX_FRAGMENT_IMAGE_UNIFORMS;
352 		case STC_GEOMETRY_SHADER:					return GL_MAX_GEOMETRY_IMAGE_UNIFORMS;
353 		case STC_TESSELLATION_CONTROL_SHADER:		return GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS;
354 		case STC_TESSELLATION_EVALUATION_SHADER:	return GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS;
355 	}
356 	DE_ASSERT(0);
357 	return GL_NONE;
358 }
359 
360 /** Initialize test case */
initTest(void)361 void TextureCubeMapArrayImageOpCompute::initTest(void)
362 {
363 	/* Get GL entry points */
364 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
365 
366 	/* Check if texture_cube_map_array extension is supported */
367 	if (!m_is_texture_cube_map_array_supported)
368 	{
369 		throw tcu::NotSupportedError(TEXTURE_CUBE_MAP_ARRAY_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
370 	}
371 	if (!m_is_geometry_shader_extension_supported && m_shader_to_check == STC_GEOMETRY_SHADER)
372 	{
373 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
374 	}
375 	if (!m_is_tessellation_shader_supported && (m_shader_to_check == STC_TESSELLATION_CONTROL_SHADER ||
376 												m_shader_to_check == STC_TESSELLATION_EVALUATION_SHADER))
377 	{
378 		throw tcu::NotSupportedError(TESSELLATION_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
379 	}
380 
381 	int maxImages;
382 	glw::GLenum pname = getQueryPname(m_shader_to_check);
383 	gl.getIntegerv(pname, &maxImages);
384 	if (maxImages < 6)
385 		throw tcu::NotSupportedError( "Shader stage does not support at least 6 image uniforms", "", __FILE__, __LINE__);
386 
387 	/* Generate and bind VAO */
388 	gl.genVertexArrays(1, &m_vao_id);
389 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate vertex array object");
390 
391 	gl.bindVertexArray(m_vao_id);
392 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding vertex array object!");
393 
394 	/* Generate and bind framebuffer */
395 	gl.genFramebuffers(1, &m_fbo_id);
396 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating frame buffer object!");
397 
398 	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_id);
399 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding frame buffer object!");
400 
401 	/* Create the floating point copy program */
402 	m_copy_po_id			   = gl.createProgram();
403 	m_copy_cs_id			   = gl.createShader(GL_COMPUTE_SHADER);
404 	const char* copy_cs_source = getFloatingPointCopyShaderSource();
405 	buildProgram(m_copy_po_id, m_copy_cs_id, 1, &copy_cs_source);
406 
407 	/* Create program */
408 	m_po_id = gl.createProgram();
409 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program object!");
410 
411 	configureProgram();
412 }
413 
414 /** Deinitialize test case */
deinit(void)415 void TextureCubeMapArrayImageOpCompute::deinit(void)
416 {
417 	/* Get GL entry points */
418 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
419 
420 	/* Reset GLES configuration */
421 	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
422 	gl.useProgram(0);
423 	gl.bindVertexArray(0);
424 
425 	/* Delete GLES objects */
426 	if (m_po_id != 0)
427 	{
428 		gl.deleteProgram(m_po_id);
429 		m_po_id = 0;
430 	}
431 	if (m_cs_id != 0)
432 	{
433 		gl.deleteShader(m_cs_id);
434 		m_cs_id = 0;
435 	}
436 	if (m_fs_id != 0)
437 	{
438 		gl.deleteShader(m_fs_id);
439 		m_fs_id = 0;
440 	}
441 	if (m_gs_id != 0)
442 	{
443 		gl.deleteShader(m_gs_id);
444 		m_gs_id = 0;
445 	}
446 	if (m_tc_id != 0)
447 	{
448 		gl.deleteShader(m_tc_id);
449 		m_tc_id = 0;
450 	}
451 	if (m_te_id != 0)
452 	{
453 		gl.deleteShader(m_te_id);
454 		m_te_id = 0;
455 	}
456 	if (m_vs_id != 0)
457 	{
458 		gl.deleteShader(m_vs_id);
459 		m_vs_id = 0;
460 	}
461 	if (m_copy_cs_id != 0)
462 	{
463 		gl.deleteShader(m_copy_cs_id);
464 		m_copy_cs_id = 0;
465 	}
466 	if (m_copy_po_id != 0)
467 	{
468 		gl.deleteProgram(m_copy_po_id);
469 		m_copy_po_id = 0;
470 	}
471 	if (m_fbo_id != 0)
472 	{
473 		gl.deleteFramebuffers(1, &m_fbo_id);
474 		m_fbo_id = 0;
475 	}
476 	if (m_vao_id != 0)
477 	{
478 		gl.deleteVertexArrays(1, &m_vao_id);
479 		m_vao_id = 0;
480 	}
481 
482 	removeTextures();
483 
484 	/* Deinitialize base class */
485 	TestCaseBase::deinit();
486 }
487 
488 /** Delete texture objects */
removeTextures()489 void TextureCubeMapArrayImageOpCompute::removeTextures()
490 {
491 	/* Get GL entry points */
492 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
493 
494 	gl.activeTexture(GL_TEXTURE0);
495 	gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
496 
497 	/* Delete texture objects */
498 	if (m_iimage_read_to_id != 0)
499 	{
500 		gl.deleteTextures(1, &m_iimage_read_to_id);
501 		m_iimage_read_to_id = 0;
502 	}
503 
504 	if (m_iimage_write_to_id != 0)
505 	{
506 		gl.deleteTextures(1, &m_iimage_write_to_id);
507 		m_iimage_write_to_id = 0;
508 	}
509 
510 	if (m_image_read_to_id != 0)
511 	{
512 		gl.deleteTextures(1, &m_image_read_to_id);
513 		m_image_read_to_id = 0;
514 	}
515 
516 	if (m_image_write_to_id != 0)
517 	{
518 		gl.deleteTextures(1, &m_image_write_to_id);
519 		m_image_write_to_id = 0;
520 	}
521 
522 	if (m_uimage_read_to_id != 0)
523 	{
524 		gl.deleteTextures(1, &m_uimage_read_to_id);
525 		m_uimage_read_to_id = 0;
526 	}
527 
528 	if (m_uimage_write_to_id != 0)
529 	{
530 		gl.deleteTextures(1, &m_uimage_write_to_id);
531 		m_uimage_write_to_id = 0;
532 	}
533 }
534 
535 /** Executes the test.
536  *
537  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
538  *
539  *  Note the function throws exception should an error occur!
540  *
541  *  @return STOP if the test has finished, CONTINUE to indicate iterate() should be called once again.
542  **/
iterate()543 tcu::TestCase::IterateResult TextureCubeMapArrayImageOpCompute::iterate()
544 {
545 	initTest();
546 
547 	/* Get GL entry points */
548 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
549 
550 	gl.useProgram(m_po_id);
551 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active program object!");
552 
553 	bool test_passed = true;
554 
555 	std::vector<glw::GLfloat> floatData;
556 	std::vector<glw::GLfloat> floatClean;
557 	std::vector<glw::GLint>   intData;
558 	std::vector<glw::GLint>   intClean;
559 	std::vector<glw::GLuint>  uIntData;
560 	std::vector<glw::GLuint>  uIntClean;
561 
562 	/* Execute test throught all resolutions, storage types, and image types */
563 	for (glw::GLuint res_index = 0; res_index < m_n_resolutions; ++res_index)
564 	{
565 		glw::GLuint width  = m_resolutions[res_index][DL_WIDTH];
566 		glw::GLuint height = m_resolutions[res_index][DL_HEIGHT];
567 		glw::GLuint depth  = m_resolutions[res_index][DL_DEPTH];
568 
569 		/* Allocate memory buffers for data */
570 		floatData.resize(width * height * depth * m_n_components);
571 		floatClean.resize(width * height * depth * m_n_components);
572 		intData.resize(width * height * depth * m_n_components);
573 		intClean.resize(width * height * depth * m_n_components);
574 		uIntData.resize(width * height * depth * m_n_components);
575 		uIntClean.resize(width * height * depth * m_n_components);
576 
577 		memset(&floatClean[0], 0, width * height * depth * m_n_components * sizeof(glw::GLfloat));
578 		memset(&intClean[0], 0, width * height * depth * m_n_components * sizeof(glw::GLint));
579 		memset(&uIntClean[0], 0, width * height * depth * m_n_components * sizeof(glw::GLuint));
580 
581 		/* Fill buffers with expected data*/
582 		fillData<glw::GLfloat>(&floatData[0], width, height, depth, m_n_components, m_f_base);
583 		fillData<glw::GLint>(&intData[0], width, height, depth, m_n_components, m_i_base);
584 		fillData<glw::GLuint>(&uIntData[0], width, height, depth, m_n_components, m_ui_base);
585 
586 		if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
587 		{
588 
589 			/**
590 			 * Mutable textures cannot be bound as image textures on ES, but can be on
591 			 * desktop GL.
592 			 * */
593 
594 			/* Work on mutable texture storage */
595 
596 			/* Generate texture objects */
597 			configureTexture<glw::GLfloat>(m_context, &m_image_read_to_id, width, height, depth, ST_MUTABLE, GL_RGBA32F,
598 										   GL_RGBA, GL_FLOAT, &floatData[0]);
599 			configureTexture<glw::GLfloat>(m_context, &m_image_write_to_id, width, height, depth, ST_MUTABLE,
600 										   GL_RGBA32F, GL_RGBA, GL_FLOAT, &floatClean[0]);
601 
602 			configureTexture<glw::GLint>(m_context, &m_iimage_read_to_id, width, height, depth, ST_MUTABLE, GL_RGBA32I,
603 										 GL_RGBA_INTEGER, GL_INT, &intData[0]);
604 			configureTexture<glw::GLint>(m_context, &m_iimage_write_to_id, width, height, depth, ST_MUTABLE, GL_RGBA32I,
605 										 GL_RGBA_INTEGER, GL_INT, &intClean[0]);
606 
607 			configureTexture<glw::GLuint>(m_context, &m_uimage_read_to_id, width, height, depth, ST_MUTABLE,
608 										  GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &uIntData[0]);
609 			configureTexture<glw::GLuint>(m_context, &m_uimage_write_to_id, width, height, depth, ST_MUTABLE,
610 										  GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &uIntClean[0]);
611 
612 			/* Bind texture objects to image units */
613 			gl.bindImageTexture(IF_IMAGE, m_image_read_to_id, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32F);
614 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
615 			gl.bindImageTexture(IF_IIMAGE, m_iimage_read_to_id, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32I);
616 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
617 			gl.bindImageTexture(IF_UIMAGE, m_uimage_read_to_id, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32UI);
618 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
619 			gl.bindImageTexture(IF_IMAGE + m_n_image_formats, m_image_write_to_id, 0, GL_TRUE, 0, GL_WRITE_ONLY,
620 								GL_RGBA32F);
621 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
622 			gl.bindImageTexture(IF_IIMAGE + m_n_image_formats, m_iimage_write_to_id, 0, GL_TRUE, 0, GL_WRITE_ONLY,
623 								GL_RGBA32I);
624 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
625 			gl.bindImageTexture(IF_UIMAGE + m_n_image_formats, m_uimage_write_to_id, 0, GL_TRUE, 0, GL_WRITE_ONLY,
626 								GL_RGBA32UI);
627 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
628 
629 			/* Call shaders */
630 			runShaders(width, height, depth);
631 
632 			/* Check results */
633 			if (!checkResults<glw::GLfloat>(m_context, m_copy_po_id, m_image_write_to_id, width, height, depth,
634 											m_n_components, GL_RGBA, GL_FLOAT, ST_MUTABLE, &floatData[0]))
635 			{
636 				test_passed = false;
637 			}
638 
639 			if (!checkResults<glw::GLint>(m_context, m_copy_po_id, m_iimage_write_to_id, width, height, depth,
640 										  m_n_components, GL_RGBA_INTEGER, GL_INT, ST_MUTABLE, &intData[0]))
641 			{
642 				test_passed = false;
643 			}
644 
645 			if (!checkResults<glw::GLuint>(m_context, m_copy_po_id, m_uimage_write_to_id, width, height, depth,
646 										   m_n_components, GL_RGBA_INTEGER, GL_UNSIGNED_INT, ST_MUTABLE, &uIntData[0]))
647 			{
648 				test_passed = false;
649 			}
650 
651 			/* Delete textures */
652 			removeTextures();
653 		}
654 
655 		/* Work on immutable texture storage */
656 
657 		/* Generate texture objects */
658 		configureTexture<glw::GLfloat>(m_context, &m_image_read_to_id, width, height, depth, ST_IMMUTABLE, GL_RGBA32F,
659 									   GL_RGBA, GL_FLOAT, &floatData[0]);
660 		configureTexture<glw::GLfloat>(m_context, &m_image_write_to_id, width, height, depth, ST_IMMUTABLE, GL_RGBA32F,
661 									   GL_RGBA, GL_FLOAT, &floatClean[0]);
662 
663 		configureTexture<glw::GLint>(m_context, &m_iimage_read_to_id, width, height, depth, ST_IMMUTABLE, GL_RGBA32I,
664 									 GL_RGBA_INTEGER, GL_INT, &intData[0]);
665 		configureTexture<glw::GLint>(m_context, &m_iimage_write_to_id, width, height, depth, ST_IMMUTABLE, GL_RGBA32I,
666 									 GL_RGBA_INTEGER, GL_INT, &intClean[0]);
667 
668 		configureTexture<glw::GLuint>(m_context, &m_uimage_read_to_id, width, height, depth, ST_IMMUTABLE, GL_RGBA32UI,
669 									  GL_RGBA_INTEGER, GL_UNSIGNED_INT, &uIntData[0]);
670 		configureTexture<glw::GLuint>(m_context, &m_uimage_write_to_id, width, height, depth, ST_IMMUTABLE, GL_RGBA32UI,
671 									  GL_RGBA_INTEGER, GL_UNSIGNED_INT, &uIntClean[0]);
672 
673 		/* Bind texture objects to image units */
674 		gl.bindImageTexture(IF_IMAGE, m_image_read_to_id, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32F);
675 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
676 		gl.bindImageTexture(IF_IIMAGE, m_iimage_read_to_id, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32I);
677 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
678 		gl.bindImageTexture(IF_UIMAGE, m_uimage_read_to_id, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32UI);
679 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
680 		gl.bindImageTexture(IF_IMAGE + m_n_image_formats, m_image_write_to_id, 0, GL_TRUE, 0, GL_WRITE_ONLY,
681 							GL_RGBA32F);
682 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
683 		gl.bindImageTexture(IF_IIMAGE + m_n_image_formats, m_iimage_write_to_id, 0, GL_TRUE, 0, GL_WRITE_ONLY,
684 							GL_RGBA32I);
685 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
686 		gl.bindImageTexture(IF_UIMAGE + m_n_image_formats, m_uimage_write_to_id, 0, GL_TRUE, 0, GL_WRITE_ONLY,
687 							GL_RGBA32UI);
688 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
689 
690 		/* Call shaders */
691 		runShaders(width, height, depth);
692 
693 		/* Check results */
694 		if (!checkResults<glw::GLfloat>(m_context, m_copy_po_id, m_image_write_to_id, width, height, depth,
695 										m_n_components, GL_RGBA, GL_FLOAT, ST_IMMUTABLE, &floatData[0]))
696 		{
697 			test_passed = false;
698 		}
699 
700 		if (!checkResults<glw::GLint>(m_context, m_copy_po_id, m_iimage_write_to_id, width, height, depth,
701 									  m_n_components, GL_RGBA_INTEGER, GL_INT, ST_IMMUTABLE, &intData[0]))
702 		{
703 			test_passed = false;
704 		}
705 
706 		if (!checkResults<glw::GLuint>(m_context, m_copy_po_id, m_uimage_write_to_id, width, height, depth,
707 									   m_n_components, GL_RGBA_INTEGER, GL_UNSIGNED_INT, ST_IMMUTABLE, &uIntData[0]))
708 		{
709 			test_passed = false;
710 		}
711 
712 		/* Delete textures */
713 		removeTextures();
714 	}
715 
716 	if (test_passed)
717 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
718 	else
719 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
720 
721 	return STOP;
722 }
723 
724 /** Run shaders - call glDispatchCompute for compuate shaders and glDrawArrays for other types of shaders */
runShaders(glw::GLuint width,glw::GLuint height,glw::GLuint depth)725 void TextureCubeMapArrayImageOpCompute::runShaders(glw::GLuint width, glw::GLuint height, glw::GLuint depth)
726 {
727 	/* Get GL entry points */
728 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
729 
730 	switch (m_shader_to_check)
731 	{
732 	/* Call compute shader */
733 	case STC_COMPUTE_SHADER:
734 	{
735 		gl.dispatchCompute(width, height, depth);
736 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error running compute shader!");
737 
738 		break;
739 	}
740 	/* Run programs for VERTEX/FRAGMENT/GEOMETRY shader */
741 	case STC_VERTEX_SHADER:
742 	case STC_FRAGMENT_SHADER:
743 	case STC_GEOMETRY_SHADER:
744 	{
745 		glw::GLint dimensions_location = gl.getUniformLocation(m_po_id, "dimensions");
746 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting uniform location!");
747 
748 		if (dimensions_location == -1)
749 		{
750 			TCU_FAIL("Invalid location returned for active uniform!");
751 		}
752 
753 		gl.uniform3i(dimensions_location, width, height, depth);
754 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting value for uniform variable!");
755 
756 		gl.drawArrays(GL_POINTS, 0, 1);
757 		GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!");
758 
759 		break;
760 	}
761 	case STC_TESSELLATION_CONTROL_SHADER:
762 	case STC_TESSELLATION_EVALUATION_SHADER:
763 	{
764 		glw::GLint dimensions_location = gl.getUniformLocation(m_po_id, "dimensions");
765 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting uniform location!");
766 
767 		if (dimensions_location == -1)
768 		{
769 			TCU_FAIL("Invalid location returned for active uniform!");
770 		}
771 
772 		gl.uniform3i(dimensions_location, width, height, depth);
773 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting value for uniform variable!");
774 
775 		gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 1);
776 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting patch parameter!");
777 
778 		gl.drawArrays(m_glExtTokens.PATCHES, 0, 1);
779 		GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!");
780 
781 		gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 3);
782 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting patch parameter!");
783 
784 		break;
785 	}
786 	}
787 }
788 
789 /** Configure program object with proper shaders depending on m_shader_to_check value */
configureProgram(void)790 void TextureCubeMapArrayImageOpCompute::configureProgram(void)
791 {
792 	/* Get GL entry points */
793 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
794 
795 	switch (m_shader_to_check)
796 	{
797 	case STC_COMPUTE_SHADER:
798 	{
799 		m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
800 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");
801 
802 		const char* csCode = getComputeShaderCode();
803 
804 		if (!buildProgram(m_po_id, m_cs_id, 1 /* part */, &csCode))
805 		{
806 			TCU_FAIL("Could not create a program from valid compute shader code!");
807 		}
808 		break;
809 	}
810 	case STC_VERTEX_SHADER:
811 	case STC_FRAGMENT_SHADER:
812 	{
813 		m_vs_id = gl.createShader(GL_VERTEX_SHADER);
814 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");
815 		m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
816 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");
817 
818 		bool vs = (m_shader_to_check == STC_VERTEX_SHADER);
819 		const char* vsCode = vs	? getVertexShaderCode()
820 								: getVertexShaderCodeBoilerPlate();
821 		const char* fsCode = vs	? getFragmentShaderCodeBoilerPlate()
822 								: getFragmentShaderCode();
823 
824 		if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fsCode, m_vs_id, 1 /* part */, &vsCode))
825 		{
826 			TCU_FAIL("Could not create shader program.");
827 		}
828 		break;
829 	}
830 	case STC_GEOMETRY_SHADER:
831 	{
832 		m_vs_id = gl.createShader(GL_VERTEX_SHADER);
833 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");
834 		m_gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
835 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");
836 		m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
837 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");
838 
839 		const char* vsCode = getVertexShaderCodeBoilerPlate();
840 		const char* gsCode = getGeometryShaderCode();
841 		const char* fsCode = getFragmentShaderCodeBoilerPlate();
842 
843 		if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fsCode, m_gs_id, 1 /* part */, &gsCode, m_vs_id,
844 						  1 /* part */, &vsCode))
845 		{
846 			TCU_FAIL("Could not create shader program.");
847 		}
848 		break;
849 	}
850 	case STC_TESSELLATION_CONTROL_SHADER:
851 	case STC_TESSELLATION_EVALUATION_SHADER:
852 	{
853 		m_vs_id = gl.createShader(GL_VERTEX_SHADER);
854 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");
855 		m_tc_id = gl.createShader(m_glExtTokens.TESS_CONTROL_SHADER);
856 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");
857 		m_te_id = gl.createShader(m_glExtTokens.TESS_EVALUATION_SHADER);
858 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");
859 		m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
860 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");
861 
862 		bool tcs = (m_shader_to_check == STC_TESSELLATION_CONTROL_SHADER);
863 		const char* vsCode  = getVertexShaderCodeBoilerPlate();
864 		const char* tcsCode = tcs	? getTessControlShaderCode()
865 									: getTessControlShaderCodeBoilerPlate();
866 		const char* tesCode = tcs	? getTessEvaluationShaderCodeBoilerPlate()
867 									: getTessEvaluationShaderCode();
868 		const char* fsCode  = getFragmentShaderCodeBoilerPlate();
869 
870 		if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fsCode, m_tc_id, 1 /* part */, &tcsCode, m_te_id,
871 						  1 /* part */, &tesCode, m_vs_id, 1 /* part */, &vsCode))
872 		{
873 			TCU_FAIL("Could not create shader program.");
874 		}
875 		break;
876 	}
877 	default:
878 		break;
879 	}
880 }
881 
882 /** Returns code for Compute Shader
883  *  @return pointer to literal with Compute Shader code
884  **/
getComputeShaderCode()885 const char* TextureCubeMapArrayImageOpCompute::getComputeShaderCode()
886 {
887 	static const char* computeShaderCode =
888 		"${VERSION}\n"
889 		"\n"
890 		"${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
891 		"\n"
892 		"precision highp float;\n"
893 		"\n"
894 		"layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
895 		"\n"
896 		"layout (rgba32f,  binding = 0) highp uniform readonly imageCubeArray  imageRead;\n"
897 		"layout (rgba32i,  binding = 1) highp uniform readonly iimageCubeArray iimageRead;\n"
898 		"layout (rgba32ui, binding = 2) highp uniform readonly uimageCubeArray uimageRead;\n"
899 		"layout (rgba32f,  binding = 3) highp uniform writeonly imageCubeArray  imageWrite;\n"
900 		"layout (rgba32i,  binding = 4) highp uniform writeonly iimageCubeArray iimageWrite;\n"
901 		"layout (rgba32ui, binding = 5) highp uniform writeonly uimageCubeArray uimageWrite;\n"
902 		"\n"
903 		"void main(void)\n"
904 		"{\n"
905 		"    ivec3 position = ivec3(gl_GlobalInvocationID.xyz);\n"
906 		"    imageStore(imageWrite,  position, imageLoad(imageRead,  position));\n"
907 		"    imageStore(iimageWrite, position, imageLoad(iimageRead, position));\n"
908 		"    imageStore(uimageWrite, position, imageLoad(uimageRead, position));\n"
909 		"}\n";
910 
911 	return computeShaderCode;
912 }
913 
914 /** Returns code for Vertex Shader
915  * @return pointer to literal with Vertex Shader code
916  **/
getVertexShaderCode(void)917 const char* TextureCubeMapArrayImageOpCompute::getVertexShaderCode(void)
918 {
919 
920 	static const char* vertexShaderCode =
921 		"${VERSION}\n"
922 		"\n"
923 		"${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
924 		"\n"
925 		"precision highp float;\n"
926 		"\n"
927 		"layout (rgba32f,  binding = 0) highp uniform readonly imageCubeArray  imageRead;\n"
928 		"layout (rgba32i,  binding = 1) highp uniform readonly iimageCubeArray iimageRead;\n"
929 		"layout (rgba32ui, binding = 2) highp uniform readonly uimageCubeArray uimageRead;\n"
930 		"layout (rgba32f,  binding = 3) highp uniform writeonly imageCubeArray  imageWrite;\n"
931 		"layout (rgba32i,  binding = 4) highp uniform writeonly iimageCubeArray iimageWrite;\n"
932 		"layout (rgba32ui, binding = 5) highp uniform writeonly uimageCubeArray uimageWrite;\n"
933 		"\n"
934 		"uniform ivec3 dimensions;\n"
935 		"\n"
936 		"void main()\n"
937 		"{\n"
938 		"\n"
939 		"    gl_PointSize = 1.0f;\n"
940 		"    for(int w = 0; w < dimensions[0]; ++w)\n" /* width */
941 		"    {\n"
942 		"        for(int h = 0; h < dimensions[1]; ++h)\n" /* height */
943 		"        {\n"
944 		"            for(int d = 0; d < dimensions[2]; ++d)\n" /* depth */
945 		"            {\n"
946 		"                ivec3  position  = ivec3(w,h,d);\n"
947 		"                imageStore(imageWrite,  position, imageLoad(imageRead,  position));\n"
948 		"                imageStore(iimageWrite, position, imageLoad(iimageRead, position));\n"
949 		"                imageStore(uimageWrite, position, imageLoad(uimageRead, position));\n"
950 		"            }\n"
951 		"        }\n"
952 		"    }\n"
953 		"\n"
954 		"}\n";
955 
956 	return vertexShaderCode;
957 }
958 
959 /** Returns code for Boiler Plate Vertex Shader
960  * @return pointer to literal with Boiler Plate Vertex Shader code
961  **/
getVertexShaderCodeBoilerPlate(void)962 const char* TextureCubeMapArrayImageOpCompute::getVertexShaderCodeBoilerPlate(void)
963 {
964 	static const char* vertexShaderBoilerPlateCode = "${VERSION}\n"
965 													 "\n"
966 													 "precision highp float;\n"
967 													 "\n"
968 													 "void main()\n"
969 													 "{\n"
970 													 "    gl_Position = vec4(0, 0, 0, 1.0f);\n"
971 													 "    gl_PointSize = 1.0f;\n"
972 													 "}\n";
973 
974 	return vertexShaderBoilerPlateCode;
975 }
976 
977 /** Returns code for Fragment Shader
978  *  @return pointer to literal with Fragment Shader code
979  **/
getFragmentShaderCode(void)980 const char* TextureCubeMapArrayImageOpCompute::getFragmentShaderCode(void)
981 {
982 	static const char* fragmentShaderCode =
983 		"${VERSION}\n"
984 		"\n"
985 		"${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
986 		"\n"
987 		"precision highp float;\n"
988 		"\n"
989 		"layout (rgba32f,  binding = 0) highp uniform readonly imageCubeArray  imageRead;\n"
990 		"layout (rgba32i,  binding = 1) highp uniform readonly iimageCubeArray iimageRead;\n"
991 		"layout (rgba32ui, binding = 2) highp uniform readonly uimageCubeArray uimageRead;\n"
992 		"layout (rgba32f,  binding = 3) highp uniform writeonly imageCubeArray  imageWrite;\n"
993 		"layout (rgba32i,  binding = 4) highp uniform writeonly iimageCubeArray iimageWrite;\n"
994 		"layout (rgba32ui, binding = 5) highp uniform writeonly uimageCubeArray uimageWrite;\n"
995 		"\n"
996 		"uniform ivec3 dimensions;\n"
997 		"\n"
998 		"void main()\n"
999 		"{\n"
1000 		"\n"
1001 		"    for(int w = 0; w < dimensions[0]; ++w)\n" /* width */
1002 		"    {\n"
1003 		"        for(int h = 0; h < dimensions[1]; ++h)\n" /* height */
1004 		"        {\n"
1005 		"            for(int d = 0; d < dimensions[2]; ++d)\n" /* depth */
1006 		"            {\n"
1007 		"                ivec3  position  = ivec3(w,h,d);\n"
1008 		"                imageStore(imageWrite,  position, imageLoad(imageRead,  position));\n"
1009 		"                imageStore(iimageWrite, position, imageLoad(iimageRead, position));\n"
1010 		"                imageStore(uimageWrite, position, imageLoad(uimageRead, position));\n"
1011 		"            }"
1012 		"        }"
1013 		"    }"
1014 		"\n"
1015 		"}\n";
1016 
1017 	return fragmentShaderCode;
1018 }
1019 
1020 /** Returns code for Boiler Plate Fragment Shader
1021  *  @return pointer to literal with Boiler Plate Fragment Shader code
1022  **/
getFragmentShaderCodeBoilerPlate(void)1023 const char* TextureCubeMapArrayImageOpCompute::getFragmentShaderCodeBoilerPlate(void)
1024 {
1025 	static const char* fragmentShaderBoilerPlateCode = "${VERSION}\n"
1026 													   "\n"
1027 													   "precision highp float;\n"
1028 													   "\n"
1029 													   "void main()\n"
1030 													   "{\n"
1031 													   "}\n";
1032 
1033 	return fragmentShaderBoilerPlateCode;
1034 }
1035 
1036 /** Returns code for Geometry Shader
1037  * @return pointer to literal with Geometry Shader code
1038  **/
getGeometryShaderCode(void)1039 const char* TextureCubeMapArrayImageOpCompute::getGeometryShaderCode(void)
1040 {
1041 	static const char* geometryShaderCode =
1042 		"${VERSION}\n"
1043 		"\n"
1044 		"${GEOMETRY_SHADER_ENABLE}\n"
1045 		"${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
1046 		"\n"
1047 		"precision highp float;\n"
1048 		"\n"
1049 		"layout (rgba32f,  binding = 0) highp uniform readonly imageCubeArray  imageRead;\n"
1050 		"layout (rgba32i,  binding = 1) highp uniform readonly iimageCubeArray iimageRead;\n"
1051 		"layout (rgba32ui, binding = 2) highp uniform readonly uimageCubeArray uimageRead;\n"
1052 		"layout (rgba32f,  binding = 3) highp uniform writeonly imageCubeArray  imageWrite;\n"
1053 		"layout (rgba32i,  binding = 4) highp uniform writeonly iimageCubeArray iimageWrite;\n"
1054 		"layout (rgba32ui, binding = 5) highp uniform writeonly uimageCubeArray uimageWrite;\n"
1055 		"\n"
1056 		"uniform ivec3 dimensions;\n"
1057 		"\n"
1058 		"layout(points) in;\n"
1059 		"layout(points, max_vertices=1) out;\n"
1060 		"\n"
1061 		"void main()\n"
1062 		"{\n"
1063 		"\n"
1064 		"    for(int w = 0; w < dimensions[0]; ++w)\n" /* width */
1065 		"    {\n"
1066 		"        for(int h = 0; h < dimensions[1]; ++h)\n" /* height */
1067 		"        {\n"
1068 		"            for(int d = 0; d < dimensions[2]; ++d)\n" /* depth */
1069 		"            {\n"
1070 		"                ivec3  position  = ivec3(w,h,d);\n"
1071 		"                imageStore(imageWrite,  position, imageLoad(imageRead,  position));\n"
1072 		"                imageStore(iimageWrite, position, imageLoad(iimageRead, position));\n"
1073 		"                imageStore(uimageWrite, position, imageLoad(uimageRead, position));\n"
1074 		"            }\n"
1075 		"        }\n"
1076 		"    }\n"
1077 		"\n"
1078 		"}\n";
1079 
1080 	return geometryShaderCode;
1081 }
1082 
1083 /** Returns code for Tessellation Control Shader
1084  *  @return pointer to literal with Tessellation Control Shader code
1085  **/
getTessControlShaderCode(void)1086 const char* TextureCubeMapArrayImageOpCompute::getTessControlShaderCode(void)
1087 {
1088 	static const char* tessellationControlShaderCode =
1089 		"${VERSION}\n"
1090 		"\n"
1091 		"${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
1092 		"${TESSELLATION_SHADER_ENABLE}\n"
1093 		"\n"
1094 		"precision highp float;\n"
1095 		"\n"
1096 		"layout (rgba32f,  binding = 0) highp uniform readonly imageCubeArray  imageRead;\n"
1097 		"layout (rgba32i,  binding = 1) highp uniform readonly iimageCubeArray iimageRead;\n"
1098 		"layout (rgba32ui, binding = 2) highp uniform readonly uimageCubeArray uimageRead;\n"
1099 		"layout (rgba32f,  binding = 3) highp uniform writeonly imageCubeArray  imageWrite;\n"
1100 		"layout (rgba32i,  binding = 4) highp uniform writeonly iimageCubeArray iimageWrite;\n"
1101 		"layout (rgba32ui, binding = 5) highp uniform writeonly uimageCubeArray uimageWrite;\n"
1102 		"\n"
1103 		"uniform ivec3 dimensions;\n"
1104 		"\n"
1105 		"layout (vertices = 1) out;\n"
1106 		"\n"
1107 		"void main()\n"
1108 		"{\n"
1109 		"\n"
1110 		"    gl_TessLevelInner[0] = 1.0;\n"
1111 		"    gl_TessLevelInner[1] = 1.0;\n"
1112 		"    gl_TessLevelOuter[0] = 1.0;\n"
1113 		"    gl_TessLevelOuter[1] = 1.0;\n"
1114 		"    gl_TessLevelOuter[2] = 1.0;\n"
1115 		"    gl_TessLevelOuter[3] = 1.0;\n"
1116 		"\n"
1117 		"    for(int w = 0; w < dimensions[0]; ++w)\n" /* width */
1118 		"    {\n"
1119 		"        for(int h = 0; h < dimensions[1]; ++h)\n" /* height */
1120 		"        {\n"
1121 		"            for(int d = 0; d < dimensions[2]; ++d)\n" /* depth */
1122 		"            {\n"
1123 		"                ivec3  position  = ivec3(w,h,d);\n"
1124 		"                imageStore(imageWrite,  position, imageLoad(imageRead,  position.xyz));\n"
1125 		"                imageStore(iimageWrite, position, imageLoad(iimageRead, position.xyz));\n"
1126 		"                imageStore(uimageWrite, position, imageLoad(uimageRead, position.xyz));\n"
1127 		"            }\n"
1128 		"        }\n"
1129 		"    }\n"
1130 		"\n"
1131 		"}\n";
1132 
1133 	return tessellationControlShaderCode;
1134 }
1135 
1136 /** Returns code for Boiler Plate Tessellation Control Shader
1137  *  @return pointer to literal with Boiler Plate Tessellation Control Shader code
1138  **/
getTessControlShaderCodeBoilerPlate(void)1139 const char* TextureCubeMapArrayImageOpCompute::getTessControlShaderCodeBoilerPlate(void)
1140 {
1141 	static const char* tessControlShaderBoilerPlateCode = "${VERSION}\n"
1142 														  "\n"
1143 														  "${TESSELLATION_SHADER_ENABLE}\n"
1144 														  "\n"
1145 														  "precision highp float;\n"
1146 														  "\n"
1147 														  "layout (vertices = 1) out;\n"
1148 														  "\n"
1149 														  "void main()\n"
1150 														  "{\n"
1151 														  "    gl_TessLevelInner[0] = 1.0;\n"
1152 														  "    gl_TessLevelInner[1] = 1.0;\n"
1153 														  "    gl_TessLevelOuter[0] = 1.0;\n"
1154 														  "    gl_TessLevelOuter[1] = 1.0;\n"
1155 														  "    gl_TessLevelOuter[2] = 1.0;\n"
1156 														  "    gl_TessLevelOuter[3] = 1.0;\n"
1157 														  "}\n";
1158 
1159 	return tessControlShaderBoilerPlateCode;
1160 }
1161 
1162 /** Returns code for Tessellation Evaluation Shader
1163  *  @return pointer to literal with Tessellation Evaluation Shader code
1164  **/
getTessEvaluationShaderCode(void)1165 const char* TextureCubeMapArrayImageOpCompute::getTessEvaluationShaderCode(void)
1166 {
1167 	static const char* tessellationEvaluationShaderCode =
1168 		"${VERSION}\n"
1169 		"\n"
1170 		"${TESSELLATION_SHADER_ENABLE}\n"
1171 		"${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
1172 		"\n"
1173 		"precision highp float;\n"
1174 		"\n"
1175 		"layout (rgba32f,  binding = 0) highp uniform readonly imageCubeArray  imageRead;\n"
1176 		"layout (rgba32i,  binding = 1) highp uniform readonly iimageCubeArray iimageRead;\n"
1177 		"layout (rgba32ui, binding = 2) highp uniform readonly uimageCubeArray uimageRead;\n"
1178 		"layout (rgba32f,  binding = 3) highp uniform writeonly imageCubeArray  imageWrite;\n"
1179 		"layout (rgba32i,  binding = 4) highp uniform writeonly iimageCubeArray iimageWrite;\n"
1180 		"layout (rgba32ui, binding = 5) highp uniform writeonly uimageCubeArray uimageWrite;\n"
1181 		"\n"
1182 		"uniform ivec3 dimensions;\n"
1183 		"\n"
1184 		"layout(isolines, point_mode) in;"
1185 		"\n"
1186 		"void main()\n"
1187 		"{\n"
1188 		"\n"
1189 		"    for(int w = 0; w < dimensions[0]; ++w)\n" /* width */
1190 		"    {\n"
1191 		"        for(int h = 0; h < dimensions[1]; ++h)\n" /* height */
1192 		"        {\n"
1193 		"            for(int d = 0; d < dimensions[2]; ++d)\n" /* depth */
1194 		"            {\n"
1195 		"                ivec3  position  = ivec3(w,h,d);\n"
1196 		"                imageStore(imageWrite,  position, imageLoad(imageRead,  position));\n"
1197 		"                imageStore(iimageWrite, position, imageLoad(iimageRead, position));\n"
1198 		"                imageStore(uimageWrite, position, imageLoad(uimageRead, position));\n"
1199 		"            }\n"
1200 		"        }\n"
1201 		"    }\n"
1202 		"\n"
1203 		"}\n";
1204 
1205 	return tessellationEvaluationShaderCode;
1206 }
1207 
1208 /** Returns code for Boiler Plate Tessellation Evaluation Shader
1209  *  @return pointer to literal with Boiler Plate Tessellation Evaluation Shader code
1210  **/
getTessEvaluationShaderCodeBoilerPlate(void)1211 const char* TextureCubeMapArrayImageOpCompute::getTessEvaluationShaderCodeBoilerPlate(void)
1212 {
1213 	static const char* tessellationEvaluationShaderBoilerPlateCode = "${VERSION}\n"
1214 																	 "\n"
1215 																	 "${TESSELLATION_SHADER_ENABLE}\n"
1216 																	 "\n"
1217 																	 "precision highp float;\n"
1218 																	 "\n"
1219 																	 "layout(isolines, point_mode) in;"
1220 																	 "\n"
1221 																	 "void main()\n"
1222 																	 "{\n"
1223 																	 "}\n";
1224 
1225 	return tessellationEvaluationShaderBoilerPlateCode;
1226 }
1227 
getFloatingPointCopyShaderSource(void)1228 const char* TextureCubeMapArrayImageOpCompute::getFloatingPointCopyShaderSource(void)
1229 {
1230 	static const char* floatingPointCopyShaderCode =
1231 		"${VERSION}\n"
1232 		"\n"
1233 		"layout (local_size_x=1) in;\n"
1234 		"\n"
1235 		"layout(binding=0, rgba32f) uniform highp readonly image2D src;\n"
1236 		"layout(binding=1, rgba32ui) uniform highp writeonly uimage2D dst;\n"
1237 		"\n"
1238 		"void main()\n"
1239 		"{\n"
1240 		"ivec2 coord = ivec2(gl_WorkGroupID.xy);\n"
1241 		"imageStore(dst, coord, floatBitsToUint(imageLoad(src, coord)));\n"
1242 		"}\n";
1243 
1244 	return floatingPointCopyShaderCode;
1245 }
1246 
1247 } /* glcts */
1248