1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES 2.0 Module 3e5c31af7Sopenharmony_ci * ------------------------------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Read pixels tests 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "es2fReadPixelsTests.hpp" 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "tcuTexture.hpp" 27e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp" 28e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp" 29e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 30e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp" 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_ci#include "deRandom.hpp" 33e5c31af7Sopenharmony_ci#include "deMath.h" 34e5c31af7Sopenharmony_ci#include "deString.h" 35e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 36e5c31af7Sopenharmony_ci 37e5c31af7Sopenharmony_ci#include "gluDefs.hpp" 38e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 39e5c31af7Sopenharmony_ci#include "gluStrUtil.hpp" 40e5c31af7Sopenharmony_ci#include "gluTextureUtil.hpp" 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_ci#include "glw.h" 43e5c31af7Sopenharmony_ci 44e5c31af7Sopenharmony_ci#include <cstring> 45e5c31af7Sopenharmony_ci 46e5c31af7Sopenharmony_cinamespace deqp 47e5c31af7Sopenharmony_ci{ 48e5c31af7Sopenharmony_cinamespace gles2 49e5c31af7Sopenharmony_ci{ 50e5c31af7Sopenharmony_cinamespace Functional 51e5c31af7Sopenharmony_ci{ 52e5c31af7Sopenharmony_ci 53e5c31af7Sopenharmony_ciclass ReadPixelsTest : public TestCase 54e5c31af7Sopenharmony_ci{ 55e5c31af7Sopenharmony_cipublic: 56e5c31af7Sopenharmony_ci ReadPixelsTest (Context& context, const char* name, const char* description, bool chooseFormat, int alignment); 57e5c31af7Sopenharmony_ci 58e5c31af7Sopenharmony_ci IterateResult iterate (void); 59e5c31af7Sopenharmony_ci void render (tcu::Texture2D& reference); 60e5c31af7Sopenharmony_ci 61e5c31af7Sopenharmony_ciprivate: 62e5c31af7Sopenharmony_ci bool m_chooseFormat; 63e5c31af7Sopenharmony_ci int m_alignment; 64e5c31af7Sopenharmony_ci int m_seed; 65e5c31af7Sopenharmony_ci 66e5c31af7Sopenharmony_ci void getFormatInfo (tcu::TextureFormat& format, GLint& glFormat, GLint& glType, int& pixelSize); 67e5c31af7Sopenharmony_ci}; 68e5c31af7Sopenharmony_ci 69e5c31af7Sopenharmony_ciReadPixelsTest::ReadPixelsTest (Context& context, const char* name, const char* description, bool chooseFormat, int alignment) 70e5c31af7Sopenharmony_ci : TestCase (context, name, description) 71e5c31af7Sopenharmony_ci , m_chooseFormat (chooseFormat) 72e5c31af7Sopenharmony_ci , m_alignment (alignment) 73e5c31af7Sopenharmony_ci , m_seed (deStringHash(name)) 74e5c31af7Sopenharmony_ci{ 75e5c31af7Sopenharmony_ci} 76e5c31af7Sopenharmony_ci 77e5c31af7Sopenharmony_civoid ReadPixelsTest::render (tcu::Texture2D& reference) 78e5c31af7Sopenharmony_ci{ 79e5c31af7Sopenharmony_ci // Create program 80e5c31af7Sopenharmony_ci const char* vertexSource = 81e5c31af7Sopenharmony_ci "attribute mediump vec2 a_coord;\n" 82e5c31af7Sopenharmony_ci "void main (void)\n" 83e5c31af7Sopenharmony_ci "{\n" 84e5c31af7Sopenharmony_ci "\tgl_Position = vec4(a_coord, 0.0, 1.0);\n" 85e5c31af7Sopenharmony_ci "}\n"; 86e5c31af7Sopenharmony_ci 87e5c31af7Sopenharmony_ci const char* fragmentSource = 88e5c31af7Sopenharmony_ci "void main (void)\n" 89e5c31af7Sopenharmony_ci "{\n" 90e5c31af7Sopenharmony_ci "\tgl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n" 91e5c31af7Sopenharmony_ci "}\n"; 92e5c31af7Sopenharmony_ci 93e5c31af7Sopenharmony_ci glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexSource, fragmentSource)); 94e5c31af7Sopenharmony_ci 95e5c31af7Sopenharmony_ci m_testCtx.getLog() << program; 96e5c31af7Sopenharmony_ci TCU_CHECK(program.isOk()); 97e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glUseProgram(program.getProgram())); 98e5c31af7Sopenharmony_ci 99e5c31af7Sopenharmony_ci // Render 100e5c31af7Sopenharmony_ci { 101e5c31af7Sopenharmony_ci const float coords[] = 102e5c31af7Sopenharmony_ci { 103e5c31af7Sopenharmony_ci -0.5f, -0.5f, 104e5c31af7Sopenharmony_ci 0.5f, -0.5f, 105e5c31af7Sopenharmony_ci 0.5f, 0.5f, 106e5c31af7Sopenharmony_ci 107e5c31af7Sopenharmony_ci 0.5f, 0.5f, 108e5c31af7Sopenharmony_ci -0.5f, 0.5f, 109e5c31af7Sopenharmony_ci -0.5f, -0.5f 110e5c31af7Sopenharmony_ci }; 111e5c31af7Sopenharmony_ci GLuint coordLoc; 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_ci coordLoc = glGetAttribLocation(program.getProgram(), "a_coord"); 114e5c31af7Sopenharmony_ci GLU_CHECK_MSG("glGetAttribLocation()"); 115e5c31af7Sopenharmony_ci 116e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glEnableVertexAttribArray(coordLoc)); 117e5c31af7Sopenharmony_ci 118e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glVertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, coords)); 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 6)); 121e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glDisableVertexAttribArray(coordLoc)); 122e5c31af7Sopenharmony_ci } 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_ci // Render reference 125e5c31af7Sopenharmony_ci 126e5c31af7Sopenharmony_ci const int coordX1 = (int)((-0.5f * (float)reference.getWidth() / 2.0f) + (float)reference.getWidth() / 2.0f); 127e5c31af7Sopenharmony_ci const int coordY1 = (int)((-0.5f * (float)reference.getHeight() / 2.0f) + (float)reference.getHeight() / 2.0f); 128e5c31af7Sopenharmony_ci const int coordX2 = (int)(( 0.5f * (float)reference.getWidth() / 2.0f) + (float)reference.getWidth() / 2.0f); 129e5c31af7Sopenharmony_ci const int coordY2 = (int)(( 0.5f * (float)reference.getHeight() / 2.0f) + (float)reference.getHeight() / 2.0f); 130e5c31af7Sopenharmony_ci 131e5c31af7Sopenharmony_ci for (int x = 0; x < reference.getWidth(); x++) 132e5c31af7Sopenharmony_ci { 133e5c31af7Sopenharmony_ci if (x < coordX1 || x > coordX2) 134e5c31af7Sopenharmony_ci continue; 135e5c31af7Sopenharmony_ci 136e5c31af7Sopenharmony_ci for (int y = 0; y < reference.getHeight(); y++) 137e5c31af7Sopenharmony_ci { 138e5c31af7Sopenharmony_ci if (y >= coordY1 && y <= coordY2) 139e5c31af7Sopenharmony_ci reference.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), x, y); 140e5c31af7Sopenharmony_ci } 141e5c31af7Sopenharmony_ci } 142e5c31af7Sopenharmony_ci} 143e5c31af7Sopenharmony_ci 144e5c31af7Sopenharmony_civoid ReadPixelsTest::getFormatInfo (tcu::TextureFormat& format, GLint& glFormat, GLint& glType, int& pixelSize) 145e5c31af7Sopenharmony_ci{ 146e5c31af7Sopenharmony_ci if (m_chooseFormat) 147e5c31af7Sopenharmony_ci { 148e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &glFormat)); 149e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &glType)); 150e5c31af7Sopenharmony_ci 151e5c31af7Sopenharmony_ci if (glFormat != GL_RGBA && glFormat != GL_BGRA && glFormat != GL_RGB) 152e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, ("Unsupported IMPLEMENTATION_COLOR_READ_FORMAT: " + de::toString(glu::getTextureFormatStr(glFormat))).c_str()); 153e5c31af7Sopenharmony_ci if (glu::getTypeName(glType) == DE_NULL) 154e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, ("Unsupported GL_IMPLEMENTATION_COLOR_READ_TYPE: " + de::toString(tcu::Format::Hex<4>(glType))).c_str()); 155e5c31af7Sopenharmony_ci 156e5c31af7Sopenharmony_ci format = glu::mapGLTransferFormat(glFormat, glType); 157e5c31af7Sopenharmony_ci pixelSize = format.getPixelSize(); 158e5c31af7Sopenharmony_ci } 159e5c31af7Sopenharmony_ci else 160e5c31af7Sopenharmony_ci { 161e5c31af7Sopenharmony_ci format = tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8); 162e5c31af7Sopenharmony_ci pixelSize = 1 * 4; 163e5c31af7Sopenharmony_ci glFormat = GL_RGBA; 164e5c31af7Sopenharmony_ci glType = GL_UNSIGNED_BYTE; 165e5c31af7Sopenharmony_ci } 166e5c31af7Sopenharmony_ci} 167e5c31af7Sopenharmony_ci 168e5c31af7Sopenharmony_ciTestCase::IterateResult ReadPixelsTest::iterate (void) 169e5c31af7Sopenharmony_ci{ 170e5c31af7Sopenharmony_ci // Create reference 171e5c31af7Sopenharmony_ci const int width = 13; 172e5c31af7Sopenharmony_ci const int height = 13; 173e5c31af7Sopenharmony_ci 174e5c31af7Sopenharmony_ci de::Random rnd(m_seed); 175e5c31af7Sopenharmony_ci 176e5c31af7Sopenharmony_ci tcu::TextureFormat format(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8); 177e5c31af7Sopenharmony_ci int pixelSize; 178e5c31af7Sopenharmony_ci GLint glFormat; 179e5c31af7Sopenharmony_ci GLint glType; 180e5c31af7Sopenharmony_ci 181e5c31af7Sopenharmony_ci getFormatInfo(format, glFormat, glType, pixelSize); 182e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Format: " << glu::getTextureFormatStr(glFormat) << ", Type: " << glu::getTypeStr(glType) << tcu::TestLog::EndMessage; 183e5c31af7Sopenharmony_ci 184e5c31af7Sopenharmony_ci tcu::Texture2D reference(format, width, height, glu::isES2Context(m_context.getRenderContext().getType())); 185e5c31af7Sopenharmony_ci reference.allocLevel(0); 186e5c31af7Sopenharmony_ci 187e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glViewport(0, 0, width, height)); 188e5c31af7Sopenharmony_ci 189e5c31af7Sopenharmony_ci // Clear color 190e5c31af7Sopenharmony_ci { 191e5c31af7Sopenharmony_ci const float red = rnd.getFloat(); 192e5c31af7Sopenharmony_ci const float green = rnd.getFloat(); 193e5c31af7Sopenharmony_ci const float blue = rnd.getFloat(); 194e5c31af7Sopenharmony_ci const float alpha = 1.0f; 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Clear color: (" << red << ", " << green << ", " << blue << ", " << alpha << ")" << tcu::TestLog::EndMessage; 197e5c31af7Sopenharmony_ci 198e5c31af7Sopenharmony_ci // Clear target 199e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glClearColor(red, green, blue, alpha)); 200e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT)); 201e5c31af7Sopenharmony_ci 202e5c31af7Sopenharmony_ci tcu::clear(reference.getLevel(0), tcu::Vec4(red, green, blue, alpha)); 203e5c31af7Sopenharmony_ci } 204e5c31af7Sopenharmony_ci 205e5c31af7Sopenharmony_ci render(reference); 206e5c31af7Sopenharmony_ci 207e5c31af7Sopenharmony_ci std::vector<deUint8> pixelData; 208e5c31af7Sopenharmony_ci const int rowPitch = m_alignment * deCeilFloatToInt32(float(pixelSize * width) / (float)m_alignment); 209e5c31af7Sopenharmony_ci 210e5c31af7Sopenharmony_ci pixelData.resize(rowPitch * height, 0); 211e5c31af7Sopenharmony_ci 212e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glPixelStorei(GL_PACK_ALIGNMENT, m_alignment)); 213e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glReadPixels(0, 0, width, height, glFormat, glType, &(pixelData[0]))); 214e5c31af7Sopenharmony_ci 215e5c31af7Sopenharmony_ci if (m_context.getRenderTarget().getNumSamples() > 1) 216e5c31af7Sopenharmony_ci { 217e5c31af7Sopenharmony_ci const tcu::IVec4 formatBitDepths = tcu::getTextureFormatBitDepth(format); 218e5c31af7Sopenharmony_ci const deUint8 redThreshold = (deUint8)deCeilFloatToInt32(256.0f * (2.0f / (float)(1 << deMin32(m_context.getRenderTarget().getPixelFormat().redBits, formatBitDepths.x())))); 219e5c31af7Sopenharmony_ci const deUint8 greenThreshold = (deUint8)deCeilFloatToInt32(256.0f * (2.0f / (float)(1 << deMin32(m_context.getRenderTarget().getPixelFormat().greenBits, formatBitDepths.y())))); 220e5c31af7Sopenharmony_ci const deUint8 blueThreshold = (deUint8)deCeilFloatToInt32(256.0f * (2.0f / (float)(1 << deMin32(m_context.getRenderTarget().getPixelFormat().blueBits, formatBitDepths.z())))); 221e5c31af7Sopenharmony_ci const deUint8 alphaThreshold = (deUint8)deCeilFloatToInt32(256.0f * (2.0f / (float)(1 << deMin32(m_context.getRenderTarget().getPixelFormat().alphaBits, formatBitDepths.w())))); 222e5c31af7Sopenharmony_ci 223e5c31af7Sopenharmony_ci // bilinearCompare only accepts RGBA, UINT8 224e5c31af7Sopenharmony_ci tcu::Texture2D referenceRGBA8 (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), width, height, glu::isES2Context(m_context.getRenderContext().getType())); 225e5c31af7Sopenharmony_ci tcu::Texture2D resultRGBA8 (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), width, height, glu::isES2Context(m_context.getRenderContext().getType())); 226e5c31af7Sopenharmony_ci 227e5c31af7Sopenharmony_ci referenceRGBA8.allocLevel(0); 228e5c31af7Sopenharmony_ci resultRGBA8.allocLevel(0); 229e5c31af7Sopenharmony_ci 230e5c31af7Sopenharmony_ci tcu::copy(referenceRGBA8.getLevel(0), reference.getLevel(0)); 231e5c31af7Sopenharmony_ci tcu::copy(resultRGBA8.getLevel(0), tcu::PixelBufferAccess(format, width, height, 1, rowPitch, 0, &(pixelData[0]))); 232e5c31af7Sopenharmony_ci 233e5c31af7Sopenharmony_ci if (tcu::bilinearCompare(m_testCtx.getLog(), "Result", "Result", referenceRGBA8.getLevel(0), resultRGBA8.getLevel(0), tcu::RGBA(redThreshold, greenThreshold, blueThreshold, alphaThreshold), tcu::COMPARE_LOG_RESULT)) 234e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 235e5c31af7Sopenharmony_ci else 236e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 237e5c31af7Sopenharmony_ci } 238e5c31af7Sopenharmony_ci else 239e5c31af7Sopenharmony_ci { 240e5c31af7Sopenharmony_ci const tcu::IVec4 formatBitDepths = tcu::getTextureFormatBitDepth(format); 241e5c31af7Sopenharmony_ci const float redThreshold = 2.0f / (float)(1 << deMin32(m_context.getRenderTarget().getPixelFormat().redBits, formatBitDepths.x())); 242e5c31af7Sopenharmony_ci const float greenThreshold = 2.0f / (float)(1 << deMin32(m_context.getRenderTarget().getPixelFormat().greenBits, formatBitDepths.y())); 243e5c31af7Sopenharmony_ci const float blueThreshold = 2.0f / (float)(1 << deMin32(m_context.getRenderTarget().getPixelFormat().blueBits, formatBitDepths.z())); 244e5c31af7Sopenharmony_ci const float alphaThreshold = 2.0f / (float)(1 << deMin32(m_context.getRenderTarget().getPixelFormat().alphaBits, formatBitDepths.w())); 245e5c31af7Sopenharmony_ci 246e5c31af7Sopenharmony_ci // Compare 247e5c31af7Sopenharmony_ci if (tcu::floatThresholdCompare(m_testCtx.getLog(), "Result", "Result", reference.getLevel(0), tcu::PixelBufferAccess(format, width, height, 1, rowPitch, 0, &(pixelData[0])), tcu::Vec4(redThreshold, greenThreshold, blueThreshold, alphaThreshold), tcu::COMPARE_LOG_RESULT)) 248e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 249e5c31af7Sopenharmony_ci else 250e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 251e5c31af7Sopenharmony_ci } 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ci return STOP; 254e5c31af7Sopenharmony_ci} 255e5c31af7Sopenharmony_ci 256e5c31af7Sopenharmony_ciReadPixelsTests::ReadPixelsTests (Context& context) 257e5c31af7Sopenharmony_ci : TestCaseGroup(context, "read_pixels", "ReadPixel tests") 258e5c31af7Sopenharmony_ci{ 259e5c31af7Sopenharmony_ci} 260e5c31af7Sopenharmony_ci 261e5c31af7Sopenharmony_civoid ReadPixelsTests::init (void) 262e5c31af7Sopenharmony_ci{ 263e5c31af7Sopenharmony_ci addChild(new ReadPixelsTest(m_context, "rgba_ubyte_align_1", "", false, 1)); 264e5c31af7Sopenharmony_ci addChild(new ReadPixelsTest(m_context, "rgba_ubyte_align_2", "", false, 2)); 265e5c31af7Sopenharmony_ci addChild(new ReadPixelsTest(m_context, "rgba_ubyte_align_4", "", false, 4)); 266e5c31af7Sopenharmony_ci addChild(new ReadPixelsTest(m_context, "rgba_ubyte_align_8", "", false, 8)); 267e5c31af7Sopenharmony_ci 268e5c31af7Sopenharmony_ci addChild(new ReadPixelsTest(m_context, "choose_align_1", "", true, 1)); 269e5c31af7Sopenharmony_ci addChild(new ReadPixelsTest(m_context, "choose_align_2", "", true, 2)); 270e5c31af7Sopenharmony_ci addChild(new ReadPixelsTest(m_context, "choose_align_4", "", true, 4)); 271e5c31af7Sopenharmony_ci addChild(new ReadPixelsTest(m_context, "choose_align_8", "", true, 8)); 272e5c31af7Sopenharmony_ci} 273e5c31af7Sopenharmony_ci 274e5c31af7Sopenharmony_ci} // Functional 275e5c31af7Sopenharmony_ci} // gles2 276e5c31af7Sopenharmony_ci} // deqp 277