void ReadPixelsTest::getFormatInfo (tcu::TextureFormat& format, GLint& glFormat, GLint& glType, int& pixelSize) { if (m_chooseFormat) { GLU_CHECK_CALL(glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &glFormat)); GLU_CHECK_CALL(glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &glType)); if (glFormat != GL_RGBA && glFormat != GL_BGRA && glFormat != GL_RGB) TCU_THROW(NotSupportedError, ("Unsupported IMPLEMENTATION_COLOR_READ_FORMAT: " + de::toString(glu::getPixelFormatStr(glFormat))).c_str()); if (glu::getTypeName(glType) == DE_NULL) TCU_THROW(NotSupportedError, ("Unsupported GL_IMPLEMENTATION_COLOR_READ_TYPE: " + de::toString(tcu::Format::Hex<4>(glType))).c_str()); format = glu::mapGLTransferFormat(glFormat, glType); pixelSize = format.getPixelSize(); } else { format = tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8); pixelSize = 1 * 4; glFormat = GL_RGBA; glType = GL_UNSIGNED_BYTE; } }
GLW_APICALL void GLW_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) { DE_UNREF(x); DE_UNREF(y); Context* const ctx = getCurrentContext(); const tcu::Vec4 clearColor (0.0f, 0.0f, 0.0f, 1.0f); // black const tcu::TextureFormat transferFormat = glu::mapGLTransferFormat(format, type); // invalid formats if (transferFormat.order == TextureFormat::CHANNELORDER_LAST || transferFormat.type == TextureFormat::CHANNELTYPE_LAST) { if (ctx->lastError == GL_NO_ERROR) ctx->lastError = GL_INVALID_ENUM; return; } // unsupported formats if (!(format == GL_RGBA && type == GL_UNSIGNED_BYTE) && !(format == GL_RGBA_INTEGER && type == GL_INT) && !(format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT) && !(format == GL_RGBA && type == GL_FLOAT)) { if (ctx->lastError == GL_NO_ERROR) ctx->lastError = GL_INVALID_ENUM; return; } // invalid arguments if (width < 0 || height < 0) { if (ctx->lastError == GL_NO_ERROR) ctx->lastError = GL_INVALID_OPERATION; return; } // read to buffer if (ctx->pixelPackBufferBufferBinding) return; // read to use pointer { const int targetRowLength = (ctx->pixelPackRowLength != 0) ? (ctx->pixelPackRowLength) : (width); const int targetSkipRows = ctx->pixelPackSkipRows; const int targetSkipPixels = ctx->pixelPackSkipPixels; const int infiniteHeight = targetSkipRows + height; // as much as needed const int targetRowPitch = (ctx->pixelPackAlignment == 0) ? (targetRowLength * transferFormat.getPixelSize()) : (deAlign32(targetRowLength * transferFormat.getPixelSize(), ctx->pixelPackAlignment)); // Create access to the whole copy target const tcu::PixelBufferAccess targetAccess (transferFormat, targetRowLength, infiniteHeight, 1, targetRowPitch, 0, pixels); // Select (skip_pixels, skip_rows, width, height) subregion from it. Clip to horizontal boundaries const tcu::PixelBufferAccess targetRectAccess = tcu::getSubregion(targetAccess, de::clamp(targetSkipPixels, 0, targetAccess.getWidth()-1), targetSkipRows, de::clamp(width, 0, de::max(0, targetAccess.getWidth() - targetSkipPixels)), height); tcu::clear(targetRectAccess, clearColor); } }