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