| /*------------------------------------------------------------------------- |
| * drawElements Quality Program OpenGL ES 3.0 Module |
| * ------------------------------------------------- |
| * |
| * Copyright 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief Pixel Buffer Object tests |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "es3fPixelBufferObjectTests.hpp" |
| |
| #include "tcuTexture.hpp" |
| #include "tcuTextureUtil.hpp" |
| #include "tcuImageCompare.hpp" |
| #include "tcuTestLog.hpp" |
| #include "tcuRenderTarget.hpp" |
| |
| #include "gluTextureUtil.hpp" |
| #include "gluPixelTransfer.hpp" |
| #include "gluShaderProgram.hpp" |
| |
| #include "deRandom.hpp" |
| #include "deString.h" |
| |
| #include <string> |
| #include <sstream> |
| |
| #include "glw.h" |
| |
| using std::string; |
| using std::stringstream; |
| |
| namespace deqp |
| { |
| namespace gles3 |
| { |
| namespace Functional |
| { |
| |
| namespace |
| { |
| |
| class ReadPixelsTest : public TestCase |
| { |
| public: |
| struct TestSpec |
| { |
| enum FramebufferType |
| { |
| FRAMEBUFFERTYPE_NATIVE = 0, |
| FRAMEBUFFERTYPE_RENDERBUFFER |
| }; |
| |
| string name; |
| string description; |
| |
| bool useColorClear; |
| bool renderTriangles; |
| |
| FramebufferType framebufferType; |
| GLenum renderbufferFormat; |
| }; |
| |
| ReadPixelsTest (Context& context, const TestSpec& spec); |
| ~ReadPixelsTest (void); |
| |
| void init (void); |
| void deinit (void); |
| |
| IterateResult iterate (void); |
| |
| private: |
| void renderTriangle (const tcu::Vec3& a, const tcu::Vec3& b, const tcu::Vec3& c); |
| void clearColor (float r, float g, float b, float a); |
| |
| de::Random m_random; |
| tcu::TestLog& m_log; |
| glu::ShaderProgram* m_program; |
| |
| TestSpec::FramebufferType m_framebuffeType; |
| |
| GLenum m_renderbufferFormat; |
| tcu::TextureChannelClass m_texChannelClass; |
| |
| bool m_useColorClears; |
| bool m_renderTriangles; |
| |
| GLfloat m_colorScale; |
| }; |
| |
| |
| ReadPixelsTest::ReadPixelsTest (Context& context, const TestSpec& spec) |
| : TestCase (context, spec.name.c_str(), spec.description.c_str()) |
| , m_random (deStringHash(spec.name.c_str())) |
| , m_log (m_testCtx.getLog()) |
| , m_program (NULL) |
| , m_framebuffeType (spec.framebufferType) |
| , m_renderbufferFormat (spec.renderbufferFormat) |
| , m_texChannelClass (tcu::TEXTURECHANNELCLASS_LAST) |
| , m_useColorClears (spec.useColorClear) |
| , m_renderTriangles (spec.renderTriangles) |
| , m_colorScale (1.0f) |
| { |
| |
| if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_NATIVE) |
| { |
| m_colorScale = 1.0f; |
| } |
| else if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER) |
| { |
| m_texChannelClass = tcu::getTextureChannelClass(glu::mapGLInternalFormat(spec.renderbufferFormat).type); |
| switch (m_texChannelClass) |
| { |
| case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: |
| m_colorScale = 1.0f; |
| break; |
| |
| case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: |
| m_colorScale = 100.0f; |
| break; |
| |
| case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: |
| m_colorScale = 100.0f; |
| break; |
| |
| case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: |
| m_colorScale = 100.0f; |
| break; |
| |
| default: |
| DE_ASSERT(false); |
| } |
| } |
| else |
| DE_ASSERT(false); |
| } |
| |
| ReadPixelsTest::~ReadPixelsTest (void) |
| { |
| } |
| |
| void ReadPixelsTest::init (void) |
| { |
| // Check extensions |
| if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER) |
| { |
| bool supported = false; |
| |
| if (m_renderbufferFormat == GL_RGBA16F |
| || m_renderbufferFormat == GL_RG16F) |
| { |
| std::istringstream extensions(std::string((const char*)glGetString(GL_EXTENSIONS))); |
| std::string extension; |
| |
| while (std::getline(extensions, extension, ' ')) |
| { |
| if (extension=="GL_EXT_color_buffer_half_float") |
| { |
| supported = true; |
| break; |
| } |
| if (extension=="GL_EXT_color_buffer_float") |
| { |
| supported = true; |
| break; |
| } |
| } |
| } |
| else if (m_renderbufferFormat == GL_RGBA32F |
| || m_renderbufferFormat == GL_RG32F |
| || m_renderbufferFormat == GL_R11F_G11F_B10F) |
| { |
| std::istringstream extensions(std::string((const char*)glGetString(GL_EXTENSIONS))); |
| std::string extension; |
| |
| while (std::getline(extensions, extension, ' ')) |
| { |
| if (extension=="GL_EXT_color_buffer_float") |
| { |
| supported = true; |
| break; |
| } |
| } |
| } |
| else |
| supported = true; |
| |
| if (!supported) |
| throw tcu::NotSupportedError("Renderbuffer format not supported", "", __FILE__, __LINE__); |
| } |
| |
| std::string outtype = ""; |
| |
| if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_NATIVE) |
| outtype = "vec4"; |
| else if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER) |
| { |
| switch (m_texChannelClass) |
| { |
| case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: |
| outtype = "vec4"; |
| break; |
| |
| case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: |
| outtype = "ivec4"; |
| break; |
| |
| case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: |
| outtype = "uvec4"; |
| break; |
| |
| case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: |
| outtype = "vec4"; |
| break; |
| |
| default: |
| DE_ASSERT(false); |
| } |
| } |
| else |
| DE_ASSERT(false); |
| |
| |
| const char* vertexShaderSource = |
| "#version 300 es\n" |
| "in mediump vec3 a_position;\n" |
| "in mediump vec4 a_color;\n" |
| "uniform mediump float u_colorScale;\n" |
| "out mediump vec4 v_color;\n" |
| "void main(void)\n" |
| "{\n" |
| "\tgl_Position = vec4(a_position, 1.0);\n" |
| "\tv_color = u_colorScale * a_color;\n" |
| "}"; |
| |
| stringstream fragmentShaderSource; |
| |
| fragmentShaderSource << |
| "#version 300 es\n" |
| "in mediump vec4 v_color;\n"; |
| |
| |
| fragmentShaderSource << "layout (location = 0) out mediump " << outtype << " o_color;\n" |
| "void main(void)\n" |
| "{\n" |
| "\to_color = " << outtype << "(v_color);\n" |
| "}"; |
| |
| m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource.str())); |
| |
| if (!m_program->isOk()) |
| { |
| m_log << *m_program; |
| TCU_FAIL("Failed to compile shader"); |
| } |
| } |
| |
| void ReadPixelsTest::deinit (void) |
| { |
| if (m_program) |
| delete m_program; |
| m_program = NULL; |
| } |
| |
| void ReadPixelsTest::renderTriangle (const tcu::Vec3& a, const tcu::Vec3& b, const tcu::Vec3& c) |
| { |
| float positions[3*3]; |
| |
| positions[0] = a.x(); |
| positions[1] = a.y(); |
| positions[2] = a.z(); |
| |
| positions[3] = b.x(); |
| positions[4] = b.y(); |
| positions[5] = b.z(); |
| |
| positions[6] = c.x(); |
| positions[7] = c.y(); |
| positions[8] = c.z(); |
| |
| float colors[] = { |
| 1.0f, 0.0f, 0.0f, 1.0f, |
| 0.0f, 1.0f, 0.0f, 1.0f, |
| 0.0f, 0.0f, 1.0f, 1.0f |
| }; |
| |
| GLU_CHECK_CALL(glUseProgram(m_program->getProgram())); |
| |
| GLuint coordLoc = (GLuint)-1; |
| GLuint colorLoc = (GLuint)-1; |
| GLuint colorScaleLoc = (GLuint)-1; |
| |
| colorScaleLoc = glGetUniformLocation(m_program->getProgram(), "u_colorScale"); |
| TCU_CHECK(colorScaleLoc != (GLuint)-1); |
| |
| GLU_CHECK_CALL(glUniform1f(colorScaleLoc, m_colorScale)); |
| |
| coordLoc = glGetAttribLocation(m_program->getProgram(), "a_position"); |
| TCU_CHECK(coordLoc != (GLuint)-1); |
| |
| colorLoc = glGetAttribLocation(m_program->getProgram(), "a_color"); |
| TCU_CHECK(colorLoc != (GLuint)-1); |
| |
| GLU_CHECK_CALL(glEnableVertexAttribArray(colorLoc)); |
| GLU_CHECK_CALL(glEnableVertexAttribArray(coordLoc)); |
| |
| GLU_CHECK_CALL(glVertexAttribPointer(coordLoc, 3, GL_FLOAT, GL_FALSE, 0, positions)); |
| GLU_CHECK_CALL(glVertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, 0, colors)); |
| |
| GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 3)); |
| |
| GLU_CHECK_CALL(glDisableVertexAttribArray(colorLoc)); |
| GLU_CHECK_CALL(glDisableVertexAttribArray(coordLoc)); |
| |
| } |
| |
| |
| void ReadPixelsTest::clearColor (float r, float g, float b, float a) |
| { |
| if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_NATIVE) |
| { |
| GLU_CHECK_CALL(glClearColor(r, g, b, a)); |
| GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT)); |
| } |
| else if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER) |
| { |
| switch (m_texChannelClass) |
| { |
| case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: |
| { |
| GLU_CHECK_CALL(glClearColor(r, g, b, a)); |
| GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT)); |
| break; |
| } |
| |
| case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: |
| { |
| GLint color[4] = { (GLint)r, (GLint)g, (GLint)b, (GLint)a }; |
| |
| GLU_CHECK_CALL(glClearBufferiv(GL_COLOR, 0, color)); |
| break; |
| } |
| |
| case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: |
| { |
| GLuint color[4] = { (GLuint)r, (GLuint)g, (GLuint)b, (GLuint)a }; |
| |
| GLU_CHECK_CALL(glClearBufferuiv(GL_COLOR, 0, color)); |
| break; |
| } |
| |
| case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: |
| { |
| GLfloat color[4] = { (GLfloat)r, (GLfloat)g, (GLfloat)b, (GLfloat)a }; |
| |
| GLU_CHECK_CALL(glClearBufferfv(GL_COLOR, 0, color)); |
| break; |
| } |
| |
| default: |
| DE_ASSERT(false); |
| } |
| } |
| else |
| DE_ASSERT(false); |
| |
| } |
| |
| TestCase::IterateResult ReadPixelsTest::iterate(void) |
| { |
| int width = m_context.getRenderTarget().getWidth(); |
| int height = m_context.getRenderTarget().getHeight(); |
| |
| GLuint framebuffer = 0; |
| GLuint renderbuffer = 0; |
| |
| switch (m_framebuffeType) |
| { |
| case TestSpec::FRAMEBUFFERTYPE_NATIVE: |
| GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); |
| break; |
| |
| case TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER: |
| { |
| GLU_CHECK_CALL(glGenFramebuffers(1, &framebuffer)); |
| GLU_CHECK_CALL(glGenRenderbuffers(1, &renderbuffer)); |
| |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer)); |
| GLU_CHECK_CALL(glRenderbufferStorage(GL_RENDERBUFFER, m_renderbufferFormat, width, height)); |
| |
| GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer)); |
| |
| break; |
| } |
| |
| default: |
| DE_ASSERT(false); |
| } |
| |
| clearColor(m_colorScale * 0.4f, m_colorScale * 1.0f, m_colorScale * 0.5f, m_colorScale * 1.0f); |
| |
| if (m_useColorClears) |
| { |
| const int maxClearCount = 10; |
| const int minClearCount = 6; |
| const int minClearSize = 15; |
| |
| int clearCount = m_random.getInt(minClearCount, maxClearCount); |
| |
| for (int clearNdx = 0; clearNdx < clearCount; clearNdx++) |
| { |
| int clearX = m_random.getInt(0, width - minClearSize); |
| int clearY = m_random.getInt(0, height - minClearSize); |
| |
| int clearWidth = m_random.getInt(minClearSize, width - clearX); |
| int clearHeight = m_random.getInt(minClearSize, height - clearY); |
| |
| float clearRed = m_colorScale * m_random.getFloat(); |
| float clearGreen = m_colorScale * m_random.getFloat(); |
| float clearBlue = m_colorScale * m_random.getFloat(); |
| float clearAlpha = m_colorScale * (0.5f + 0.5f * m_random.getFloat()); |
| |
| GLU_CHECK_CALL(glEnable(GL_SCISSOR_TEST)); |
| GLU_CHECK_CALL(glScissor(clearX, clearY, clearWidth, clearHeight)); |
| |
| clearColor(clearRed, clearGreen, clearBlue, clearAlpha); |
| } |
| |
| GLU_CHECK_CALL(glDisable(GL_SCISSOR_TEST)); |
| } |
| |
| if (m_renderTriangles) |
| { |
| const int minTriangleCount = 4; |
| const int maxTriangleCount = 10; |
| |
| int triangleCount = m_random.getInt(minTriangleCount, maxTriangleCount); |
| |
| for (int triangleNdx = 0; triangleNdx < triangleCount; triangleNdx++) |
| { |
| float x1 = 2.0f * m_random.getFloat() - 1.0f; |
| float y1 = 2.0f * m_random.getFloat() - 1.0f; |
| float z1 = 2.0f * m_random.getFloat() - 1.0f; |
| |
| float x2 = 2.0f * m_random.getFloat() - 1.0f; |
| float y2 = 2.0f * m_random.getFloat() - 1.0f; |
| float z2 = 2.0f * m_random.getFloat() - 1.0f; |
| |
| float x3 = 2.0f * m_random.getFloat() - 1.0f; |
| float y3 = 2.0f * m_random.getFloat() - 1.0f; |
| float z3 = 2.0f * m_random.getFloat() - 1.0f; |
| |
| renderTriangle(tcu::Vec3(x1, y1, z1), tcu::Vec3(x2, y2, z2), tcu::Vec3(x3, y3, z3)); |
| } |
| } |
| |
| tcu::TextureFormat readFormat; |
| GLenum readPixelsFormat; |
| GLenum readPixelsType; |
| bool floatCompare; |
| |
| |
| if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_NATIVE) |
| { |
| readFormat = glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE); |
| readPixelsFormat = GL_RGBA; |
| readPixelsType = GL_UNSIGNED_BYTE; |
| floatCompare = false; |
| } |
| else if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER) |
| { |
| switch (m_texChannelClass) |
| { |
| case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: |
| readFormat = glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE); |
| readPixelsFormat = GL_RGBA; |
| readPixelsType = GL_UNSIGNED_BYTE; |
| floatCompare = true; |
| break; |
| |
| case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: |
| readFormat = glu::mapGLTransferFormat(GL_RGBA_INTEGER, GL_INT); |
| readPixelsFormat = GL_RGBA_INTEGER; |
| readPixelsType = GL_INT; |
| floatCompare = false; |
| break; |
| |
| case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: |
| readFormat = glu::mapGLTransferFormat(GL_RGBA_INTEGER, GL_UNSIGNED_INT); |
| readPixelsFormat = GL_RGBA_INTEGER; |
| readPixelsType = GL_UNSIGNED_INT; |
| floatCompare = false; |
| break; |
| |
| case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: |
| readFormat = glu::mapGLTransferFormat(GL_RGBA, GL_FLOAT); |
| readPixelsFormat = GL_RGBA; |
| readPixelsType = GL_FLOAT; |
| floatCompare = true; |
| break; |
| |
| default: |
| DE_ASSERT(false); |
| // Silence warnings |
| readFormat = glu::mapGLTransferFormat(GL_RGBA, GL_FLOAT); |
| readPixelsFormat = GL_RGBA; |
| readPixelsType = GL_FLOAT; |
| floatCompare = true; |
| } |
| } |
| else |
| { |
| // Silence warnings |
| readFormat = glu::mapGLTransferFormat(GL_RGBA, GL_FLOAT); |
| readPixelsFormat = GL_RGBA; |
| readPixelsType = GL_FLOAT; |
| floatCompare = true; |
| DE_ASSERT(false); |
| } |
| |
| tcu::Texture2D readRefrence (readFormat, width, height); |
| const int readDataSize = readRefrence.getWidth() * readRefrence.getHeight() * readFormat.getPixelSize(); |
| |
| readRefrence.allocLevel(0); |
| |
| GLuint pixelBuffer = (GLuint)-1; |
| |
| GLU_CHECK_CALL(glGenBuffers(1, &pixelBuffer)); |
| GLU_CHECK_CALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, pixelBuffer)); |
| GLU_CHECK_CALL(glBufferData(GL_PIXEL_PACK_BUFFER, readDataSize, NULL, GL_STREAM_READ)); |
| |
| GLU_CHECK_CALL(glReadPixels(0, 0, width, height, readPixelsFormat, readPixelsType, 0)); |
| |
| const deUint8* bufferData = (const deUint8*)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, readDataSize, GL_MAP_READ_BIT); |
| GLU_CHECK_MSG("glMapBufferRange() failed"); |
| |
| tcu::ConstPixelBufferAccess readResult(readFormat, width, height, 1, bufferData); |
| |
| GLU_CHECK_CALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); |
| |
| GLU_CHECK_CALL(glReadPixels(0, 0, width, height, readPixelsFormat, readPixelsType, readRefrence.getLevel(0).getDataPtr())); |
| |
| if (framebuffer) |
| GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer)); |
| |
| if (renderbuffer) |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer)); |
| |
| |
| bool isOk = false; |
| |
| if (floatCompare) |
| { |
| const tcu::IVec4 formatBitDepths = tcu::getTextureFormatBitDepth(readFormat); |
| const float redThreshold = 2.0f / (float)(1 << deMin32(m_context.getRenderTarget().getPixelFormat().redBits, formatBitDepths.x())); |
| const float greenThreshold = 2.0f / (float)(1 << deMin32(m_context.getRenderTarget().getPixelFormat().greenBits, formatBitDepths.y())); |
| const float blueThreshold = 2.0f / (float)(1 << deMin32(m_context.getRenderTarget().getPixelFormat().blueBits, formatBitDepths.z())); |
| const float alphaThreshold = 2.0f / (float)(1 << deMin32(m_context.getRenderTarget().getPixelFormat().alphaBits, formatBitDepths.w())); |
| |
| isOk = tcu::floatThresholdCompare(m_log, "Result comparision", "Result of read pixels to memory compared with result of read pixels to buffer", readRefrence.getLevel(0), readResult, tcu::Vec4(redThreshold, greenThreshold, blueThreshold, alphaThreshold), tcu::COMPARE_LOG_RESULT); |
| } |
| else |
| { |
| isOk = tcu::intThresholdCompare(m_log, "Result comparision", "Result of read pixels to memory compared with result of read pixels to buffer", readRefrence.getLevel(0), readResult, tcu::UVec4(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT); |
| } |
| |
| GLU_CHECK_CALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, pixelBuffer)); |
| GLU_CHECK_CALL(glUnmapBuffer(GL_PIXEL_PACK_BUFFER)); |
| GLU_CHECK_CALL(glDeleteBuffers(1, &pixelBuffer)); |
| |
| if (isOk) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| return STOP; |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| return STOP; |
| } |
| } |
| |
| } // anonymous |
| |
| PixelBufferObjectTests::PixelBufferObjectTests (Context& context) |
| : TestCaseGroup (context, "pbo", "Pixel buffer objects tests") |
| { |
| } |
| |
| PixelBufferObjectTests::~PixelBufferObjectTests (void) |
| { |
| } |
| |
| void PixelBufferObjectTests::init (void) |
| { |
| TestCaseGroup* nativeFramebufferGroup = new TestCaseGroup(m_context, "native", "Tests with reading from native framebuffer"); |
| |
| ReadPixelsTest::TestSpec nativeFramebufferTests[] = { |
| { |
| "clears", |
| "Simple read pixels test with color clears", |
| true, |
| false, |
| ReadPixelsTest::TestSpec::FRAMEBUFFERTYPE_NATIVE, |
| GL_NONE |
| }, |
| { |
| "triangles", |
| "Simple read pixels test rendering triangles", |
| false, |
| true, |
| ReadPixelsTest::TestSpec::FRAMEBUFFERTYPE_NATIVE, |
| GL_NONE |
| } |
| }; |
| |
| for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(nativeFramebufferTests); testNdx++) |
| { |
| nativeFramebufferGroup->addChild(new ReadPixelsTest(m_context, nativeFramebufferTests[testNdx])); |
| } |
| |
| addChild(nativeFramebufferGroup); |
| |
| TestCaseGroup* renderbufferGroup = new TestCaseGroup(m_context, "renderbuffer", "Tests with reading from renderbuffer"); |
| |
| GLenum renderbufferFormats[] = { |
| GL_RGBA8, |
| GL_RGBA8I, |
| GL_RGBA8UI, |
| GL_RGBA16F, |
| GL_RGBA16I, |
| GL_RGBA16UI, |
| GL_RGBA32F, |
| GL_RGBA32I, |
| GL_RGBA32UI, |
| |
| GL_SRGB8_ALPHA8, |
| GL_RGB10_A2, |
| GL_RGB10_A2UI, |
| GL_RGBA4, |
| GL_RGB5_A1, |
| |
| GL_RGB8, |
| GL_RGB565, |
| |
| GL_R11F_G11F_B10F, |
| |
| GL_RG8, |
| GL_RG8I, |
| GL_RG8UI, |
| GL_RG16F, |
| GL_RG16I, |
| GL_RG16UI, |
| GL_RG32F, |
| GL_RG32I, |
| GL_RG32UI |
| }; |
| |
| const char* renderbufferFormatsStr[] = { |
| "rgba8", |
| "rgba8i", |
| "rgba8ui", |
| "rgba16f", |
| "rgba16i", |
| "rgba16ui", |
| "rgba32f", |
| "rgba32i", |
| "rgba32ui", |
| |
| "srgb8_alpha8", |
| "rgb10_a2", |
| "rgb10_a2ui", |
| "rgba4", |
| "rgb5_a1", |
| |
| "rgb8", |
| "rgb565", |
| |
| "r11f_g11f_b10f", |
| |
| "rg8", |
| "rg8i", |
| "rg8ui", |
| "rg16f", |
| "rg16i", |
| "rg16ui", |
| "rg32f", |
| "rg32i", |
| "rg32ui" |
| }; |
| |
| DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(renderbufferFormatsStr) == DE_LENGTH_OF_ARRAY(renderbufferFormats)); |
| |
| for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(renderbufferFormats); formatNdx++) |
| { |
| for (int trianglesClears = 0; trianglesClears < 2; trianglesClears++) |
| { |
| ReadPixelsTest::TestSpec testSpec; |
| |
| testSpec.name = string(renderbufferFormatsStr [formatNdx]) + "_" + (trianglesClears == 0 ? "triangles" : "clears"), |
| testSpec.description = testSpec.name; |
| testSpec.useColorClear = trianglesClears == 1, |
| testSpec.renderTriangles = trianglesClears == 0, |
| testSpec.framebufferType = ReadPixelsTest::TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER, |
| testSpec.renderbufferFormat = renderbufferFormats[formatNdx]; |
| |
| renderbufferGroup->addChild(new ReadPixelsTest(m_context, testSpec)); |
| } |
| } |
| |
| addChild(renderbufferGroup); |
| } |
| |
| } // Functional |
| } // gles3 |
| } // deqp |