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::__anon63c430160111::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 int samples = getSamples();
368
369 for (;;) {
370 gl.genFramebuffers(1, &framebuffer);
371 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
372 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, width);
373 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, height);
374 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_SAMPLES, samples);
375
376 GLenum status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
377 if (status == GL_FRAMEBUFFER_COMPLETE)
378 break;
379 else
380 {
381 gl.deleteFramebuffers(1, &framebuffer);
382 framebuffer = 0;
383
384 if (status == GL_FRAMEBUFFER_UNSUPPORTED)
385 if (samples >= 2)
386 samples /= 2;
387 else
388 break;
389 else
390 {
391 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected no-attachment framebuffer status");
392 return STOP;
393 }
394 }
395 }
396 if (!framebuffer)
397 {
398 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unable to find a supported no-attachment framebuffer width/height/samples");
399 return STOP;
400 }
401
402 log << TestLog::Message << "Verifying " << width << "x" << height << " framebuffer with " << samples << "x multisampling" << TestLog::EndMessage;
403
404 if(checkFramebufferRenderable(log, m_renderCtx, framebuffer, IVec2(width, height)) && 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,
463 const glu::RenderContext& renderCtx,
464 const char* name,
465 const char* desc,
466 const FboSpec& defaultSpec,
467 const FboSpec& attachmentSpec);
~AttachmentInteractionCase(void)468 virtual ~AttachmentInteractionCase (void) {}
469
470 virtual IterateResult iterate (void);
471
472 private:
473 const glu::RenderContext& m_renderCtx;
474 const FboSpec m_defaultSpec;
475 const FboSpec m_attachmentSpec;
476 };
477
AttachmentInteractionCase(tcu::TestContext & testCtx,const glu::RenderContext & renderCtx,const char * name,const char * desc,const FboSpec & defaultSpec,const FboSpec & attachmentSpec)478 AttachmentInteractionCase::AttachmentInteractionCase (tcu::TestContext& testCtx,
479 const glu::RenderContext& renderCtx,
480 const char* name,
481 const char* desc,
482 const FboSpec& defaultSpec,
483 const FboSpec& attachmentSpec)
484 : TestCase (testCtx, name, desc)
485 , m_renderCtx (renderCtx)
486 , m_defaultSpec (defaultSpec)
487 , m_attachmentSpec (attachmentSpec)
488 {
489 }
490
iterate(void)491 AttachmentInteractionCase::IterateResult AttachmentInteractionCase::iterate (void)
492 {
493 const glw::Functions& gl = m_renderCtx.getFunctions();
494 TestLog& log = m_testCtx.getLog();
495 GLuint framebuffer = 0;
496 GLuint renderbuffer= 0;
497
498 gl.genFramebuffers(1, &framebuffer);
499 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
500 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, m_defaultSpec.width);
501 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, m_defaultSpec.height);
502 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_SAMPLES, m_defaultSpec.samples);
503
504 gl.genRenderbuffers(1, &renderbuffer);
505 gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
506 gl.renderbufferStorageMultisample(GL_RENDERBUFFER, m_attachmentSpec.samples, GL_RGBA8, m_attachmentSpec.width, m_attachmentSpec.height);
507 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
508
509 log << TestLog::Message << "Verifying " << m_attachmentSpec.width << "x" << m_attachmentSpec.height << " framebuffer with " << m_attachmentSpec.samples << "x multisampling"
510 << " and defaults set to " << m_defaultSpec.width << "x" << m_defaultSpec.height << " with " << m_defaultSpec.samples << "x multisampling" << TestLog::EndMessage;
511
512 if(checkFramebufferRenderable(log, m_renderCtx, framebuffer, IVec2(m_attachmentSpec.width, m_attachmentSpec.height))
513 && checkFramebufferSize(log, m_renderCtx, framebuffer, IVec2(m_attachmentSpec.width, m_attachmentSpec.height)))
514 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
515 else
516 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Framebuffer did not behave as expected");
517
518 gl.deleteRenderbuffers(1, &renderbuffer);
519 gl.deleteFramebuffers(1, &framebuffer);
520
521 return STOP;
522 }
523
524 } // Anonymous
525
createFboNoAttachmentTests(Context & context)526 tcu::TestCaseGroup* createFboNoAttachmentTests(Context& context)
527 {
528 const glu::RenderContext& renderCtx = context.getRenderContext();
529 tcu::TestContext& testCtx = context.getTestContext();
530
531 const int maxWidth = 2048; // MAX_FRAMEBUFFER_WIDTH in ES 3.1
532 const int maxHeight = 2048; // MAX_FRAMEBUFFER_HEIGHT in ES 3.1
533 const int maxSamples = 4;
534
535 tcu::TestCaseGroup* const root = new tcu::TestCaseGroup(testCtx, "no_attachments", "Framebuffer without attachments");
536
537 // Size
538 {
539 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "size", "Basic functionality tests with varying default size");
540
541 root->addChild(group);
542
543 for (int width = 16; width <= maxWidth; width *= 4)
544 {
545 for (int height = 16; height <= maxHeight; height *= 4)
546 {
547 const FboSpec spec (width, height, 0);
548 stringstream name;
549
550 name << width << "x" << height;
551
552 group->addChild(new SizeCase(testCtx, renderCtx, name.str().c_str(), name.str().c_str(), spec));
553 }
554 }
555 }
556
557 // NPOT size
558 {
559 const FboSpec specs[] =
560 {
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 = new tcu::TestCaseGroup(testCtx, "npot_size", "Basic functionality with Non-power-of-two size");
588
589 root->addChild(group);
590
591 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(specs); caseNdx++)
592 {
593 const FboSpec& spec = specs[caseNdx];
594 stringstream name;
595
596 name << spec.width << "x" << spec.height;
597
598 group->addChild(new SizeCase(testCtx, renderCtx, name.str().c_str(), name.str().c_str(), spec));
599 }
600 }
601
602 // Multisample
603 {
604 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "multisample", "Basic functionality with multisampled fbo");
605
606 root->addChild(group);
607
608 for (int samples = 0; samples <= maxSamples; samples++)
609 {
610 const FboSpec spec (128, 128, samples);
611 stringstream name;
612
613 name << "samples" << samples;
614
615 group->addChild(new SizeCase(testCtx, renderCtx, name.str().c_str(), name.str().c_str(), spec));
616 }
617 }
618
619 // Randomized
620 {
621 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "random", "Randomized size & multisampling");
622 de::Random rng (0xF0E1E2D3 ^ testCtx.getCommandLine().getBaseSeed());
623
624 root->addChild(group);
625
626 for (int caseNdx = 0; caseNdx < 16; caseNdx++)
627 {
628 const int width = rng.getInt(1, maxWidth);
629 const int height = rng.getInt(1, maxHeight);
630 const int samples = rng.getInt(0, maxSamples);
631 const FboSpec spec (width, height, samples);
632 const string name = de::toString(caseNdx);
633
634 group->addChild(new SizeCase(testCtx, renderCtx, name.c_str(), name.c_str(), spec));
635 }
636 }
637
638 // Normal fbo with defaults set
639 {
640 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "interaction", "Interaction of default parameters with normal fbo");
641
642 root->addChild(group);
643
644 const FboSpec specs[][2] =
645 {
646 { FboSpec(256, 256, 0), FboSpec(128, 128, 1) },
647 { FboSpec(256, 256, 1), FboSpec(128, 128, 0) },
648 { FboSpec(256, 256, 0), FboSpec(512, 512, 2) },
649 { FboSpec(256, 256, 2), FboSpec(128, 512, 0) },
650 { FboSpec(127, 127, 0), FboSpec(129, 129, 0) },
651 { FboSpec(17, 512, 4), FboSpec(16, 16, 2) },
652 { FboSpec(2048, 2048, 4), FboSpec(1, 1, 0) },
653 { FboSpec(1, 1, 0), FboSpec(2048, 2048, 4) },
654 };
655
656 for (int specNdx = 0; specNdx < DE_LENGTH_OF_ARRAY(specs); specNdx++)
657 {
658 const FboSpec& baseSpec = specs[specNdx][0];
659 const FboSpec& altSpec = specs[specNdx][1];
660 stringstream baseSpecName, altSpecName;
661
662 baseSpecName << baseSpec.width << "x" << baseSpec.height << "ms" << baseSpec.samples;
663 altSpecName << altSpec.width << "x" << altSpec.height << "ms" << altSpec.samples;
664
665 {
666 const string name = baseSpecName.str() + "_default_" + altSpecName.str();
667
668 group->addChild(new AttachmentInteractionCase(testCtx, renderCtx, name.c_str(), name.c_str(), altSpec, baseSpec));
669 }
670 }
671 }
672
673 // Maximums
674 {
675 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "maximums", "Maximum dimensions");
676
677 root->addChild(group);
678 group->addChild(new SizeCase(testCtx, renderCtx, "width", "Maximum width", FboSpec(SizeCase::USE_MAXIMUM, 128, 0)));
679 group->addChild(new SizeCase(testCtx, renderCtx, "height", "Maximum height", FboSpec(128, SizeCase::USE_MAXIMUM, 0)));
680 group->addChild(new SizeCase(testCtx, renderCtx, "size", "Maximum size", FboSpec(SizeCase::USE_MAXIMUM, SizeCase::USE_MAXIMUM, 0)));
681 group->addChild(new SizeCase(testCtx, renderCtx, "samples", "Maximum samples", FboSpec(128, 128, SizeCase::USE_MAXIMUM)));
682 group->addChild(new SizeCase(testCtx, renderCtx, "all", "Maximum size & samples", FboSpec(SizeCase::USE_MAXIMUM, SizeCase::USE_MAXIMUM, SizeCase::USE_MAXIMUM)));
683 }
684
685 return root;
686 }
687
createFboNoAttachmentCompletenessTests(Context & context)688 tcu::TestCaseGroup* createFboNoAttachmentCompletenessTests(Context& context)
689 {
690 TestCaseGroup* const group = new TestCaseGroup(context, "completeness", "Completeness tests");
691
692 group->addChild(new FramebufferCompletenessCase(context.getTestContext(), context.getRenderContext(), "no_attachments", "No attachments completeness"));
693
694 return group;
695 }
696
697 } // Functional
698 } // gles31
699 } // deqp
700