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