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