Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / modules / gles31 / functional / es31fShaderFramebufferFetchTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.1 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2017 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 EXT Shader Framebuffer Fetch Tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "es31fShaderFramebufferFetchTests.hpp"
25 #include "es31fFboTestUtil.hpp"
26
27 #include "tcuTestLog.hpp"
28 #include "tcuSurface.hpp"
29 #include "tcuTextureUtil.hpp"
30 #include "tcuImageCompare.hpp"
31 #include "tcuVectorUtil.hpp"
32
33 #include "gluShaderProgram.hpp"
34 #include "gluPixelTransfer.hpp"
35 #include "gluTextureUtil.hpp"
36 #include "gluContextInfo.hpp"
37 #include "gluObjectWrapper.hpp"
38
39 #include "glwFunctions.hpp"
40 #include "glwEnums.hpp"
41
42 #include "deStringUtil.hpp"
43
44 #include <vector>
45
46 namespace deqp
47 {
48 namespace gles31
49 {
50 namespace Functional
51 {
52 namespace
53 {
54
55 using std::vector;
56 using std::string;
57 using tcu::TestLog;
58
59 using namespace glw;
60 using namespace FboTestUtil;
61
62 static void checkExtensionSupport (Context& context, const char* extName)
63 {
64         if (!context.getContextInfo().isExtensionSupported(extName))
65                 throw tcu::NotSupportedError(string(extName) + " not supported");
66 }
67
68 static void checkFramebufferFetchSupport (Context& context)
69 {
70         checkExtensionSupport(context, "GL_EXT_shader_framebuffer_fetch");
71 }
72
73 static bool isRequiredFormat (deUint32 format, glu::RenderContext& renderContext)
74 {
75         const bool isES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
76         switch (format)
77         {
78                 // Color-renderable formats
79                 case GL_RGBA32I:
80                 case GL_RGBA32UI:
81                 case GL_RGBA16I:
82                 case GL_RGBA16UI:
83                 case GL_RGBA8:
84                 case GL_RGBA8I:
85                 case GL_RGBA8UI:
86                 case GL_SRGB8_ALPHA8:
87                 case GL_RGB10_A2:
88                 case GL_RGB10_A2UI:
89                 case GL_RGBA4:
90                 case GL_RGB5_A1:
91                 case GL_RGB8:
92                 case GL_RGB565:
93                 case GL_RG32I:
94                 case GL_RG32UI:
95                 case GL_RG16I:
96                 case GL_RG16UI:
97                 case GL_RG8:
98                 case GL_RG8I:
99                 case GL_RG8UI:
100                 case GL_R32I:
101                 case GL_R32UI:
102                 case GL_R16I:
103                 case GL_R16UI:
104                 case GL_R8:
105                 case GL_R8I:
106                 case GL_R8UI:
107                         return true;
108
109                 // Float format
110                 case GL_RGBA32F:
111                 case GL_RGB32F:
112                 case GL_R11F_G11F_B10F:
113                 case GL_RG32F:
114                 case GL_R32F:
115                         return isES32;
116
117                 default:
118                         return false;
119         }
120 }
121
122 tcu::TextureFormat getReadPixelFormat (const tcu::TextureFormat& format)
123 {
124         switch (tcu::getTextureChannelClass(format.type))
125         {
126                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
127                         return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32);
128
129                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
130                         return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32);
131
132                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
133                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
134                         return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
135
136                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
137                         return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT);
138
139                 default:
140                         DE_ASSERT(false);
141                         return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
142         }
143 }
144
145 tcu::Vec4 getFixedPointFormatThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat)
146 {
147         DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
148         DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
149
150         DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
151         DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
152
153         DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
154         DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
155
156         const tcu::IVec4        srcBits         = tcu::getTextureFormatBitDepth(sourceFormat);
157         const tcu::IVec4        readBits        = tcu::getTextureFormatBitDepth(readPixelsFormat);
158
159         return tcu::Vec4(3.0f) / ((tcu::Vector<deUint64, 4>(1) << (tcu::min(srcBits, readBits).cast<deUint64>())) - tcu::Vector<deUint64, 4>(1)).cast<float>();
160 }
161
162 tcu::UVec4 getFloatULPThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat)
163 {
164         const tcu::IVec4        srcMantissaBits         = tcu::getTextureFormatMantissaBitDepth(sourceFormat);
165         const tcu::IVec4        readMantissaBits        = tcu::getTextureFormatMantissaBitDepth(readPixelsFormat);
166         tcu::IVec4                      ULPDiff(0);
167
168         for (int i = 0; i < 4; i++)
169                 if (readMantissaBits[i] >= srcMantissaBits[i])
170                         ULPDiff[i] = readMantissaBits[i] - srcMantissaBits[i];
171
172         return tcu::UVec4(4) * (tcu::UVec4(1) << (ULPDiff.cast<deUint32>()));
173 }
174
175 static bool isAnyExtensionSupported (Context& context, const std::vector<std::string>& requiredExts)
176 {
177         for (std::vector<std::string>::const_iterator iter = requiredExts.begin(); iter != requiredExts.end(); iter++)
178         {
179                 const std::string& extension = *iter;
180
181                 if (context.getContextInfo().isExtensionSupported(extension.c_str()))
182                         return true;
183         }
184
185         return false;
186 }
187
188 static std::string getColorOutputType(tcu::TextureFormat format)
189 {
190         switch (tcu::getTextureChannelClass(format.type))
191         {
192                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:         return "uvec4";
193                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:           return "ivec4";
194                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
195                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
196                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:           return "vec4";
197                 default:
198                         DE_FATAL("Unsupported TEXTURECHANNELCLASS");
199                         return "";
200         }
201 }
202
203 static std::vector<std::string> getEnablingExtensions (deUint32 format, glu::RenderContext& renderContext)
204 {
205         const bool                                      isES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
206         std::vector<std::string>        out;
207
208         DE_ASSERT(!isRequiredFormat(format, renderContext));
209
210         switch (format)
211         {
212                 case GL_RGB16F:
213                         out.push_back("GL_EXT_color_buffer_half_float");
214                         break;
215
216                 case GL_RGBA16F:
217                 case GL_RG16F:
218                 case GL_R16F:
219                         out.push_back("GL_EXT_color_buffer_half_float");
220                 // Fallthrough
221
222                 case GL_RGBA32F:
223                 case GL_RGB32F:
224                 case GL_R11F_G11F_B10F:
225                 case GL_RG32F:
226                 case GL_R32F:
227                         if (!isES32)
228                                 out.push_back("GL_EXT_color_buffer_float");
229                         break;
230
231                 default:
232                         break;
233         }
234
235         return out;
236 }
237
238 void checkFormatSupport (Context& context, deUint32 sizedFormat)
239 {
240         const bool                                              isCoreFormat    = isRequiredFormat(sizedFormat, context.getRenderContext());
241         const std::vector<std::string>  requiredExts    = (!isCoreFormat) ? getEnablingExtensions(sizedFormat, context.getRenderContext()) : std::vector<std::string>();
242
243         // Check that we don't try to use invalid formats.
244         DE_ASSERT(isCoreFormat || !requiredExts.empty());
245
246         if (!requiredExts.empty() && !isAnyExtensionSupported(context, requiredExts))
247                 throw tcu::NotSupportedError("Format not supported");
248 }
249
250 tcu::Vec4 scaleColorValue (tcu::TextureFormat format, const tcu::Vec4& color)
251 {
252         const tcu::TextureFormatInfo    fmtInfo                 = tcu::getTextureFormatInfo(format);
253         const tcu::Vec4                                 cScale                  = fmtInfo.valueMax-fmtInfo.valueMin;
254         const tcu::Vec4                                 cBias                   = fmtInfo.valueMin;
255
256         return tcu::RGBA(color).toVec() * cScale + cBias;
257 }
258
259 // Base class for framebuffer fetch test cases
260
261 class FramebufferFetchTestCase : public TestCase
262 {
263 public:
264                                                                         FramebufferFetchTestCase                (Context& context, const char* name, const char* desc, deUint32 format);
265                                                                         ~FramebufferFetchTestCase               (void);
266
267         void                                                    init                                                    (void);
268         void                                                    deinit                                                  (void);
269
270 protected:
271         string                                                  genPassThroughVertSource                (void);
272         virtual glu::ProgramSources             genShaderSources                                (void);
273
274         void                                                    genFramebufferWithTexture               (const tcu::Vec4& color);
275         void                                                    genAttachementTexture                   (const tcu::Vec4& color);
276         void                                                    genUniformColor                                 (const tcu::Vec4& color);
277
278         void                                                    render                                                  (void);
279         void                                                    verifyRenderbuffer                              (TestLog& log, const tcu::TextureFormat& format, const tcu::TextureLevel& reference, const tcu::TextureLevel& result);
280
281         const glw::Functions&                   m_gl;
282         const deUint32                                  m_format;
283
284         glu::ShaderProgram*                             m_program;
285         GLuint                                                  m_framebuffer;
286         GLuint                                                  m_texColorBuffer;
287
288         tcu::TextureFormat                              m_texFmt;
289         glu::TransferFormat                             m_transferFmt;
290         bool                                                    m_isFilterable;
291
292         enum
293         {
294                 VIEWPORT_WIDTH  = 64,
295                 VIEWPORT_HEIGHT = 64,
296         };
297 };
298
299 FramebufferFetchTestCase::FramebufferFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format)
300         : TestCase (context, name, desc)
301         , m_gl                                  (m_context.getRenderContext().getFunctions())
302         , m_format                              (format)
303         , m_program                             (DE_NULL)
304         , m_framebuffer                 (0)
305         , m_texColorBuffer              (0)
306         , m_texFmt                              (glu::mapGLInternalFormat(m_format))
307         , m_transferFmt                 (glu::getTransferFormat(m_texFmt))
308         , m_isFilterable                (glu::isGLInternalColorFormatFilterable(m_format))
309 {
310 }
311
312 FramebufferFetchTestCase::~FramebufferFetchTestCase (void)
313 {
314         FramebufferFetchTestCase::deinit();
315 }
316
317 void FramebufferFetchTestCase::init (void)
318 {
319         checkFramebufferFetchSupport (m_context);
320         checkFormatSupport(m_context, m_format);
321
322         if (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)) && tcu::isSRGB(m_texFmt)) {
323                 m_gl.enable(GL_FRAMEBUFFER_SRGB);
324         }
325
326         DE_ASSERT(!m_program);
327         m_program = new glu::ShaderProgram(m_context.getRenderContext(), genShaderSources());
328
329         m_testCtx.getLog() << *m_program;
330
331         if (!m_program->isOk())
332         {
333                 delete m_program;
334                 m_program = DE_NULL;
335                 TCU_FAIL("Failed to compile shader program");
336         }
337
338         m_gl.useProgram(m_program->getProgram());
339 }
340
341 void FramebufferFetchTestCase::deinit (void)
342 {
343         delete m_program;
344         m_program = DE_NULL;
345
346         if (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))) {
347                 m_gl.disable(GL_FRAMEBUFFER_SRGB);
348         }
349
350         if (m_framebuffer)
351         {
352                 m_gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
353                 m_gl.deleteFramebuffers(1, &m_framebuffer);
354                 m_framebuffer = 0;
355         }
356
357         if (m_texColorBuffer)
358         {
359                 m_gl.deleteTextures(1, &m_texColorBuffer);
360                 m_texColorBuffer = 0;
361         }
362 }
363
364 string FramebufferFetchTestCase::genPassThroughVertSource (void)
365 {
366         std::ostringstream vertShaderSource;
367
368         vertShaderSource        << "#version 310 es\n"
369                                                 << "in highp vec4 a_position;\n"
370                                                 << "\n"
371                                                 << "void main (void)\n"
372                                                 << "{\n"
373                                                 << "    gl_Position = a_position;\n"
374                                                 << "}\n";
375
376         return vertShaderSource.str();
377 }
378
379 glu::ProgramSources FramebufferFetchTestCase::genShaderSources (void)
380 {
381         const string                            vecType = getColorOutputType(m_texFmt);
382         std::ostringstream                      fragShaderSource;
383         tcu::TextureChannelClass        textureChannelClass = tcu::getTextureChannelClass(m_texFmt.type);
384         tcu::Vec4                                       maxValue = getTextureFormatInfo(m_texFmt).valueMax;
385         tcu::Vec4                                       minValue = getTextureFormatInfo(m_texFmt).valueMin;
386         string                                          maxStr;
387         string                                          minStr;
388
389         if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
390         {
391                 maxStr = de::toString(maxValue.asUint());
392                 minStr = de::toString(minValue.asUint());
393         }
394         else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
395         {
396                 maxStr = de::toString(maxValue.asInt());
397                 minStr = de::toString(minValue.asInt());
398         }
399         else
400         {
401                 maxStr = de::toString(maxValue);
402                 minStr = de::toString(minValue);
403         }
404
405         fragShaderSource        << "#version 310 es\n"
406                                                 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
407                                                 << "layout(location = 0) inout highp " << vecType << " o_color;\n"
408                                                 << "uniform highp " << vecType << " u_color;\n"
409                                                 << "\n"
410                                                 << "void main (void)\n"
411                                                 << "{\n"
412                                                 << "    o_color = clamp(o_color + u_color, " << vecType << minStr << ", " << vecType << maxStr << ");\n"
413                                                 << "}\n";
414
415         return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
416 }
417
418 void FramebufferFetchTestCase::genFramebufferWithTexture (const tcu::Vec4& color)
419 {
420         m_gl.genFramebuffers(1, &m_framebuffer);
421         m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
422
423         genAttachementTexture(color);
424         GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachementTexture()");
425
426         m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0);
427         TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
428 }
429
430 void FramebufferFetchTestCase::genAttachementTexture (const tcu::Vec4& color)
431 {
432         tcu::TextureLevel                       data                                    (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
433         tcu::TextureChannelClass        textureChannelClass =   tcu::getTextureChannelClass(m_texFmt.type);
434
435         m_gl.genTextures(1, &m_texColorBuffer);
436         m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
437
438         m_gl.texParameteri(GL_TEXTURE_2D,       GL_TEXTURE_WRAP_S,              GL_CLAMP_TO_EDGE);
439         m_gl.texParameteri(GL_TEXTURE_2D,       GL_TEXTURE_WRAP_T,              GL_CLAMP_TO_EDGE);
440         m_gl.texParameteri(GL_TEXTURE_2D,       GL_TEXTURE_WRAP_R,              GL_CLAMP_TO_EDGE);
441         m_gl.texParameteri(GL_TEXTURE_2D,       GL_TEXTURE_MIN_FILTER,  m_isFilterable ? GL_LINEAR : GL_NEAREST);
442         m_gl.texParameteri(GL_TEXTURE_2D,       GL_TEXTURE_MAG_FILTER,  m_isFilterable ? GL_LINEAR : GL_NEAREST);
443
444         if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
445                 tcu::clear(data.getAccess(), color.asUint());
446         else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
447                 tcu::clear(data.getAccess(), color.asInt());
448         else
449                 tcu::clear(data.getAccess(), color);
450
451         m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
452         m_gl.bindTexture(GL_TEXTURE_2D, 0);
453 }
454
455 void FramebufferFetchTestCase::verifyRenderbuffer (TestLog&     log, const tcu::TextureFormat& format, const tcu::TextureLevel& reference, const tcu::TextureLevel&     result)
456 {
457         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
458
459         switch (tcu::getTextureChannelClass(format.type))
460         {
461                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
462                 {
463                         const string            name            = "Renderbuffer";
464                         const string            desc            = "Compare renderbuffer (floating_point)";
465                         const tcu::UVec4        threshold       = getFloatULPThreshold(format, result.getFormat());
466
467                         if (!tcu::floatUlpThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
468                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
469
470                         break;
471                 }
472
473                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
474                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
475                 {
476                         const string            name            = "Renderbuffer";
477                         const string            desc            = "Compare renderbuffer (integer)";
478                         const tcu::UVec4        threshold       (1, 1, 1, 1);
479
480                         if (!tcu::intThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
481                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
482
483                         break;
484                 }
485
486                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
487                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
488                 {
489                         const string            name            = "Renderbuffer";
490                         const string            desc            = "Compare renderbuffer (fixed point)";
491                         const tcu::Vec4         threshold       = getFixedPointFormatThreshold(format, result.getFormat());
492
493                         if (!tcu::floatThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
494                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
495
496                         break;
497                 }
498
499                 default:
500                 {
501                         DE_ASSERT(DE_FALSE);
502                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
503                 }
504         }
505 }
506
507 void FramebufferFetchTestCase::genUniformColor (const tcu::Vec4& color)
508 {
509         const GLuint colorLocation      = m_gl.getUniformLocation(m_program->getProgram(), "u_color");
510
511         switch (tcu::getTextureChannelClass(m_texFmt.type))
512         {
513                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
514                 {
515                         m_gl.uniform4uiv(colorLocation, 1, color.asUint().getPtr());
516                         break;
517                 }
518
519                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
520                 {
521                         m_gl.uniform4iv(colorLocation, 1, color.asInt().getPtr());
522                         break;
523                 }
524                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
525                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
526                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
527                 {
528                         m_gl.uniform4fv(colorLocation, 1, color.asFloat().getPtr());
529                         break;
530                 }
531                 default:
532                         DE_ASSERT(DE_FALSE);
533         }
534
535         GLU_EXPECT_NO_ERROR(m_gl.getError(), "genUniformColor()");
536 }
537
538 void FramebufferFetchTestCase::render (void)
539 {
540         const GLfloat coords[] =
541         {
542                 -1.0f, -1.0f,
543                 +1.0f, -1.0f,
544                 +1.0f, +1.0f,
545                 -1.0f, +1.0f,
546         };
547
548         const GLushort indices[] =
549         {
550                 0, 1, 2, 2, 3, 0,
551         };
552
553         GLuint vaoID;
554         m_gl.genVertexArrays(1, &vaoID);
555         m_gl.bindVertexArray(vaoID);
556
557         const GLuint    coordLocation   = m_gl.getAttribLocation(m_program->getProgram(), "a_position");
558
559         m_gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
560
561         glu::Buffer coordinatesBuffer(m_context.getRenderContext());
562         glu::Buffer elementsBuffer(m_context.getRenderContext());
563
564         m_gl.bindBuffer(GL_ARRAY_BUFFER, *coordinatesBuffer);
565         m_gl.bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW);
566         m_gl.enableVertexAttribArray(coordLocation);
567         m_gl.vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL);
568
569         m_gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *elementsBuffer);
570         m_gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0], GL_STATIC_DRAW);
571
572         m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL);
573         GLU_EXPECT_NO_ERROR(m_gl.getError(), "render()");
574
575         m_gl.deleteVertexArrays(1, &vaoID);
576 }
577
578 // Test description:
579 // - Attach texture containing solid color to framebuffer.
580 // - Draw full quad covering the entire viewport.
581 // - Sum framebuffer read color with passed in uniform color.
582 // - Compare resulting surface with reference.
583
584 class TextureFormatTestCase : public FramebufferFetchTestCase
585 {
586 public:
587                                                 TextureFormatTestCase           (Context& context, const char* name, const char* desc, deUint32 format);
588                                                 ~TextureFormatTestCase          (void) {}
589
590         IterateResult           iterate                                         (void);
591
592 private:
593         tcu::TextureLevel       genReferenceTexture                     (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
594 };
595
596 TextureFormatTestCase::TextureFormatTestCase (Context& context, const char* name, const char* desc, deUint32 format)
597         : FramebufferFetchTestCase(context, name, desc, format)
598 {
599 }
600
601 tcu::TextureLevel TextureFormatTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
602 {
603         tcu::TextureLevel                       reference                       (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
604         tcu::TextureChannelClass        textureChannelClass = tcu::getTextureChannelClass(m_texFmt.type);
605
606         tcu::Vec4 formatMaxValue = getTextureFormatInfo(m_texFmt).valueMax;
607         tcu::Vec4 formatMinValue = getTextureFormatInfo(m_texFmt).valueMin;
608
609
610         if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
611         {
612                 tcu::clear(reference.getAccess(), tcu::clamp(fbColor.asUint() + uniformColor.asUint(), formatMinValue.asUint(), formatMaxValue.asUint()));
613         }
614         else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
615         {
616                 tcu::IVec4 clearColor;
617
618                 // Calculate using 64 bits to avoid signed integer overflow.
619                 for (int i = 0; i < 4; i++)
620                         clearColor[i] = static_cast<int>((static_cast<deInt64>(fbColor.asInt()[i]) + static_cast<deInt64>(uniformColor.asInt()[i])) & 0xffffffff);
621
622                 tcu::clear(reference.getAccess(), clearColor);
623         }
624         else
625         {
626                 if (tcu::isSRGB(m_texFmt))
627                 {
628                         const tcu::Vec4 fragmentColor = tcu::clamp(tcu::sRGBToLinear(fbColor) + uniformColor, formatMinValue, formatMaxValue);
629                         tcu::clear(reference.getAccess(), tcu::linearToSRGB(fragmentColor));
630                 }
631                 else
632                 {
633                         tcu::clear(reference.getAccess(), tcu::clamp(fbColor + uniformColor, formatMinValue, formatMaxValue));
634                 }
635         }
636
637         return reference;
638 }
639
640 TextureFormatTestCase::IterateResult TextureFormatTestCase::iterate (void)
641 {
642         const tcu::Vec4         uniformColor    = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
643         const tcu::Vec4         fbColor                 = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
644
645         tcu::TextureLevel       reference               = genReferenceTexture(fbColor, uniformColor);
646         tcu::TextureLevel       result                  (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
647
648         genFramebufferWithTexture(fbColor);
649         genUniformColor(uniformColor);
650         render();
651
652         glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
653         verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
654
655         return STOP;
656 }
657
658 // Test description:
659 // - Attach multiple textures containing solid colors to framebuffer.
660 // - Draw full quad covering the entire viewport.
661 // - For each render target sum framebuffer read color with passed in uniform color.
662 // - Compare resulting surfaces with references.
663
664 class MultipleRenderTargetsTestCase : public FramebufferFetchTestCase
665 {
666 public:
667                                                 MultipleRenderTargetsTestCase           (Context& context, const char* name, const char* desc, deUint32 format);
668                                                 ~MultipleRenderTargetsTestCase          (void);
669
670         IterateResult           iterate                                                         (void);
671         void                            deinit                                                          (void);
672
673 private:
674         void                            genFramebufferWithTextures                      (const vector<tcu::Vec4>& colors);
675         void                            genAttachmentTextures                           (const vector<tcu::Vec4>& colors);
676         tcu::TextureLevel       genReferenceTexture                                     (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
677         glu::ProgramSources genShaderSources                                    (void);
678
679         enum
680         {
681                 MAX_COLOR_BUFFERS = 4
682         };
683
684         GLuint                          m_texColorBuffers                                       [MAX_COLOR_BUFFERS];
685         GLenum                          m_colorBuffers                                          [MAX_COLOR_BUFFERS];
686 };
687
688 MultipleRenderTargetsTestCase::MultipleRenderTargetsTestCase (Context& context, const char* name, const char* desc, deUint32 format)
689         : FramebufferFetchTestCase(context, name, desc, format)
690         , m_texColorBuffers ()
691 {
692         m_colorBuffers[0] = GL_COLOR_ATTACHMENT0;
693         m_colorBuffers[1] = GL_COLOR_ATTACHMENT1;
694         m_colorBuffers[2] = GL_COLOR_ATTACHMENT2;
695         m_colorBuffers[3] = GL_COLOR_ATTACHMENT3;
696 }
697
698 MultipleRenderTargetsTestCase::~MultipleRenderTargetsTestCase (void)
699 {
700         MultipleRenderTargetsTestCase::deinit();
701 }
702
703 void MultipleRenderTargetsTestCase::deinit (void)
704 {
705         // Clean up texture data
706         for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
707         {
708                 if (m_texColorBuffers[i])
709                         m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texColorBuffers[i]);
710         }
711
712         FramebufferFetchTestCase::deinit();
713 }
714
715 void MultipleRenderTargetsTestCase::genFramebufferWithTextures (const vector<tcu::Vec4>& colors)
716 {
717         m_gl.genFramebuffers(1, &m_framebuffer);
718         m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
719
720         genAttachmentTextures(colors);
721
722         for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
723                 m_gl.framebufferTexture2D(GL_FRAMEBUFFER, m_colorBuffers[i], GL_TEXTURE_2D, m_texColorBuffers[i], 0);
724
725         TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
726
727         m_gl.drawBuffers((glw::GLsizei)MAX_COLOR_BUFFERS, &m_colorBuffers[0]);
728         GLU_EXPECT_NO_ERROR(m_gl.getError(), "genFramebufferWithTextures()");
729 }
730
731 void MultipleRenderTargetsTestCase::genAttachmentTextures (const vector<tcu::Vec4>& colors)
732 {
733         tcu::TextureLevel       data    (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
734
735         m_gl.genTextures(MAX_COLOR_BUFFERS, m_texColorBuffers);
736
737         for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
738         {
739                 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffers[i]);
740
741                 m_gl.texParameteri(GL_TEXTURE_2D,       GL_TEXTURE_WRAP_S,              GL_CLAMP_TO_EDGE);
742                 m_gl.texParameteri(GL_TEXTURE_2D,       GL_TEXTURE_WRAP_T,              GL_CLAMP_TO_EDGE);
743                 m_gl.texParameteri(GL_TEXTURE_2D,       GL_TEXTURE_WRAP_R,              GL_CLAMP_TO_EDGE);
744                 m_gl.texParameteri(GL_TEXTURE_2D,       GL_TEXTURE_MIN_FILTER,  m_isFilterable ? GL_LINEAR : GL_NEAREST);
745                 m_gl.texParameteri(GL_TEXTURE_2D,       GL_TEXTURE_MAG_FILTER,  m_isFilterable ? GL_LINEAR : GL_NEAREST);
746
747                 clear(data.getAccess(), colors[i]);
748                 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
749         }
750
751         m_gl.bindTexture(GL_TEXTURE_2D, 0);
752         GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachmentTextures()");
753 }
754
755 tcu::TextureLevel MultipleRenderTargetsTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
756 {
757         tcu::TextureLevel       reference       (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
758         tcu::clear(reference.getAccess(), fbColor + uniformColor);
759
760         return reference;
761 }
762
763 glu::ProgramSources MultipleRenderTargetsTestCase::genShaderSources (void)
764 {
765         const string            vecType = getColorOutputType(m_texFmt);
766         std::ostringstream      fragShaderSource;
767
768         fragShaderSource        << "#version 310 es\n"
769                                                 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
770                                                 << "layout(location = 0) inout highp " << vecType << " o_color0;\n"
771                                                 << "layout(location = 1) inout highp " << vecType << " o_color1;\n"
772                                                 << "layout(location = 2) inout highp " << vecType << " o_color2;\n"
773                                                 << "layout(location = 3) inout highp " << vecType << " o_color3;\n"
774                                                 << "uniform highp " << vecType << " u_color;\n"
775                                                 << "\n"
776                                                 << "void main (void)\n"
777                                                 << "{\n"
778                                                 << "    o_color0 += u_color;\n"
779                                                 << "    o_color1 += u_color;\n"
780                                                 << "    o_color2 += u_color;\n"
781                                                 << "    o_color3 += u_color;\n"
782                                                 << "}\n";
783
784         return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
785 }
786
787 MultipleRenderTargetsTestCase::IterateResult MultipleRenderTargetsTestCase::iterate (void)
788 {
789         const tcu::Vec4         uniformColor    = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
790         tcu::TextureLevel       result                  (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
791
792         vector<tcu::Vec4> colors;
793         colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.9f, 0.0f, 0.0f, 1.0f)));
794         colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.0f, 1.0f)));
795         colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.9f, 1.0f)));
796         colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.9f, 1.0f)));
797
798         genFramebufferWithTextures(colors);
799         genUniformColor(uniformColor);
800         render();
801
802         for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_colorBuffers); ++i)
803         {
804                 tcu::TextureLevel       reference               = genReferenceTexture(colors[i], uniformColor);
805
806                 m_gl.readBuffer(m_colorBuffers[i]);
807                 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
808                 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
809         }
810
811         return STOP;
812 }
813
814 // Test description:
815 // - Same as TextureFormatTestCase except uses built-in fragment output of ES 2.0
816
817 class LastFragDataTestCase : public FramebufferFetchTestCase
818 {
819 public:
820                                                 LastFragDataTestCase                    (Context& context, const char* name, const char* desc, deUint32 format);
821                                                 ~LastFragDataTestCase                   (void) {}
822
823         IterateResult           iterate                                                 (void);
824
825 private:
826         glu::ProgramSources genShaderSources                            (void);
827         tcu::TextureLevel       genReferenceTexture                             (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
828 };
829
830 LastFragDataTestCase::LastFragDataTestCase (Context& context, const char* name, const char* desc, deUint32 format)
831         : FramebufferFetchTestCase(context, name, desc, format)
832 {
833 }
834
835 glu::ProgramSources LastFragDataTestCase::genShaderSources (void)
836 {
837         const string            vecType = getColorOutputType(m_texFmt);
838         std::ostringstream      vertShaderSource;
839         std::ostringstream      fragShaderSource;
840
841         vertShaderSource        << "#version 100\n"
842                                                 << "attribute vec4 a_position;\n"
843                                                 << "\n"
844                                                 << "void main (void)\n"
845                                                 << "{\n"
846                                                 << "    gl_Position = a_position;\n"
847                                                 << "}\n";
848
849         fragShaderSource        << "#version 100\n"
850                                                 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
851                                                 << "uniform highp " << vecType << " u_color;\n"
852                                                 << "\n"
853                                                 << "void main (void)\n"
854                                                 << "{\n"
855                                                 << "    gl_FragColor = u_color + gl_LastFragData[0];\n"
856                                                 << "}\n";
857
858         return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str());
859 }
860
861 tcu::TextureLevel LastFragDataTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
862 {
863         tcu::TextureLevel       reference       (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
864         tcu::clear(reference.getAccess(), fbColor + uniformColor);
865
866         return reference;
867 }
868
869 LastFragDataTestCase::IterateResult LastFragDataTestCase::iterate (void)
870 {
871         const tcu::Vec4         uniformColor    = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
872         const tcu::Vec4         fbColor                 = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
873
874         tcu::TextureLevel       reference               = genReferenceTexture(fbColor, uniformColor);
875         tcu::TextureLevel       result                  (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
876
877         genFramebufferWithTexture(fbColor);
878         genUniformColor(uniformColor);
879         render();
880
881         glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
882         verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
883
884         return STOP;
885 }
886
887 // Test description:
888 // - Attach texture containing solid color to framebuffer.
889 // - Create one 2D texture for sampler with a grid pattern
890 // - Draw full screen quad covering the entire viewport.
891 // - Sum color values taken from framebuffer texture and sampled texture
892 // - Compare resulting surface with reference.
893
894 class TexelFetchTestCase : public FramebufferFetchTestCase
895 {
896 public:
897                                                 TexelFetchTestCase              (Context& context, const char* name, const char* desc, deUint32 format);
898                                                 ~TexelFetchTestCase             (void) {}
899
900         IterateResult           iterate                                 (void);
901
902 private:
903         glu::ProgramSources genShaderSources            (void);
904         tcu::TextureLevel       genReferenceTexture             (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor);
905         void                            genSamplerTexture               (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd);
906
907         GLuint                          m_samplerTexture;
908 };
909
910 TexelFetchTestCase::TexelFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format)
911         : FramebufferFetchTestCase(context, name, desc, format)
912         , m_samplerTexture(0)
913 {
914 }
915
916 void TexelFetchTestCase::genSamplerTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd)
917 {
918         tcu::TextureLevel       data    (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
919
920         m_gl.activeTexture(GL_TEXTURE1);
921
922         m_gl.genTextures(1, &m_samplerTexture);
923         m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
924         m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
925         m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
926
927         tcu::fillWithGrid(data.getAccess(), 8, colorEven, colorOdd);
928
929         m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
930         m_gl.bindTexture(GL_TEXTURE_2D, 0);
931
932         const GLuint samplerLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_sampler");
933         m_gl.uniform1i(samplerLocation, 1);
934
935         GLU_EXPECT_NO_ERROR(m_gl.getError(), "genSamplerTexture()");
936 }
937
938 glu::ProgramSources TexelFetchTestCase::genShaderSources (void)
939 {
940         const string            vecType = getColorOutputType(m_texFmt);
941         std::ostringstream      fragShaderSource;
942
943         fragShaderSource        << "#version 310 es\n"
944                                                 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
945                                                 << "layout(location = 0) inout highp " << vecType << " o_color;\n"
946                                                 << "\n"
947                                                 << "uniform sampler2D u_sampler;\n"
948                                                 << "void main (void)\n"
949                                                 << "{\n"
950                                                 << "    o_color += texelFetch(u_sampler, ivec2(gl_FragCoord), 0);\n"
951                                                 << "}\n";
952
953         return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
954 }
955
956 tcu::TextureLevel TexelFetchTestCase::genReferenceTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor)
957 {
958         tcu::TextureLevel       reference       (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
959         tcu::fillWithGrid(reference.getAccess(), 8, colorEven + fbColor, colorOdd + fbColor);
960
961         return reference;
962 }
963
964 TexelFetchTestCase::IterateResult TexelFetchTestCase::iterate (void)
965 {
966         const tcu::Vec4         fbColor                 = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f));
967         const tcu::Vec4         colorEven               = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f));
968         const tcu::Vec4         colorOdd                = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f));
969
970         genSamplerTexture(colorEven, colorOdd);
971         tcu::TextureLevel       reference               = genReferenceTexture(colorEven, colorOdd, fbColor);
972         tcu::TextureLevel       result                  (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
973
974         genFramebufferWithTexture(fbColor);
975         render();
976
977         glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
978         verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
979
980         // cleanup
981         m_gl.deleteTextures(1, &m_samplerTexture);
982
983         return STOP;
984 }
985
986 // Test description:
987 // - Attach texture containing solid color to framebuffer.
988 // - Draw full screen quad covering the entire viewport.
989 // - Multiple assignments are made to the output color for fragments on the right vertical half of the screen.
990 // - A single assignment is made to the output color for fragments on the left vertical centre of the screen.
991 // - Values are calculated using the sum of the passed in uniform color and the previous framebuffer color.
992 // - Compare resulting surface with reference.
993
994 class MultipleAssignmentTestCase : public FramebufferFetchTestCase
995 {
996 public:
997                                                 MultipleAssignmentTestCase              (Context& context, const char* name, const char* desc, deUint32 format);
998                                                 ~MultipleAssignmentTestCase             (void) {}
999
1000         IterateResult           iterate                                                 (void);
1001
1002 private:
1003         glu::ProgramSources genShaderSources                            (void);
1004         tcu::TextureLevel       genReferenceTexture                             (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
1005 };
1006
1007 MultipleAssignmentTestCase::MultipleAssignmentTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1008         : FramebufferFetchTestCase(context, name, desc, format)
1009 {
1010 }
1011
1012 glu::ProgramSources MultipleAssignmentTestCase::genShaderSources (void)
1013 {
1014         const string            vecType = getColorOutputType(m_texFmt);
1015         std::ostringstream      vertShaderSource;
1016         std::ostringstream      fragShaderSource;
1017
1018         vertShaderSource        << "#version 310 es\n"
1019                                                 << "in highp vec4 a_position;\n"
1020                                                 << "out highp vec4 v_position;\n"
1021                                                 << "\n"
1022                                                 << "void main (void)\n"
1023                                                 << "{\n"
1024                                                 << "    gl_Position = a_position;\n"
1025                                                 << "    v_position  = gl_Position;\n"
1026                                                 << "}\n";
1027
1028         fragShaderSource        << "#version 310 es\n"
1029                                                 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
1030                                                 << "in highp vec4 v_position;\n"
1031                                                 << "layout(location = 0) inout highp " << vecType << " o_color;\n"
1032                                                 << "uniform highp " << vecType << " u_color;\n"
1033                                                 << "\n"
1034                                                 << "void main (void)\n"
1035                                                 << "{\n"
1036                                                 << "    if (v_position.x > 0.0f)\n"
1037                                                 << "            o_color += u_color;\n"
1038                                                 << "\n"
1039                                                 << "    o_color += u_color;\n"
1040                                                 << "}\n";
1041
1042         return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str());
1043 }
1044
1045 tcu::TextureLevel MultipleAssignmentTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
1046 {
1047         tcu::TextureLevel       reference       (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1048
1049         int     width   = reference.getAccess().getWidth();
1050         int     height  = reference.getAccess().getHeight();
1051         int     left    = width /2;
1052         int     top             = height/2;
1053
1054         tcu::Vec4 compositeColor(uniformColor * 2.0f);
1055
1056         tcu::clear(getSubregion(reference.getAccess(), left,            0,              0, width-left,  top,            1),     fbColor + compositeColor);
1057         tcu::clear(getSubregion(reference.getAccess(), 0,                       top,    0, left,                height-top,     1), fbColor + uniformColor);
1058         tcu::clear(getSubregion(reference.getAccess(), left,            top,    0, width-left,  height-top, 1), fbColor + compositeColor);
1059         tcu::clear(getSubregion(reference.getAccess(), 0,                       0,              0, left,                top,            1),     fbColor + uniformColor);
1060
1061         return reference;
1062 }
1063
1064 MultipleAssignmentTestCase::IterateResult MultipleAssignmentTestCase::iterate (void)
1065 {
1066         const tcu::Vec4         fbColor                 = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
1067         const tcu::Vec4         uniformColor    = scaleColorValue(m_texFmt, tcu::Vec4(0.25f, 0.0f, 0.0f, 1.0f));
1068
1069         tcu::TextureLevel       reference               = genReferenceTexture(fbColor, uniformColor);
1070         tcu::TextureLevel       result                  (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1071
1072         genFramebufferWithTexture(fbColor);
1073         genUniformColor(uniformColor);
1074         render();
1075
1076         glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1077         verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1078
1079         return STOP;
1080 }
1081
1082 // Test description:
1083 // - Attach texture containing grid pattern to framebuffer.
1084 // - Using framebuffer reads discard odd squares in the grid.
1085 // - The even squares framebuffer color is added to the passed in uniform color.
1086
1087 class FragmentDiscardTestCase : public FramebufferFetchTestCase
1088 {
1089 public:
1090                                                 FragmentDiscardTestCase         (Context& context, const char* name, const char* desc, deUint32 format);
1091                                                 ~FragmentDiscardTestCase        (void) {}
1092
1093         IterateResult           iterate                                         (void);
1094
1095 private:
1096         glu::ProgramSources genShaderSources                    (void);
1097         void                            genFramebufferWithGrid          (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd);
1098         tcu::TextureLevel       genReferenceTexture                     (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd);
1099 };
1100
1101 FragmentDiscardTestCase::FragmentDiscardTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1102         : FramebufferFetchTestCase(context, name, desc, format)
1103 {
1104 }
1105
1106 glu::ProgramSources FragmentDiscardTestCase::genShaderSources (void)
1107 {
1108         const string            vecType = getColorOutputType(m_texFmt);
1109         std::ostringstream      fragShaderSource;
1110
1111         fragShaderSource        << "#version 310 es\n"
1112                                                 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
1113                                                 << "layout(location = 0) inout highp " << vecType << " o_color;\n"
1114                                                 << "uniform highp " << vecType << " u_color;\n"
1115                                                 << "\n"
1116                                                 << "void main (void)\n"
1117                                                 << "{\n"
1118                                                 << "    const highp float threshold = 0.0005f;\n"
1119                                                 << "    bool valuesEqual = all(lessThan(abs(o_color - u_color), vec4(threshold)));\n\n"
1120                                                 << "    if (valuesEqual)\n"
1121                                                 << "            o_color += u_color;\n"
1122                                                 << "    else\n"
1123                                                 << "            discard;\n"
1124                                                 << "}\n";
1125
1126         return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
1127 }
1128
1129 void FragmentDiscardTestCase::genFramebufferWithGrid (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd)
1130 {
1131         tcu::TextureLevel data  (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1132
1133         m_gl.genFramebuffers(1, &m_framebuffer);
1134         m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
1135
1136         m_gl.genTextures(1, &m_texColorBuffer);
1137         m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
1138
1139         tcu::fillWithGrid(data.getAccess(), 8, fbColorEven, fbColorOdd);
1140
1141         m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
1142         m_gl.bindTexture(GL_TEXTURE_2D, 0);
1143
1144         m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0);
1145         TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
1146 }
1147
1148 tcu::TextureLevel FragmentDiscardTestCase::genReferenceTexture (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd)
1149 {
1150         tcu::TextureLevel       reference       (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1151         tcu::fillWithGrid(reference.getAccess(), 8, fbColorEven + fbColorEven, fbColorOdd);
1152
1153         return reference;
1154 }
1155
1156 FragmentDiscardTestCase::IterateResult FragmentDiscardTestCase::iterate (void)
1157 {
1158         const tcu::Vec4         fbColorEven             = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 1.0f, 1.0f));
1159         const tcu::Vec4         fbColorOdd              = scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f));
1160
1161         tcu::TextureLevel       reference               = genReferenceTexture(fbColorEven, fbColorOdd);
1162         tcu::TextureLevel       result                  (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1163         genFramebufferWithGrid(fbColorEven, fbColorOdd);
1164
1165         genUniformColor(fbColorEven);
1166         render();
1167
1168         glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1169         verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1170
1171         return STOP;
1172 }
1173
1174 // Test description:
1175 // - Create 2D texture array containing three mipmaps.
1176 // - Each mipmap level is assigned a different color.
1177 // - Attach single mipmap level to framebuffer and draw full screen quad.
1178 // - Sum framebuffer read color with passed in uniform color.
1179 // - Compare resulting surface with reference.
1180 // - Repeat for subsequent mipmap levels.
1181
1182 class TextureLevelTestCase : public FramebufferFetchTestCase
1183 {
1184 public:
1185                                                 TextureLevelTestCase                    (Context& context, const char* name, const char* desc, deUint32 format);
1186                                                 ~TextureLevelTestCase                   (void) {}
1187
1188         IterateResult           iterate                                                 (void);
1189
1190 private:
1191         void                            create2DTextureArrayMipMaps             (const vector<tcu::Vec4>& colors);
1192         tcu::TextureLevel       genReferenceTexture                             (int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor);
1193         void                            genReferenceMipmap                              (const tcu::Vec4& color, tcu::TextureLevel& reference);
1194 };
1195
1196 TextureLevelTestCase::TextureLevelTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1197         : FramebufferFetchTestCase(context, name, desc, format)
1198 {
1199 }
1200
1201 void TextureLevelTestCase::create2DTextureArrayMipMaps (const vector<tcu::Vec4>& colors)
1202 {
1203         int                                             numLevels       = (int)colors.size();
1204         tcu::TextureLevel               levelData       (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType));
1205
1206         m_gl.genTextures(1, &m_texColorBuffer);
1207         m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer);
1208
1209         m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1, 0, m_transferFmt.format, m_transferFmt.dataType, DE_NULL);
1210         m_gl.generateMipmap(GL_TEXTURE_2D_ARRAY);
1211
1212         for (int level = 0; level < numLevels; level++)
1213         {
1214                 int             levelW          = de::max(1, VIEWPORT_WIDTH             >> level);
1215                 int             levelH          = de::max(1, VIEWPORT_HEIGHT    >> level);
1216
1217                 levelData.setSize(levelW, levelH, 1);
1218
1219                 clear(levelData.getAccess(), colors[level]);
1220                 m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, level, m_format, levelW, levelH, 1, 0, m_transferFmt.format, m_transferFmt.dataType, levelData.getAccess().getDataPtr());
1221         }
1222
1223         m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
1224         GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayMipMaps()");
1225 }
1226
1227 tcu::TextureLevel TextureLevelTestCase::genReferenceTexture (int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor)
1228 {
1229         tcu::TextureLevel       reference       (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level, 1);
1230
1231         genReferenceMipmap(colors[level] + uniformColor, reference);
1232
1233         return reference;
1234 }
1235
1236 void TextureLevelTestCase::genReferenceMipmap (const tcu::Vec4& color, tcu::TextureLevel& reference)
1237 {
1238         const int       width   = reference.getAccess().getWidth();
1239         const int       height  = reference.getAccess().getHeight();
1240         const int       left    = width  / 2;
1241         const int       top             = height / 2;
1242
1243         clear(getSubregion(reference.getAccess(), left,         0,              0, width-left,  top,            1),     color);
1244         clear(getSubregion(reference.getAccess(), 0,            top,    0, left,                height-top,     1), color);
1245         clear(getSubregion(reference.getAccess(), left,         top,    0, width-left,  height-top, 1), color);
1246         clear(getSubregion(reference.getAccess(), 0,            0,              0, left,                top,            1),     color);
1247 }
1248
1249 TextureLevelTestCase::IterateResult TextureLevelTestCase::iterate (void)
1250 {
1251         const tcu::Vec4         uniformColor    = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.0f, 0.0f, 1.0f));
1252         vector<tcu::Vec4>       levelColors;
1253
1254         levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f)));
1255         levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f)));
1256         levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
1257
1258         m_gl.genFramebuffers(1, &m_framebuffer);
1259         m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
1260
1261         create2DTextureArrayMipMaps(levelColors);
1262
1263         // attach successive mipmap layers to framebuffer and render
1264         for (int level = 0; level < (int)levelColors.size(); ++level)
1265         {
1266                 std::ostringstream name, desc;
1267                 name << "Level "                << level;
1268                 desc << "Mipmap level " << level;
1269
1270                 const tcu::ScopedLogSection     section                 (m_testCtx.getLog(), name.str(), desc.str());
1271                 tcu::TextureLevel                       result                  (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level);
1272                 tcu::TextureLevel                       reference               = genReferenceTexture(level, levelColors, uniformColor);
1273
1274                 m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, level, 0);
1275
1276                 genUniformColor(uniformColor);
1277                 render();
1278
1279                 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1280                 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1281
1282                 if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
1283                         return STOP;
1284         }
1285
1286         return STOP;
1287 }
1288
1289 class TextureLayerTestCase : public FramebufferFetchTestCase
1290 {
1291 public:
1292                                                 TextureLayerTestCase            (Context& context, const char* name, const char* desc, deUint32 format);
1293                                                 ~TextureLayerTestCase           (void) {}
1294
1295         IterateResult           iterate                                         (void);
1296
1297 private:
1298         void                            create2DTextureArrayLayers      (const vector<tcu::Vec4>&  colors);
1299         tcu::TextureLevel       genReferenceTexture                     (int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor);
1300 };
1301
1302 TextureLayerTestCase::TextureLayerTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1303         : FramebufferFetchTestCase(context, name, desc, format)
1304 {
1305 }
1306
1307 void TextureLayerTestCase::create2DTextureArrayLayers (const vector<tcu::Vec4>& colors)
1308 {
1309         int                                             numLayers       = (int)colors.size();
1310         tcu::TextureLevel               layerData       (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType));
1311
1312         m_gl.genTextures(1, &m_texColorBuffer);
1313         m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer);
1314         m_gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers);
1315         m_gl.bindImageTexture(0, m_texColorBuffer, 0, GL_FALSE, 0, GL_READ_ONLY, m_format);
1316
1317         layerData.setSize(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers);
1318
1319         for (int layer = 0; layer < numLayers; layer++)
1320         {
1321                 clear(layerData.getAccess(), colors[layer]);
1322                 m_gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1, m_transferFmt.format, m_transferFmt.dataType, layerData.getAccess().getDataPtr());
1323         }
1324
1325         m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
1326         GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayLayers()");
1327 }
1328
1329 tcu::TextureLevel TextureLayerTestCase::genReferenceTexture (int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor)
1330 {
1331         tcu::TextureLevel       reference       (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1332         clear(reference.getAccess(), colors[layer] + uniformColor);
1333
1334         return reference;
1335 }
1336
1337 // Test description
1338 // - Create 2D texture array containing three layers.
1339 // - Each layer is assigned a different color.
1340 // - Attach single layer to framebuffer and draw full screen quad.
1341 // - Sum framebuffer read color with passed in uniform color.
1342 // - Compare resulting surface with reference.
1343 // - Repeat for subsequent texture layers.
1344
1345 TextureLayerTestCase::IterateResult TextureLayerTestCase::iterate (void)
1346 {
1347         const tcu::Vec4         uniformColor    = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
1348         tcu::TextureLevel       result                  (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1349         vector<tcu::Vec4>       layerColors;
1350
1351         layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f)));
1352         layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f)));
1353         layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
1354
1355         m_gl.genFramebuffers(1, &m_framebuffer);
1356         m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
1357
1358         create2DTextureArrayLayers(layerColors);
1359
1360         for (int layer = 0; layer < (int)layerColors.size(); ++layer)
1361         {
1362                 std::ostringstream name, desc;
1363                 name << "Layer " << layer;
1364                 desc << "Layer " << layer;
1365
1366                 const tcu::ScopedLogSection section             (m_testCtx.getLog(), name.str(), desc.str());
1367                 tcu::TextureLevel                       reference       = genReferenceTexture(layer, layerColors, uniformColor);
1368
1369                 m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, 0, layer);
1370
1371                 genUniformColor(uniformColor);
1372                 render();
1373
1374                 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1375                 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1376
1377                 if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
1378                         return STOP;
1379         }
1380
1381         return STOP;
1382 }
1383
1384 } // Anonymous
1385
1386 ShaderFramebufferFetchTests::ShaderFramebufferFetchTests (Context& context)
1387         : TestCaseGroup (context, "framebuffer_fetch", "GL_EXT_shader_framebuffer_fetch tests")
1388 {
1389 }
1390
1391 ShaderFramebufferFetchTests::~ShaderFramebufferFetchTests (void)
1392 {
1393 }
1394
1395 void ShaderFramebufferFetchTests::init (void)
1396 {
1397         tcu::TestCaseGroup* const basicTestGroup                                = new tcu::TestCaseGroup(m_testCtx, "basic",                            "Basic framebuffer shader fetch tests");
1398         tcu::TestCaseGroup* const framebufferFormatTestGroup    = new tcu::TestCaseGroup(m_testCtx, "framebuffer_format",       "Texture render target formats tests");
1399
1400         // basic
1401         {
1402                 basicTestGroup->addChild(new TexelFetchTestCase                         (m_context,             "texel_fetch",                                  "Framebuffer fetches in conjunction with shader texel fetches",                 GL_RGBA8));
1403                 basicTestGroup->addChild(new LastFragDataTestCase                       (m_context,             "last_frag_data",                               "Framebuffer fetches with built-in fragment output of ES 2.0",                  GL_RGBA8));
1404                 basicTestGroup->addChild(new FragmentDiscardTestCase            (m_context,             "fragment_discard",                             "Framebuffer fetches in combination with fragment discards",                    GL_RGBA8));
1405                 basicTestGroup->addChild(new MultipleAssignmentTestCase         (m_context,             "multiple_assignment",                  "Multiple assignments to fragment color inout",                                                 GL_RGBA8));
1406                 basicTestGroup->addChild(new MultipleRenderTargetsTestCase      (m_context,             "multiple_render_targets",              "Framebuffer fetches used in combination with multiple render targets", GL_RGBA8));
1407                 basicTestGroup->addChild(new TextureLevelTestCase                       (m_context,             "framebuffer_texture_level",    "Framebuffer fetches with individual texture render target mipmaps",    GL_RGBA8));
1408                 basicTestGroup->addChild(new TextureLayerTestCase                       (m_context,             "framebuffer_texture_layer",    "Framebuffer fetches with individual texture render target layers",             GL_RGBA8));
1409         }
1410
1411         // framebuffer formats
1412         {
1413                 static const deUint32 colorFormats[] =
1414                 {
1415                         // RGBA formats
1416                         GL_RGBA32I,
1417                         GL_RGBA32UI,
1418                         GL_RGBA16I,
1419                         GL_RGBA16UI,
1420                         GL_RGBA8,
1421                         GL_RGBA8I,
1422                         GL_RGBA8UI,
1423                         GL_SRGB8_ALPHA8,
1424                         GL_RGB10_A2,
1425                         GL_RGB10_A2UI, GL_RGBA4, GL_RGB5_A1,
1426
1427                         // RGB formats
1428                         GL_RGB8,
1429                         GL_RGB565,
1430
1431                         // RG formats
1432                         GL_RG32I,
1433                         GL_RG32UI,
1434                         GL_RG16I,
1435                         GL_RG16UI,
1436                         GL_RG8,
1437                         GL_RG8I,
1438                         GL_RG8UI,
1439
1440                         // R formats
1441                         GL_R32I,
1442                         GL_R32UI,
1443                         GL_R16I,
1444                         GL_R16UI,
1445                         GL_R8,
1446                         GL_R8I,
1447                         GL_R8UI,
1448
1449                         // GL_EXT_color_buffer_float
1450                         GL_RGBA32F,
1451                         GL_RGBA16F,
1452                         GL_R11F_G11F_B10F,
1453                         GL_RG32F,
1454                         GL_RG16F,
1455                         GL_R32F,
1456                         GL_R16F,
1457
1458                         // GL_EXT_color_buffer_half_float
1459                         GL_RGB16F
1460                 };
1461
1462                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
1463                         framebufferFormatTestGroup->addChild(new TextureFormatTestCase(m_context, getFormatName(colorFormats[ndx]), "Framebuffer fetches from texture attachments with varying formats", colorFormats[ndx]));
1464         }
1465
1466         addChild(basicTestGroup);
1467         addChild(framebufferFormatTestGroup);
1468 }
1469
1470 } // Functional
1471 } // gles31
1472 } // deqp