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 esextcTextureBufferOperations.cpp 26 * \brief Texture Buffer Operations (Test 1) 27 */ /*-------------------------------------------------------------------*/ 28 29 #include "esextcTextureBufferOperations.hpp" 30 #include "gluContextInfo.hpp" 31 #include "gluDefs.hpp" 32 #include "glwEnums.hpp" 33 #include "glwFunctions.hpp" 34 #include "tcuTestLog.hpp" 35 #include <cstring> 36 #include <iostream> 37 #include <vector> 38 39 namespace glcts 40 { 41 42 const glw::GLuint TextureBufferOperations::m_n_vector_components = 4; 43 44 /** Constructor 45 * 46 * @param context Test context 47 * @param name Test case's name 48 * @param description Test case's description 49 **/ 50 TextureBufferOperations::TextureBufferOperations(Context& context, const ExtParameters& extParams, const char* name, 51 const char* description) 52 : TestCaseBase(context, extParams, name, description) 53 , m_n_vectors_in_buffer_texture(0) 54 , m_tb_bo_id(0) 55 , m_texbuff_id(0) 56 , m_cs_id(0) 57 , m_po_cs_id(0) 58 , m_ssbo_bo_id(0) 59 , m_fbo_id(0) 60 , m_fs_id(0) 61 , m_po_vs_fs_id(0) 62 , m_to_id(0) 63 , m_vao_id(0) 64 , m_vbo_id(0) 65 , m_vbo_indicies_id(0) 66 , m_vs_id(0) 67 , m_vertex_location(-1) 68 , m_index_location(-1) 69 { 70 /* Nothing to be done here */ 71 } 72 73 /** Initializes GLES objects used during the test. 74 * 75 */ 76 void TextureBufferOperations::initTest(void) 77 { 78 /* Check if texture buffer extension is supported */ 79 if (!m_is_texture_buffer_supported) 80 { 81 throw tcu::NotSupportedError(TEXTURE_BUFFER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 82 } 83 84 /* Get GL entry points */ 85 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 86 87 gl.getIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &m_n_vectors_in_buffer_texture); 88 GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting GL_MAX_COMPUTE_WORK_GROUP_SIZE parameter value!"); 89 90 /* Create buffer object*/ 91 gl.genBuffers(1, &m_tb_bo_id); 92 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!"); 93 94 gl.bindBuffer(m_glExtTokens.TEXTURE_BUFFER, m_tb_bo_id); 95 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object !"); 96 97 gl.bufferData(m_glExtTokens.TEXTURE_BUFFER, 98 m_n_vectors_in_buffer_texture * m_n_vector_components * sizeof(glw::GLint), 0, GL_DYNAMIC_DRAW); 99 GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating data store for buffer object!"); 100 101 /* Create texture buffer */ 102 gl.genTextures(1, &m_texbuff_id); 103 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!"); 104 105 gl.activeTexture(GL_TEXTURE0); 106 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active texture unit!"); 107 108 gl.bindTexture(m_glExtTokens.TEXTURE_BUFFER, m_texbuff_id); 109 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!"); 110 111 gl.texBuffer(m_glExtTokens.TEXTURE_BUFFER, GL_RGBA32I, m_tb_bo_id); 112 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object to texture buffer!"); 113 114 /* Initialize texture buffer object */ 115 initializeBufferObjectData(); 116 117 /* Initialize first phase */ 118 initFirstPhase(); 119 120 /* Initialize second phase */ 121 initSecondPhase(); 122 } 123 124 void TextureBufferOperations::initFirstPhase(void) 125 { 126 /* Get GL entry points */ 127 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 128 129 /* Create program object */ 130 m_po_cs_id = gl.createProgram(); 131 GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program object!"); 132 133 m_cs_id = gl.createShader(GL_COMPUTE_SHADER); 134 GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating shader object!"); 135 136 std::string csSource = getComputeShaderCode(); 137 const char* csCode = csSource.c_str(); 138 139 if (!buildProgram(m_po_cs_id, m_cs_id, 1, &csCode)) 140 { 141 TCU_FAIL("Could not create a program from valid compute shader code!"); 142 } 143 144 /* Create Shader Storage Buffer Object */ 145 gl.genBuffers(1, &m_ssbo_bo_id); 146 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!"); 147 gl.bindBuffer(GL_ARRAY_BUFFER, m_ssbo_bo_id); 148 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!"); 149 gl.bufferData(GL_ARRAY_BUFFER, m_n_vectors_in_buffer_texture * m_n_vector_components * sizeof(glw::GLint), 0, 150 GL_DYNAMIC_DRAW); 151 GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating data store for buffer object!"); 152 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 153 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!"); 154 } 155 156 /** Returns Compute shader Code 157 * 158 * @return pointer to literal with Compute Shader Code 159 */ 160 std::string TextureBufferOperations::getComputeShaderCode() const 161 { 162 std::stringstream strstream; 163 164 strstream << "${VERSION}\n" 165 "\n" 166 "${TEXTURE_BUFFER_REQUIRE}\n" 167 "\n" 168 "precision highp float;\n" 169 "\n" 170 "layout(rgba32i, binding = 0) uniform readonly highp iimageBuffer image_buffer;\n" 171 "\n" 172 "buffer ComputeSSBO\n" 173 "{\n" 174 " ivec4 value[];\n" 175 "} computeSSBO;\n" 176 "\n" 177 "layout (local_size_x = " 178 << m_n_vectors_in_buffer_texture << " ) in;\n" 179 "\n" 180 "void main(void)\n" 181 "{\n" 182 " int index = int(gl_LocalInvocationID.x);\n" 183 " computeSSBO.value[index] = imageLoad( image_buffer, index);\n" 184 "}\n"; 185 186 return strstream.str(); 187 } 188 189 void TextureBufferOperations::initSecondPhase(void) 190 { 191 /* Get GL entry points */ 192 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 193 194 /* Create vertex array object */ 195 gl.genVertexArrays(1, &m_vao_id); 196 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating vertex array object!"); 197 198 /* Create framebuffer object */ 199 gl.genFramebuffers(1, &m_fbo_id); 200 GLU_EXPECT_NO_ERROR(gl.getError(), "Error genertaing framebuffer object!"); 201 202 /* Prepare texture object */ 203 gl.genTextures(1, &m_to_id); 204 GLU_EXPECT_NO_ERROR(gl.getError(), "Error genertaing texture buffer!"); 205 206 gl.bindTexture(GL_TEXTURE_2D, m_to_id); 207 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!"); 208 209 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32I, m_n_vectors_in_buffer_texture /* width */, 1 /* height */); 210 GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object's texel data!"); 211 212 /* Set GL_TEXTURE_MAG_FILTER and GL_TEXTURE_MIN_FILTER parameters values to GL_NEAREST*/ 213 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 214 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting value for GL_TEXTURE_MAG_FILTER parameter!"); 215 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 216 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting value for GL_TEXTURE_MIN_FILTER parameter!"); 217 218 gl.bindTexture(GL_TEXTURE_2D, 0); 219 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!"); 220 221 /* Create program object */ 222 m_po_vs_fs_id = gl.createProgram(); 223 GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program object!"); 224 225 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 226 GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating fragment shader object!"); 227 228 m_vs_id = gl.createShader(GL_VERTEX_SHADER); 229 GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating vertex shader object!"); 230 231 std::string fsSource = getFragmentShaderCode(); 232 std::string vsSource = getVertexShaderCode(); 233 234 const char* fsCode = fsSource.c_str(); 235 const char* vsCode = vsSource.c_str(); 236 237 if (!buildProgram(m_po_vs_fs_id, m_fs_id, 1, &fsCode, m_vs_id, 1, &vsCode)) 238 { 239 TCU_FAIL("Could not create a program from valid vertex/fragment shader source!"); 240 } 241 242 /* Full screen quad */ 243 glw::GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 244 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }; 245 246 /* Generate buffer object */ 247 gl.genBuffers(1, &m_vbo_id); 248 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!"); 249 /* Bind buffer object */ 250 gl.bindBuffer(GL_ARRAY_BUFFER, m_vbo_id); 251 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!"); 252 /* Set data for buffer object */ 253 gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 254 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting data for buffer object!"); 255 256 /* Indicies */ 257 glw::GLfloat indicies[] = { 0.f, 0.f, static_cast<glw::GLfloat>(m_n_vectors_in_buffer_texture) * 1.f, 258 static_cast<glw::GLfloat>(m_n_vectors_in_buffer_texture) * 1.f }; 259 260 /* Generate buffer object */ 261 gl.genBuffers(1, &m_vbo_indicies_id); 262 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!"); 263 /* Bind buffer object */ 264 gl.bindBuffer(GL_ARRAY_BUFFER, m_vbo_indicies_id); 265 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!"); 266 /* Set data for buffer object */ 267 gl.bufferData(GL_ARRAY_BUFFER, sizeof(indicies), indicies, GL_STATIC_DRAW); 268 GLU_EXPECT_NO_ERROR(gl.getError(), "Error seting data for buffer object!"); 269 270 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 271 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!"); 272 } 273 274 /** Returns Fragment Shader Code 275 * 276 * @return pointer to literal with Fragment Shader Code 277 */ 278 std::string TextureBufferOperations::getFragmentShaderCode() const 279 { 280 std::stringstream strstream; 281 282 strstream << "${VERSION}\n" 283 "\n" 284 "${TEXTURE_BUFFER_REQUIRE}\n" 285 "\n" 286 "precision highp float;\n" 287 "\n" 288 "in float fs_index;\n" 289 "\n" 290 "layout(location = 0) out ivec4 color;\n" 291 "\n" 292 "uniform highp isamplerBuffer sampler_buffer;\n" 293 "\n" 294 "void main(void)\n" 295 "{\n" 296 " color = texelFetch( sampler_buffer, int(fs_index) );\n " 297 "}\n"; 298 299 return strstream.str(); 300 } 301 302 /** Returns Vertex Shader Code 303 * 304 * @return pointer to literal with Vertex Shader Code 305 */ 306 std::string TextureBufferOperations::getVertexShaderCode() const 307 { 308 std::stringstream strstream; 309 310 strstream << "${VERSION}\n" 311 "\n" 312 "${TEXTURE_BUFFER_REQUIRE}\n" 313 "\n" 314 "precision highp float;\n" 315 "\n" 316 "in vec4 vs_position;\n" 317 "in float vs_index;\n" 318 "\n" 319 "out float fs_index;\n" 320 "\n" 321 "void main(void)\n" 322 "{\n" 323 " gl_Position = vs_position;\n" 324 " fs_index = vs_index;\n" 325 "}\n"; 326 327 return strstream.str(); 328 } 329 330 /** Executes the test. 331 * 332 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 333 * 334 * Note the function throws exception should an error occur! 335 * 336 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 337 **/ 338 tcu::TestNode::IterateResult TextureBufferOperations::iterate(void) 339 { 340 /* Initialize */ 341 initTest(); 342 343 /* Get GL entry points */ 344 glw::GLboolean test_result = true; 345 346 /* Prepare expected data */ 347 std::vector<glw::GLint> reference(m_n_vectors_in_buffer_texture * m_n_vector_components); 348 fillBufferWithData(&reference[0], m_n_vectors_in_buffer_texture * m_n_vector_components); 349 350 std::vector<glw::GLint> result(m_n_vectors_in_buffer_texture * m_n_vector_components); 351 352 iterateFirstPhase(&result[0], static_cast<glw::GLuint>(m_n_vectors_in_buffer_texture * m_n_vector_components * 353 sizeof(glw::GLint))); 354 if (!verifyResults(&reference[0], &result[0], static_cast<glw::GLuint>(m_n_vectors_in_buffer_texture * 355 m_n_vector_components * sizeof(glw::GLint)), 356 "1st Phase Compute Shader\n")) 357 { 358 test_result = false; 359 } 360 361 iterateSecondPhase(&result[0]); 362 if (!verifyResults(&reference[0], &result[0], static_cast<glw::GLuint>(m_n_vectors_in_buffer_texture * 363 m_n_vector_components * sizeof(glw::GLint)), 364 "2st Phase Vertex + Fragment Shader\n")) 365 { 366 test_result = false; 367 } 368 369 if (test_result) 370 { 371 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 372 } 373 else 374 { 375 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 376 } 377 378 return STOP; 379 } 380 381 void TextureBufferOperations::iterateFirstPhase(glw::GLint* result, glw::GLuint size) 382 { 383 /* Get GL entry points */ 384 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 385 386 gl.bindBuffer(GL_ARRAY_BUFFER, m_ssbo_bo_id); 387 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!"); 388 389 gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_ssbo_bo_id); 390 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind buffer object to shader storage binding point!"); 391 392 gl.useProgram(m_po_cs_id); 393 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active program!"); 394 395 gl.bindImageTexture(0, m_texbuff_id, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32I); 396 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture to image unit!"); 397 398 gl.dispatchCompute(1, 1, 1); 399 GLU_EXPECT_NO_ERROR(gl.getError(), "Error running compute shader!"); 400 401 gl.memoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 402 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting memory barrier!"); 403 404 /* Get result data */ 405 glw::GLint* result_mapped = (glw::GLint*)gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, size, GL_MAP_READ_BIT); 406 GLU_EXPECT_NO_ERROR(gl.getError(), "Error mapping buffer object's data store to client's address space!"); 407 408 memcpy(result, result_mapped, size); 409 410 gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER); 411 GLU_EXPECT_NO_ERROR(gl.getError(), "Error unmapping buffer object's data store from client's address space!"); 412 413 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 414 gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0); 415 gl.useProgram(0); 416 } 417 418 void TextureBufferOperations::iterateSecondPhase(glw::GLint* result) 419 { 420 /* Get GL entry points */ 421 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 422 423 gl.bindVertexArray(m_vao_id); 424 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding vertex array object!"); 425 426 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_id); 427 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding framebuffer object!"); 428 429 gl.bindTexture(GL_TEXTURE_2D, m_to_id); 430 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!"); 431 432 /* Attach output texture to framebuffer */ 433 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_id, 0); 434 GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to framebuffer's color attachment"); 435 436 /* Check framebuffer status */ 437 checkFramebufferStatus(GL_DRAW_FRAMEBUFFER); 438 439 /* Configure view port */ 440 gl.viewport(0, 0, m_n_vectors_in_buffer_texture, 1); 441 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting viewport!"); 442 443 /* Use program */ 444 gl.useProgram(m_po_vs_fs_id); 445 GLU_EXPECT_NO_ERROR(gl.getError(), "Error using program object!"); 446 447 glw::GLint sampler_location = gl.getUniformLocation(m_po_vs_fs_id, "sampler_buffer"); 448 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not get attribute location!"); 449 if (sampler_location == -1) 450 { 451 TCU_FAIL("Could not get uniform location"); 452 } 453 454 gl.uniform1i(sampler_location, 0); 455 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding sampler with texture unit!"); 456 457 /* Configure vertex position attribute */ 458 gl.bindBuffer(GL_ARRAY_BUFFER, m_vbo_id); 459 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind buffer object!"); 460 461 m_vertex_location = gl.getAttribLocation(m_po_vs_fs_id, "vs_position"); 462 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not get attribute location!"); 463 if (m_vertex_location == -1) 464 { 465 TCU_FAIL("Could not get uniform location"); 466 } 467 468 gl.vertexAttribPointer(m_vertex_location, 4, GL_FLOAT, GL_FALSE, 0, 0); 469 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set vertex attribute pointer!"); 470 471 gl.enableVertexAttribArray(m_vertex_location); 472 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not enable vertex attribute array!"); 473 474 /* Configure index attribute */ 475 gl.bindBuffer(GL_ARRAY_BUFFER, m_vbo_indicies_id); 476 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind buffer object!"); 477 478 m_index_location = gl.getAttribLocation(m_po_vs_fs_id, "vs_index"); 479 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not get attribute location!"); 480 if (m_index_location == -1) 481 { 482 TCU_FAIL("Could not get uniform location"); 483 } 484 485 gl.vertexAttribPointer(m_index_location, 1, GL_FLOAT, GL_FALSE, 0, 0); 486 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set vertex attribute pointer!"); 487 488 gl.enableVertexAttribArray(m_index_location); 489 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not enable vertex attribute array!"); 490 491 /* Clear texture */ 492 gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 493 gl.clear(GL_COLOR_BUFFER_BIT); 494 GLU_EXPECT_NO_ERROR(gl.getError(), "Error clearing color buffer"); 495 496 /* Render */ 497 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4); 498 GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!"); 499 500 /* Read result data */ 501 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_id); 502 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding framebuffer object !"); 503 504 gl.readPixels(0, 0, m_n_vectors_in_buffer_texture, 1, GL_RGBA_INTEGER, GL_INT, result); 505 GLU_EXPECT_NO_ERROR(gl.getError(), "Error reading pixels !"); 506 507 gl.bindVertexArray(0); 508 gl.bindTexture(GL_TEXTURE_2D, 0); 509 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 510 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0); 511 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 512 gl.disableVertexAttribArray(m_vertex_location); 513 gl.disableVertexAttribArray(m_index_location); 514 gl.useProgram(0); 515 516 m_vertex_location = -1; 517 m_index_location = -1; 518 } 519 520 /** Check if result data is the same as reference data - log error if not 521 * 522 * @param reference pointer to buffer with reference data 523 * @param result pointer to buffer with result data 524 * @param size size of buffers 525 * @param message pointer to literal with message (informing about test phase) 526 * 527 * @return returns true if reference data equals result data, otherwise log error and return false 528 */ 529 glw::GLboolean TextureBufferOperations::verifyResults(glw::GLint* reference, glw::GLint* result, glw::GLuint size, 530 const char* message) 531 { 532 /* Log error if expected and result data is not equal */ 533 if (memcmp(reference, result, size)) 534 { 535 std::stringstream referenceData; 536 std::stringstream resultData; 537 538 referenceData << "["; 539 resultData << "["; 540 541 glw::GLuint n_entries = static_cast<glw::GLuint>(size / sizeof(glw::GLint)); 542 543 for (glw::GLuint i = 0; i < n_entries; ++i) 544 { 545 referenceData << reference[i] << ","; 546 resultData << result[i] << ","; 547 } 548 549 referenceData << "]"; 550 resultData << "]"; 551 552 m_testCtx.getLog() << tcu::TestLog::Message << message 553 << "Result buffer contains different data than reference buffer\n" 554 << "Reference Buffer: " << referenceData.str() << "\n" 555 << "Result Buffer: " << resultData.str() << "\n" 556 << tcu::TestLog::EndMessage; 557 return false; 558 } 559 560 return true; 561 } 562 563 /** Fill buffer with test data 564 * 565 * @param buffer pointer to buffer 566 * @param bufferLenth buffer length 567 */ 568 void TextureBufferOperations::fillBufferWithData(glw::GLint* buffer, glw::GLuint bufferLength) 569 { 570 for (glw::GLuint i = 0; i < bufferLength; ++i) 571 { 572 buffer[i] = (glw::GLint)i; 573 } 574 } 575 576 /** Check Framebuffer Status - throw exception if status is different than GL_FRAMEBUFFER_COMPLETE 577 * 578 * @param framebuffer - GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER or GL_FRAMEBUFFER 579 * 580 */ 581 void TextureBufferOperations::checkFramebufferStatus(glw::GLenum framebuffer) 582 { 583 /* Get GL entry points */ 584 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 585 586 /* Check framebuffer status */ 587 glw::GLenum framebufferStatus = gl.checkFramebufferStatus(framebuffer); 588 589 if (GL_FRAMEBUFFER_COMPLETE != framebufferStatus) 590 { 591 switch (framebufferStatus) 592 { 593 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 594 { 595 TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"); 596 } 597 598 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: 599 { 600 TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); 601 } 602 603 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 604 { 605 TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); 606 } 607 608 case GL_FRAMEBUFFER_UNSUPPORTED: 609 { 610 TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_UNSUPPORTED"); 611 } 612 613 default: 614 { 615 TCU_FAIL("Framebuffer incomplete, status not recognized"); 616 } 617 }; 618 } /* if (GL_FRAMEBUFFER_COMPLETE != framebuffer_status) */ 619 } 620 621 /** Deinitializes GLES objects created during the test. 622 * 623 */ 624 void TextureBufferOperations::deinit(void) 625 { 626 /* Get GLES entry points */ 627 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 628 629 /* Reset GLES state */ 630 gl.bindBuffer(m_glExtTokens.TEXTURE_BUFFER, 0); 631 gl.bindTexture(m_glExtTokens.TEXTURE_BUFFER, 0); 632 633 /* Delete GLES objects */ 634 if (0 != m_texbuff_id) 635 { 636 gl.deleteTextures(1, &m_texbuff_id); 637 m_texbuff_id = 0; 638 } 639 640 if (0 != m_tb_bo_id) 641 { 642 gl.deleteBuffers(1, &m_tb_bo_id); 643 m_tb_bo_id = 0; 644 } 645 646 deinitFirstPhase(); 647 deinitSecondPhase(); 648 649 /* Deinitialize base class */ 650 TestCaseBase::deinit(); 651 } 652 653 void TextureBufferOperations::deinitFirstPhase(void) 654 { 655 /* Get GLES entry points */ 656 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 657 658 /* Reset GLES state */ 659 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 660 gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0); 661 gl.useProgram(0); 662 663 /* Delete GLES objects */ 664 if (0 != m_po_cs_id) 665 { 666 gl.deleteProgram(m_po_cs_id); 667 m_po_cs_id = 0; 668 } 669 670 if (0 != m_cs_id) 671 { 672 gl.deleteShader(m_cs_id); 673 m_cs_id = 0; 674 } 675 676 if (0 != m_ssbo_bo_id) 677 { 678 gl.deleteBuffers(1, &m_ssbo_bo_id); 679 m_ssbo_bo_id = 0; 680 } 681 } 682 683 void TextureBufferOperations::deinitSecondPhase(void) 684 { 685 /* Get GLES entry points */ 686 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 687 688 /* Reset GLES state */ 689 gl.bindVertexArray(0); 690 gl.bindTexture(GL_TEXTURE_2D, 0); 691 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 692 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0); 693 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 694 695 if (m_vertex_location != -1) 696 { 697 gl.disableVertexAttribArray(m_vertex_location); 698 m_vertex_location = -1; 699 } 700 701 if (m_index_location != -1) 702 { 703 gl.disableVertexAttribArray(m_index_location); 704 m_index_location = -1; 705 } 706 707 gl.useProgram(0); 708 709 /* Delete GLES objects */ 710 if (0 != m_po_vs_fs_id) 711 { 712 gl.deleteProgram(m_po_vs_fs_id); 713 m_po_vs_fs_id = 0; 714 } 715 716 if (0 != m_fs_id) 717 { 718 gl.deleteShader(m_fs_id); 719 m_fs_id = 0; 720 } 721 722 if (0 != m_vs_id) 723 { 724 gl.deleteShader(m_vs_id); 725 m_vs_id = 0; 726 } 727 728 if (0 != m_fbo_id) 729 { 730 gl.deleteFramebuffers(1, &m_fbo_id); 731 m_fbo_id = 0; 732 } 733 734 if (0 != m_to_id) 735 { 736 gl.deleteTextures(1, &m_to_id); 737 m_to_id = 0; 738 } 739 740 if (0 != m_vao_id) 741 { 742 gl.deleteVertexArrays(1, &m_vao_id); 743 m_vao_id = 0; 744 } 745 746 if (0 != m_vbo_id) 747 { 748 gl.deleteBuffers(1, &m_vbo_id); 749 m_vbo_id = 0; 750 } 751 752 if (0 != m_vbo_indicies_id) 753 { 754 gl.deleteBuffers(1, &m_vbo_indicies_id); 755 m_vbo_indicies_id = 0; 756 } 757 } 758 759 /** Constructor for Test Case 1 760 * 761 * @param context Test context 762 * @param name Test case's name 763 * @param description Test case's description 764 **/ 765 TextureBufferOperationsViaBufferObjectLoad::TextureBufferOperationsViaBufferObjectLoad(Context& context, 766 const ExtParameters& extParams, 767 const char* name, 768 const char* description) 769 : TextureBufferOperations(context, extParams, name, description) 770 { 771 } 772 773 /** Initialize texture buffer object with test data using glBufferSubData() 774 * 775 **/ 776 void TextureBufferOperationsViaBufferObjectLoad::initializeBufferObjectData(void) 777 { 778 /* Get GL entry points */ 779 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 780 781 std::vector<glw::GLint> data(m_n_vectors_in_buffer_texture * m_n_vector_components); 782 fillBufferWithData(&data[0], m_n_vectors_in_buffer_texture * m_n_vector_components); 783 784 gl.bufferSubData(m_glExtTokens.TEXTURE_BUFFER, 0, 785 m_n_vectors_in_buffer_texture * m_n_vector_components * sizeof(glw::GLint), &data[0]); 786 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting buffer object data!"); 787 } 788 789 /** Constructor for Test Case 2 790 * 791 * @param context Test context 792 * @param name Test case's name 793 * @param description Test case's description 794 **/ 795 TextureBufferOperationsViaCPUWrites::TextureBufferOperationsViaCPUWrites(Context& context, 796 const ExtParameters& extParams, 797 const char* name, const char* description) 798 : TextureBufferOperations(context, extParams, name, description) 799 { 800 } 801 802 /** Initialize texture buffer object with test data using CPU Write 803 * 804 **/ 805 void TextureBufferOperationsViaCPUWrites::initializeBufferObjectData(void) 806 { 807 /* Get GL entry points */ 808 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 809 810 std::vector<glw::GLint> data(m_n_vectors_in_buffer_texture * m_n_vector_components); 811 fillBufferWithData(&data[0], m_n_vectors_in_buffer_texture * m_n_vector_components); 812 813 glw::GLint* tempBuffer = (glw::GLint*)gl.mapBufferRange( 814 m_glExtTokens.TEXTURE_BUFFER, 0, m_n_vectors_in_buffer_texture * m_n_vector_components * sizeof(glw::GLint), 815 GL_MAP_WRITE_BIT); 816 GLU_EXPECT_NO_ERROR(gl.getError(), "Error mapping buffer object's data store to client's address space!"); 817 818 for (glw::GLuint i = 0; i < data.size(); ++i) 819 { 820 tempBuffer[i] = data[i]; 821 } 822 823 gl.unmapBuffer(m_glExtTokens.TEXTURE_BUFFER); 824 GLU_EXPECT_NO_ERROR(gl.getError(), "Error ummapping buffer object's data store from client's address space!"); 825 } 826 827 /** Constructor for Test Case 3 828 * 829 * @param context Test context 830 * @param name Test case's name 831 * @param description Test case's description 832 **/ 833 TextureBufferOperationsViaFrambufferReadBack::TextureBufferOperationsViaFrambufferReadBack( 834 Context& context, const ExtParameters& extParams, const char* name, const char* description) 835 : TextureBufferOperations(context, extParams, name, description) 836 , m_fb_fbo_id(0) 837 , m_fb_fs_id(0) 838 , m_fb_po_id(0) 839 , m_fb_to_id(0) 840 , m_fb_vao_id(0) 841 , m_fb_vbo_id(0) 842 , m_fb_vs_id(0) 843 , m_position_location(-1) 844 { 845 } 846 847 /** Initialize texture buffer object with test data using framebuffer readbacks to pixel buffer object 848 * 849 **/ 850 void TextureBufferOperationsViaFrambufferReadBack::initializeBufferObjectData() 851 { 852 /* Get GL entry points */ 853 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 854 855 std::vector<glw::GLint> data(m_n_vectors_in_buffer_texture * m_n_vector_components); 856 fillBufferWithData(&data[0], m_n_vectors_in_buffer_texture * m_n_vector_components); 857 858 /* Configure vertex array object */ 859 gl.genVertexArrays(1, &m_fb_vao_id); 860 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating vertex array object!"); 861 862 gl.bindVertexArray(m_fb_vao_id); 863 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding vertex array object!"); 864 865 /* Prepare framebuffer object */ 866 gl.genFramebuffers(1, &m_fb_fbo_id); 867 GLU_EXPECT_NO_ERROR(gl.getError(), "Error genertaing framebuffer object!"); 868 869 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fb_fbo_id); 870 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding framebuffer object!"); 871 872 /* Prepare texture object */ 873 gl.genTextures(1, &m_fb_to_id); 874 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!"); 875 876 gl.bindTexture(GL_TEXTURE_2D, m_fb_to_id); 877 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!"); 878 879 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32I, m_n_vectors_in_buffer_texture /* width */, 1 /* height */); 880 GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object's data store!"); 881 882 /* Attach texture to framebuffer */ 883 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_fb_to_id, 0); 884 GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to framebuffer's color attachment!"); 885 886 /* Check framebuffer status */ 887 checkFramebufferStatus(GL_DRAW_FRAMEBUFFER); 888 889 /* Configure view port */ 890 gl.viewport(0, 0, m_n_vectors_in_buffer_texture, 1); 891 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting viewport!"); 892 893 /* Create program object */ 894 m_fb_po_id = gl.createProgram(); 895 GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program object!"); 896 897 m_fb_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 898 GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating fragment shader object!"); 899 900 m_fb_vs_id = gl.createShader(GL_VERTEX_SHADER); 901 GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating vertex shader object!"); 902 903 std::string fsSource = getFBFragmentShaderCode(); 904 std::string vsSource = getFBVertexShaderCode(); 905 906 const char* fsCode = fsSource.c_str(); 907 const char* vsCode = vsSource.c_str(); 908 909 if (!buildProgram(m_fb_po_id, m_fb_fs_id, 1, &fsCode, m_fb_vs_id, 1, &vsCode)) 910 { 911 TCU_FAIL("Could not create a program from valid vertex/fragment shader code!"); 912 } 913 914 /* Full screen quad */ 915 glw::GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 916 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }; 917 918 /* Generate buffer object */ 919 gl.genBuffers(1, &m_fb_vbo_id); 920 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!"); 921 922 /* Bind buffer object */ 923 gl.bindBuffer(GL_ARRAY_BUFFER, m_fb_vbo_id); 924 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!"); 925 926 /* Set data for buffer object */ 927 gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 928 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting data for buffer object!"); 929 930 gl.useProgram(m_fb_po_id); 931 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active program object!"); 932 933 m_position_location = gl.getAttribLocation(m_fb_po_id, "inPosition"); 934 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not get attribute location!"); 935 if (m_position_location == -1) 936 { 937 TCU_FAIL("Could not get uniform location"); 938 } 939 940 gl.vertexAttribPointer(m_position_location, 4, GL_FLOAT, GL_FALSE, 0, 0); 941 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set vertex attribute pointer!"); 942 943 gl.enableVertexAttribArray(m_position_location); 944 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not enable vertex attribute array!"); 945 946 /* Clear texture */ 947 gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 948 gl.clear(GL_COLOR_BUFFER_BIT); 949 GLU_EXPECT_NO_ERROR(gl.getError(), "Error clearing color buffer"); 950 951 /* Render */ 952 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4); 953 GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!"); 954 955 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fb_fbo_id); 956 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding frame buffer object!"); 957 958 /* Bind buffer object to pixel pack buffer */ 959 gl.bindBuffer(GL_PIXEL_PACK_BUFFER, m_tb_bo_id); 960 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object !"); 961 962 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1); 963 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting GL_UNPACK_ALIGNMENT parameter to 1"); 964 965 gl.pixelStorei(GL_PACK_ALIGNMENT, 1); 966 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting GL_PACK_ALIGNMENT parameter to 1"); 967 968 /* Fill buffer object with data from framebuffer object's color attachment */ 969 gl.readPixels(0, 0, m_n_vectors_in_buffer_texture, 1, GL_RGBA_INTEGER, GL_INT, 0); 970 GLU_EXPECT_NO_ERROR(gl.getError(), "Error reading pixels !"); 971 972 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 4); 973 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting GL_UNPACK_ALIGNMENT parameter to default value"); 974 975 gl.pixelStorei(GL_PACK_ALIGNMENT, 4); 976 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting GL_PACK_ALIGNMENT parameter to default value"); 977 978 gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0); 979 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!"); 980 981 gl.bindBuffer(m_glExtTokens.TEXTURE_BUFFER, m_tb_bo_id); 982 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!"); 983 984 gl.bindVertexArray(0); 985 gl.bindTexture(GL_TEXTURE_2D, 0); 986 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 987 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0); 988 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 989 990 if (glu::isContextTypeES(m_context.getRenderContext().getType())) 991 gl.disableVertexAttribArray(m_position_location); 992 993 gl.useProgram(0); 994 995 m_position_location = -1; 996 } 997 998 /** Returns Fragment Shader Code 999 * 1000 * @return pointer to literal with Fragment Shader Code 1001 */ 1002 std::string TextureBufferOperationsViaFrambufferReadBack::getFBFragmentShaderCode() const 1003 { 1004 std::stringstream strstream; 1005 1006 strstream << "${VERSION}\n" 1007 "\n" 1008 "precision highp float;\n" 1009 "\n" 1010 "out ivec4 color;\n" 1011 "\n" 1012 "void main(void)\n" 1013 "{\n" 1014 " color = ivec4(0, 1, 0, 1);\n" 1015 "}\n"; 1016 1017 return strstream.str(); 1018 } 1019 1020 /** Returns Vertex Shader Code 1021 * 1022 * @return pointer to literal with Vertex Shader Code 1023 */ 1024 std::string TextureBufferOperationsViaFrambufferReadBack::getFBVertexShaderCode() const 1025 { 1026 std::stringstream strstream; 1027 1028 strstream << "${VERSION}\n" 1029 "\n" 1030 "precision highp float;\n" 1031 "\n" 1032 "in vec4 inPosition;\n" 1033 "\n" 1034 "void main(void)\n" 1035 "{\n" 1036 " gl_Position = inPosition;\n" 1037 "}\n"; 1038 1039 return strstream.str(); 1040 } 1041 1042 /** Fills buffer with test data 1043 * 1044 * @param buffer pointer to buffer 1045 * @param bufferLenth buffer length 1046 */ 1047 void TextureBufferOperationsViaFrambufferReadBack::fillBufferWithData(glw::GLint* buffer, glw::GLuint bufferLength) 1048 { 1049 for (glw::GLuint i = 0; i < bufferLength; ++i) 1050 { 1051 buffer[i] = (glw::GLint)(i % 2); /* Reference color is 0, 1, 0, 1 */ 1052 } 1053 } 1054 1055 /** Deinitializes GLES objects created during the test. 1056 * 1057 */ 1058 void TextureBufferOperationsViaFrambufferReadBack::deinit(void) 1059 { 1060 /* Get GL entry points */ 1061 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1062 1063 /* Reset GLES state */ 1064 gl.bindVertexArray(0); 1065 gl.bindTexture(GL_TEXTURE_2D, 0); 1066 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 1067 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0); 1068 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 1069 1070 if (m_position_location != -1) 1071 { 1072 gl.disableVertexAttribArray(m_position_location); 1073 m_position_location = -1; 1074 } 1075 1076 gl.useProgram(0); 1077 1078 /* Delete GLES objects */ 1079 if (0 != m_fb_po_id) 1080 { 1081 gl.deleteProgram(m_fb_po_id); 1082 m_fb_po_id = 0; 1083 } 1084 1085 if (0 != m_fb_fs_id) 1086 { 1087 gl.deleteShader(m_fb_fs_id); 1088 m_fb_fs_id = 0; 1089 } 1090 1091 if (0 != m_fb_vs_id) 1092 { 1093 gl.deleteShader(m_fb_vs_id); 1094 m_fb_vs_id = 0; 1095 } 1096 1097 if (0 != m_fb_fbo_id) 1098 { 1099 gl.deleteFramebuffers(1, &m_fb_fbo_id); 1100 m_fb_fbo_id = 0; 1101 } 1102 1103 if (0 != m_fb_to_id) 1104 { 1105 gl.deleteTextures(1, &m_fb_to_id); 1106 m_fb_to_id = 0; 1107 } 1108 1109 if (0 != m_fb_vbo_id) 1110 { 1111 gl.deleteBuffers(1, &m_fb_vbo_id); 1112 m_fb_vbo_id = 0; 1113 } 1114 1115 if (0 != m_fb_vao_id) 1116 { 1117 gl.deleteVertexArrays(1, &m_fb_vao_id); 1118 m_fb_vao_id = 0; 1119 } 1120 1121 /* Deinitialize base class */ 1122 TextureBufferOperations::deinit(); 1123 } 1124 1125 /** Constructor for Test Case 4 1126 * 1127 * @param context Test context 1128 * @param name Test case's name 1129 * @param description Test case's description 1130 **/ 1131 TextureBufferOperationsViaTransformFeedback::TextureBufferOperationsViaTransformFeedback(Context& context, 1132 const ExtParameters& extParams, 1133 const char* name, 1134 const char* description) 1135 : TextureBufferOperations(context, extParams, name, description) 1136 , m_tf_fs_id(0) 1137 , m_tf_po_id(0) 1138 , m_tf_vao_id(0) 1139 , m_tf_vbo_id(0) 1140 , m_tf_vs_id(0) 1141 , m_position_location(-1) 1142 { 1143 } 1144 1145 /** Initialize buffer object with test data using transform feedback 1146 * 1147 **/ 1148 void TextureBufferOperationsViaTransformFeedback::initializeBufferObjectData() 1149 { 1150 /* Get GL entry points */ 1151 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1152 1153 std::vector<glw::GLint> data(m_n_vectors_in_buffer_texture * m_n_vector_components); 1154 fillBufferWithData(&data[0], m_n_vectors_in_buffer_texture * m_n_vector_components); 1155 1156 /* Configure vertex array object */ 1157 gl.genVertexArrays(1, &m_tf_vao_id); 1158 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating vertex array object!"); 1159 1160 gl.bindVertexArray(m_tf_vao_id); 1161 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding vertex array object!"); 1162 1163 /* Configure buffer object*/ 1164 gl.genBuffers(1, &m_tf_vbo_id); 1165 GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating vertex buffer object!"); 1166 1167 gl.bindBuffer(GL_ARRAY_BUFFER, m_tf_vbo_id); 1168 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding vertex buffer object!"); 1169 1170 gl.bufferData(GL_ARRAY_BUFFER, m_n_vectors_in_buffer_texture * m_n_vector_components * sizeof(glw::GLint), &data[0], 1171 GL_DYNAMIC_DRAW); 1172 GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating buffer object's data store!"); 1173 1174 m_tf_po_id = gl.createProgram(); 1175 GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program object!"); 1176 1177 /* Setup transform feedback varyings */ 1178 const char* varyings[] = { "outPosition" }; 1179 gl.transformFeedbackVaryings(m_tf_po_id, 1, varyings, GL_SEPARATE_ATTRIBS); 1180 GLU_EXPECT_NO_ERROR(gl.getError(), "Error specifying transform feedback varyings!"); 1181 1182 m_tf_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 1183 GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating fragment shader object!"); 1184 1185 m_tf_vs_id = gl.createShader(GL_VERTEX_SHADER); 1186 GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating vertex shader object!"); 1187 1188 std::string fsSource = getTFFragmentShaderCode(); 1189 std::string vsSource = getTFVertexShaderCode(); 1190 1191 const char* fsCode = fsSource.c_str(); 1192 const char* vsCode = vsSource.c_str(); 1193 1194 if (!buildProgram(m_tf_po_id, m_tf_fs_id, 1, &fsCode, m_tf_vs_id, 1, &vsCode)) 1195 { 1196 TCU_FAIL("Could not create a program from valid vertex/fragment shader code!"); 1197 } 1198 1199 gl.useProgram(m_tf_po_id); 1200 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active program object!"); 1201 1202 m_position_location = gl.getAttribLocation(m_tf_po_id, "inPosition"); 1203 GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting attrib location!"); 1204 1205 gl.vertexAttribIPointer(m_position_location, m_n_vector_components, GL_INT, 0, 0); 1206 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting vertex attrib pointer!"); 1207 1208 gl.enableVertexAttribArray(m_position_location); 1209 GLU_EXPECT_NO_ERROR(gl.getError(), "Error enabling vertex attrib array!"); 1210 1211 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_tb_bo_id); 1212 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object to transform feedback binding point!"); 1213 1214 gl.beginTransformFeedback(GL_POINTS); 1215 GLU_EXPECT_NO_ERROR(gl.getError(), "Error starting transform feedback!"); 1216 1217 /* Render */ 1218 gl.drawArrays(GL_POINTS, 0, m_n_vectors_in_buffer_texture); 1219 GLU_EXPECT_NO_ERROR(gl.getError(), "Error during rendering!"); 1220 1221 gl.endTransformFeedback(); 1222 GLU_EXPECT_NO_ERROR(gl.getError(), "Error ending transform feedback!"); 1223 1224 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0); 1225 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 1226 gl.bindVertexArray(0); 1227 1228 if (glu::isContextTypeES(m_context.getRenderContext().getType())) 1229 gl.disableVertexAttribArray(m_position_location); 1230 1231 gl.useProgram(0); 1232 1233 m_position_location = -1; 1234 } 1235 1236 /** Returns Fragment shader Code 1237 * 1238 * @return pointer to literal with Fragment Shader Code 1239 */ 1240 std::string TextureBufferOperationsViaTransformFeedback::getTFFragmentShaderCode() const 1241 { 1242 std::stringstream strstream; 1243 1244 strstream << "${VERSION}\n" 1245 "\n" 1246 "${TEXTURE_BUFFER_REQUIRE}\n" 1247 "\n" 1248 "in flat ivec4 outPosition;\n" 1249 "\n" 1250 "precision highp float;\n" 1251 "\n" 1252 "void main(void)\n" 1253 "{\n" 1254 "}\n"; 1255 1256 return strstream.str(); 1257 } 1258 1259 /** Returns Vertex Shader Code 1260 * 1261 * @return pointer to literal with Vertex Shader Code 1262 */ 1263 std::string TextureBufferOperationsViaTransformFeedback::getTFVertexShaderCode() const 1264 { 1265 std::stringstream strstream; 1266 1267 strstream << "${VERSION}\n" 1268 "\n" 1269 "${TEXTURE_BUFFER_REQUIRE}\n" 1270 "\n" 1271 "precision highp float;\n" 1272 "\n" 1273 "in ivec4 inPosition;\n" 1274 "\n" 1275 "flat out ivec4 outPosition;\n" 1276 "\n" 1277 "void main(void)\n" 1278 "{\n" 1279 " gl_Position = vec4(0.0, 0.0, 0.0, 0.0);\n" 1280 " outPosition = inPosition;\n" 1281 "}\n"; 1282 1283 return strstream.str(); 1284 } 1285 1286 /** Deinitializes GLES objects created during the test. */ 1287 void TextureBufferOperationsViaTransformFeedback::deinit(void) 1288 { 1289 /* Get GL entry points */ 1290 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1291 1292 /* Reset GLES state */ 1293 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0); 1294 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 1295 gl.bindVertexArray(0); 1296 1297 if (m_position_location != -1) 1298 { 1299 gl.disableVertexAttribArray(m_position_location); 1300 m_position_location = -1; 1301 } 1302 1303 gl.useProgram(0); 1304 1305 /* Delete GLES objects */ 1306 if (0 != m_tf_po_id) 1307 { 1308 gl.deleteProgram(m_tf_po_id); 1309 m_tf_po_id = 0; 1310 } 1311 1312 if (0 != m_tf_vs_id) 1313 { 1314 gl.deleteShader(m_tf_vs_id); 1315 m_tf_vs_id = 0; 1316 } 1317 1318 if (0 != m_tf_fs_id) 1319 { 1320 gl.deleteShader(m_tf_fs_id); 1321 m_tf_fs_id = 0; 1322 } 1323 1324 if (0 != m_tf_vbo_id) 1325 { 1326 gl.deleteBuffers(1, &m_tf_vbo_id); 1327 m_tf_vbo_id = 0; 1328 } 1329 1330 if (0 != m_tf_vao_id) 1331 { 1332 gl.deleteVertexArrays(1, &m_tf_vao_id); 1333 m_tf_vao_id = 0; 1334 } 1335 1336 /* Deinitialize base class */ 1337 TextureBufferOperations::deinit(); 1338 } 1339 1340 const glw::GLuint TextureBufferOperationsViaImageStore::m_image_unit = 0; 1341 1342 /** Constructor for Test Case 5 1343 * 1344 * @param context Test context 1345 * @param name Test case's name 1346 * @param description Test case's description 1347 **/ 1348 TextureBufferOperationsViaImageStore::TextureBufferOperationsViaImageStore(Context& context, 1349 const ExtParameters& extParams, 1350 const char* name, const char* description) 1351 : TextureBufferOperations(context, extParams, name, description), m_is_cs_id(0), m_is_po_id(0) 1352 { 1353 } 1354 1355 /** Initialize buffer object with test data using image store 1356 * 1357 **/ 1358 void TextureBufferOperationsViaImageStore::initializeBufferObjectData() 1359 { 1360 /* Get Gl entry points */ 1361 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1362 1363 /* Configure program object */ 1364 m_is_po_id = gl.createProgram(); 1365 GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program object!"); 1366 1367 m_is_cs_id = gl.createShader(GL_COMPUTE_SHADER); 1368 GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating compute shader object!"); 1369 1370 std::string csSource = getISComputeShaderCode(); 1371 const char* csCode = csSource.c_str(); 1372 1373 if (!buildProgram(m_is_po_id, m_is_cs_id, 1, &csCode)) 1374 { 1375 TCU_FAIL("Could not create a program from valid compute shader source!"); 1376 } 1377 1378 gl.useProgram(m_is_po_id); 1379 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active program object!"); 1380 1381 gl.bindImageTexture(m_image_unit, m_texbuff_id, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32I); 1382 GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!"); 1383 1384 gl.dispatchCompute(1, 1, 1); 1385 GLU_EXPECT_NO_ERROR(gl.getError(), "Error running compute shader!"); 1386 1387 gl.memoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); 1388 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting memory barrier!"); 1389 1390 gl.useProgram(0); 1391 } 1392 1393 /** Returns Compute Shader Code 1394 * 1395 * @return pointer to literal with Compute Shader Code 1396 */ 1397 std::string TextureBufferOperationsViaImageStore::getISComputeShaderCode() const 1398 { 1399 std::stringstream strstream; 1400 1401 strstream << "${VERSION}\n" 1402 "\n" 1403 "${TEXTURE_BUFFER_REQUIRE}\n" 1404 "\n" 1405 "precision highp float;\n" 1406 "\n" 1407 "layout(rgba32i, binding = 0) uniform writeonly highp iimageBuffer image_buffer;\n" 1408 "\n" 1409 "layout (local_size_x = " 1410 << m_n_vectors_in_buffer_texture 1411 << " ) in;\n" 1412 "\n" 1413 "void main(void)\n" 1414 "{\n" 1415 " imageStore(image_buffer, int(gl_LocalInvocationID.x), ivec4(gl_LocalInvocationID.x) );\n" 1416 "}\n"; 1417 1418 return strstream.str(); 1419 } 1420 1421 /** Fill buffer with test data 1422 * 1423 * @param buffer pointer to buffer 1424 * @param bufferLenth buffer length 1425 */ 1426 void TextureBufferOperationsViaImageStore::fillBufferWithData(glw::GLint* buffer, glw::GLuint bufferLength) 1427 { 1428 for (glw::GLuint i = 0; i < bufferLength; ++i) 1429 { 1430 buffer[i] = (glw::GLint)(i / m_n_vector_components); 1431 } 1432 } 1433 1434 /** Deinitializes GLES objects created during the test. */ 1435 void TextureBufferOperationsViaImageStore::deinit(void) 1436 { 1437 /* Get Gl entry points */ 1438 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1439 1440 /* Reset GLES state */ 1441 gl.useProgram(0); 1442 1443 /* Delete GLES objects */ 1444 if (0 != m_is_po_id) 1445 { 1446 gl.deleteProgram(m_is_po_id); 1447 m_is_po_id = 0; 1448 } 1449 1450 if (0 != m_is_cs_id) 1451 { 1452 gl.deleteShader(m_is_cs_id); 1453 m_is_cs_id = 0; 1454 } 1455 1456 /* Deinitalize base class */ 1457 TextureBufferOperations::deinit(); 1458 } 1459 1460 /** Constructor for Test Case 6 1461 * 1462 * @param context Test context 1463 * @param name Test case's name 1464 * @param description Test case's description 1465 **/ 1466 TextureBufferOperationsViaSSBOWrites::TextureBufferOperationsViaSSBOWrites(Context& context, 1467 const ExtParameters& extParams, 1468 const char* name, const char* description) 1469 : TextureBufferOperations(context, extParams, name, description), m_ssbo_cs_id(0), m_ssbo_po_id(0) 1470 { 1471 } 1472 1473 /** Initialize buffer object with test data using ssbo writes 1474 * 1475 **/ 1476 void TextureBufferOperationsViaSSBOWrites::initializeBufferObjectData() 1477 { 1478 /* Get Gl entry points */ 1479 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1480 1481 /* Configure program object */ 1482 m_ssbo_po_id = gl.createProgram(); 1483 GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program object!"); 1484 1485 m_ssbo_cs_id = gl.createShader(GL_COMPUTE_SHADER); 1486 GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating compute shader object!"); 1487 1488 std::string csSource = getSSBOComputeShaderCode(); 1489 const char* csCode = csSource.c_str(); 1490 1491 if (!buildProgram(m_ssbo_po_id, m_ssbo_cs_id, 1, &csCode)) 1492 { 1493 TCU_FAIL("Could not create a program from valid compute shader source!"); 1494 } 1495 1496 gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_tb_bo_id); 1497 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind buffer object to shader storage binding point!"); 1498 1499 gl.useProgram(m_ssbo_po_id); 1500 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active program object!"); 1501 1502 gl.dispatchCompute(1, 1, 1); 1503 GLU_EXPECT_NO_ERROR(gl.getError(), "Error running compute shader!"); 1504 1505 gl.memoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); 1506 GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting memory barrier!"); 1507 1508 gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 1509 gl.useProgram(0); 1510 } 1511 1512 /** Returns Compute Shader Code 1513 * 1514 * @return pointer to literal with Compute Shader Code 1515 */ 1516 std::string TextureBufferOperationsViaSSBOWrites::getSSBOComputeShaderCode() const 1517 { 1518 std::stringstream strstream; 1519 1520 strstream << "${VERSION}\n" 1521 "\n" 1522 "${TEXTURE_BUFFER_REQUIRE}\n" 1523 "\n" 1524 "precision highp float;\n" 1525 "\n" 1526 "buffer ComputeSSBO\n" 1527 "{\n" 1528 " ivec4 value[];\n" 1529 "} computeSSBO;\n" 1530 "\n" 1531 "layout (local_size_x = " 1532 << m_n_vectors_in_buffer_texture 1533 << " ) in;\n" 1534 "\n" 1535 "void main(void)\n" 1536 "{\n" 1537 " computeSSBO.value[gl_LocalInvocationID.x] = ivec4(gl_LocalInvocationID.x);\n" 1538 "}\n"; 1539 1540 return strstream.str(); 1541 } 1542 1543 /** Fill buffer with test data 1544 * 1545 * @param buffer pointer to buffer 1546 * @param bufferLenth buffer length 1547 */ 1548 void TextureBufferOperationsViaSSBOWrites::fillBufferWithData(glw::GLint* buffer, glw::GLuint bufferLength) 1549 { 1550 for (glw::GLuint i = 0; i < bufferLength; ++i) 1551 { 1552 buffer[i] = (glw::GLint)(i / m_n_vector_components); 1553 } 1554 } 1555 1556 /** Deinitializes GLES objects created during the test. */ 1557 void TextureBufferOperationsViaSSBOWrites::deinit(void) 1558 { 1559 /* Get Gl entry points */ 1560 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1561 1562 /* Reset GLES state */ 1563 gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 1564 gl.useProgram(0); 1565 1566 /* Delete GLES objects */ 1567 if (0 != m_ssbo_po_id) 1568 { 1569 gl.deleteProgram(m_ssbo_po_id); 1570 m_ssbo_po_id = 0; 1571 } 1572 1573 if (0 != m_ssbo_cs_id) 1574 { 1575 gl.deleteShader(m_ssbo_cs_id); 1576 m_ssbo_cs_id = 0; 1577 } 1578 1579 /* Deinitalize base class */ 1580 TextureBufferOperations::deinit(); 1581 } 1582 1583 } // namespace glcts 1584