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");
224 case GL_R11F_G11F_B10F:
228 out.push_back("GL_EXT_color_buffer_float");
238 void checkFormatSupport (Context& context, deUint32 sizedFormat)
240 const bool isCoreFormat = isRequiredFormat(sizedFormat, context.getRenderContext());
241 const std::vector<std::string> requiredExts = (!isCoreFormat) ? getEnablingExtensions(sizedFormat, context.getRenderContext()) : std::vector<std::string>();
243 // Check that we don't try to use invalid formats.
244 DE_ASSERT(isCoreFormat || !requiredExts.empty());
246 if (!requiredExts.empty() && !isAnyExtensionSupported(context, requiredExts))
247 throw tcu::NotSupportedError("Format not supported");
250 tcu::Vec4 scaleColorValue (tcu::TextureFormat format, const tcu::Vec4& color)
252 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(format);
253 const tcu::Vec4 cScale = fmtInfo.valueMax-fmtInfo.valueMin;
254 const tcu::Vec4 cBias = fmtInfo.valueMin;
256 return tcu::RGBA(color).toVec() * cScale + cBias;
259 // Base class for framebuffer fetch test cases
261 class FramebufferFetchTestCase : public TestCase
264 FramebufferFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format);
265 ~FramebufferFetchTestCase (void);
271 string genPassThroughVertSource (void);
272 virtual glu::ProgramSources genShaderSources (void);
274 void genFramebufferWithTexture (const tcu::Vec4& color);
275 void genAttachementTexture (const tcu::Vec4& color);
276 void genUniformColor (const tcu::Vec4& color);
279 void verifyRenderbuffer (TestLog& log, const tcu::TextureFormat& format, const tcu::TextureLevel& reference, const tcu::TextureLevel& result);
281 const glw::Functions& m_gl;
282 const deUint32 m_format;
284 glu::ShaderProgram* m_program;
285 GLuint m_framebuffer;
286 GLuint m_texColorBuffer;
288 tcu::TextureFormat m_texFmt;
289 glu::TransferFormat m_transferFmt;
295 VIEWPORT_HEIGHT = 64,
299 FramebufferFetchTestCase::FramebufferFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format)
300 : TestCase (context, name, desc)
301 , m_gl (m_context.getRenderContext().getFunctions())
303 , m_program (DE_NULL)
305 , m_texColorBuffer (0)
306 , m_texFmt (glu::mapGLInternalFormat(m_format))
307 , m_transferFmt (glu::getTransferFormat(m_texFmt))
308 , m_isFilterable (glu::isGLInternalColorFormatFilterable(m_format))
312 FramebufferFetchTestCase::~FramebufferFetchTestCase (void)
314 FramebufferFetchTestCase::deinit();
317 void FramebufferFetchTestCase::init (void)
319 checkFramebufferFetchSupport (m_context);
320 checkFormatSupport(m_context, m_format);
322 if (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)) && tcu::isSRGB(m_texFmt)) {
323 m_gl.enable(GL_FRAMEBUFFER_SRGB);
326 DE_ASSERT(!m_program);
327 m_program = new glu::ShaderProgram(m_context.getRenderContext(), genShaderSources());
329 m_testCtx.getLog() << *m_program;
331 if (!m_program->isOk())
335 TCU_FAIL("Failed to compile shader program");
338 m_gl.useProgram(m_program->getProgram());
341 void FramebufferFetchTestCase::deinit (void)
346 if (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))) {
347 m_gl.disable(GL_FRAMEBUFFER_SRGB);
352 m_gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
353 m_gl.deleteFramebuffers(1, &m_framebuffer);
357 if (m_texColorBuffer)
359 m_gl.deleteTextures(1, &m_texColorBuffer);
360 m_texColorBuffer = 0;
364 string FramebufferFetchTestCase::genPassThroughVertSource (void)
366 std::ostringstream vertShaderSource;
368 vertShaderSource << "#version 310 es\n"
369 << "in highp vec4 a_position;\n"
371 << "void main (void)\n"
373 << " gl_Position = a_position;\n"
376 return vertShaderSource.str();
379 glu::ProgramSources FramebufferFetchTestCase::genShaderSources (void)
381 const string vecType = getColorOutputType(m_texFmt);
382 std::ostringstream fragShaderSource;
383 tcu::TextureChannelClass textureChannelClass = tcu::getTextureChannelClass(m_texFmt.type);
384 tcu::Vec4 maxValue = getTextureFormatInfo(m_texFmt).valueMax;
385 tcu::Vec4 minValue = getTextureFormatInfo(m_texFmt).valueMin;
389 if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
391 maxStr = de::toString(maxValue.asUint());
392 minStr = de::toString(minValue.asUint());
394 else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
396 maxStr = de::toString(maxValue.asInt());
397 minStr = de::toString(minValue.asInt());
401 maxStr = de::toString(maxValue);
402 minStr = de::toString(minValue);
405 fragShaderSource << "#version 310 es\n"
406 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
407 << "layout(location = 0) inout highp " << vecType << " o_color;\n"
408 << "uniform highp " << vecType << " u_color;\n"
410 << "void main (void)\n"
412 << " o_color = clamp(o_color + u_color, " << vecType << minStr << ", " << vecType << maxStr << ");\n"
415 return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
418 void FramebufferFetchTestCase::genFramebufferWithTexture (const tcu::Vec4& color)
420 m_gl.genFramebuffers(1, &m_framebuffer);
421 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
423 genAttachementTexture(color);
424 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachementTexture()");
426 m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0);
427 TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
430 void FramebufferFetchTestCase::genAttachementTexture (const tcu::Vec4& color)
432 tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
433 tcu::TextureChannelClass textureChannelClass = tcu::getTextureChannelClass(m_texFmt.type);
435 m_gl.genTextures(1, &m_texColorBuffer);
436 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
438 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
439 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
440 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
441 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST);
442 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST);
444 if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
445 tcu::clear(data.getAccess(), color.asUint());
446 else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
447 tcu::clear(data.getAccess(), color.asInt());
449 tcu::clear(data.getAccess(), color);
451 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
452 m_gl.bindTexture(GL_TEXTURE_2D, 0);
455 void FramebufferFetchTestCase::verifyRenderbuffer (TestLog& log, const tcu::TextureFormat& format, const tcu::TextureLevel& reference, const tcu::TextureLevel& result)
457 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
459 switch (tcu::getTextureChannelClass(format.type))
461 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
463 const string name = "Renderbuffer";
464 const string desc = "Compare renderbuffer (floating_point)";
465 const tcu::UVec4 threshold = getFloatULPThreshold(format, result.getFormat());
467 if (!tcu::floatUlpThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
468 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
473 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
474 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
476 const string name = "Renderbuffer";
477 const string desc = "Compare renderbuffer (integer)";
478 const tcu::UVec4 threshold (1, 1, 1, 1);
480 if (!tcu::intThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
481 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
486 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
487 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
489 const string name = "Renderbuffer";
490 const string desc = "Compare renderbuffer (fixed point)";
491 const tcu::Vec4 threshold = getFixedPointFormatThreshold(format, result.getFormat());
493 if (!tcu::floatThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
494 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
502 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
507 void FramebufferFetchTestCase::genUniformColor (const tcu::Vec4& color)
509 const GLuint colorLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_color");
511 switch (tcu::getTextureChannelClass(m_texFmt.type))
513 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
515 m_gl.uniform4uiv(colorLocation, 1, color.asUint().getPtr());
519 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
521 m_gl.uniform4iv(colorLocation, 1, color.asInt().getPtr());
524 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
525 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
526 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
528 m_gl.uniform4fv(colorLocation, 1, color.asFloat().getPtr());
535 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genUniformColor()");
538 void FramebufferFetchTestCase::render (void)
540 const GLfloat coords[] =
548 const GLushort indices[] =
554 m_gl.genVertexArrays(1, &vaoID);
555 m_gl.bindVertexArray(vaoID);
557 const GLuint coordLocation = m_gl.getAttribLocation(m_program->getProgram(), "a_position");
559 m_gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
561 glu::Buffer coordinatesBuffer(m_context.getRenderContext());
562 glu::Buffer elementsBuffer(m_context.getRenderContext());
564 m_gl.bindBuffer(GL_ARRAY_BUFFER, *coordinatesBuffer);
565 m_gl.bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW);
566 m_gl.enableVertexAttribArray(coordLocation);
567 m_gl.vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL);
569 m_gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *elementsBuffer);
570 m_gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0], GL_STATIC_DRAW);
572 m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL);
573 GLU_EXPECT_NO_ERROR(m_gl.getError(), "render()");
575 m_gl.deleteVertexArrays(1, &vaoID);
579 // - Attach texture containing solid color to framebuffer.
580 // - Draw full quad covering the entire viewport.
581 // - Sum framebuffer read color with passed in uniform color.
582 // - Compare resulting surface with reference.
584 class TextureFormatTestCase : public FramebufferFetchTestCase
587 TextureFormatTestCase (Context& context, const char* name, const char* desc, deUint32 format);
588 ~TextureFormatTestCase (void) {}
590 IterateResult iterate (void);
593 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
596 TextureFormatTestCase::TextureFormatTestCase (Context& context, const char* name, const char* desc, deUint32 format)
597 : FramebufferFetchTestCase(context, name, desc, format)
601 tcu::TextureLevel TextureFormatTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
603 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
604 tcu::TextureChannelClass textureChannelClass = tcu::getTextureChannelClass(m_texFmt.type);
606 tcu::Vec4 formatMaxValue = getTextureFormatInfo(m_texFmt).valueMax;
607 tcu::Vec4 formatMinValue = getTextureFormatInfo(m_texFmt).valueMin;
610 if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
612 tcu::clear(reference.getAccess(), tcu::clamp(fbColor.asUint() + uniformColor.asUint(), formatMinValue.asUint(), formatMaxValue.asUint()));
614 else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
616 tcu::IVec4 clearColor;
618 // Calculate using 64 bits to avoid signed integer overflow.
619 for (int i = 0; i < 4; i++)
620 clearColor[i] = static_cast<int>((static_cast<deInt64>(fbColor.asInt()[i]) + static_cast<deInt64>(uniformColor.asInt()[i])) & 0xffffffff);
622 tcu::clear(reference.getAccess(), clearColor);
626 if (tcu::isSRGB(m_texFmt))
628 const tcu::Vec4 fragmentColor = tcu::clamp(tcu::sRGBToLinear(fbColor) + uniformColor, formatMinValue, formatMaxValue);
629 tcu::clear(reference.getAccess(), tcu::linearToSRGB(fragmentColor));
633 tcu::clear(reference.getAccess(), tcu::clamp(fbColor + uniformColor, formatMinValue, formatMaxValue));
640 TextureFormatTestCase::IterateResult TextureFormatTestCase::iterate (void)
642 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
643 const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
645 tcu::TextureLevel reference = genReferenceTexture(fbColor, uniformColor);
646 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
648 genFramebufferWithTexture(fbColor);
649 genUniformColor(uniformColor);
652 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
653 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
659 // - Attach multiple textures containing solid colors to framebuffer.
660 // - Draw full quad covering the entire viewport.
661 // - For each render target sum framebuffer read color with passed in uniform color.
662 // - Compare resulting surfaces with references.
664 class MultipleRenderTargetsTestCase : public FramebufferFetchTestCase
667 MultipleRenderTargetsTestCase (Context& context, const char* name, const char* desc, deUint32 format);
668 ~MultipleRenderTargetsTestCase (void);
670 IterateResult iterate (void);
674 void genFramebufferWithTextures (const vector<tcu::Vec4>& colors);
675 void genAttachmentTextures (const vector<tcu::Vec4>& colors);
676 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
677 glu::ProgramSources genShaderSources (void);
681 MAX_COLOR_BUFFERS = 4
684 GLuint m_texColorBuffers [MAX_COLOR_BUFFERS];
685 GLenum m_colorBuffers [MAX_COLOR_BUFFERS];
688 MultipleRenderTargetsTestCase::MultipleRenderTargetsTestCase (Context& context, const char* name, const char* desc, deUint32 format)
689 : FramebufferFetchTestCase(context, name, desc, format)
690 , m_texColorBuffers ()
692 m_colorBuffers[0] = GL_COLOR_ATTACHMENT0;
693 m_colorBuffers[1] = GL_COLOR_ATTACHMENT1;
694 m_colorBuffers[2] = GL_COLOR_ATTACHMENT2;
695 m_colorBuffers[3] = GL_COLOR_ATTACHMENT3;
698 MultipleRenderTargetsTestCase::~MultipleRenderTargetsTestCase (void)
700 MultipleRenderTargetsTestCase::deinit();
703 void MultipleRenderTargetsTestCase::deinit (void)
705 // Clean up texture data
706 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
708 if (m_texColorBuffers[i])
709 m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texColorBuffers[i]);
712 FramebufferFetchTestCase::deinit();
715 void MultipleRenderTargetsTestCase::genFramebufferWithTextures (const vector<tcu::Vec4>& colors)
717 m_gl.genFramebuffers(1, &m_framebuffer);
718 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
720 genAttachmentTextures(colors);
722 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
723 m_gl.framebufferTexture2D(GL_FRAMEBUFFER, m_colorBuffers[i], GL_TEXTURE_2D, m_texColorBuffers[i], 0);
725 TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
727 m_gl.drawBuffers((glw::GLsizei)MAX_COLOR_BUFFERS, &m_colorBuffers[0]);
728 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genFramebufferWithTextures()");
731 void MultipleRenderTargetsTestCase::genAttachmentTextures (const vector<tcu::Vec4>& colors)
733 tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
735 m_gl.genTextures(MAX_COLOR_BUFFERS, m_texColorBuffers);
737 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
739 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffers[i]);
741 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
742 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
743 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
744 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST);
745 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST);
747 clear(data.getAccess(), colors[i]);
748 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
751 m_gl.bindTexture(GL_TEXTURE_2D, 0);
752 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachmentTextures()");
755 tcu::TextureLevel MultipleRenderTargetsTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
757 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
758 tcu::clear(reference.getAccess(), fbColor + uniformColor);
763 glu::ProgramSources MultipleRenderTargetsTestCase::genShaderSources (void)
765 const string vecType = getColorOutputType(m_texFmt);
766 std::ostringstream fragShaderSource;
768 fragShaderSource << "#version 310 es\n"
769 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
770 << "layout(location = 0) inout highp " << vecType << " o_color0;\n"
771 << "layout(location = 1) inout highp " << vecType << " o_color1;\n"
772 << "layout(location = 2) inout highp " << vecType << " o_color2;\n"
773 << "layout(location = 3) inout highp " << vecType << " o_color3;\n"
774 << "uniform highp " << vecType << " u_color;\n"
776 << "void main (void)\n"
778 << " o_color0 += u_color;\n"
779 << " o_color1 += u_color;\n"
780 << " o_color2 += u_color;\n"
781 << " o_color3 += u_color;\n"
784 return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
787 MultipleRenderTargetsTestCase::IterateResult MultipleRenderTargetsTestCase::iterate (void)
789 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
790 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
792 vector<tcu::Vec4> colors;
793 colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.9f, 0.0f, 0.0f, 1.0f)));
794 colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.0f, 1.0f)));
795 colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.9f, 1.0f)));
796 colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.9f, 1.0f)));
798 genFramebufferWithTextures(colors);
799 genUniformColor(uniformColor);
802 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_colorBuffers); ++i)
804 tcu::TextureLevel reference = genReferenceTexture(colors[i], uniformColor);
806 m_gl.readBuffer(m_colorBuffers[i]);
807 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
808 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
815 // - Same as TextureFormatTestCase except uses built-in fragment output of ES 2.0
817 class LastFragDataTestCase : public FramebufferFetchTestCase
820 LastFragDataTestCase (Context& context, const char* name, const char* desc, deUint32 format);
821 ~LastFragDataTestCase (void) {}
823 IterateResult iterate (void);
826 glu::ProgramSources genShaderSources (void);
827 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
830 LastFragDataTestCase::LastFragDataTestCase (Context& context, const char* name, const char* desc, deUint32 format)
831 : FramebufferFetchTestCase(context, name, desc, format)
835 glu::ProgramSources LastFragDataTestCase::genShaderSources (void)
837 const string vecType = getColorOutputType(m_texFmt);
838 std::ostringstream vertShaderSource;
839 std::ostringstream fragShaderSource;
841 vertShaderSource << "#version 100\n"
842 << "attribute vec4 a_position;\n"
844 << "void main (void)\n"
846 << " gl_Position = a_position;\n"
849 fragShaderSource << "#version 100\n"
850 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
851 << "uniform highp " << vecType << " u_color;\n"
853 << "void main (void)\n"
855 << " gl_FragColor = u_color + gl_LastFragData[0];\n"
858 return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str());
861 tcu::TextureLevel LastFragDataTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
863 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
864 tcu::clear(reference.getAccess(), fbColor + uniformColor);
869 LastFragDataTestCase::IterateResult LastFragDataTestCase::iterate (void)
871 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
872 const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
874 tcu::TextureLevel reference = genReferenceTexture(fbColor, uniformColor);
875 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
877 genFramebufferWithTexture(fbColor);
878 genUniformColor(uniformColor);
881 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
882 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
888 // - Attach texture containing solid color to framebuffer.
889 // - Create one 2D texture for sampler with a grid pattern
890 // - Draw full screen quad covering the entire viewport.
891 // - Sum color values taken from framebuffer texture and sampled texture
892 // - Compare resulting surface with reference.
894 class TexelFetchTestCase : public FramebufferFetchTestCase
897 TexelFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format);
898 ~TexelFetchTestCase (void) {}
900 IterateResult iterate (void);
903 glu::ProgramSources genShaderSources (void);
904 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor);
905 void genSamplerTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd);
907 GLuint m_samplerTexture;
910 TexelFetchTestCase::TexelFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format)
911 : FramebufferFetchTestCase(context, name, desc, format)
912 , m_samplerTexture(0)
916 void TexelFetchTestCase::genSamplerTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd)
918 tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
920 m_gl.activeTexture(GL_TEXTURE1);
922 m_gl.genTextures(1, &m_samplerTexture);
923 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
924 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
925 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
927 tcu::fillWithGrid(data.getAccess(), 8, colorEven, colorOdd);
929 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
930 m_gl.bindTexture(GL_TEXTURE_2D, 0);
932 const GLuint samplerLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_sampler");
933 m_gl.uniform1i(samplerLocation, 1);
935 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genSamplerTexture()");
938 glu::ProgramSources TexelFetchTestCase::genShaderSources (void)
940 const string vecType = getColorOutputType(m_texFmt);
941 std::ostringstream fragShaderSource;
943 fragShaderSource << "#version 310 es\n"
944 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
945 << "layout(location = 0) inout highp " << vecType << " o_color;\n"
947 << "uniform sampler2D u_sampler;\n"
948 << "void main (void)\n"
950 << " o_color += texelFetch(u_sampler, ivec2(gl_FragCoord), 0);\n"
953 return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
956 tcu::TextureLevel TexelFetchTestCase::genReferenceTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor)
958 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
959 tcu::fillWithGrid(reference.getAccess(), 8, colorEven + fbColor, colorOdd + fbColor);
964 TexelFetchTestCase::IterateResult TexelFetchTestCase::iterate (void)
966 const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f));
967 const tcu::Vec4 colorEven = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f));
968 const tcu::Vec4 colorOdd = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f));
970 genSamplerTexture(colorEven, colorOdd);
971 tcu::TextureLevel reference = genReferenceTexture(colorEven, colorOdd, fbColor);
972 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
974 genFramebufferWithTexture(fbColor);
977 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
978 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
981 m_gl.deleteTextures(1, &m_samplerTexture);
987 // - Attach texture containing solid color to framebuffer.
988 // - Draw full screen quad covering the entire viewport.
989 // - Multiple assignments are made to the output color for fragments on the right vertical half of the screen.
990 // - A single assignment is made to the output color for fragments on the left vertical centre of the screen.
991 // - Values are calculated using the sum of the passed in uniform color and the previous framebuffer color.
992 // - Compare resulting surface with reference.
994 class MultipleAssignmentTestCase : public FramebufferFetchTestCase
997 MultipleAssignmentTestCase (Context& context, const char* name, const char* desc, deUint32 format);
998 ~MultipleAssignmentTestCase (void) {}
1000 IterateResult iterate (void);
1003 glu::ProgramSources genShaderSources (void);
1004 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
1007 MultipleAssignmentTestCase::MultipleAssignmentTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1008 : FramebufferFetchTestCase(context, name, desc, format)
1012 glu::ProgramSources MultipleAssignmentTestCase::genShaderSources (void)
1014 const string vecType = getColorOutputType(m_texFmt);
1015 std::ostringstream vertShaderSource;
1016 std::ostringstream fragShaderSource;
1018 vertShaderSource << "#version 310 es\n"
1019 << "in highp vec4 a_position;\n"
1020 << "out highp vec4 v_position;\n"
1022 << "void main (void)\n"
1024 << " gl_Position = a_position;\n"
1025 << " v_position = gl_Position;\n"
1028 fragShaderSource << "#version 310 es\n"
1029 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
1030 << "in highp vec4 v_position;\n"
1031 << "layout(location = 0) inout highp " << vecType << " o_color;\n"
1032 << "uniform highp " << vecType << " u_color;\n"
1034 << "void main (void)\n"
1036 << " if (v_position.x > 0.0f)\n"
1037 << " o_color += u_color;\n"
1039 << " o_color += u_color;\n"
1042 return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str());
1045 tcu::TextureLevel MultipleAssignmentTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
1047 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1049 int width = reference.getAccess().getWidth();
1050 int height = reference.getAccess().getHeight();
1051 int left = width /2;
1054 tcu::Vec4 compositeColor(uniformColor * 2.0f);
1056 tcu::clear(getSubregion(reference.getAccess(), left, 0, 0, width-left, top, 1), fbColor + compositeColor);
1057 tcu::clear(getSubregion(reference.getAccess(), 0, top, 0, left, height-top, 1), fbColor + uniformColor);
1058 tcu::clear(getSubregion(reference.getAccess(), left, top, 0, width-left, height-top, 1), fbColor + compositeColor);
1059 tcu::clear(getSubregion(reference.getAccess(), 0, 0, 0, left, top, 1), fbColor + uniformColor);
1064 MultipleAssignmentTestCase::IterateResult MultipleAssignmentTestCase::iterate (void)
1066 const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
1067 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.25f, 0.0f, 0.0f, 1.0f));
1069 tcu::TextureLevel reference = genReferenceTexture(fbColor, uniformColor);
1070 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1072 genFramebufferWithTexture(fbColor);
1073 genUniformColor(uniformColor);
1076 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1077 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1082 // Test description:
1083 // - Attach texture containing grid pattern to framebuffer.
1084 // - Using framebuffer reads discard odd squares in the grid.
1085 // - The even squares framebuffer color is added to the passed in uniform color.
1087 class FragmentDiscardTestCase : public FramebufferFetchTestCase
1090 FragmentDiscardTestCase (Context& context, const char* name, const char* desc, deUint32 format);
1091 ~FragmentDiscardTestCase (void) {}
1093 IterateResult iterate (void);
1096 glu::ProgramSources genShaderSources (void);
1097 void genFramebufferWithGrid (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd);
1098 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd);
1101 FragmentDiscardTestCase::FragmentDiscardTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1102 : FramebufferFetchTestCase(context, name, desc, format)
1106 glu::ProgramSources FragmentDiscardTestCase::genShaderSources (void)
1108 const string vecType = getColorOutputType(m_texFmt);
1109 std::ostringstream fragShaderSource;
1111 fragShaderSource << "#version 310 es\n"
1112 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
1113 << "layout(location = 0) inout highp " << vecType << " o_color;\n"
1114 << "uniform highp " << vecType << " u_color;\n"
1116 << "void main (void)\n"
1118 << " const highp float threshold = 0.0005f;\n"
1119 << " bool valuesEqual = all(lessThan(abs(o_color - u_color), vec4(threshold)));\n\n"
1120 << " if (valuesEqual)\n"
1121 << " o_color += u_color;\n"
1126 return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
1129 void FragmentDiscardTestCase::genFramebufferWithGrid (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd)
1131 tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1133 m_gl.genFramebuffers(1, &m_framebuffer);
1134 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
1136 m_gl.genTextures(1, &m_texColorBuffer);
1137 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
1139 tcu::fillWithGrid(data.getAccess(), 8, fbColorEven, fbColorOdd);
1141 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
1142 m_gl.bindTexture(GL_TEXTURE_2D, 0);
1144 m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0);
1145 TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
1148 tcu::TextureLevel FragmentDiscardTestCase::genReferenceTexture (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd)
1150 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1151 tcu::fillWithGrid(reference.getAccess(), 8, fbColorEven + fbColorEven, fbColorOdd);
1156 FragmentDiscardTestCase::IterateResult FragmentDiscardTestCase::iterate (void)
1158 const tcu::Vec4 fbColorEven = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 1.0f, 1.0f));
1159 const tcu::Vec4 fbColorOdd = scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f));
1161 tcu::TextureLevel reference = genReferenceTexture(fbColorEven, fbColorOdd);
1162 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1163 genFramebufferWithGrid(fbColorEven, fbColorOdd);
1165 genUniformColor(fbColorEven);
1168 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1169 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1174 // Test description:
1175 // - Create 2D texture array containing three mipmaps.
1176 // - Each mipmap level is assigned a different color.
1177 // - Attach single mipmap level to framebuffer and draw full screen quad.
1178 // - Sum framebuffer read color with passed in uniform color.
1179 // - Compare resulting surface with reference.
1180 // - Repeat for subsequent mipmap levels.
1182 class TextureLevelTestCase : public FramebufferFetchTestCase
1185 TextureLevelTestCase (Context& context, const char* name, const char* desc, deUint32 format);
1186 ~TextureLevelTestCase (void) {}
1188 IterateResult iterate (void);
1191 void create2DTextureArrayMipMaps (const vector<tcu::Vec4>& colors);
1192 tcu::TextureLevel genReferenceTexture (int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor);
1193 void genReferenceMipmap (const tcu::Vec4& color, tcu::TextureLevel& reference);
1196 TextureLevelTestCase::TextureLevelTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1197 : FramebufferFetchTestCase(context, name, desc, format)
1201 void TextureLevelTestCase::create2DTextureArrayMipMaps (const vector<tcu::Vec4>& colors)
1203 int numLevels = (int)colors.size();
1204 tcu::TextureLevel levelData (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType));
1206 m_gl.genTextures(1, &m_texColorBuffer);
1207 m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer);
1209 m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1, 0, m_transferFmt.format, m_transferFmt.dataType, DE_NULL);
1210 m_gl.generateMipmap(GL_TEXTURE_2D_ARRAY);
1212 for (int level = 0; level < numLevels; level++)
1214 int levelW = de::max(1, VIEWPORT_WIDTH >> level);
1215 int levelH = de::max(1, VIEWPORT_HEIGHT >> level);
1217 levelData.setSize(levelW, levelH, 1);
1219 clear(levelData.getAccess(), colors[level]);
1220 m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, level, m_format, levelW, levelH, 1, 0, m_transferFmt.format, m_transferFmt.dataType, levelData.getAccess().getDataPtr());
1223 m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
1224 GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayMipMaps()");
1227 tcu::TextureLevel TextureLevelTestCase::genReferenceTexture (int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor)
1229 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level, 1);
1231 genReferenceMipmap(colors[level] + uniformColor, reference);
1236 void TextureLevelTestCase::genReferenceMipmap (const tcu::Vec4& color, tcu::TextureLevel& reference)
1238 const int width = reference.getAccess().getWidth();
1239 const int height = reference.getAccess().getHeight();
1240 const int left = width / 2;
1241 const int top = height / 2;
1243 clear(getSubregion(reference.getAccess(), left, 0, 0, width-left, top, 1), color);
1244 clear(getSubregion(reference.getAccess(), 0, top, 0, left, height-top, 1), color);
1245 clear(getSubregion(reference.getAccess(), left, top, 0, width-left, height-top, 1), color);
1246 clear(getSubregion(reference.getAccess(), 0, 0, 0, left, top, 1), color);
1249 TextureLevelTestCase::IterateResult TextureLevelTestCase::iterate (void)
1251 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.0f, 0.0f, 1.0f));
1252 vector<tcu::Vec4> levelColors;
1254 levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f)));
1255 levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f)));
1256 levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
1258 m_gl.genFramebuffers(1, &m_framebuffer);
1259 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
1261 create2DTextureArrayMipMaps(levelColors);
1263 // attach successive mipmap layers to framebuffer and render
1264 for (int level = 0; level < (int)levelColors.size(); ++level)
1266 std::ostringstream name, desc;
1267 name << "Level " << level;
1268 desc << "Mipmap level " << level;
1270 const tcu::ScopedLogSection section (m_testCtx.getLog(), name.str(), desc.str());
1271 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level);
1272 tcu::TextureLevel reference = genReferenceTexture(level, levelColors, uniformColor);
1274 m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, level, 0);
1276 genUniformColor(uniformColor);
1279 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1280 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1282 if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
1289 class TextureLayerTestCase : public FramebufferFetchTestCase
1292 TextureLayerTestCase (Context& context, const char* name, const char* desc, deUint32 format);
1293 ~TextureLayerTestCase (void) {}
1295 IterateResult iterate (void);
1298 void create2DTextureArrayLayers (const vector<tcu::Vec4>& colors);
1299 tcu::TextureLevel genReferenceTexture (int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor);
1302 TextureLayerTestCase::TextureLayerTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1303 : FramebufferFetchTestCase(context, name, desc, format)
1307 void TextureLayerTestCase::create2DTextureArrayLayers (const vector<tcu::Vec4>& colors)
1309 int numLayers = (int)colors.size();
1310 tcu::TextureLevel layerData (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType));
1312 m_gl.genTextures(1, &m_texColorBuffer);
1313 m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer);
1314 m_gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers);
1315 m_gl.bindImageTexture(0, m_texColorBuffer, 0, GL_FALSE, 0, GL_READ_ONLY, m_format);
1317 layerData.setSize(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers);
1319 for (int layer = 0; layer < numLayers; layer++)
1321 clear(layerData.getAccess(), colors[layer]);
1322 m_gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1, m_transferFmt.format, m_transferFmt.dataType, layerData.getAccess().getDataPtr());
1325 m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
1326 GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayLayers()");
1329 tcu::TextureLevel TextureLayerTestCase::genReferenceTexture (int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor)
1331 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1332 clear(reference.getAccess(), colors[layer] + uniformColor);
1338 // - Create 2D texture array containing three layers.
1339 // - Each layer is assigned a different color.
1340 // - Attach single layer to framebuffer and draw full screen quad.
1341 // - Sum framebuffer read color with passed in uniform color.
1342 // - Compare resulting surface with reference.
1343 // - Repeat for subsequent texture layers.
1345 TextureLayerTestCase::IterateResult TextureLayerTestCase::iterate (void)
1347 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
1348 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1349 vector<tcu::Vec4> layerColors;
1351 layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f)));
1352 layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f)));
1353 layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
1355 m_gl.genFramebuffers(1, &m_framebuffer);
1356 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
1358 create2DTextureArrayLayers(layerColors);
1360 for (int layer = 0; layer < (int)layerColors.size(); ++layer)
1362 std::ostringstream name, desc;
1363 name << "Layer " << layer;
1364 desc << "Layer " << layer;
1366 const tcu::ScopedLogSection section (m_testCtx.getLog(), name.str(), desc.str());
1367 tcu::TextureLevel reference = genReferenceTexture(layer, layerColors, uniformColor);
1369 m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, 0, layer);
1371 genUniformColor(uniformColor);
1374 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1375 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1377 if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
1386 ShaderFramebufferFetchTests::ShaderFramebufferFetchTests (Context& context)
1387 : TestCaseGroup (context, "framebuffer_fetch", "GL_EXT_shader_framebuffer_fetch tests")
1391 ShaderFramebufferFetchTests::~ShaderFramebufferFetchTests (void)
1395 void ShaderFramebufferFetchTests::init (void)
1397 tcu::TestCaseGroup* const basicTestGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic framebuffer shader fetch tests");
1398 tcu::TestCaseGroup* const framebufferFormatTestGroup = new tcu::TestCaseGroup(m_testCtx, "framebuffer_format", "Texture render target formats tests");
1402 basicTestGroup->addChild(new TexelFetchTestCase (m_context, "texel_fetch", "Framebuffer fetches in conjunction with shader texel fetches", GL_RGBA8));
1403 basicTestGroup->addChild(new LastFragDataTestCase (m_context, "last_frag_data", "Framebuffer fetches with built-in fragment output of ES 2.0", GL_RGBA8));
1404 basicTestGroup->addChild(new FragmentDiscardTestCase (m_context, "fragment_discard", "Framebuffer fetches in combination with fragment discards", GL_RGBA8));
1405 basicTestGroup->addChild(new MultipleAssignmentTestCase (m_context, "multiple_assignment", "Multiple assignments to fragment color inout", GL_RGBA8));
1406 basicTestGroup->addChild(new MultipleRenderTargetsTestCase (m_context, "multiple_render_targets", "Framebuffer fetches used in combination with multiple render targets", GL_RGBA8));
1407 basicTestGroup->addChild(new TextureLevelTestCase (m_context, "framebuffer_texture_level", "Framebuffer fetches with individual texture render target mipmaps", GL_RGBA8));
1408 basicTestGroup->addChild(new TextureLayerTestCase (m_context, "framebuffer_texture_layer", "Framebuffer fetches with individual texture render target layers", GL_RGBA8));
1411 // framebuffer formats
1413 static const deUint32 colorFormats[] =
1425 GL_RGB10_A2UI, GL_RGBA4, GL_RGB5_A1,
1449 // GL_EXT_color_buffer_float
1458 // GL_EXT_color_buffer_half_float
1462 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
1463 framebufferFormatTestGroup->addChild(new TextureFormatTestCase(m_context, getFormatName(colorFormats[ndx]), "Framebuffer fetches from texture attachments with varying formats", colorFormats[ndx]));
1466 addChild(basicTestGroup);
1467 addChild(framebufferFormatTestGroup);