1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 Module
3 * -------------------------------------------------
5 * Copyright 2017 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief EXT Shader Framebuffer Fetch Tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es31fShaderFramebufferFetchTests.hpp"
25 #include "es31fFboTestUtil.hpp"
27 #include "tcuTestLog.hpp"
28 #include "tcuSurface.hpp"
29 #include "tcuTextureUtil.hpp"
30 #include "tcuImageCompare.hpp"
31 #include "tcuVectorUtil.hpp"
33 #include "gluShaderProgram.hpp"
34 #include "gluPixelTransfer.hpp"
35 #include "gluTextureUtil.hpp"
36 #include "gluContextInfo.hpp"
37 #include "gluObjectWrapper.hpp"
39 #include "glwFunctions.hpp"
40 #include "glwEnums.hpp"
42 #include "deStringUtil.hpp"
60 using namespace FboTestUtil;
62 static void checkExtensionSupport (Context& context, const char* extName)
64 if (!context.getContextInfo().isExtensionSupported(extName))
65 throw tcu::NotSupportedError(string(extName) + " not supported");
68 static void checkFramebufferFetchSupport (Context& context)
70 checkExtensionSupport(context, "GL_EXT_shader_framebuffer_fetch");
73 static bool isRequiredFormat (deUint32 format, glu::RenderContext& renderContext)
75 const bool isES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
78 // Color-renderable formats
112 case GL_R11F_G11F_B10F:
122 tcu::TextureFormat getReadPixelFormat (const tcu::TextureFormat& format)
124 switch (tcu::getTextureChannelClass(format.type))
126 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
127 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32);
129 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
130 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32);
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);
136 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
137 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT);
141 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
145 tcu::Vec4 getFixedPointFormatThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat)
147 DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
148 DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
150 DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
151 DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
153 DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
154 DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
156 const tcu::IVec4 srcBits = tcu::getTextureFormatBitDepth(sourceFormat);
157 const tcu::IVec4 readBits = tcu::getTextureFormatBitDepth(readPixelsFormat);
159 return tcu::Vec4(3.0f) / ((tcu::Vector<deUint64, 4>(1) << (tcu::min(srcBits, readBits).cast<deUint64>())) - tcu::Vector<deUint64, 4>(1)).cast<float>();
162 tcu::UVec4 getFloatULPThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat)
164 const tcu::IVec4 srcMantissaBits = tcu::getTextureFormatMantissaBitDepth(sourceFormat);
165 const tcu::IVec4 readMantissaBits = tcu::getTextureFormatMantissaBitDepth(readPixelsFormat);
166 tcu::IVec4 ULPDiff(0);
168 for (int i = 0; i < 4; i++)
169 if (readMantissaBits[i] >= srcMantissaBits[i])
170 ULPDiff[i] = readMantissaBits[i] - srcMantissaBits[i];
172 return tcu::UVec4(4) * (tcu::UVec4(1) << (ULPDiff.cast<deUint32>()));
175 static bool isAnyExtensionSupported (Context& context, const std::vector<std::string>& requiredExts)
177 for (std::vector<std::string>::const_iterator iter = requiredExts.begin(); iter != requiredExts.end(); iter++)
179 const std::string& extension = *iter;
181 if (context.getContextInfo().isExtensionSupported(extension.c_str()))
188 static std::string getColorOutputType(tcu::TextureFormat format)
190 switch (tcu::getTextureChannelClass(format.type))
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";
198 DE_FATAL("Unsupported TEXTURECHANNELCLASS");
203 static std::vector<std::string> getEnablingExtensions (deUint32 format, glu::RenderContext& renderContext)
205 const bool isES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
206 std::vector<std::string> out;
208 DE_ASSERT(!isRequiredFormat(format, renderContext));
213 out.push_back("GL_EXT_color_buffer_half_float");
219 out.push_back("GL_EXT_color_buffer_half_float");
223 case GL_R11F_G11F_B10F:
227 out.push_back("GL_EXT_color_buffer_float");
237 void checkFormatSupport (Context& context, deUint32 sizedFormat)
239 const bool isCoreFormat = isRequiredFormat(sizedFormat, context.getRenderContext());
240 const std::vector<std::string> requiredExts = (!isCoreFormat) ? getEnablingExtensions(sizedFormat, context.getRenderContext()) : std::vector<std::string>();
242 // Check that we don't try to use invalid formats.
243 DE_ASSERT(isCoreFormat || !requiredExts.empty());
245 if (!requiredExts.empty() && !isAnyExtensionSupported(context, requiredExts))
246 throw tcu::NotSupportedError("Format not supported");
249 tcu::Vec4 scaleColorValue (tcu::TextureFormat format, const tcu::Vec4& color)
251 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(format);
252 const tcu::Vec4 cScale = fmtInfo.valueMax-fmtInfo.valueMin;
253 const tcu::Vec4 cBias = fmtInfo.valueMin;
255 return tcu::RGBA(color).toVec() * cScale + cBias;
258 // Base class for framebuffer fetch test cases
260 class FramebufferFetchTestCase : public TestCase
263 FramebufferFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format);
264 ~FramebufferFetchTestCase (void);
270 string genPassThroughVertSource (void);
271 virtual glu::ProgramSources genShaderSources (void);
273 void genFramebufferWithTexture (const tcu::Vec4& color);
274 void genAttachementTexture (const tcu::Vec4& color);
275 void genUniformColor (const tcu::Vec4& color);
278 void verifyRenderbuffer (TestLog& log, const tcu::TextureFormat& format, const tcu::TextureLevel& reference, const tcu::TextureLevel& result);
280 const glw::Functions& m_gl;
281 const deUint32 m_format;
283 glu::ShaderProgram* m_program;
284 GLuint m_framebuffer;
285 GLuint m_texColorBuffer;
287 tcu::TextureFormat m_texFmt;
288 glu::TransferFormat m_transferFmt;
294 VIEWPORT_HEIGHT = 64,
298 FramebufferFetchTestCase::FramebufferFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format)
299 : TestCase (context, name, desc)
300 , m_gl (m_context.getRenderContext().getFunctions())
302 , m_program (DE_NULL)
304 , m_texColorBuffer (0)
305 , m_texFmt (glu::mapGLInternalFormat(m_format))
306 , m_transferFmt (glu::getTransferFormat(m_texFmt))
307 , m_isFilterable (glu::isGLInternalColorFormatFilterable(m_format))
311 FramebufferFetchTestCase::~FramebufferFetchTestCase (void)
313 FramebufferFetchTestCase::deinit();
316 void FramebufferFetchTestCase::init (void)
318 checkFramebufferFetchSupport (m_context);
319 checkFormatSupport(m_context, m_format);
321 DE_ASSERT(!m_program);
322 m_program = new glu::ShaderProgram(m_context.getRenderContext(), genShaderSources());
324 m_testCtx.getLog() << *m_program;
326 if (!m_program->isOk())
330 TCU_FAIL("Failed to compile shader program");
333 m_gl.useProgram(m_program->getProgram());
336 void FramebufferFetchTestCase::deinit (void)
343 m_gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
344 m_gl.deleteFramebuffers(1, &m_framebuffer);
348 if (m_texColorBuffer)
350 m_gl.deleteTextures(1, &m_texColorBuffer);
351 m_texColorBuffer = 0;
355 string FramebufferFetchTestCase::genPassThroughVertSource (void)
357 std::ostringstream vertShaderSource;
359 vertShaderSource << "#version 310 es\n"
360 << "in highp vec4 a_position;\n"
362 << "void main (void)\n"
364 << " gl_Position = a_position;\n"
367 return vertShaderSource.str();
370 glu::ProgramSources FramebufferFetchTestCase::genShaderSources (void)
372 const string vecType = getColorOutputType(m_texFmt);
373 std::ostringstream fragShaderSource;
375 fragShaderSource << "#version 310 es\n"
376 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
377 << "layout(location = 0) inout highp " << vecType << " o_color;\n"
378 << "uniform highp " << vecType << " u_color;\n"
380 << "void main (void)\n"
382 << " o_color += u_color;\n"
385 return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
388 void FramebufferFetchTestCase::genFramebufferWithTexture (const tcu::Vec4& color)
390 m_gl.genFramebuffers(1, &m_framebuffer);
391 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
393 genAttachementTexture(color);
394 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachementTexture()");
396 m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0);
397 TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
400 void FramebufferFetchTestCase::genAttachementTexture (const tcu::Vec4& color)
402 tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
403 tcu::TextureChannelClass textureChannelClass = tcu::getTextureChannelClass(m_texFmt.type);
405 m_gl.genTextures(1, &m_texColorBuffer);
406 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
408 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
409 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
410 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
411 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST);
412 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST);
414 if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
415 tcu::clear(data.getAccess(), color.asUint());
416 else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
417 tcu::clear(data.getAccess(), color.asInt());
419 tcu::clear(data.getAccess(), color);
421 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
422 m_gl.bindTexture(GL_TEXTURE_2D, 0);
425 void FramebufferFetchTestCase::verifyRenderbuffer (TestLog& log, const tcu::TextureFormat& format, const tcu::TextureLevel& reference, const tcu::TextureLevel& result)
427 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
429 switch (tcu::getTextureChannelClass(format.type))
431 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
433 const string name = "Renderbuffer";
434 const string desc = "Compare renderbuffer (floating_point)";
435 const tcu::UVec4 threshold = getFloatULPThreshold(format, result.getFormat());
437 if (!tcu::floatUlpThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
438 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
443 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
444 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
446 const string name = "Renderbuffer";
447 const string desc = "Compare renderbuffer (integer)";
448 const tcu::UVec4 threshold (1, 1, 1, 1);
450 if (!tcu::intThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
451 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
456 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
457 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
459 const string name = "Renderbuffer";
460 const string desc = "Compare renderbuffer (fixed point)";
461 const tcu::Vec4 threshold = getFixedPointFormatThreshold(format, result.getFormat());
463 if (!tcu::floatThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
464 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
472 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
477 void FramebufferFetchTestCase::genUniformColor (const tcu::Vec4& color)
479 const GLuint colorLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_color");
481 switch (tcu::getTextureChannelClass(m_texFmt.type))
483 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
485 m_gl.uniform4uiv(colorLocation, 1, color.asUint().getPtr());
489 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
491 m_gl.uniform4iv(colorLocation, 1, color.asInt().getPtr());
494 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
495 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
496 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
498 m_gl.uniform4fv(colorLocation, 1, color.asFloat().getPtr());
505 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genUniformColor()");
508 void FramebufferFetchTestCase::render (void)
510 const GLfloat coords[] =
518 const GLushort indices[] =
523 const GLuint coordLocation = m_gl.getAttribLocation(m_program->getProgram(), "a_position");
525 m_gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
527 glu::Buffer coordinatesBuffer(m_context.getRenderContext());
528 glu::Buffer elementsBuffer(m_context.getRenderContext());
530 m_gl.bindBuffer(GL_ARRAY_BUFFER, *coordinatesBuffer);
531 m_gl.bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW);
532 m_gl.enableVertexAttribArray(coordLocation);
533 m_gl.vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL);
535 m_gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *elementsBuffer);
536 m_gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0], GL_STATIC_DRAW);
538 m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL);
539 GLU_EXPECT_NO_ERROR(m_gl.getError(), "render()");
543 // - Attach texture containing solid color to framebuffer.
544 // - Draw full quad covering the entire viewport.
545 // - Sum framebuffer read color with passed in uniform color.
546 // - Compare resulting surface with reference.
548 class TextureFormatTestCase : public FramebufferFetchTestCase
551 TextureFormatTestCase (Context& context, const char* name, const char* desc, deUint32 format);
552 ~TextureFormatTestCase (void) {};
554 IterateResult iterate (void);
557 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
560 TextureFormatTestCase::TextureFormatTestCase (Context& context, const char* name, const char* desc, deUint32 format)
561 : FramebufferFetchTestCase(context, name, desc, format)
565 tcu::TextureLevel TextureFormatTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
567 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
568 tcu::TextureChannelClass textureChannelClass = tcu::getTextureChannelClass(m_texFmt.type);
570 if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
572 tcu::clear(reference.getAccess(), fbColor.asUint() + uniformColor.asUint());
574 else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
576 tcu::clear(reference.getAccess(), fbColor.asInt() + uniformColor.asInt());
580 if (tcu::isSRGB(m_texFmt))
582 const tcu::Vec4 fragmentColor = tcu::sRGBToLinear(fbColor) + uniformColor;
583 tcu::clear(reference.getAccess(), tcu::linearToSRGB(fragmentColor));
587 tcu::clear(reference.getAccess(), fbColor + uniformColor);
594 TextureFormatTestCase::IterateResult TextureFormatTestCase::iterate (void)
596 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
597 const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
599 tcu::TextureLevel reference = genReferenceTexture(fbColor, uniformColor);
600 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
602 genFramebufferWithTexture(fbColor);
603 genUniformColor(uniformColor);
606 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
607 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
613 // - Attach multiple textures containing solid colors to framebuffer.
614 // - Draw full quad covering the entire viewport.
615 // - For each render target sum framebuffer read color with passed in uniform color.
616 // - Compare resulting surfaces with references.
618 class MultipleRenderTargetsTestCase : public FramebufferFetchTestCase
621 MultipleRenderTargetsTestCase (Context& context, const char* name, const char* desc, deUint32 format);
622 ~MultipleRenderTargetsTestCase (void);
624 IterateResult iterate (void);
628 void genFramebufferWithTextures (const vector<tcu::Vec4>& colors);
629 void genAttachmentTextures (const vector<tcu::Vec4>& colors);
630 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
631 glu::ProgramSources genShaderSources (void);
635 MAX_COLOR_BUFFERS = 4
638 GLuint m_texColorBuffers [MAX_COLOR_BUFFERS];
639 GLenum m_colorBuffers [MAX_COLOR_BUFFERS];
642 MultipleRenderTargetsTestCase::MultipleRenderTargetsTestCase (Context& context, const char* name, const char* desc, deUint32 format)
643 : FramebufferFetchTestCase(context, name, desc, format)
644 , m_texColorBuffers ()
646 m_colorBuffers[0] = GL_COLOR_ATTACHMENT0;
647 m_colorBuffers[1] = GL_COLOR_ATTACHMENT1;
648 m_colorBuffers[2] = GL_COLOR_ATTACHMENT2;
649 m_colorBuffers[3] = GL_COLOR_ATTACHMENT3;
652 MultipleRenderTargetsTestCase::~MultipleRenderTargetsTestCase (void)
654 MultipleRenderTargetsTestCase::deinit();
657 void MultipleRenderTargetsTestCase::deinit (void)
659 // Clean up texture data
660 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
662 if (m_texColorBuffers[i])
663 m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texColorBuffers[i]);
666 FramebufferFetchTestCase::deinit();
669 void MultipleRenderTargetsTestCase::genFramebufferWithTextures (const vector<tcu::Vec4>& colors)
671 m_gl.genFramebuffers(1, &m_framebuffer);
672 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
674 genAttachmentTextures(colors);
676 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
677 m_gl.framebufferTexture2D(GL_FRAMEBUFFER, m_colorBuffers[i], GL_TEXTURE_2D, m_texColorBuffers[i], 0);
679 TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
681 m_gl.drawBuffers((glw::GLsizei)MAX_COLOR_BUFFERS, &m_colorBuffers[0]);
682 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genFramebufferWithTextures()");
685 void MultipleRenderTargetsTestCase::genAttachmentTextures (const vector<tcu::Vec4>& colors)
687 tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
689 m_gl.genTextures(MAX_COLOR_BUFFERS, m_texColorBuffers);
691 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
693 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffers[i]);
695 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
696 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
697 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
698 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST);
699 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST);
701 clear(data.getAccess(), colors[i]);
702 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
705 m_gl.bindTexture(GL_TEXTURE_2D, 0);
706 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachmentTextures()");
709 tcu::TextureLevel MultipleRenderTargetsTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
711 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
712 tcu::clear(reference.getAccess(), fbColor + uniformColor);
717 glu::ProgramSources MultipleRenderTargetsTestCase::genShaderSources (void)
719 const string vecType = getColorOutputType(m_texFmt);
720 std::ostringstream fragShaderSource;
722 fragShaderSource << "#version 310 es\n"
723 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
724 << "layout(location = 0) inout highp " << vecType << " o_color0;\n"
725 << "layout(location = 1) inout highp " << vecType << " o_color1;\n"
726 << "layout(location = 2) inout highp " << vecType << " o_color2;\n"
727 << "layout(location = 3) inout highp " << vecType << " o_color3;\n"
728 << "uniform highp " << vecType << " u_color;\n"
730 << "void main (void)\n"
732 << " o_color0 += u_color;\n"
733 << " o_color1 += u_color;\n"
734 << " o_color2 += u_color;\n"
735 << " o_color3 += u_color;\n"
738 return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
741 MultipleRenderTargetsTestCase::IterateResult MultipleRenderTargetsTestCase::iterate (void)
743 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
744 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
746 vector<tcu::Vec4> colors;
747 colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.9f, 0.0f, 0.0f, 1.0f)));
748 colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.0f, 1.0f)));
749 colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.9f, 1.0f)));
750 colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.9f, 1.0f)));
752 genFramebufferWithTextures(colors);
753 genUniformColor(uniformColor);
756 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_colorBuffers); ++i)
758 tcu::TextureLevel reference = genReferenceTexture(colors[i], uniformColor);
760 m_gl.readBuffer(m_colorBuffers[i]);
761 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
762 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
769 // - Same as TextureFormatTestCase except uses built-in fragment output of ES 2.0
771 class LastFragDataTestCase : public FramebufferFetchTestCase
774 LastFragDataTestCase (Context& context, const char* name, const char* desc, deUint32 format);
775 ~LastFragDataTestCase (void) {};
777 IterateResult iterate (void);
780 glu::ProgramSources genShaderSources (void);
781 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
784 LastFragDataTestCase::LastFragDataTestCase (Context& context, const char* name, const char* desc, deUint32 format)
785 : FramebufferFetchTestCase(context, name, desc, format)
789 glu::ProgramSources LastFragDataTestCase::genShaderSources (void)
791 const string vecType = getColorOutputType(m_texFmt);
792 std::ostringstream vertShaderSource;
793 std::ostringstream fragShaderSource;
795 vertShaderSource << "#version 100\n"
796 << "attribute vec4 a_position;\n"
798 << "void main (void)\n"
800 << " gl_Position = a_position;\n"
803 fragShaderSource << "#version 100\n"
804 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
805 << "uniform highp " << vecType << " u_color;\n"
807 << "void main (void)\n"
809 << " gl_FragColor = u_color + gl_LastFragData[0];\n"
812 return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str());
815 tcu::TextureLevel LastFragDataTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
817 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
818 tcu::clear(reference.getAccess(), fbColor + uniformColor);
823 LastFragDataTestCase::IterateResult LastFragDataTestCase::iterate (void)
825 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
826 const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
828 tcu::TextureLevel reference = genReferenceTexture(fbColor, uniformColor);
829 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
831 genFramebufferWithTexture(fbColor);
832 genUniformColor(uniformColor);
835 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
836 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
842 // - Attach texture containing solid color to framebuffer.
843 // - Create one 2D texture for sampler with a grid pattern
844 // - Draw full screen quad covering the entire viewport.
845 // - Sum color values taken from framebuffer texture and sampled texture
846 // - Compare resulting surface with reference.
848 class TexelFetchTestCase : public FramebufferFetchTestCase
851 TexelFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format);
852 ~TexelFetchTestCase (void) {}
854 IterateResult iterate (void);
857 glu::ProgramSources genShaderSources (void);
858 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor);
859 void genSamplerTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd);
861 GLuint m_samplerTexture;
864 TexelFetchTestCase::TexelFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format)
865 : FramebufferFetchTestCase(context, name, desc, format)
866 , m_samplerTexture(0)
870 void TexelFetchTestCase::genSamplerTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd)
872 tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
874 m_gl.activeTexture(GL_TEXTURE1);
876 m_gl.genTextures(1, &m_samplerTexture);
877 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
878 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
879 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
881 tcu::fillWithGrid(data.getAccess(), 8, colorEven, colorOdd);
883 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
884 m_gl.bindTexture(GL_TEXTURE_2D, 0);
886 const GLuint samplerLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_sampler");
887 m_gl.uniform1i(samplerLocation, 1);
889 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genSamplerTexture()");
892 glu::ProgramSources TexelFetchTestCase::genShaderSources (void)
894 const string vecType = getColorOutputType(m_texFmt);
895 std::ostringstream fragShaderSource;
897 fragShaderSource << "#version 310 es\n"
898 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
899 << "layout(location = 0) inout highp " << vecType << " o_color;\n"
901 << "uniform sampler2D u_sampler;\n"
902 << "void main (void)\n"
904 << " o_color += texelFetch(u_sampler, ivec2(gl_FragCoord), 0);\n"
907 return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
910 tcu::TextureLevel TexelFetchTestCase::genReferenceTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor)
912 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
913 tcu::fillWithGrid(reference.getAccess(), 8, colorEven + fbColor, colorOdd + fbColor);
918 TexelFetchTestCase::IterateResult TexelFetchTestCase::iterate (void)
920 const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f));
921 const tcu::Vec4 colorEven = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f));
922 const tcu::Vec4 colorOdd = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f));
924 genSamplerTexture(colorEven, colorOdd);
925 tcu::TextureLevel reference = genReferenceTexture(colorEven, colorOdd, fbColor);
926 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
928 genFramebufferWithTexture(fbColor);
931 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
932 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
935 m_gl.deleteTextures(1, &m_samplerTexture);
941 // - Attach texture containing solid color to framebuffer.
942 // - Draw full screen quad covering the entire viewport.
943 // - Multiple assignments are made to the output color for fragments on the right vertical half of the screen.
944 // - A single assignment is made to the output color for fragments on the left vertical centre of the screen.
945 // - Values are calculated using the sum of the passed in uniform color and the previous framebuffer color.
946 // - Compare resulting surface with reference.
948 class MultipleAssignmentTestCase : public FramebufferFetchTestCase
951 MultipleAssignmentTestCase (Context& context, const char* name, const char* desc, deUint32 format);
952 ~MultipleAssignmentTestCase (void) {}
954 IterateResult iterate (void);
957 glu::ProgramSources genShaderSources (void);
958 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
961 MultipleAssignmentTestCase::MultipleAssignmentTestCase (Context& context, const char* name, const char* desc, deUint32 format)
962 : FramebufferFetchTestCase(context, name, desc, format)
966 glu::ProgramSources MultipleAssignmentTestCase::genShaderSources (void)
968 const string vecType = getColorOutputType(m_texFmt);
969 std::ostringstream vertShaderSource;
970 std::ostringstream fragShaderSource;
972 vertShaderSource << "#version 310 es\n"
973 << "in highp vec4 a_position;\n"
974 << "out highp vec4 v_position;\n"
976 << "void main (void)\n"
978 << " gl_Position = a_position;\n"
979 << " v_position = gl_Position;\n"
982 fragShaderSource << "#version 310 es\n"
983 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
984 << "in highp vec4 v_position;\n"
985 << "layout(location = 0) inout highp " << vecType << " o_color;\n"
986 << "uniform highp " << vecType << " u_color;\n"
988 << "void main (void)\n"
990 << " if (v_position.x > 0.0f)\n"
991 << " o_color += u_color;\n"
993 << " o_color += u_color;\n"
996 return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str());
999 tcu::TextureLevel MultipleAssignmentTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
1001 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1003 int width = reference.getAccess().getWidth();
1004 int height = reference.getAccess().getHeight();
1005 int left = width /2;
1008 tcu::Vec4 compositeColor(uniformColor * 2.0f);
1010 tcu::clear(getSubregion(reference.getAccess(), left, 0, 0, width-left, top, 1), fbColor + compositeColor);
1011 tcu::clear(getSubregion(reference.getAccess(), 0, top, 0, left, height-top, 1), fbColor + uniformColor);
1012 tcu::clear(getSubregion(reference.getAccess(), left, top, 0, width-left, height-top, 1), fbColor + compositeColor);
1013 tcu::clear(getSubregion(reference.getAccess(), 0, 0, 0, left, top, 1), fbColor + uniformColor);
1018 MultipleAssignmentTestCase::IterateResult MultipleAssignmentTestCase::iterate (void)
1020 const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
1021 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.25f, 0.0f, 0.0f, 1.0f));
1023 tcu::TextureLevel reference = genReferenceTexture(fbColor, uniformColor);
1024 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1026 genFramebufferWithTexture(fbColor);
1027 genUniformColor(uniformColor);
1030 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1031 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1036 // Test description:
1037 // - Attach texture containing grid pattern to framebuffer.
1038 // - Using framebuffer reads discard odd squares in the grid.
1039 // - The even squares framebuffer color is added to the passed in uniform color.
1041 class FragmentDiscardTestCase : public FramebufferFetchTestCase
1044 FragmentDiscardTestCase (Context& context, const char* name, const char* desc, deUint32 format);
1045 ~FragmentDiscardTestCase (void) {}
1047 IterateResult iterate (void);
1050 glu::ProgramSources genShaderSources (void);
1051 void genFramebufferWithGrid (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd);
1052 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd);
1055 FragmentDiscardTestCase::FragmentDiscardTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1056 : FramebufferFetchTestCase(context, name, desc, format)
1060 glu::ProgramSources FragmentDiscardTestCase::genShaderSources (void)
1062 const string vecType = getColorOutputType(m_texFmt);
1063 std::ostringstream fragShaderSource;
1065 fragShaderSource << "#version 310 es\n"
1066 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
1067 << "layout(location = 0) inout highp " << vecType << " o_color;\n"
1068 << "uniform highp " << vecType << " u_color;\n"
1070 << "void main (void)\n"
1072 << " const highp float threshold = 0.0005f;\n"
1073 << " bool valuesEqual = all(lessThan(abs(o_color - u_color), vec4(threshold)));\n\n"
1074 << " if (valuesEqual)\n"
1075 << " o_color += u_color;\n"
1080 return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
1083 void FragmentDiscardTestCase::genFramebufferWithGrid (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd)
1085 tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1087 m_gl.genFramebuffers(1, &m_framebuffer);
1088 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
1090 m_gl.genTextures(1, &m_texColorBuffer);
1091 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
1093 tcu::fillWithGrid(data.getAccess(), 8, fbColorEven, fbColorOdd);
1095 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
1096 m_gl.bindTexture(GL_TEXTURE_2D, 0);
1098 m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0);
1099 TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
1102 tcu::TextureLevel FragmentDiscardTestCase::genReferenceTexture (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd)
1104 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1105 tcu::fillWithGrid(reference.getAccess(), 8, fbColorEven + fbColorEven, fbColorOdd);
1110 FragmentDiscardTestCase::IterateResult FragmentDiscardTestCase::iterate (void)
1112 const tcu::Vec4 fbColorEven = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 1.0f, 1.0f));
1113 const tcu::Vec4 fbColorOdd = scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f));
1115 tcu::TextureLevel reference = genReferenceTexture(fbColorEven, fbColorOdd);
1116 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1117 genFramebufferWithGrid(fbColorEven, fbColorOdd);
1119 genUniformColor(fbColorEven);
1122 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1123 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1128 // Test description:
1129 // - Create 2D texture array containing three mipmaps.
1130 // - Each mipmap level is assigned a different color.
1131 // - Attach single mipmap level to framebuffer and draw full screen quad.
1132 // - Sum framebuffer read color with passed in uniform color.
1133 // - Compare resulting surface with reference.
1134 // - Repeat for subsequent mipmap levels.
1136 class TextureLevelTestCase : public FramebufferFetchTestCase
1139 TextureLevelTestCase (Context& context, const char* name, const char* desc, deUint32 format);
1140 ~TextureLevelTestCase (void) {}
1142 IterateResult iterate (void);
1145 void create2DTextureArrayMipMaps (const vector<tcu::Vec4>& colors);
1146 tcu::TextureLevel genReferenceTexture (int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor);
1147 void genReferenceMipmap (const tcu::Vec4& color, tcu::TextureLevel& reference);
1150 TextureLevelTestCase::TextureLevelTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1151 : FramebufferFetchTestCase(context, name, desc, format)
1155 void TextureLevelTestCase::create2DTextureArrayMipMaps (const vector<tcu::Vec4>& colors)
1157 int numLevels = (int)colors.size();
1158 tcu::TextureLevel levelData (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType));
1160 m_gl.genTextures(1, &m_texColorBuffer);
1161 m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer);
1163 m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1, 0, m_transferFmt.format, m_transferFmt.dataType, DE_NULL);
1164 m_gl.generateMipmap(GL_TEXTURE_2D_ARRAY);
1166 for (int level = 0; level < numLevels; level++)
1168 int levelW = de::max(1, VIEWPORT_WIDTH >> level);
1169 int levelH = de::max(1, VIEWPORT_HEIGHT >> level);
1171 levelData.setSize(levelW, levelH, 1);
1173 clear(levelData.getAccess(), colors[level]);
1174 m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, level, m_format, levelW, levelH, 1, 0, m_transferFmt.format, m_transferFmt.dataType, levelData.getAccess().getDataPtr());
1177 m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
1178 GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayMipMaps()");
1181 tcu::TextureLevel TextureLevelTestCase::genReferenceTexture (int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor)
1183 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level, 1);
1185 genReferenceMipmap(colors[level] + uniformColor, reference);
1190 void TextureLevelTestCase::genReferenceMipmap (const tcu::Vec4& color, tcu::TextureLevel& reference)
1192 const int width = reference.getAccess().getWidth();
1193 const int height = reference.getAccess().getHeight();
1194 const int left = width / 2;
1195 const int top = height / 2;
1197 clear(getSubregion(reference.getAccess(), left, 0, 0, width-left, top, 1), color);
1198 clear(getSubregion(reference.getAccess(), 0, top, 0, left, height-top, 1), color);
1199 clear(getSubregion(reference.getAccess(), left, top, 0, width-left, height-top, 1), color);
1200 clear(getSubregion(reference.getAccess(), 0, 0, 0, left, top, 1), color);
1203 TextureLevelTestCase::IterateResult TextureLevelTestCase::iterate (void)
1205 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.0f, 0.0f, 1.0f));
1206 vector<tcu::Vec4> levelColors;
1208 levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f)));
1209 levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f)));
1210 levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
1212 m_gl.genFramebuffers(1, &m_framebuffer);
1213 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
1215 create2DTextureArrayMipMaps(levelColors);
1217 // attach successive mipmap layers to framebuffer and render
1218 for (int level = 0; level < (int)levelColors.size(); ++level)
1220 std::ostringstream name, desc;
1221 name << "Level " << level;
1222 desc << "Mipmap level " << level;
1224 const tcu::ScopedLogSection section (m_testCtx.getLog(), name.str(), desc.str());
1225 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level);
1226 tcu::TextureLevel reference = genReferenceTexture(level, levelColors, uniformColor);
1228 m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, level, 0);
1230 genUniformColor(uniformColor);
1233 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1234 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1236 if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
1243 class TextureLayerTestCase : public FramebufferFetchTestCase
1246 TextureLayerTestCase (Context& context, const char* name, const char* desc, deUint32 format);
1247 ~TextureLayerTestCase (void) {}
1249 IterateResult iterate (void);
1252 void create2DTextureArrayLayers (const vector<tcu::Vec4>& colors);
1253 tcu::TextureLevel genReferenceTexture (int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor);
1256 TextureLayerTestCase::TextureLayerTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1257 : FramebufferFetchTestCase(context, name, desc, format)
1261 void TextureLayerTestCase::create2DTextureArrayLayers (const vector<tcu::Vec4>& colors)
1263 int numLayers = (int)colors.size();
1264 tcu::TextureLevel layerData (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType));
1266 m_gl.genTextures(1, &m_texColorBuffer);
1267 m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer);
1268 m_gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers);
1269 m_gl.bindImageTexture(0, m_texColorBuffer, 0, GL_FALSE, 0, GL_READ_ONLY, m_format);
1271 layerData.setSize(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers);
1273 for (int layer = 0; layer < numLayers; layer++)
1275 clear(layerData.getAccess(), colors[layer]);
1276 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());
1279 m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
1280 GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayLayers()");
1283 tcu::TextureLevel TextureLayerTestCase::genReferenceTexture (int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor)
1285 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1286 clear(reference.getAccess(), colors[layer] + uniformColor);
1292 // - Create 2D texture array containing three layers.
1293 // - Each layer is assigned a different color.
1294 // - Attach single layer to framebuffer and draw full screen quad.
1295 // - Sum framebuffer read color with passed in uniform color.
1296 // - Compare resulting surface with reference.
1297 // - Repeat for subsequent texture layers.
1299 TextureLayerTestCase::IterateResult TextureLayerTestCase::iterate (void)
1301 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
1302 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1303 vector<tcu::Vec4> layerColors;
1305 layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f)));
1306 layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f)));
1307 layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
1309 m_gl.genFramebuffers(1, &m_framebuffer);
1310 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
1312 create2DTextureArrayLayers(layerColors);
1314 for (int layer = 0; layer < (int)layerColors.size(); ++layer)
1316 std::ostringstream name, desc;
1317 name << "Layer " << layer;
1318 desc << "Layer " << layer;
1320 const tcu::ScopedLogSection section (m_testCtx.getLog(), name.str(), desc.str());
1321 tcu::TextureLevel reference = genReferenceTexture(layer, layerColors, uniformColor);
1323 m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, 0, layer);
1325 genUniformColor(uniformColor);
1328 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1329 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1331 if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
1340 ShaderFramebufferFetchTests::ShaderFramebufferFetchTests (Context& context)
1341 : TestCaseGroup (context, "framebuffer_fetch", "GL_EXT_shader_framebuffer_fetch tests")
1345 ShaderFramebufferFetchTests::~ShaderFramebufferFetchTests (void)
1349 void ShaderFramebufferFetchTests::init (void)
1351 tcu::TestCaseGroup* const basicTestGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic framebuffer shader fetch tests");
1352 tcu::TestCaseGroup* const framebufferFormatTestGroup = new tcu::TestCaseGroup(m_testCtx, "framebuffer_format", "Texture render target formats tests");
1356 basicTestGroup->addChild(new TexelFetchTestCase (m_context, "texel_fetch", "Framebuffer fetches in conjunction with shader texel fetches", GL_RGBA8));
1357 basicTestGroup->addChild(new LastFragDataTestCase (m_context, "last_frag_data", "Framebuffer fetches with built-in fragment output of ES 2.0", GL_RGBA8));
1358 basicTestGroup->addChild(new FragmentDiscardTestCase (m_context, "fragment_discard", "Framebuffer fetches in combination with fragment discards", GL_RGBA8));
1359 basicTestGroup->addChild(new MultipleAssignmentTestCase (m_context, "multiple_assignment", "Multiple assignments to fragment color inout", GL_RGBA8));
1360 basicTestGroup->addChild(new MultipleRenderTargetsTestCase (m_context, "multiple_render_targets", "Framebuffer fetches used in combination with multiple render targets", GL_RGBA8));
1361 basicTestGroup->addChild(new TextureLevelTestCase (m_context, "framebuffer_texture_level", "Framebuffer fetches with individual texture render target mipmaps", GL_RGBA8));
1362 basicTestGroup->addChild(new TextureLayerTestCase (m_context, "framebuffer_texture_layer", "Framebuffer fetches with individual texture render target layers", GL_RGBA8));
1365 // framebuffer formats
1367 static const deUint32 colorFormats[] =
1379 GL_RGB10_A2UI, GL_RGBA4, GL_RGB5_A1,
1403 // GL_EXT_color_buffer_float
1412 // GL_EXT_color_buffer_half_float
1416 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
1417 framebufferFormatTestGroup->addChild(new TextureFormatTestCase(m_context, getFormatName(colorFormats[ndx]), "Framebuffer fetches from texture attachments with varying formats", colorFormats[ndx]));
1420 addChild(basicTestGroup);
1421 addChild(framebufferFormatTestGroup);