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