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::string;
64 using std::stringstream;
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,
103 size.y() * 2); // Oversized viewport so that it will not accidentally limit us to the correct size
104
105 log << TestLog::Message << "Using " << size.x() * 2 << "x" << size.y() * 2 << " viewport" << TestLog::EndMessage;
106 log << TestLog::Message << "Discarding fragments outside pixel of interest" << TestLog::EndMessage;
107 log << TestLog::Message << "Using occlusion query to check for rendered fragments" << TestLog::EndMessage;
108
109 TCU_CHECK(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
110
111 // Render
112 {
113 const float data[] = {
114 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f,
115 };
116
117 GLuint vertexArray = 0;
118 GLuint vertexBuffer = 0;
119
120 gl.genQueries(1, &query);
121 gl.genVertexArrays(1, &vertexArray);
122 gl.bindVertexArray(vertexArray);
123
124 gl.genBuffers(1, &vertexBuffer);
125 gl.bindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
126 gl.bufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
127
128 gl.enableVertexAttribArray(0);
129 gl.vertexAttribPointer(0, 2, GL_FLOAT, false, 0, DE_NULL);
130
131 gl.uniform2i(0, size.x() - 1, size.y() - 1);
132 gl.beginQuery(GL_ANY_SAMPLES_PASSED, query);
133 gl.drawArrays(GL_TRIANGLES, 0, 6);
134 gl.endQuery(GL_ANY_SAMPLES_PASSED);
135 gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &insidePassed);
136 log << TestLog::Message << "A fragment was not discarded at (" << size.x() - 1 << ", " << size.y() - 1 << "). "
137 << "Occlusion query reports it was " << (insidePassed > 0 ? "rendered." : "not rendered")
138 << TestLog::EndMessage;
139
140 gl.uniform2i(0, size.x(), size.y() - 1);
141 gl.beginQuery(GL_ANY_SAMPLES_PASSED, query);
142 gl.drawArrays(GL_TRIANGLES, 0, 6);
143 gl.endQuery(GL_ANY_SAMPLES_PASSED);
144 gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &outsideXPassed);
145 log << TestLog::Message << "A fragment was not discarded at (" << size.x() << ", " << size.y() - 1 << "). "
146 << "Occlusion query reports it was " << (outsideXPassed > 0 ? "rendered." : "not rendered")
147 << TestLog::EndMessage;
148
149 gl.uniform2i(0, size.x() - 1, size.y());
150 gl.beginQuery(GL_ANY_SAMPLES_PASSED, query);
151 gl.drawArrays(GL_TRIANGLES, 0, 6);
152 gl.endQuery(GL_ANY_SAMPLES_PASSED);
153 gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &outsideYPassed);
154 log << TestLog::Message << "A fragment was not discarded at (" << size.x() - 1 << ", " << size.y() << "). "
155 << "Occlusion query reports it was " << (outsideYPassed > 0 ? "rendered." : "not rendered")
156 << TestLog::EndMessage;
157
158 gl.disableVertexAttribArray(0);
159 gl.bindBuffer(GL_ARRAY_BUFFER, 0);
160 gl.bindVertexArray(0);
161 gl.deleteBuffers(1, &vertexBuffer);
162 gl.deleteVertexArrays(1, &vertexArray);
163 }
164
165 gl.deleteQueries(1, &query);
166
167 GLU_EXPECT_NO_ERROR(gl.getError(), "Query failed");
168
169 return insidePassed && !outsideXPassed && !outsideYPassed;
170 }
171
checkFramebufferRenderable(TestLog & log,const glu::RenderContext & renderCtx,GLuint framebuffer,const IVec2 & size)172 bool checkFramebufferRenderable(TestLog &log, const glu::RenderContext &renderCtx, GLuint framebuffer,
173 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
208 << "Rendering full framebuffer quad with color ouput, verifying output presence with occlusion query"
209 << TestLog::EndMessage;
210
211 // Render
212 {
213 const float data[] = {
214 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f,
215 };
216
217 GLuint vertexArray = 0;
218 GLuint vertexBuffer = 0;
219
220 gl.genQueries(1, &query);
221 gl.genVertexArrays(1, &vertexArray);
222 gl.bindVertexArray(vertexArray);
223
224 gl.genBuffers(1, &vertexBuffer);
225 gl.bindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
226 gl.bufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
227
228 gl.enableVertexAttribArray(0);
229 gl.vertexAttribPointer(0, 2, GL_FLOAT, false, 0, DE_NULL);
230
231 gl.beginQuery(GL_ANY_SAMPLES_PASSED, query);
232 gl.drawArrays(GL_TRIANGLES, 0, 6);
233 gl.endQuery(GL_ANY_SAMPLES_PASSED);
234
235 gl.disableVertexAttribArray(0);
236 gl.bindBuffer(GL_ARRAY_BUFFER, 0);
237 gl.bindVertexArray(0);
238 gl.deleteBuffers(1, &vertexBuffer);
239 gl.deleteVertexArrays(1, &vertexArray);
240 }
241
242 // Read
243 {
244 GLuint passed = 0;
245
246 gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &passed);
247 gl.deleteQueries(1, &query);
248
249 GLU_EXPECT_NO_ERROR(gl.getError(), "Query failed");
250
251 if (passed)
252 log << TestLog::Message << "Query passed" << TestLog::EndMessage;
253 else
254 log << TestLog::Message << "Query did not pass" << TestLog::EndMessage;
255
256 return passed != 0;
257 }
258 }
259
260 class FramebufferCompletenessCase : public tcu::TestCase
261 {
262 public:
263 FramebufferCompletenessCase(tcu::TestContext &testCtx, const glu::RenderContext &renderCtx, const char *name,
264 const char *desc);
~FramebufferCompletenessCase(void)265 virtual ~FramebufferCompletenessCase(void)
266 {
267 }
268 virtual IterateResult iterate(void);
269
270 private:
271 const glu::RenderContext &m_renderCtx;
272 tcu::ResultCollector m_results;
273 };
274
FramebufferCompletenessCase(tcu::TestContext & testCtx,const glu::RenderContext & renderCtx,const char * name,const char * desc)275 FramebufferCompletenessCase::FramebufferCompletenessCase(tcu::TestContext &testCtx, const glu::RenderContext &renderCtx,
276 const char *name, const char *desc)
277 : TestCase(testCtx, name, desc)
278 , m_renderCtx(renderCtx)
279 {
280 }
281
iterate(void)282 FramebufferCompletenessCase::IterateResult FramebufferCompletenessCase::iterate(void)
283 {
284 const glw::Functions &gl = m_renderCtx.getFunctions();
285 GLuint framebuffer = 0;
286
287 gl.genFramebuffers(1, &framebuffer);
288 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
289
290 m_results.check(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
291 "Framebuffer was incorrectly reported as complete when it had no width, height or attachments");
292
293 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 16);
294 m_results.check(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
295 "Framebuffer was incorrectly reported as complete when it only had a width");
296
297 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 16);
298 m_results.check(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE,
299 "Framebuffer not reported as complete when it had width and height set");
300
301 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
302 m_results.check(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
303 "Framebuffer was incorrectly reported as complete when it only had a height");
304
305 gl.deleteFramebuffers(1, &framebuffer);
306
307 m_results.setTestContextResult(m_testCtx);
308 return STOP;
309 }
310
311 struct FboSpec
312 {
313 int width;
314 int height;
315 int samples;
316
FboSpecdeqp::gles31::Functional::__anonec4a052b0111::FboSpec317 FboSpec(int width_, int height_, int samples_) : width(width_), height(height_), samples(samples_)
318 {
319 }
320 };
321
322 class SizeCase : public tcu::TestCase
323 {
324 public:
325 SizeCase(tcu::TestContext &testCtx, const glu::RenderContext &renderCtx, const char *name, const char *desc,
326 const FboSpec &spec);
~SizeCase(void)327 virtual ~SizeCase(void)
328 {
329 }
330
331 virtual IterateResult iterate(void);
332
333 enum
334 {
335 USE_MAXIMUM = -1
336 };
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, const glu::RenderContext &renderCtx, const char *name, const char *desc,
349 const FboSpec &spec)
350 : TestCase(testCtx, name, desc)
351 , m_renderCtx(renderCtx)
352 , m_spec(spec)
353 {
354 }
355
iterate(void)356 SizeCase::IterateResult SizeCase::iterate(void)
357 {
358 const glw::Functions &gl = m_renderCtx.getFunctions();
359 TestLog &log = m_testCtx.getLog();
360 GLuint framebuffer = 0;
361 const int width = getWidth();
362 const int height = getHeight();
363 int samples = getSamples();
364
365 for (;;)
366 {
367 gl.genFramebuffers(1, &framebuffer);
368 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
369 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, width);
370 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, height);
371 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_SAMPLES, samples);
372
373 GLenum status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
374 if (status == GL_FRAMEBUFFER_COMPLETE)
375 break;
376 else
377 {
378 gl.deleteFramebuffers(1, &framebuffer);
379 framebuffer = 0;
380
381 if (status == GL_FRAMEBUFFER_UNSUPPORTED)
382 if (samples >= 2)
383 samples /= 2;
384 else
385 break;
386 else
387 {
388 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected no-attachment framebuffer status");
389 return STOP;
390 }
391 }
392 }
393 if (!framebuffer)
394 {
395 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL,
396 "Unable to find a supported no-attachment framebuffer width/height/samples");
397 return STOP;
398 }
399
400 log << TestLog::Message << "Verifying " << width << "x" << height << " framebuffer with " << samples
401 << "x multisampling" << TestLog::EndMessage;
402
403 if (checkFramebufferRenderable(log, m_renderCtx, framebuffer, IVec2(width, height)) &&
404 checkFramebufferSize(log, m_renderCtx, framebuffer, IVec2(width, height)))
405 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
406 else
407 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Framebuffer did not behave as expected");
408
409 gl.deleteFramebuffers(1, &framebuffer);
410
411 return STOP;
412 }
413
getWidth(void) const414 int SizeCase::getWidth(void) const
415 {
416 if (m_spec.width != USE_MAXIMUM)
417 return m_spec.width;
418 else
419 {
420 const glw::Functions &gl = m_renderCtx.getFunctions();
421 GLint width = 0;
422
423 gl.getIntegerv(GL_MAX_FRAMEBUFFER_WIDTH, &width);
424
425 return width;
426 }
427 }
428
getHeight(void) const429 int SizeCase::getHeight(void) const
430 {
431 if (m_spec.height != USE_MAXIMUM)
432 return m_spec.height;
433 else
434 {
435 const glw::Functions &gl = m_renderCtx.getFunctions();
436 GLint height = 0;
437
438 gl.getIntegerv(GL_MAX_FRAMEBUFFER_HEIGHT, &height);
439
440 return height;
441 }
442 }
443
getSamples(void) const444 int SizeCase::getSamples(void) const
445 {
446 if (m_spec.samples != USE_MAXIMUM)
447 return m_spec.samples;
448 else
449 {
450 const glw::Functions &gl = m_renderCtx.getFunctions();
451 GLint samples = 0;
452
453 gl.getIntegerv(GL_MAX_FRAMEBUFFER_SAMPLES, &samples);
454
455 return samples;
456 }
457 }
458
459 class AttachmentInteractionCase : public tcu::TestCase
460 {
461 public:
462 AttachmentInteractionCase(tcu::TestContext &testCtx, const glu::RenderContext &renderCtx, const char *name,
463 const char *desc, const FboSpec &defaultSpec, const FboSpec &attachmentSpec);
~AttachmentInteractionCase(void)464 virtual ~AttachmentInteractionCase(void)
465 {
466 }
467
468 virtual IterateResult iterate(void);
469
470 private:
471 const glu::RenderContext &m_renderCtx;
472 const FboSpec m_defaultSpec;
473 const FboSpec m_attachmentSpec;
474 };
475
AttachmentInteractionCase(tcu::TestContext & testCtx,const glu::RenderContext & renderCtx,const char * name,const char * desc,const FboSpec & defaultSpec,const FboSpec & attachmentSpec)476 AttachmentInteractionCase::AttachmentInteractionCase(tcu::TestContext &testCtx, const glu::RenderContext &renderCtx,
477 const char *name, const char *desc, const FboSpec &defaultSpec,
478 const FboSpec &attachmentSpec)
479 : TestCase(testCtx, name, desc)
480 , m_renderCtx(renderCtx)
481 , m_defaultSpec(defaultSpec)
482 , m_attachmentSpec(attachmentSpec)
483 {
484 }
485
iterate(void)486 AttachmentInteractionCase::IterateResult AttachmentInteractionCase::iterate(void)
487 {
488 const glw::Functions &gl = m_renderCtx.getFunctions();
489 TestLog &log = m_testCtx.getLog();
490 GLuint framebuffer = 0;
491 GLuint renderbuffer = 0;
492
493 gl.genFramebuffers(1, &framebuffer);
494 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
495 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, m_defaultSpec.width);
496 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, m_defaultSpec.height);
497 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_SAMPLES, m_defaultSpec.samples);
498
499 gl.genRenderbuffers(1, &renderbuffer);
500 gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
501 gl.renderbufferStorageMultisample(GL_RENDERBUFFER, m_attachmentSpec.samples, GL_RGBA8, m_attachmentSpec.width,
502 m_attachmentSpec.height);
503 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
504
505 log << TestLog::Message << "Verifying " << m_attachmentSpec.width << "x" << m_attachmentSpec.height
506 << " framebuffer with " << m_attachmentSpec.samples << "x multisampling"
507 << " and defaults set to " << m_defaultSpec.width << "x" << m_defaultSpec.height << " with "
508 << m_defaultSpec.samples << "x multisampling" << TestLog::EndMessage;
509
510 if (checkFramebufferRenderable(log, m_renderCtx, framebuffer,
511 IVec2(m_attachmentSpec.width, m_attachmentSpec.height)) &&
512 checkFramebufferSize(log, m_renderCtx, framebuffer, IVec2(m_attachmentSpec.width, m_attachmentSpec.height)))
513 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
514 else
515 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Framebuffer did not behave as expected");
516
517 gl.deleteRenderbuffers(1, &renderbuffer);
518 gl.deleteFramebuffers(1, &framebuffer);
519
520 return STOP;
521 }
522
523 } // namespace
524
createFboNoAttachmentTests(Context & context)525 tcu::TestCaseGroup *createFboNoAttachmentTests(Context &context)
526 {
527 const glu::RenderContext &renderCtx = context.getRenderContext();
528 tcu::TestContext &testCtx = context.getTestContext();
529
530 const int maxWidth = 2048; // MAX_FRAMEBUFFER_WIDTH in ES 3.1
531 const int maxHeight = 2048; // MAX_FRAMEBUFFER_HEIGHT in ES 3.1
532 const int maxSamples = 4;
533
534 tcu::TestCaseGroup *const root =
535 new tcu::TestCaseGroup(testCtx, "no_attachments", "Framebuffer without attachments");
536
537 // Size
538 {
539 tcu::TestCaseGroup *const group =
540 new tcu::TestCaseGroup(testCtx, "size", "Basic functionality tests with varying default size");
541
542 root->addChild(group);
543
544 for (int width = 16; width <= maxWidth; width *= 4)
545 {
546 for (int height = 16; height <= maxHeight; height *= 4)
547 {
548 const FboSpec spec(width, height, 0);
549 stringstream name;
550
551 name << width << "x" << height;
552
553 group->addChild(new SizeCase(testCtx, renderCtx, name.str().c_str(), name.str().c_str(), spec));
554 }
555 }
556 }
557
558 // NPOT size
559 {
560 const FboSpec specs[] = {
561 // Square
562 FboSpec(1, 1, 0),
563 FboSpec(3, 3, 0),
564 FboSpec(15, 15, 0),
565 FboSpec(17, 17, 0),
566 FboSpec(31, 31, 0),
567 FboSpec(33, 33, 0),
568 FboSpec(63, 63, 0),
569 FboSpec(65, 65, 0),
570 FboSpec(127, 127, 0),
571 FboSpec(129, 129, 0),
572 FboSpec(255, 255, 0),
573 FboSpec(257, 257, 0),
574 FboSpec(511, 511, 0),
575 FboSpec(513, 513, 0),
576 FboSpec(1023, 1023, 0),
577 FboSpec(1025, 1025, 0),
578 FboSpec(2047, 2047, 0),
579
580 // Non-square
581 FboSpec(15, 511, 0),
582 FboSpec(127, 15, 0),
583 FboSpec(129, 127, 0),
584 FboSpec(511, 127, 0),
585 FboSpec(2047, 1025, 0),
586 };
587 tcu::TestCaseGroup *const group =
588 new tcu::TestCaseGroup(testCtx, "npot_size", "Basic functionality with Non-power-of-two size");
589
590 root->addChild(group);
591
592 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(specs); caseNdx++)
593 {
594 const FboSpec &spec = specs[caseNdx];
595 stringstream name;
596
597 name << spec.width << "x" << spec.height;
598
599 group->addChild(new SizeCase(testCtx, renderCtx, name.str().c_str(), name.str().c_str(), spec));
600 }
601 }
602
603 // Multisample
604 {
605 tcu::TestCaseGroup *const group =
606 new tcu::TestCaseGroup(testCtx, "multisample", "Basic functionality with multisampled fbo");
607
608 root->addChild(group);
609
610 for (int samples = 0; samples <= maxSamples; samples++)
611 {
612 const FboSpec spec(128, 128, samples);
613 stringstream name;
614
615 name << "samples" << samples;
616
617 group->addChild(new SizeCase(testCtx, renderCtx, name.str().c_str(), name.str().c_str(), spec));
618 }
619 }
620
621 // Randomized
622 {
623 tcu::TestCaseGroup *const group = new tcu::TestCaseGroup(testCtx, "random", "Randomized size & multisampling");
624 de::Random rng(0xF0E1E2D3 ^ testCtx.getCommandLine().getBaseSeed());
625
626 root->addChild(group);
627
628 for (int caseNdx = 0; caseNdx < 16; caseNdx++)
629 {
630 const int width = rng.getInt(1, maxWidth);
631 const int height = rng.getInt(1, maxHeight);
632 const int samples = rng.getInt(0, maxSamples);
633 const FboSpec spec(width, height, samples);
634 const string name = de::toString(caseNdx);
635
636 group->addChild(new SizeCase(testCtx, renderCtx, name.c_str(), name.c_str(), spec));
637 }
638 }
639
640 // Normal fbo with defaults set
641 {
642 tcu::TestCaseGroup *const group =
643 new tcu::TestCaseGroup(testCtx, "interaction", "Interaction of default parameters with normal fbo");
644
645 root->addChild(group);
646
647 const FboSpec specs[][2] = {
648 {FboSpec(256, 256, 0), FboSpec(128, 128, 1)}, {FboSpec(256, 256, 1), FboSpec(128, 128, 0)},
649 {FboSpec(256, 256, 0), FboSpec(512, 512, 2)}, {FboSpec(256, 256, 2), FboSpec(128, 512, 0)},
650 {FboSpec(127, 127, 0), FboSpec(129, 129, 0)}, {FboSpec(17, 512, 4), FboSpec(16, 16, 2)},
651 {FboSpec(2048, 2048, 4), FboSpec(1, 1, 0)}, {FboSpec(1, 1, 0), FboSpec(2048, 2048, 4)},
652 };
653
654 for (int specNdx = 0; specNdx < DE_LENGTH_OF_ARRAY(specs); specNdx++)
655 {
656 const FboSpec &baseSpec = specs[specNdx][0];
657 const FboSpec &altSpec = specs[specNdx][1];
658 stringstream baseSpecName, altSpecName;
659
660 baseSpecName << baseSpec.width << "x" << baseSpec.height << "ms" << baseSpec.samples;
661 altSpecName << altSpec.width << "x" << altSpec.height << "ms" << altSpec.samples;
662
663 {
664 const string name = baseSpecName.str() + "_default_" + altSpecName.str();
665
666 group->addChild(
667 new AttachmentInteractionCase(testCtx, renderCtx, name.c_str(), name.c_str(), altSpec, baseSpec));
668 }
669 }
670 }
671
672 // Maximums
673 {
674 tcu::TestCaseGroup *const group = new tcu::TestCaseGroup(testCtx, "maximums", "Maximum dimensions");
675
676 root->addChild(group);
677 group->addChild(
678 new SizeCase(testCtx, renderCtx, "width", "Maximum width", FboSpec(SizeCase::USE_MAXIMUM, 128, 0)));
679 group->addChild(
680 new SizeCase(testCtx, renderCtx, "height", "Maximum height", FboSpec(128, SizeCase::USE_MAXIMUM, 0)));
681 group->addChild(new SizeCase(testCtx, renderCtx, "size", "Maximum size",
682 FboSpec(SizeCase::USE_MAXIMUM, SizeCase::USE_MAXIMUM, 0)));
683 group->addChild(
684 new SizeCase(testCtx, renderCtx, "samples", "Maximum samples", FboSpec(128, 128, SizeCase::USE_MAXIMUM)));
685 group->addChild(new SizeCase(testCtx, renderCtx, "all", "Maximum size & samples",
686 FboSpec(SizeCase::USE_MAXIMUM, SizeCase::USE_MAXIMUM, SizeCase::USE_MAXIMUM)));
687 }
688
689 return root;
690 }
691
createFboNoAttachmentCompletenessTests(Context & context)692 tcu::TestCaseGroup *createFboNoAttachmentCompletenessTests(Context &context)
693 {
694 TestCaseGroup *const group = new TestCaseGroup(context, "completeness", "Completeness tests");
695
696 group->addChild(new FramebufferCompletenessCase(context.getTestContext(), context.getRenderContext(),
697 "no_attachments", "No attachments completeness"));
698
699 return group;
700 }
701
702 } // namespace Functional
703 } // namespace gles31
704 } // namespace deqp
705