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