Fix PIPELINE_STAGE_TOP_OF_PIPE_BIT usage in api tests
[platform/upstream/VK-GL-CTS.git] / modules / gles31 / functional / es31fFboNoAttachmentTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.1 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
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 Framebuffer without attachments (GL_ARB_framebuffer_no_attachments) tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "es31fFboNoAttachmentTests.hpp"
25
26 #include "glwDefs.hpp"
27 #include "glwEnums.hpp"
28 #include "glwFunctions.hpp"
29
30 #include "gluRenderContext.hpp"
31 #include "gluDefs.hpp"
32 #include "gluShaderProgram.hpp"
33
34 #include "tcuTestContext.hpp"
35 #include "tcuVectorType.hpp"
36 #include "tcuVectorUtil.hpp"
37 #include "tcuTestLog.hpp"
38 #include "tcuCommandLine.hpp"
39 #include "tcuResultCollector.hpp"
40
41 #include "deMemory.h"
42 #include "deRandom.hpp"
43 #include "deString.h"
44 #include "deStringUtil.hpp"
45
46 #include <string>
47 #include <vector>
48
49 namespace deqp
50 {
51 namespace gles31
52 {
53 namespace Functional
54 {
55 namespace
56 {
57
58 using namespace glw;
59
60 using tcu::IVec2;
61 using tcu::TestLog;
62
63 using std::stringstream;
64 using std::string;
65 using std::vector;
66
67 bool checkFramebufferSize (TestLog& log, const glu::RenderContext& renderCtx, GLuint framebuffer, const IVec2& size)
68 {
69         const glw::Functions&           gl                              = renderCtx.getFunctions();
70
71         const char* const                       vertexSource    = "#version 310 es\n"
72                                                                                                   "in layout(location = 0) highp vec2 a_position;\n\n"
73                                                                                                   "void main()\n"
74                                                                                                   "{\n"
75                                                                                                   "     gl_Position = vec4(a_position, 0.0, 1.0);\n"
76                                                                                                   "}\n";
77
78         const char* const                       fragmentSource  = "#version 310 es\n"
79                                                                                                   "uniform layout(location = 0) highp ivec2 u_expectedSize;\n"
80                                                                                                   "out layout(location = 0) mediump vec4 f_color;\n\n"
81                                                                                                   "void main()\n"
82                                                                                                   "{\n"
83                                                                                                   "     if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;\n"
84                                                                                                   "     f_color = vec4(1.0, 0.5, 0.25, 1.0);\n"
85                                                                                                   "}\n";
86
87         const glu::ShaderProgram        program                 (renderCtx, glu::makeVtxFragSources(vertexSource, fragmentSource));
88         GLuint                                          query                   = 0;
89         GLuint                                          insidePassed    = 0;
90         GLuint                                          outsideXPassed  = 0;
91         GLuint                                          outsideYPassed  = 0;
92
93         if (!program.isOk())
94                 log << program;
95
96         TCU_CHECK(program.isOk());
97
98         gl.useProgram(program.getProgram());
99         gl.enable(GL_DEPTH_TEST);
100         gl.depthFunc(GL_ALWAYS);
101         gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
102         gl.viewport(0, 0, size.x()*2, size.y()*2); // Oversized viewport so that it will not accidentally limit us to the correct size
103
104         log << TestLog::Message << "Using " << size.x()*2 << "x" << size.y()*2 << " viewport" << TestLog::EndMessage;
105         log << TestLog::Message << "Discarding fragments outside pixel of interest" << TestLog::EndMessage;
106         log << TestLog::Message << "Using occlusion query to check for rendered fragments" << TestLog::EndMessage;
107
108         TCU_CHECK(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
109
110         // Render
111         {
112                 const float data[] =
113                 {
114                          1.0f,  1.0f,
115                          1.0f, -1.0f,
116                         -1.0f,  1.0f,
117                         -1.0f,  1.0f,
118                          1.0f, -1.0f,
119                         -1.0f, -1.0f,
120                 };
121
122                 GLuint vertexArray      = 0;
123                 GLuint vertexBuffer     = 0;
124
125                 gl.genQueries(1, &query);
126                 gl.genVertexArrays(1, &vertexArray);
127                 gl.bindVertexArray(vertexArray);
128
129                 gl.genBuffers(1, &vertexBuffer);
130                 gl.bindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
131                 gl.bufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
132
133                 gl.enableVertexAttribArray(0);
134                 gl.vertexAttribPointer(0, 2, GL_FLOAT, false, 0, DE_NULL);
135
136                 gl.uniform2i(0, size.x()-1, size.y()-1);
137                 gl.beginQuery(GL_ANY_SAMPLES_PASSED, query);
138                 gl.drawArrays(GL_TRIANGLES, 0, 6);
139                 gl.endQuery(GL_ANY_SAMPLES_PASSED);
140                 gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &insidePassed);
141                 log << TestLog::Message << "A fragment was not discarded at (" << size.x()-1 << ", " << size.y()-1 << "). "
142                         << "Occlusion query reports it was " << (insidePassed > 0 ? "rendered." : "not rendered") << TestLog::EndMessage;
143
144                 gl.uniform2i(0, size.x(), size.y()-1);
145                 gl.beginQuery(GL_ANY_SAMPLES_PASSED, query);
146                 gl.drawArrays(GL_TRIANGLES, 0, 6);
147                 gl.endQuery(GL_ANY_SAMPLES_PASSED);
148                 gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &outsideXPassed);
149                 log << TestLog::Message << "A fragment was not discarded at (" << size.x() << ", " << size.y()-1 << "). "
150                         << "Occlusion query reports it was " << (outsideXPassed > 0 ? "rendered." : "not rendered") << TestLog::EndMessage;
151
152                 gl.uniform2i(0, size.x()-1, size.y());
153                 gl.beginQuery(GL_ANY_SAMPLES_PASSED, query);
154                 gl.drawArrays(GL_TRIANGLES, 0, 6);
155                 gl.endQuery(GL_ANY_SAMPLES_PASSED);
156                 gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &outsideYPassed);
157                 log << TestLog::Message << "A fragment was not discarded at (" << size.x()-1 << ", " << size.y() << "). "
158                         << "Occlusion query reports it was " << (outsideYPassed > 0 ? "rendered." : "not rendered") << TestLog::EndMessage;
159
160                 gl.disableVertexAttribArray(0);
161                 gl.bindBuffer(GL_ARRAY_BUFFER, 0);
162                 gl.bindVertexArray(0);
163                 gl.deleteBuffers(1, &vertexBuffer);
164                 gl.deleteVertexArrays(1, &vertexArray);
165         }
166
167         gl.deleteQueries(1, &query);
168
169         GLU_EXPECT_NO_ERROR(gl.getError(), "Query failed");
170
171         return insidePassed && !outsideXPassed && !outsideYPassed;
172 }
173
174 bool checkFramebufferRenderable (TestLog& log, const glu::RenderContext& renderCtx, GLuint framebuffer, const IVec2& size)
175 {
176         const glw::Functions&           gl                              = renderCtx.getFunctions();
177
178         const char* const                       vertexSource    = "#version 310 es\n"
179                                                                                                   "in layout(location = 0) highp vec2 a_position;\n\n"
180                                                                                                   "void main()\n"
181                                                                                                   "{\n"
182                                                                                                   "     gl_Position = vec4(a_position, 0.0, 1.0);\n"
183                                                                                                   "}\n";
184
185         const char* const                       fragmentSource  = "#version 310 es\n"
186                                                                                                   "out layout(location = 0) mediump vec4 f_color;\n\n"
187                                                                                                   "void main()\n"
188                                                                                                   "{\n"
189                                                                                                   "     f_color = vec4(1.0, 0.5, 0.25, 1.0);\n"
190                                                                                                   "}\n";
191
192         const glu::ShaderProgram        program                 (renderCtx, glu::makeVtxFragSources(vertexSource, fragmentSource));
193         GLuint                                          query                   = 0;
194
195         if (!program.isOk())
196                 log << program;
197
198         TCU_CHECK(program.isOk());
199
200         gl.useProgram(program.getProgram());
201         gl.enable(GL_DEPTH_TEST);
202         gl.depthFunc(GL_ALWAYS);
203         gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
204         gl.viewport(0, 0, size.x(), size.y());
205
206         TCU_CHECK(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
207
208         log << TestLog::Message << "Rendering full framebuffer quad with color ouput, verifying output presence with occlusion query" << TestLog::EndMessage;
209
210         // Render
211         {
212                 const float data[] =
213                 {
214                          1.0f,  1.0f,
215                          1.0f, -1.0f,
216                         -1.0f,  1.0f,
217                         -1.0f,  1.0f,
218                          1.0f, -1.0f,
219                         -1.0f, -1.0f,
220                 };
221
222                 GLuint vertexArray      = 0;
223                 GLuint vertexBuffer     = 0;
224
225                 gl.genQueries(1, &query);
226                 gl.genVertexArrays(1, &vertexArray);
227                 gl.bindVertexArray(vertexArray);
228
229                 gl.genBuffers(1, &vertexBuffer);
230                 gl.bindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
231                 gl.bufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
232
233                 gl.enableVertexAttribArray(0);
234                 gl.vertexAttribPointer(0, 2, GL_FLOAT, false, 0, DE_NULL);
235
236                 gl.beginQuery(GL_ANY_SAMPLES_PASSED, query);
237                 gl.drawArrays(GL_TRIANGLES, 0, 6);
238                 gl.endQuery(GL_ANY_SAMPLES_PASSED);
239
240                 gl.disableVertexAttribArray(0);
241                 gl.bindBuffer(GL_ARRAY_BUFFER, 0);
242                 gl.bindVertexArray(0);
243                 gl.deleteBuffers(1, &vertexBuffer);
244                 gl.deleteVertexArrays(1, &vertexArray);
245         }
246
247         // Read
248         {
249                 GLuint passed = 0;
250
251                 gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &passed);
252                 gl.deleteQueries(1, &query);
253
254                 GLU_EXPECT_NO_ERROR(gl.getError(), "Query failed");
255
256                 if (passed)
257                         log << TestLog::Message << "Query passed" << TestLog::EndMessage;
258                 else
259                         log << TestLog::Message << "Query did not pass" << TestLog::EndMessage;
260
261                 return passed != 0;
262         }
263 }
264
265 class FramebufferCompletenessCase : public tcu::TestCase
266 {
267 public:
268                                                                 FramebufferCompletenessCase             (tcu::TestContext&                      testCtx,
269                                                                                                                                  const glu::RenderContext&      renderCtx,
270                                                                                                                                  const char*                            name,
271                                                                                                                                  const char*                            desc);
272         virtual                                         ~FramebufferCompletenessCase     (void) {}
273         virtual IterateResult           iterate                                                 (void);
274
275 private:
276         const glu::RenderContext&       m_renderCtx;
277         tcu::ResultCollector            m_results;
278 };
279
280 FramebufferCompletenessCase::FramebufferCompletenessCase (tcu::TestContext&                     testCtx,
281                                                                                                                   const glu::RenderContext&     renderCtx,
282                                                                                                                   const char*                           name,
283                                                                                                                   const char*                           desc)
284         : TestCase              (testCtx, name, desc)
285         , m_renderCtx   (renderCtx)
286 {
287 }
288
289 FramebufferCompletenessCase::IterateResult FramebufferCompletenessCase::iterate (void)
290 {
291         const glw::Functions&   gl                      = m_renderCtx.getFunctions();
292         GLuint                                  framebuffer     = 0;
293
294         gl.genFramebuffers(1, &framebuffer);
295         gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
296
297         m_results.check(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, "Framebuffer was incorrectly reported as complete when it had no width, height or attachments");
298
299         gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 16);
300         m_results.check(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, "Framebuffer was incorrectly reported as complete when it only had a width");
301
302         gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 16);
303         m_results.check(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Framebuffer not reported as complete when it had width and height set");
304
305         gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
306         m_results.check(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, "Framebuffer was incorrectly reported as complete when it only had a height");
307
308         gl.deleteFramebuffers(1, &framebuffer);
309
310         m_results.setTestContextResult(m_testCtx);
311         return STOP;
312 }
313
314 struct FboSpec
315 {
316         int width;
317         int height;
318         int samples;
319
320         FboSpec(int width_, int height_, int samples_) : width(width_), height(height_), samples(samples_){}
321 };
322
323 class SizeCase : public tcu::TestCase
324 {
325 public:
326                                                                 SizeCase        (tcu::TestContext&                      testCtx,
327                                                                                          const glu::RenderContext&      renderCtx,
328                                                                                          const char*                            name,
329                                                                                          const char*                            desc,
330                                                                                          const FboSpec&                         spec);
331         virtual                                         ~SizeCase       (void) {}
332
333         virtual IterateResult           iterate         (void);
334
335         enum
336         {
337                 USE_MAXIMUM = -1
338         };
339 private:
340         int                                                     getWidth        (void) const;
341         int                                                     getHeight       (void) const;
342         int                                                     getSamples      (void) const;
343
344         const glu::RenderContext&       m_renderCtx;
345
346         const FboSpec                           m_spec;
347 };
348
349 SizeCase::SizeCase (tcu::TestContext&                   testCtx,
350                                         const glu::RenderContext&       renderCtx,
351                                         const char*                                     name,
352                                         const char*                                     desc,
353                                         const FboSpec&                          spec)
354         : TestCase              (testCtx, name, desc)
355         , m_renderCtx   (renderCtx)
356         , m_spec                (spec)
357 {
358 }
359
360 SizeCase::IterateResult SizeCase::iterate (void)
361 {
362         const glw::Functions&   gl                      = m_renderCtx.getFunctions();
363         TestLog&                                log                     = m_testCtx.getLog();
364         GLuint                                  framebuffer     = 0;
365         const int                               width           = getWidth();
366         const int                               height          = getHeight();
367         const int                               samples         = getSamples();
368
369         gl.genFramebuffers(1, &framebuffer);
370         gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
371         gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, width);
372         gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, height);
373         gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_SAMPLES, samples);
374
375         log << TestLog::Message << "Verifying " << width << "x" << height << " framebuffer with " << samples << "x multisampling" << TestLog::EndMessage;
376
377         if(checkFramebufferRenderable(log, m_renderCtx, framebuffer, IVec2(width, height)) && checkFramebufferSize(log, m_renderCtx, framebuffer, IVec2(width, height)))
378                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
379         else
380                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Framebuffer did not behave as expected");
381
382         gl.deleteFramebuffers(1, &framebuffer);
383
384         return STOP;
385 }
386
387 int SizeCase::getWidth (void) const
388 {
389         if (m_spec.width != USE_MAXIMUM)
390                 return m_spec.width;
391         else
392         {
393                 const glw::Functions&   gl              = m_renderCtx.getFunctions();
394                 GLint                                   width   = 0;
395
396                 gl.getIntegerv(GL_MAX_FRAMEBUFFER_WIDTH, &width);
397
398                 return width;
399         }
400 }
401
402 int SizeCase::getHeight (void) const
403 {
404         if (m_spec.height != USE_MAXIMUM)
405                 return m_spec.height;
406         else
407         {
408                 const glw::Functions&   gl              = m_renderCtx.getFunctions();
409                 GLint                                   height  = 0;
410
411                 gl.getIntegerv(GL_MAX_FRAMEBUFFER_HEIGHT, &height);
412
413                 return height;
414         }
415 }
416
417 int SizeCase::getSamples (void) const
418 {
419         if (m_spec.samples != USE_MAXIMUM)
420                 return m_spec.samples;
421         else
422         {
423                 const glw::Functions&   gl              = m_renderCtx.getFunctions();
424                 GLint                                   samples = 0;
425
426                 gl.getIntegerv(GL_MAX_FRAMEBUFFER_SAMPLES, &samples);
427
428                 return samples;
429         }
430 }
431
432 class AttachmentInteractionCase : public tcu::TestCase
433 {
434 public:
435                                                                 AttachmentInteractionCase       (tcu::TestContext&                      testCtx,
436                                                                                                                          const glu::RenderContext&      renderCtx,
437                                                                                                                          const char*                            name,
438                                                                                                                          const char*                            desc,
439                                                                                                                          const FboSpec&                         defaultSpec,
440                                                                                                                          const FboSpec&                         attachmentSpec);
441         virtual                                         ~AttachmentInteractionCase      (void) {}
442
443         virtual IterateResult           iterate                                         (void);
444
445 private:
446         const glu::RenderContext&       m_renderCtx;
447         const FboSpec                           m_defaultSpec;
448         const FboSpec                           m_attachmentSpec;
449 };
450
451 AttachmentInteractionCase::AttachmentInteractionCase (tcu::TestContext&                 testCtx,
452                                                                                                           const glu::RenderContext&     renderCtx,
453                                                                                                           const char*                           name,
454                                                                                                           const char*                           desc,
455                                                                                                           const FboSpec&                        defaultSpec,
456                                                                                                           const FboSpec&                        attachmentSpec)
457         : TestCase                      (testCtx, name, desc)
458         , m_renderCtx           (renderCtx)
459         , m_defaultSpec         (defaultSpec)
460         , m_attachmentSpec      (attachmentSpec)
461 {
462 }
463
464 AttachmentInteractionCase::IterateResult AttachmentInteractionCase::iterate (void)
465 {
466         const glw::Functions&   gl                      = m_renderCtx.getFunctions();
467         TestLog&                                log                     = m_testCtx.getLog();
468         GLuint                                  framebuffer     = 0;
469         GLuint                                  renderbuffer= 0;
470
471         gl.genFramebuffers(1, &framebuffer);
472         gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
473         gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, m_defaultSpec.width);
474         gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, m_defaultSpec.height);
475         gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_SAMPLES, m_defaultSpec.samples);
476
477         gl.genRenderbuffers(1, &renderbuffer);
478         gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
479         gl.renderbufferStorageMultisample(GL_RENDERBUFFER, m_attachmentSpec.samples, GL_RGBA8, m_attachmentSpec.width, m_attachmentSpec.height);
480         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
481
482         log << TestLog::Message << "Verifying " << m_attachmentSpec.width << "x" << m_attachmentSpec.height << " framebuffer with " << m_attachmentSpec.samples << "x multisampling"
483                 << " and defaults set to " << m_defaultSpec.width << "x" << m_defaultSpec.height << " with " << m_defaultSpec.samples << "x multisampling" << TestLog::EndMessage;
484
485         if(checkFramebufferRenderable(log, m_renderCtx, framebuffer, IVec2(m_attachmentSpec.width, m_attachmentSpec.height))
486            && checkFramebufferSize(log, m_renderCtx, framebuffer, IVec2(m_attachmentSpec.width, m_attachmentSpec.height)))
487                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
488         else
489                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Framebuffer did not behave as expected");
490
491         gl.deleteRenderbuffers(1, &renderbuffer);
492         gl.deleteFramebuffers(1, &framebuffer);
493
494         return STOP;
495 }
496
497 } // Anonymous
498
499 tcu::TestCaseGroup* createFboNoAttachmentTests(Context& context)
500 {
501         const glu::RenderContext&       renderCtx       = context.getRenderContext();
502         tcu::TestContext&                       testCtx         = context.getTestContext();
503
504         const int                                       maxWidth        = 2048; // MAX_FRAMEBUFFER_WIDTH in ES 3.1
505         const int                                       maxHeight       = 2048; // MAX_FRAMEBUFFER_HEIGHT in ES 3.1
506         const int                                       maxSamples      = 4;
507
508         tcu::TestCaseGroup* const       root            = new tcu::TestCaseGroup(testCtx, "no_attachments", "Framebuffer without attachments");
509
510         // Size
511         {
512                 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "size", "Basic functionality tests with varying default size");
513
514                 root->addChild(group);
515
516                 for (int width = 16; width <= maxWidth; width *= 4)
517                 {
518                         for (int height = 16; height <= maxHeight; height *= 4)
519                         {
520                                 const FboSpec   spec (width, height, 0);
521                                 stringstream    name;
522
523                                 name << width << "x" << height;
524
525                                 group->addChild(new SizeCase(testCtx, renderCtx, name.str().c_str(), name.str().c_str(), spec));
526                         }
527                 }
528         }
529
530         // NPOT size
531         {
532                 const FboSpec specs[] =
533                 {
534                         // Square
535                         FboSpec(1,    1,    0),
536                         FboSpec(3,    3,    0),
537                         FboSpec(15,   15,   0),
538                         FboSpec(17,   17,   0),
539                         FboSpec(31,   31,   0),
540                         FboSpec(33,   33,   0),
541                         FboSpec(63,   63,   0),
542                         FboSpec(65,   65,   0),
543                         FboSpec(127,  127,  0),
544                         FboSpec(129,  129,  0),
545                         FboSpec(255,  255,  0),
546                         FboSpec(257,  257,  0),
547                         FboSpec(511,  511,  0),
548                         FboSpec(513,  513,  0),
549                         FboSpec(1023, 1023, 0),
550                         FboSpec(1025, 1025, 0),
551                         FboSpec(2047, 2047, 0),
552
553                         // Non-square
554                         FboSpec(15,   511,  0),
555                         FboSpec(127,  15,   0),
556                         FboSpec(129,  127,  0),
557                         FboSpec(511,  127,  0),
558                         FboSpec(2047, 1025, 0),
559                 };
560                 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "npot_size", "Basic functionality with Non-power-of-two size");
561
562                 root->addChild(group);
563
564                 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(specs); caseNdx++)
565                 {
566                         const FboSpec&  spec = specs[caseNdx];
567                         stringstream    name;
568
569                         name << spec.width << "x" << spec.height;
570
571                         group->addChild(new SizeCase(testCtx, renderCtx, name.str().c_str(), name.str().c_str(), spec));
572                 }
573         }
574
575         // Multisample
576         {
577                 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "multisample", "Basic functionality with multisampled fbo");
578
579                 root->addChild(group);
580
581                 for (int samples = 0; samples <= maxSamples; samples++)
582                 {
583                         const FboSpec   spec (128, 128, samples);
584                         stringstream    name;
585
586                         name << "samples" << samples;
587
588                         group->addChild(new SizeCase(testCtx, renderCtx, name.str().c_str(), name.str().c_str(), spec));
589                 }
590         }
591
592         // Randomized
593         {
594                 tcu::TestCaseGroup* const       group   = new tcu::TestCaseGroup(testCtx, "random", "Randomized size & multisampling");
595                 de::Random                                      rng             (0xF0E1E2D3 ^ testCtx.getCommandLine().getBaseSeed());
596
597                 root->addChild(group);
598
599                 for (int caseNdx = 0; caseNdx < 16; caseNdx++)
600                 {
601                         const int               width   = rng.getInt(1, maxWidth);
602                         const int               height  = rng.getInt(1, maxHeight);
603                         const int               samples = rng.getInt(0, maxSamples);
604                         const FboSpec   spec    (width, height, samples);
605                         const string    name    = de::toString(caseNdx);
606
607                         group->addChild(new SizeCase(testCtx, renderCtx, name.c_str(), name.c_str(), spec));
608                 }
609         }
610
611         // Normal fbo with defaults set
612         {
613                 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "interaction", "Interaction of default parameters with normal fbo");
614
615                 root->addChild(group);
616
617                 const FboSpec specs[][2] =
618                 {
619                         { FboSpec(256,  256,  0), FboSpec(128,  128,  1) },
620                         { FboSpec(256,  256,  1), FboSpec(128,  128,  0) },
621                         { FboSpec(256,  256,  0), FboSpec(512,  512,  2) },
622                         { FboSpec(256,  256,  2), FboSpec(128,  512,  0) },
623                         { FboSpec(127,  127,  0), FboSpec(129,  129,  0) },
624                         { FboSpec(17,   512,  4), FboSpec(16,   16,   2) },
625                         { FboSpec(2048, 2048, 4), FboSpec(1,    1,    0) },
626                         { FboSpec(1,    1,    0), FboSpec(2048, 2048, 4) },
627                 };
628
629                 for (int specNdx = 0; specNdx < DE_LENGTH_OF_ARRAY(specs); specNdx++)
630                 {
631                         const FboSpec& baseSpec = specs[specNdx][0];
632                         const FboSpec& altSpec  = specs[specNdx][1];
633                         stringstream baseSpecName, altSpecName;
634
635                         baseSpecName << baseSpec.width << "x" << baseSpec.height << "ms" << baseSpec.samples;
636                         altSpecName << altSpec.width << "x" << altSpec.height << "ms" << altSpec.samples;
637
638                         {
639                                 const string name = baseSpecName.str() + "_default_" + altSpecName.str();
640
641                                 group->addChild(new AttachmentInteractionCase(testCtx, renderCtx, name.c_str(), name.c_str(), altSpec, baseSpec));
642                         }
643                 }
644         }
645
646         // Maximums
647         {
648                 tcu::TestCaseGroup* const       group   = new tcu::TestCaseGroup(testCtx, "maximums", "Maximum dimensions");
649
650                 root->addChild(group);
651                 group->addChild(new SizeCase(testCtx, renderCtx, "width",       "Maximum width",                  FboSpec(SizeCase::USE_MAXIMUM,        128,                                    0)));
652                 group->addChild(new SizeCase(testCtx, renderCtx, "height",      "Maximum height",                 FboSpec(128,                                          SizeCase::USE_MAXIMUM,  0)));
653                 group->addChild(new SizeCase(testCtx, renderCtx, "size",        "Maximum size",                   FboSpec(SizeCase::USE_MAXIMUM,        SizeCase::USE_MAXIMUM,  0)));
654                 group->addChild(new SizeCase(testCtx, renderCtx, "samples", "Maximum samples",            FboSpec(128,                                          128,                                    SizeCase::USE_MAXIMUM)));
655                 group->addChild(new SizeCase(testCtx, renderCtx, "all",         "Maximum size & samples", FboSpec(SizeCase::USE_MAXIMUM,        SizeCase::USE_MAXIMUM,  SizeCase::USE_MAXIMUM)));
656         }
657
658         return root;
659 }
660
661 tcu::TestCaseGroup* createFboNoAttachmentCompletenessTests(Context& context)
662 {
663         TestCaseGroup* const group = new TestCaseGroup(context, "completeness", "Completeness tests");
664
665         group->addChild(new FramebufferCompletenessCase(context.getTestContext(), context.getRenderContext(), "no_attachments", "No attachments completeness"));
666
667         return group;
668 }
669
670 } // Functional
671 } // gles31
672 } // deqp