xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fPixelBufferObjectTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 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 Pixel Buffer Object tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es3fPixelBufferObjectTests.hpp"
25 
26 #include "tcuTexture.hpp"
27 #include "tcuTextureUtil.hpp"
28 #include "tcuImageCompare.hpp"
29 #include "tcuTestLog.hpp"
30 #include "tcuRenderTarget.hpp"
31 
32 #include "gluTextureUtil.hpp"
33 #include "gluPixelTransfer.hpp"
34 #include "gluShaderProgram.hpp"
35 
36 #include "deRandom.hpp"
37 #include "deString.h"
38 
39 #include <string>
40 #include <sstream>
41 
42 #include "glw.h"
43 
44 using std::string;
45 using std::stringstream;
46 
47 namespace deqp
48 {
49 namespace gles3
50 {
51 namespace Functional
52 {
53 
54 namespace
55 {
56 
57 class ReadPixelsTest : public TestCase
58 {
59 public:
60     struct TestSpec
61     {
62         enum FramebufferType
63         {
64             FRAMEBUFFERTYPE_NATIVE = 0,
65             FRAMEBUFFERTYPE_RENDERBUFFER
66         };
67 
68         string name;
69         string description;
70 
71         bool useColorClear;
72         bool renderTriangles;
73 
74         FramebufferType framebufferType;
75         GLenum renderbufferFormat;
76     };
77 
78     ReadPixelsTest(Context &context, const TestSpec &spec);
79     ~ReadPixelsTest(void);
80 
81     void init(void);
82     void deinit(void);
83 
84     IterateResult iterate(void);
85 
86 private:
87     void renderTriangle(const tcu::Vec3 &a, const tcu::Vec3 &b, const tcu::Vec3 &c);
88     void clearColor(float r, float g, float b, float a);
89 
90     de::Random m_random;
91     tcu::TestLog &m_log;
92     glu::ShaderProgram *m_program;
93 
94     TestSpec::FramebufferType m_framebuffeType;
95 
96     GLenum m_renderbufferFormat;
97     tcu::TextureChannelClass m_texChannelClass;
98 
99     bool m_useColorClears;
100     bool m_renderTriangles;
101 
102     GLfloat m_colorScale;
103 };
104 
ReadPixelsTest(Context & context,const TestSpec & spec)105 ReadPixelsTest::ReadPixelsTest(Context &context, const TestSpec &spec)
106     : TestCase(context, spec.name.c_str(), spec.description.c_str())
107     , m_random(deStringHash(spec.name.c_str()))
108     , m_log(m_testCtx.getLog())
109     , m_program(NULL)
110     , m_framebuffeType(spec.framebufferType)
111     , m_renderbufferFormat(spec.renderbufferFormat)
112     , m_texChannelClass(tcu::TEXTURECHANNELCLASS_LAST)
113     , m_useColorClears(spec.useColorClear)
114     , m_renderTriangles(spec.renderTriangles)
115     , m_colorScale(1.0f)
116 {
117 
118     if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_NATIVE)
119     {
120         m_colorScale = 1.0f;
121     }
122     else if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER)
123     {
124         m_texChannelClass = tcu::getTextureChannelClass(glu::mapGLInternalFormat(spec.renderbufferFormat).type);
125         switch (m_texChannelClass)
126         {
127         case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
128             m_colorScale = 1.0f;
129             break;
130 
131         case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
132             m_colorScale = 100.0f;
133             break;
134 
135         case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
136             m_colorScale = 100.0f;
137             break;
138 
139         case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
140             m_colorScale = 100.0f;
141             break;
142 
143         default:
144             DE_ASSERT(false);
145         }
146     }
147     else
148         DE_ASSERT(false);
149 }
150 
~ReadPixelsTest(void)151 ReadPixelsTest::~ReadPixelsTest(void)
152 {
153 }
154 
init(void)155 void ReadPixelsTest::init(void)
156 {
157     // Check extensions
158     if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER)
159     {
160         bool supported = false;
161 
162         if (m_renderbufferFormat == GL_RGBA16F || m_renderbufferFormat == GL_RG16F)
163         {
164             std::istringstream extensions(std::string((const char *)glGetString(GL_EXTENSIONS)));
165             std::string extension;
166 
167             while (std::getline(extensions, extension, ' '))
168             {
169                 if (extension == "GL_EXT_color_buffer_half_float")
170                 {
171                     supported = true;
172                     break;
173                 }
174                 if (extension == "GL_EXT_color_buffer_float")
175                 {
176                     supported = true;
177                     break;
178                 }
179             }
180         }
181         else if (m_renderbufferFormat == GL_RGBA32F || m_renderbufferFormat == GL_RG32F ||
182                  m_renderbufferFormat == GL_R11F_G11F_B10F)
183         {
184             std::istringstream extensions(std::string((const char *)glGetString(GL_EXTENSIONS)));
185             std::string extension;
186 
187             while (std::getline(extensions, extension, ' '))
188             {
189                 if (extension == "GL_EXT_color_buffer_float")
190                 {
191                     supported = true;
192                     break;
193                 }
194             }
195         }
196         else
197             supported = true;
198 
199         if (!supported)
200             throw tcu::NotSupportedError("Renderbuffer format not supported", "", __FILE__, __LINE__);
201     }
202 
203     std::string outtype = "";
204 
205     if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_NATIVE)
206         outtype = "vec4";
207     else if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER)
208     {
209         switch (m_texChannelClass)
210         {
211         case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
212             outtype = "vec4";
213             break;
214 
215         case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
216             outtype = "ivec4";
217             break;
218 
219         case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
220             outtype = "uvec4";
221             break;
222 
223         case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
224             outtype = "vec4";
225             break;
226 
227         default:
228             DE_ASSERT(false);
229         }
230     }
231     else
232         DE_ASSERT(false);
233 
234     const char *vertexShaderSource = "#version 300 es\n"
235                                      "in mediump vec3 a_position;\n"
236                                      "in mediump vec4 a_color;\n"
237                                      "uniform mediump float u_colorScale;\n"
238                                      "out mediump vec4 v_color;\n"
239                                      "void main(void)\n"
240                                      "{\n"
241                                      "\tgl_Position = vec4(a_position, 1.0);\n"
242                                      "\tv_color = u_colorScale * a_color;\n"
243                                      "}";
244 
245     stringstream fragmentShaderSource;
246 
247     fragmentShaderSource << "#version 300 es\n"
248                             "in mediump vec4 v_color;\n";
249 
250     fragmentShaderSource << "layout (location = 0) out mediump " << outtype
251                          << " o_color;\n"
252                             "void main(void)\n"
253                             "{\n"
254                             "\to_color = "
255                          << outtype
256                          << "(v_color);\n"
257                             "}";
258 
259     m_program = new glu::ShaderProgram(m_context.getRenderContext(),
260                                        glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource.str()));
261 
262     if (!m_program->isOk())
263     {
264         m_log << *m_program;
265         TCU_FAIL("Failed to compile shader");
266     }
267 }
268 
deinit(void)269 void ReadPixelsTest::deinit(void)
270 {
271     if (m_program)
272         delete m_program;
273     m_program = NULL;
274 }
275 
renderTriangle(const tcu::Vec3 & a,const tcu::Vec3 & b,const tcu::Vec3 & c)276 void ReadPixelsTest::renderTriangle(const tcu::Vec3 &a, const tcu::Vec3 &b, const tcu::Vec3 &c)
277 {
278     float positions[3 * 3];
279 
280     positions[0] = a.x();
281     positions[1] = a.y();
282     positions[2] = a.z();
283 
284     positions[3] = b.x();
285     positions[4] = b.y();
286     positions[5] = b.z();
287 
288     positions[6] = c.x();
289     positions[7] = c.y();
290     positions[8] = c.z();
291 
292     float colors[] = {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f};
293 
294     GLU_CHECK_CALL(glUseProgram(m_program->getProgram()));
295 
296     GLuint coordLoc      = (GLuint)-1;
297     GLuint colorLoc      = (GLuint)-1;
298     GLuint colorScaleLoc = (GLuint)-1;
299 
300     colorScaleLoc = glGetUniformLocation(m_program->getProgram(), "u_colorScale");
301     TCU_CHECK(colorScaleLoc != (GLuint)-1);
302 
303     GLU_CHECK_CALL(glUniform1f(colorScaleLoc, m_colorScale));
304 
305     coordLoc = glGetAttribLocation(m_program->getProgram(), "a_position");
306     TCU_CHECK(coordLoc != (GLuint)-1);
307 
308     colorLoc = glGetAttribLocation(m_program->getProgram(), "a_color");
309     TCU_CHECK(colorLoc != (GLuint)-1);
310 
311     GLU_CHECK_CALL(glEnableVertexAttribArray(colorLoc));
312     GLU_CHECK_CALL(glEnableVertexAttribArray(coordLoc));
313 
314     GLU_CHECK_CALL(glVertexAttribPointer(coordLoc, 3, GL_FLOAT, GL_FALSE, 0, positions));
315     GLU_CHECK_CALL(glVertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, 0, colors));
316 
317     GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 3));
318 
319     GLU_CHECK_CALL(glDisableVertexAttribArray(colorLoc));
320     GLU_CHECK_CALL(glDisableVertexAttribArray(coordLoc));
321 }
322 
clearColor(float r,float g,float b,float a)323 void ReadPixelsTest::clearColor(float r, float g, float b, float a)
324 {
325     if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_NATIVE)
326     {
327         GLU_CHECK_CALL(glClearColor(r, g, b, a));
328         GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
329     }
330     else if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER)
331     {
332         switch (m_texChannelClass)
333         {
334         case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
335         {
336             GLU_CHECK_CALL(glClearColor(r, g, b, a));
337             GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
338             break;
339         }
340 
341         case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
342         {
343             GLint color[4] = {(GLint)r, (GLint)g, (GLint)b, (GLint)a};
344 
345             GLU_CHECK_CALL(glClearBufferiv(GL_COLOR, 0, color));
346             break;
347         }
348 
349         case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
350         {
351             GLuint color[4] = {(GLuint)r, (GLuint)g, (GLuint)b, (GLuint)a};
352 
353             GLU_CHECK_CALL(glClearBufferuiv(GL_COLOR, 0, color));
354             break;
355         }
356 
357         case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
358         {
359             GLfloat color[4] = {(GLfloat)r, (GLfloat)g, (GLfloat)b, (GLfloat)a};
360 
361             GLU_CHECK_CALL(glClearBufferfv(GL_COLOR, 0, color));
362             break;
363         }
364 
365         default:
366             DE_ASSERT(false);
367         }
368     }
369     else
370         DE_ASSERT(false);
371 }
372 
iterate(void)373 TestCase::IterateResult ReadPixelsTest::iterate(void)
374 {
375     int width  = m_context.getRenderTarget().getWidth();
376     int height = m_context.getRenderTarget().getHeight();
377 
378     GLuint framebuffer  = 0;
379     GLuint renderbuffer = 0;
380 
381     switch (m_framebuffeType)
382     {
383     case TestSpec::FRAMEBUFFERTYPE_NATIVE:
384         GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
385         break;
386 
387     case TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER:
388     {
389         GLU_CHECK_CALL(glGenFramebuffers(1, &framebuffer));
390         GLU_CHECK_CALL(glGenRenderbuffers(1, &renderbuffer));
391 
392         GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer));
393         GLU_CHECK_CALL(glRenderbufferStorage(GL_RENDERBUFFER, m_renderbufferFormat, width, height));
394 
395         GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
396         GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer));
397 
398         break;
399     }
400 
401     default:
402         DE_ASSERT(false);
403     }
404 
405     clearColor(m_colorScale * 0.4f, m_colorScale * 1.0f, m_colorScale * 0.5f, m_colorScale * 1.0f);
406 
407     if (m_useColorClears)
408     {
409         const int maxClearCount = 10;
410         const int minClearCount = 6;
411         const int minClearSize  = 15;
412 
413         int clearCount = m_random.getInt(minClearCount, maxClearCount);
414 
415         for (int clearNdx = 0; clearNdx < clearCount; clearNdx++)
416         {
417             int clearX = m_random.getInt(0, width - minClearSize);
418             int clearY = m_random.getInt(0, height - minClearSize);
419 
420             int clearWidth  = m_random.getInt(minClearSize, width - clearX);
421             int clearHeight = m_random.getInt(minClearSize, height - clearY);
422 
423             float clearRed   = m_colorScale * m_random.getFloat();
424             float clearGreen = m_colorScale * m_random.getFloat();
425             float clearBlue  = m_colorScale * m_random.getFloat();
426             float clearAlpha = m_colorScale * (0.5f + 0.5f * m_random.getFloat());
427 
428             GLU_CHECK_CALL(glEnable(GL_SCISSOR_TEST));
429             GLU_CHECK_CALL(glScissor(clearX, clearY, clearWidth, clearHeight));
430 
431             clearColor(clearRed, clearGreen, clearBlue, clearAlpha);
432         }
433 
434         GLU_CHECK_CALL(glDisable(GL_SCISSOR_TEST));
435     }
436 
437     if (m_renderTriangles)
438     {
439         const int minTriangleCount = 4;
440         const int maxTriangleCount = 10;
441 
442         int triangleCount = m_random.getInt(minTriangleCount, maxTriangleCount);
443 
444         for (int triangleNdx = 0; triangleNdx < triangleCount; triangleNdx++)
445         {
446             float x1 = 2.0f * m_random.getFloat() - 1.0f;
447             float y1 = 2.0f * m_random.getFloat() - 1.0f;
448             float z1 = 2.0f * m_random.getFloat() - 1.0f;
449 
450             float x2 = 2.0f * m_random.getFloat() - 1.0f;
451             float y2 = 2.0f * m_random.getFloat() - 1.0f;
452             float z2 = 2.0f * m_random.getFloat() - 1.0f;
453 
454             float x3 = 2.0f * m_random.getFloat() - 1.0f;
455             float y3 = 2.0f * m_random.getFloat() - 1.0f;
456             float z3 = 2.0f * m_random.getFloat() - 1.0f;
457 
458             renderTriangle(tcu::Vec3(x1, y1, z1), tcu::Vec3(x2, y2, z2), tcu::Vec3(x3, y3, z3));
459         }
460     }
461 
462     tcu::TextureFormat readFormat;
463     GLenum readPixelsFormat;
464     GLenum readPixelsType;
465     bool floatCompare;
466 
467     if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_NATIVE)
468     {
469         readFormat       = glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
470         readPixelsFormat = GL_RGBA;
471         readPixelsType   = GL_UNSIGNED_BYTE;
472         floatCompare     = false;
473     }
474     else if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER)
475     {
476         switch (m_texChannelClass)
477         {
478         case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
479             readFormat       = glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
480             readPixelsFormat = GL_RGBA;
481             readPixelsType   = GL_UNSIGNED_BYTE;
482             floatCompare     = true;
483             break;
484 
485         case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
486             readFormat       = glu::mapGLTransferFormat(GL_RGBA_INTEGER, GL_INT);
487             readPixelsFormat = GL_RGBA_INTEGER;
488             readPixelsType   = GL_INT;
489             floatCompare     = false;
490             break;
491 
492         case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
493             readFormat       = glu::mapGLTransferFormat(GL_RGBA_INTEGER, GL_UNSIGNED_INT);
494             readPixelsFormat = GL_RGBA_INTEGER;
495             readPixelsType   = GL_UNSIGNED_INT;
496             floatCompare     = false;
497             break;
498 
499         case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
500             readFormat       = glu::mapGLTransferFormat(GL_RGBA, GL_FLOAT);
501             readPixelsFormat = GL_RGBA;
502             readPixelsType   = GL_FLOAT;
503             floatCompare     = true;
504             break;
505 
506         default:
507             DE_ASSERT(false);
508             // Silence warnings
509             readFormat       = glu::mapGLTransferFormat(GL_RGBA, GL_FLOAT);
510             readPixelsFormat = GL_RGBA;
511             readPixelsType   = GL_FLOAT;
512             floatCompare     = true;
513         }
514     }
515     else
516     {
517         // Silence warnings
518         readFormat       = glu::mapGLTransferFormat(GL_RGBA, GL_FLOAT);
519         readPixelsFormat = GL_RGBA;
520         readPixelsType   = GL_FLOAT;
521         floatCompare     = true;
522         DE_ASSERT(false);
523     }
524 
525     tcu::Texture2D readRefrence(readFormat, width, height);
526     const int readDataSize = readRefrence.getWidth() * readRefrence.getHeight() * readFormat.getPixelSize();
527 
528     readRefrence.allocLevel(0);
529 
530     GLuint pixelBuffer = (GLuint)-1;
531 
532     GLU_CHECK_CALL(glGenBuffers(1, &pixelBuffer));
533     GLU_CHECK_CALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, pixelBuffer));
534     GLU_CHECK_CALL(glBufferData(GL_PIXEL_PACK_BUFFER, readDataSize, NULL, GL_STREAM_READ));
535 
536     GLU_CHECK_CALL(glReadPixels(0, 0, width, height, readPixelsFormat, readPixelsType, 0));
537 
538     const uint8_t *bufferData =
539         (const uint8_t *)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, readDataSize, GL_MAP_READ_BIT);
540     GLU_CHECK_MSG("glMapBufferRange() failed");
541 
542     tcu::ConstPixelBufferAccess readResult(readFormat, width, height, 1, bufferData);
543 
544     GLU_CHECK_CALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
545 
546     GLU_CHECK_CALL(
547         glReadPixels(0, 0, width, height, readPixelsFormat, readPixelsType, readRefrence.getLevel(0).getDataPtr()));
548 
549     if (framebuffer)
550         GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer));
551 
552     if (renderbuffer)
553         GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer));
554 
555     bool isOk = false;
556 
557     if (floatCompare)
558     {
559         const tcu::IVec4 formatBitDepths = tcu::getTextureFormatBitDepth(readFormat);
560         const float redThreshold =
561             2.0f / (float)(1 << deMin32(m_context.getRenderTarget().getPixelFormat().redBits, formatBitDepths.x()));
562         const float greenThreshold =
563             2.0f / (float)(1 << deMin32(m_context.getRenderTarget().getPixelFormat().greenBits, formatBitDepths.y()));
564         const float blueThreshold =
565             2.0f / (float)(1 << deMin32(m_context.getRenderTarget().getPixelFormat().blueBits, formatBitDepths.z()));
566         const float alphaThreshold =
567             2.0f / (float)(1 << deMin32(m_context.getRenderTarget().getPixelFormat().alphaBits, formatBitDepths.w()));
568 
569         isOk = tcu::floatThresholdCompare(
570             m_log, "Result comparision",
571             "Result of read pixels to memory compared with result of read pixels to buffer", readRefrence.getLevel(0),
572             readResult, tcu::Vec4(redThreshold, greenThreshold, blueThreshold, alphaThreshold),
573             tcu::COMPARE_LOG_RESULT);
574     }
575     else
576     {
577         isOk = tcu::intThresholdCompare(m_log, "Result comparision",
578                                         "Result of read pixels to memory compared with result of read pixels to buffer",
579                                         readRefrence.getLevel(0), readResult, tcu::UVec4(0, 0, 0, 0),
580                                         tcu::COMPARE_LOG_RESULT);
581     }
582 
583     GLU_CHECK_CALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, pixelBuffer));
584     GLU_CHECK_CALL(glUnmapBuffer(GL_PIXEL_PACK_BUFFER));
585     GLU_CHECK_CALL(glDeleteBuffers(1, &pixelBuffer));
586 
587     if (isOk)
588     {
589         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
590         return STOP;
591     }
592     else
593     {
594         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
595         return STOP;
596     }
597 }
598 
599 } // namespace
600 
PixelBufferObjectTests(Context & context)601 PixelBufferObjectTests::PixelBufferObjectTests(Context &context)
602     : TestCaseGroup(context, "pbo", "Pixel buffer objects tests")
603 {
604 }
605 
~PixelBufferObjectTests(void)606 PixelBufferObjectTests::~PixelBufferObjectTests(void)
607 {
608 }
609 
init(void)610 void PixelBufferObjectTests::init(void)
611 {
612     TestCaseGroup *nativeFramebufferGroup =
613         new TestCaseGroup(m_context, "native", "Tests with reading from native framebuffer");
614 
615     ReadPixelsTest::TestSpec nativeFramebufferTests[] = {
616         {"clears", "Simple read pixels test with color clears", true, false,
617          ReadPixelsTest::TestSpec::FRAMEBUFFERTYPE_NATIVE, GL_NONE},
618         {"triangles", "Simple read pixels test rendering triangles", false, true,
619          ReadPixelsTest::TestSpec::FRAMEBUFFERTYPE_NATIVE, GL_NONE}};
620 
621     for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(nativeFramebufferTests); testNdx++)
622     {
623         nativeFramebufferGroup->addChild(new ReadPixelsTest(m_context, nativeFramebufferTests[testNdx]));
624     }
625 
626     addChild(nativeFramebufferGroup);
627 
628     TestCaseGroup *renderbufferGroup =
629         new TestCaseGroup(m_context, "renderbuffer", "Tests with reading from renderbuffer");
630 
631     GLenum renderbufferFormats[] = {GL_RGBA8,
632                                     GL_RGBA8I,
633                                     GL_RGBA8UI,
634                                     GL_RGBA16F,
635                                     GL_RGBA16I,
636                                     GL_RGBA16UI,
637                                     GL_RGBA32F,
638                                     GL_RGBA32I,
639                                     GL_RGBA32UI,
640 
641                                     GL_SRGB8_ALPHA8,
642                                     GL_RGB10_A2,
643                                     GL_RGB10_A2UI,
644                                     GL_RGBA4,
645                                     GL_RGB5_A1,
646 
647                                     GL_RGB8,
648                                     GL_RGB565,
649 
650                                     GL_R11F_G11F_B10F,
651 
652                                     GL_RG8,
653                                     GL_RG8I,
654                                     GL_RG8UI,
655                                     GL_RG16F,
656                                     GL_RG16I,
657                                     GL_RG16UI,
658                                     GL_RG32F,
659                                     GL_RG32I,
660                                     GL_RG32UI};
661 
662     const char *renderbufferFormatsStr[] = {"rgba8",
663                                             "rgba8i",
664                                             "rgba8ui",
665                                             "rgba16f",
666                                             "rgba16i",
667                                             "rgba16ui",
668                                             "rgba32f",
669                                             "rgba32i",
670                                             "rgba32ui",
671 
672                                             "srgb8_alpha8",
673                                             "rgb10_a2",
674                                             "rgb10_a2ui",
675                                             "rgba4",
676                                             "rgb5_a1",
677 
678                                             "rgb8",
679                                             "rgb565",
680 
681                                             "r11f_g11f_b10f",
682 
683                                             "rg8",
684                                             "rg8i",
685                                             "rg8ui",
686                                             "rg16f",
687                                             "rg16i",
688                                             "rg16ui",
689                                             "rg32f",
690                                             "rg32i",
691                                             "rg32ui"};
692 
693     DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(renderbufferFormatsStr) == DE_LENGTH_OF_ARRAY(renderbufferFormats));
694 
695     for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(renderbufferFormats); formatNdx++)
696     {
697         for (int trianglesClears = 0; trianglesClears < 2; trianglesClears++)
698         {
699             ReadPixelsTest::TestSpec testSpec;
700 
701             testSpec.name =
702                 string(renderbufferFormatsStr[formatNdx]) + "_" + (trianglesClears == 0 ? "triangles" : "clears");
703             testSpec.description        = testSpec.name;
704             testSpec.useColorClear      = trianglesClears == 1;
705             testSpec.renderTriangles    = trianglesClears == 0;
706             testSpec.framebufferType    = ReadPixelsTest::TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER;
707             testSpec.renderbufferFormat = renderbufferFormats[formatNdx];
708 
709             renderbufferGroup->addChild(new ReadPixelsTest(m_context, testSpec));
710         }
711     }
712 
713     addChild(renderbufferGroup);
714 }
715 
716 } // namespace Functional
717 } // namespace gles3
718 } // namespace deqp
719