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
checkFramebufferSize(TestLog & log,const glu::RenderContext & renderCtx,GLuint framebuffer,const IVec2 & size)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
checkFramebufferRenderable(TestLog & log,const glu::RenderContext & renderCtx,GLuint framebuffer,const IVec2 & size)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);
~FramebufferCompletenessCase(void)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
FramebufferCompletenessCase(tcu::TestContext & testCtx,const glu::RenderContext & renderCtx,const char * name,const char * desc)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
iterate(void)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
FboSpecdeqp::gles31::Functional::__anon731108350111::FboSpec320 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);
~SizeCase(void)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
SizeCase(tcu::TestContext & testCtx,const glu::RenderContext & renderCtx,const char * name,const char * desc,const FboSpec & spec)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
iterate(void)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
getWidth(void) const387 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
getHeight(void) const402 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
getSamples(void) const417 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);
~AttachmentInteractionCase(void)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
AttachmentInteractionCase(tcu::TestContext & testCtx,const glu::RenderContext & renderCtx,const char * name,const char * desc,const FboSpec & defaultSpec,const FboSpec & attachmentSpec)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
iterate(void)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
createFboNoAttachmentTests(Context & context)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
createFboNoAttachmentCompletenessTests(Context & context)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
673