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, ©_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