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