a2ff07dc2f91f49cf2a217142b257ddd801a4890
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / gl / gl4cIndirectParametersTests.cpp
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2017 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  */ /*!
26  * \file  gl4cIndirectParametersTests.cpp
27  * \brief Conformance tests for the GL_ARB_indirect_parameters functionality.
28  */ /*-------------------------------------------------------------------*/
29
30 #include "gl4cIndirectParametersTests.hpp"
31 #include "gluContextInfo.hpp"
32 #include "gluDefs.hpp"
33 #include "gluDrawUtil.hpp"
34 #include "gluShaderProgram.hpp"
35 #include "glwEnums.hpp"
36 #include "glwFunctions.hpp"
37 #include "tcuRenderTarget.hpp"
38 #include "tcuTestLog.hpp"
39
40 using namespace glw;
41 using namespace glu;
42
43 namespace gl4cts
44 {
45
46 static const char* c_vertShader = "#version 430\n"
47                                                                   "\n"
48                                                                   "in vec3 vertex;\n"
49                                                                   "\n"
50                                                                   "void main()\n"
51                                                                   "{\n"
52                                                                   "    gl_Position = vec4(vertex, 1);\n"
53                                                                   "}\n";
54
55 static const char* c_fragShader = "#version 430\n"
56                                                                   "\n"
57                                                                   "out vec4 fragColor;\n"
58                                                                   "\n"
59                                                                   "void main()\n"
60                                                                   "{\n"
61                                                                   "    fragColor = vec4(1, 1, 1, 0.5);\n"
62                                                                   "}\n";
63
64 /** Constructor.
65  *
66  *  @param context     Rendering context
67  */
68 ParameterBufferOperationsCase::ParameterBufferOperationsCase(deqp::Context& context)
69         : TestCase(context, "ParameterBufferOperations",
70                            "Verifies if operations on new buffer object PARAMETER_BUFFER_ARB works as expected.")
71 {
72         /* Left blank intentionally */
73 }
74
75 /** Stub init method */
76 void ParameterBufferOperationsCase::init()
77 {
78 }
79
80 /** Executes test iteration.
81  *
82  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
83  */
84 tcu::TestNode::IterateResult ParameterBufferOperationsCase::iterate()
85 {
86         if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_indirect_parameters"))
87         {
88                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
89                 return STOP;
90         }
91
92         const Functions& gl = m_context.getRenderContext().getFunctions();
93
94         GLuint paramBuffer;
95
96         GLint data[]    = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
97         GLint subData[] = { 10, 11, 12, 13, 14 };
98         GLint expData[] = { 0, 1, 10, 11, 12, 13, 14, 7, 8, 9 };
99
100         bool result = true;
101
102         // Test buffer generating and binding
103         gl.genBuffers(1, &paramBuffer);
104         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
105
106         gl.bindBuffer(GL_PARAMETER_BUFFER_ARB, paramBuffer);
107         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
108
109         GLint paramBinding;
110         gl.getIntegerv(GL_PARAMETER_BUFFER_BINDING_ARB, &paramBinding);
111         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv");
112
113         if ((GLuint)paramBinding != paramBuffer)
114         {
115                 result = false;
116                 m_testCtx.getLog() << tcu::TestLog::Message << "Buffer binding mismatch" << tcu::TestLog::EndMessage;
117         }
118         else
119         {
120                 // Test filling buffer with data
121                 gl.bufferData(GL_PARAMETER_BUFFER_ARB, 10 * sizeof(GLint), data, GL_DYNAMIC_DRAW);
122                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
123
124                 gl.bufferSubData(GL_PARAMETER_BUFFER_ARB, 2 * sizeof(GLint), 5 * sizeof(GLint), subData);
125                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
126
127                 // Test buffer mapping
128                 GLvoid* buffer = gl.mapBuffer(GL_PARAMETER_BUFFER_ARB, GL_READ_ONLY);
129                 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer");
130
131                 if (memcmp(buffer, expData, 10 * sizeof(GLint)) != 0)
132                 {
133                         result = false;
134                         m_testCtx.getLog() << tcu::TestLog::Message << "Buffer data mismatch" << tcu::TestLog::EndMessage;
135                 }
136                 else
137                 {
138                         GLvoid* bufferPointer;
139                         gl.getBufferPointerv(GL_PARAMETER_BUFFER_ARB, GL_BUFFER_MAP_POINTER, &bufferPointer);
140                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferPointerv");
141
142                         if (buffer != bufferPointer)
143                         {
144                                 result = false;
145                                 m_testCtx.getLog() << tcu::TestLog::Message << "Buffer pointer mismatch" << tcu::TestLog::EndMessage;
146                         }
147                         else
148                         {
149                                 GLint bufferSize;
150                                 GLint bufferUsage;
151                                 gl.getBufferParameteriv(GL_PARAMETER_BUFFER_ARB, GL_BUFFER_SIZE, &bufferSize);
152                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferParameteriv");
153                                 gl.getBufferParameteriv(GL_PARAMETER_BUFFER_ARB, GL_BUFFER_USAGE, &bufferUsage);
154                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferParameteriv");
155
156                                 if (bufferSize != 10 * sizeof(GLint))
157                                 {
158                                         result = false;
159                                         m_testCtx.getLog() << tcu::TestLog::Message << "Buffer size mismatch" << tcu::TestLog::EndMessage;
160                                 }
161                                 else if (bufferUsage != GL_DYNAMIC_DRAW)
162                                 {
163                                         result = false;
164                                         m_testCtx.getLog() << tcu::TestLog::Message << "Buffer usage mismatch" << tcu::TestLog::EndMessage;
165                                 }
166                         }
167                 }
168
169                 gl.unmapBuffer(GL_PARAMETER_BUFFER_ARB);
170                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer");
171
172                 // Test buffer ranged mapping
173                 buffer =
174                         gl.mapBufferRange(GL_PARAMETER_BUFFER_ARB, 0, sizeof(GLint), GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
175                 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange");
176
177                 // Test buffer flushing
178                 GLint* bufferInt = (GLint*)buffer;
179
180                 bufferInt[0] = 100;
181                 gl.flushMappedBufferRange(GL_PARAMETER_BUFFER_ARB, 0, sizeof(GLint));
182                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFlushMappedBufferRange");
183
184                 gl.unmapBuffer(GL_PARAMETER_BUFFER_ARB);
185                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer");
186
187                 // Test buffers data copying
188                 GLuint arrayBuffer;
189                 gl.genBuffers(1, &arrayBuffer);
190                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
191
192                 gl.bindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
193                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
194
195                 gl.bufferData(GL_ARRAY_BUFFER, 10 * sizeof(GLint), data, GL_DYNAMIC_DRAW);
196                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
197
198                 gl.copyBufferSubData(GL_PARAMETER_BUFFER_ARB, GL_ARRAY_BUFFER, 0, 0, sizeof(GLint));
199                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyBufferSubData");
200
201                 gl.mapBufferRange(GL_ARRAY_BUFFER, 0, 1, GL_MAP_READ_BIT);
202                 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange");
203
204                 bufferInt = (GLint*)buffer;
205                 if (bufferInt[0] != 100)
206                 {
207                         result = false;
208                         m_testCtx.getLog() << tcu::TestLog::Message << "Buffer copy operation failed" << tcu::TestLog::EndMessage;
209                 }
210
211                 gl.unmapBuffer(GL_ARRAY_BUFFER);
212                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer");
213
214                 // Release array buffer
215                 gl.deleteBuffers(1, &arrayBuffer);
216                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers");
217         }
218
219         // Release parameter buffer
220         gl.deleteBuffers(1, &paramBuffer);
221         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers");
222
223         if (result)
224                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
225         else
226                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
227
228         return STOP;
229 }
230
231 /** Constructor.
232  *
233  *  @param context     Rendering context
234  */
235 VertexArrayIndirectDrawingBaseCase::VertexArrayIndirectDrawingBaseCase(deqp::Context& context, const char* name,
236                                                                                                                                            const char* description)
237         : TestCase(context, name, description)
238 {
239         /* Left blank intentionally */
240 }
241
242 /** Executes test iteration.
243  *
244  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
245  */
246 tcu::TestNode::IterateResult VertexArrayIndirectDrawingBaseCase::iterate()
247 {
248         if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_indirect_parameters"))
249         {
250                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
251                 return STOP;
252         }
253
254         if (draw() && verify())
255                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
256         else
257                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
258
259         return STOP;
260 }
261
262 /** This method verifies if drawn quads are as expected.
263  *
264  *  @return Returns true if quads are drawn properly, false otherwise.
265  */
266 bool VertexArrayIndirectDrawingBaseCase::verify()
267 {
268         const Functions&                 gl = m_context.getRenderContext().getFunctions();
269         const tcu::RenderTarget& rt = m_context.getRenderContext().getRenderTarget();
270
271         const int width  = rt.getWidth();
272         const int height = rt.getHeight();
273
274         std::vector<GLubyte> pixels;
275         pixels.resize(width * height);
276
277         gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
278         gl.readPixels(0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, pixels.data());
279         gl.pixelStorei(GL_PACK_ALIGNMENT, 4);
280
281         //Verify first quad
282         for (int y = 2; y < height - 2; ++y)
283         {
284                 for (int x = 2; x < width / 2 - 2; ++x)
285                 {
286                         GLubyte value = pixels[x + y * width];
287                         if (value < 190 || value > 194)
288                         {
289                                 m_testCtx.getLog() << tcu::TestLog::Message << "First quad verification failed. "
290                                                                    << "Wrong value read from framebuffer at " << x << "/" << y << " value: " << value
291                                                                    << ", expected: <190-194>" << tcu::TestLog::EndMessage;
292                                 return false;
293                         }
294                 }
295         }
296
297         //Verify second quad
298         for (int y = 2; y < height - 2; ++y)
299         {
300                 for (int x = width / 2 + 2; x < width - 2; ++x)
301                 {
302                         GLubyte value = pixels[x + y * width];
303                         if (value < 126 || value > 130)
304                         {
305                                 m_testCtx.getLog() << tcu::TestLog::Message << "Second quad verification failed. "
306                                                                    << "Wrong value read from framebuffer at " << x << "/" << y << " value: " << value
307                                                                    << ", expected: <126-130>" << tcu::TestLog::EndMessage;
308                                 return false;
309                         }
310                 }
311         }
312
313         return verifyErrors();
314 }
315
316 /** Constructor.
317  *
318  *  @param context     Rendering context
319  */
320 MultiDrawArraysIndirectCountCase::MultiDrawArraysIndirectCountCase(deqp::Context& context)
321         : VertexArrayIndirectDrawingBaseCase(context, "MultiDrawArraysIndirectCount",
322                                                                                  "Test verifies if MultiDrawArraysIndirectCountARB function works as expected.")
323         , m_vao(0)
324         , m_arrayBuffer(0)
325         , m_drawIndirectBuffer(0)
326         , m_parameterBuffer(0)
327 {
328         /* Left blank intentionally */
329 }
330
331 /** Stub init method */
332 void MultiDrawArraysIndirectCountCase::init()
333 {
334         if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_indirect_parameters"))
335                 return;
336
337         const Functions& gl = m_context.getRenderContext().getFunctions();
338
339         const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, -1.0f, 1.0f,  0.0f, 0.0f, -1.0f, 0.0f,
340                                                                  0.0f,  1.0f,  0.0f, 1.0f,  -1.0f, 0.0f, 1.0f, 1.0f,  0.0f };
341
342         const DrawArraysIndirectCommand indirect[] = {
343                 { 4, 2, 0, 0 }, //4 vertices, 2 instanceCount, 0 first, 0 baseInstance
344                 { 4, 1, 2, 0 }  //4 vertices, 1 instanceCount, 2 first, 0 baseInstance
345         };
346
347         const GLushort parameters[] = { 2, 1 };
348
349         // Generate vertex array object
350         gl.genVertexArrays(1, &m_vao);
351         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
352
353         gl.bindVertexArray(m_vao);
354         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");
355
356         // Setup vertex array buffer
357         gl.genBuffers(1, &m_arrayBuffer);
358         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
359
360         gl.bindBuffer(GL_ARRAY_BUFFER, m_arrayBuffer);
361         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
362
363         gl.bufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
364         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
365
366         // Setup indirect command buffer
367         gl.genBuffers(1, &m_drawIndirectBuffer);
368         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
369
370         gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_drawIndirectBuffer);
371         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
372
373         gl.bufferData(GL_DRAW_INDIRECT_BUFFER, 2 * sizeof(DrawArraysIndirectCommand), indirect, GL_STATIC_DRAW);
374         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
375
376         // Setup parameter buffer
377         gl.genBuffers(1, &m_parameterBuffer);
378         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
379
380         gl.bindBuffer(GL_PARAMETER_BUFFER_ARB, m_parameterBuffer);
381         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
382
383         gl.bufferData(GL_PARAMETER_BUFFER_ARB, 100 * sizeof(GLushort), parameters, GL_STATIC_DRAW);
384         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
385 }
386
387 /** Stub deinit method */
388 void MultiDrawArraysIndirectCountCase::deinit()
389 {
390         const Functions& gl = m_context.getRenderContext().getFunctions();
391
392         if (m_vao)
393                 gl.deleteVertexArrays(1, &m_vao);
394         if (m_arrayBuffer)
395                 gl.deleteBuffers(1, &m_arrayBuffer);
396         if (m_drawIndirectBuffer)
397                 gl.deleteBuffers(1, &m_drawIndirectBuffer);
398         if (m_parameterBuffer)
399                 gl.deleteBuffers(1, &m_parameterBuffer);
400 }
401
402 /** Drawing quads method using drawArrays.
403  */
404 bool MultiDrawArraysIndirectCountCase::draw()
405 {
406         const Functions& gl = m_context.getRenderContext().getFunctions();
407
408         ProgramSources sources = makeVtxFragSources(c_vertShader, c_fragShader);
409         ShaderProgram  program(gl, sources);
410
411         if (!program.isOk())
412         {
413                 m_testCtx.getLog() << tcu::TestLog::Message << "Shader build failed.\n"
414                                                    << "Vertex: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
415                                                    << "Fragment: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
416                                                    << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
417                 return false;
418         }
419
420         gl.useProgram(program.getProgram());
421         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
422
423         gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
424         gl.clear(GL_COLOR_BUFFER_BIT);
425
426         gl.enable(GL_BLEND);
427         gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
428
429         gl.enableVertexAttribArray(0);
430         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
431         gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
432         GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
433
434         gl.multiDrawArraysIndirectCount(GL_TRIANGLE_STRIP, 0, 0, 2, 0);
435         GLU_EXPECT_NO_ERROR(gl.getError(), "glMultiDrawArraysIndirectCountARB");
436
437         gl.disableVertexAttribArray(0);
438         GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
439
440         gl.disable(GL_BLEND);
441
442         return true;
443 }
444
445 /** Verify MultiDrawArrayIndirectCountARB errors
446  */
447 bool MultiDrawArraysIndirectCountCase::verifyErrors()
448 {
449         const Functions& gl = m_context.getRenderContext().getFunctions();
450
451         GLint errorCode;
452
453         bool result = true;
454
455         // INVALID_VALUE - drawcount offset not multiple of 4
456         gl.multiDrawArraysIndirectCount(GL_TRIANGLE_STRIP, 0, 2, 1, 0);
457         errorCode = gl.getError();
458         if (errorCode != GL_INVALID_VALUE)
459         {
460                 m_testCtx.getLog() << tcu::TestLog::Message
461                                                    << "MultiDrawArraysIndirectCount error verifying failed (1). Expected code: "
462                                                    << GL_INVALID_VALUE << ", current code: " << errorCode << tcu::TestLog::EndMessage;
463                 result = false;
464         }
465
466         // INVALID_OPERATION - maxdrawcount greater then parameter buffer size
467         gl.multiDrawArraysIndirectCount(GL_TRIANGLE_STRIP, 0, 0, 4, 0);
468         errorCode = gl.getError();
469         if (errorCode != GL_INVALID_OPERATION)
470         {
471                 m_testCtx.getLog() << tcu::TestLog::Message
472                                                    << "MultiDrawArraysIndirectCount error verifying failed (2). Expected code: "
473                                                    << GL_INVALID_OPERATION << ", current code: " << errorCode << tcu::TestLog::EndMessage;
474                 result = false;
475         }
476
477         gl.bindBuffer(GL_PARAMETER_BUFFER_ARB, 0);
478         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
479
480         // INVALID_OPERATION - GL_PARAMETER_BUFFER_ARB not bound
481         gl.multiDrawArraysIndirectCount(GL_TRIANGLE_STRIP, 0, 0, 2, 0);
482         errorCode = gl.getError();
483         if (errorCode != GL_INVALID_OPERATION)
484         {
485                 m_testCtx.getLog() << tcu::TestLog::Message
486                                                    << "MultiDrawArraysIndirectCount error verifying failed (3). Expected code: "
487                                                    << GL_INVALID_OPERATION << ", current code: " << errorCode << tcu::TestLog::EndMessage;
488                 result = false;
489         }
490
491         return result;
492 }
493
494 /** Constructor.
495  *
496  *  @param context     Rendering context
497  */
498 MultiDrawElementsIndirectCountCase::MultiDrawElementsIndirectCountCase(deqp::Context& context)
499         : VertexArrayIndirectDrawingBaseCase(
500                   context, "MultiDrawElementsIndirectCount",
501                   "Test verifies if MultiDrawElementsIndirectCountARB function works as expected.")
502         , m_vao(0)
503         , m_arrayBuffer(0)
504         , m_drawIndirectBuffer(0)
505         , m_parameterBuffer(0)
506 {
507         /* Left blank intentionally */
508 }
509
510 /** Stub init method */
511 void MultiDrawElementsIndirectCountCase::init()
512 {
513         if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_indirect_parameters"))
514                 return;
515
516         const Functions& gl = m_context.getRenderContext().getFunctions();
517
518         const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, -1.0f, 1.0f,  0.0f, 0.0f, -1.0f, 0.0f,
519                                                                  0.0f,  1.0f,  0.0f, 1.0f,  -1.0f, 0.0f, 1.0f, 1.0f,  0.0f };
520
521         const GLushort elements[] = { 0, 1, 2, 3, 4, 5 };
522
523         const DrawElementsIndirectCommand indirect[] = {
524                 { 4, 2, 0, 0, 0 }, //4 indices, 2 instanceCount, 0 firstIndex, 0 baseVertex, 0 baseInstance
525                 { 4, 1, 2, 0, 0 }  //4 indices, 1 instanceCount, 2 firstIndex, 0 baseVertex, 0 baseInstance
526         };
527
528         const GLushort parameters[] = { 2, 1 };
529
530         // Generate vertex array object
531         gl.genVertexArrays(1, &m_vao);
532         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
533
534         gl.bindVertexArray(m_vao);
535         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");
536
537         // Setup vertex array buffer
538         gl.genBuffers(1, &m_arrayBuffer);
539         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
540
541         gl.bindBuffer(GL_ARRAY_BUFFER, m_arrayBuffer);
542         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
543
544         gl.bufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
545         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
546
547         // Setup element array buffer
548         gl.genBuffers(1, &m_elementBuffer);
549         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
550
551         gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementBuffer);
552         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
553
554         gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLushort), elements, GL_STATIC_DRAW);
555         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
556
557         // Setup indirect command buffer
558         gl.genBuffers(1, &m_drawIndirectBuffer);
559         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
560
561         gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_drawIndirectBuffer);
562         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
563
564         gl.bufferData(GL_DRAW_INDIRECT_BUFFER, 3 * sizeof(DrawElementsIndirectCommand), indirect, GL_STATIC_DRAW);
565         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
566
567         // Setup parameters Re: buffer
568         gl.genBuffers(1, &m_parameterBuffer);
569         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
570
571         gl.bindBuffer(GL_PARAMETER_BUFFER_ARB, m_parameterBuffer);
572         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
573
574         gl.bufferData(GL_PARAMETER_BUFFER_ARB, 2 * sizeof(GLushort), parameters, GL_STATIC_DRAW);
575         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
576 }
577
578 /** Stub deinit method */
579 void MultiDrawElementsIndirectCountCase::deinit()
580 {
581         const Functions& gl = m_context.getRenderContext().getFunctions();
582
583         if (m_vao)
584                 gl.deleteVertexArrays(1, &m_vao);
585         if (m_arrayBuffer)
586                 gl.deleteBuffers(1, &m_arrayBuffer);
587         if (m_elementBuffer)
588                 gl.deleteBuffers(1, &m_elementBuffer);
589         if (m_drawIndirectBuffer)
590                 gl.deleteBuffers(1, &m_drawIndirectBuffer);
591         if (m_parameterBuffer)
592                 gl.deleteBuffers(1, &m_parameterBuffer);
593 }
594
595 /** Drawing quads method using drawArrays.
596  */
597 bool MultiDrawElementsIndirectCountCase::draw()
598 {
599         const Functions& gl = m_context.getRenderContext().getFunctions();
600
601         ProgramSources sources = makeVtxFragSources(c_vertShader, c_fragShader);
602         ShaderProgram  program(gl, sources);
603
604         if (!program.isOk())
605         {
606                 m_testCtx.getLog() << tcu::TestLog::Message << "Shader build failed.\n"
607                                                    << "Vertex: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
608                                                    << "Fragment: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
609                                                    << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
610                 return false;
611         }
612
613         gl.useProgram(program.getProgram());
614         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
615
616         gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
617         gl.clear(GL_COLOR_BUFFER_BIT);
618
619         gl.enable(GL_BLEND);
620         gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
621
622         gl.enableVertexAttribArray(0);
623         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
624         gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
625         GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
626
627         gl.multiDrawElementsIndirectCount(GL_TRIANGLE_STRIP, GL_UNSIGNED_SHORT, 0, 0, 2, 0);
628         GLU_EXPECT_NO_ERROR(gl.getError(), "glMultiDrawElementsIndirectCountARB");
629
630         gl.disableVertexAttribArray(0);
631         GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
632
633         gl.disable(GL_BLEND);
634
635         return true;
636 }
637
638 /** Verify MultiDrawElementsIndirectCountARB errors
639  */
640 bool MultiDrawElementsIndirectCountCase::verifyErrors()
641 {
642         const Functions& gl = m_context.getRenderContext().getFunctions();
643
644         GLint errorCode;
645
646         bool result = true;
647
648         // INVALID_VALUE - drawcount offset not multiple of 4
649         gl.multiDrawElementsIndirectCount(GL_TRIANGLE_STRIP, GL_UNSIGNED_BYTE, 0, 2, 1, 0);
650         errorCode = gl.getError();
651         if (errorCode != GL_INVALID_VALUE)
652         {
653                 m_testCtx.getLog() << tcu::TestLog::Message
654                                                    << "MultiDrawElementIndirectCount error verifying failed (1). Expected code: "
655                                                    << GL_INVALID_VALUE << ", current code: " << errorCode << tcu::TestLog::EndMessage;
656                 result = false;
657         }
658
659         // INVALID_OPERATION - maxdrawcount greater then parameter buffer size
660         gl.multiDrawElementsIndirectCount(GL_TRIANGLE_STRIP, GL_UNSIGNED_BYTE, 0, 0, 4, 0);
661         errorCode = gl.getError();
662         if (errorCode != GL_INVALID_OPERATION)
663         {
664                 m_testCtx.getLog() << tcu::TestLog::Message
665                                                    << "MultiDrawElementIndirectCount error verifying failed (2). Expected code: "
666                                                    << GL_INVALID_OPERATION << ", current code: " << errorCode << tcu::TestLog::EndMessage;
667                 result = false;
668         }
669
670         gl.bindBuffer(GL_PARAMETER_BUFFER_ARB, 0);
671         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
672
673         // INVALID_OPERATION - GL_PARAMETER_BUFFER_ARB not bound
674         gl.multiDrawElementsIndirectCount(GL_TRIANGLE_STRIP, GL_UNSIGNED_BYTE, 0, 0, 3, 0);
675         errorCode = gl.getError();
676         if (errorCode != GL_INVALID_OPERATION)
677         {
678                 m_testCtx.getLog() << tcu::TestLog::Message
679                                                    << "MultiDrawElementIndirectCount error verifying failed (3). Expected code: "
680                                                    << GL_INVALID_OPERATION << ", current code: " << errorCode << tcu::TestLog::EndMessage;
681                 result = false;
682         }
683
684         return result;
685 }
686
687 /** Constructor.
688  *
689  *  @param context Rendering context.
690  */
691 IndirectParametersTests::IndirectParametersTests(deqp::Context& context)
692         : TestCaseGroup(context, "indirect_parameters_tests",
693                                         "Verify conformance of CTS_ARB_indirect_parameters implementation")
694 {
695 }
696
697 /** Initializes the test group contents. */
698 void IndirectParametersTests::init()
699 {
700         addChild(new ParameterBufferOperationsCase(m_context));
701         addChild(new MultiDrawArraysIndirectCountCase(m_context));
702         addChild(new MultiDrawElementsIndirectCountCase(m_context));
703 }
704
705 } /* gl4cts namespace */