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