From 6aee7a59e9e1fb67f4384e4317c04bb684dc7e0f Mon Sep 17 00:00:00 2001 From: Tom Gall Date: Wed, 16 Jan 2013 15:47:40 -0600 Subject: v2 - restructured approach to be data driven, as well as separating valid and invalid variations into separate tests. Tests glReadPixels specifically for OpenGL ES2 2.0. Covers a variety of formats and types, both valid and invalid. --- tests/spec/gles-2.0/CMakeLists.txt | 2 + tests/spec/gles-2.0/api/CMakeLists.gles2.txt | 8 + tests/spec/gles-2.0/api/CMakeLists.txt | 1 + tests/spec/gles-2.0/api/glreadpixels-common.c | 342 +++++++++++++++++++++++++ tests/spec/gles-2.0/api/glreadpixels-common.h | 77 ++++++ tests/spec/gles-2.0/api/glreadpixels-invalid.c | 284 ++++++++++++++++++++ tests/spec/gles-2.0/api/glreadpixels.c | 293 +++++++++++++++++++++ 7 files changed, 1007 insertions(+) create mode 100644 tests/spec/gles-2.0/api/CMakeLists.gles2.txt create mode 100644 tests/spec/gles-2.0/api/CMakeLists.txt create mode 100644 tests/spec/gles-2.0/api/glreadpixels-common.c create mode 100644 tests/spec/gles-2.0/api/glreadpixels-common.h create mode 100644 tests/spec/gles-2.0/api/glreadpixels-invalid.c create mode 100644 tests/spec/gles-2.0/api/glreadpixels.c diff --git a/tests/spec/gles-2.0/CMakeLists.txt b/tests/spec/gles-2.0/CMakeLists.txt index 144a306f..fb759f60 100644 --- a/tests/spec/gles-2.0/CMakeLists.txt +++ b/tests/spec/gles-2.0/CMakeLists.txt @@ -1 +1,3 @@ +add_subdirectory (api) + piglit_include_target_api() diff --git a/tests/spec/gles-2.0/api/CMakeLists.gles2.txt b/tests/spec/gles-2.0/api/CMakeLists.gles2.txt new file mode 100644 index 00000000..c4894309 --- /dev/null +++ b/tests/spec/gles-2.0/api/CMakeLists.gles2.txt @@ -0,0 +1,8 @@ +link_libraries( + piglitutil_${piglit_target_api} + ) + +piglit_add_executable(glreadpixels_gles2 glreadpixels.c glreadpixels-common.c) +piglit_add_executable(glreadpixels-invalid_gles2 glreadpixels-invalid.c glreadpixels-common.c) + +# vim: ft=cmake: diff --git a/tests/spec/gles-2.0/api/CMakeLists.txt b/tests/spec/gles-2.0/api/CMakeLists.txt new file mode 100644 index 00000000..144a306f --- /dev/null +++ b/tests/spec/gles-2.0/api/CMakeLists.txt @@ -0,0 +1 @@ +piglit_include_target_api() diff --git a/tests/spec/gles-2.0/api/glreadpixels-common.c b/tests/spec/gles-2.0/api/glreadpixels-common.c new file mode 100644 index 00000000..34ffcf8d --- /dev/null +++ b/tests/spec/gles-2.0/api/glreadpixels-common.c @@ -0,0 +1,342 @@ +/* + * Copyright © 2013 Linaro Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Common code for testing glReadPixels + * as specified by the OpenGL ES 2.0.25 spec. + * + * \author Tom Gall + */ + +#include +#include +#include "piglit-util-gl-common.h" +#include "glreadpixels-common.h" + +void +clear_buffer(GLubyte *buffer) +{ + memset(buffer, TEST_PATTERN_BYTE, piglit_width*(piglit_height+50)*4); +} + + +enum piglit_result +check_buffer_RGB(GLubyte *buffer) +{ + pixel_f888 *p888; + int i,j; + + /* check that the rectangle was rendered correctly */ + for (i = piglit_height/4; i < piglit_height/4*3; i++) { + for (j = piglit_width/4; j < piglit_width/4*3; j++) { + p888 = (pixel_f888 *)(buffer + (((i * piglit_width)+ j) * 3)); + if (p888->red != 0xff && p888->green != 0x00 && + p888->blue != 0x00) + return PIGLIT_FAIL; + } + } + + /* check that the remaining area is black */ + for(i = 0; i < piglit_height/4; i++) { + for(j = 0; j < piglit_width; j++) { + p888 = (pixel_f888 *)(buffer + (((i*piglit_width)+ j) * 3)); + if (p888->red != 0x00 && p888->green != 0x00 && + p888->blue != 0x00) + return PIGLIT_FAIL; + } + } + for(i = piglit_height/4*3; i < piglit_height; i++) { + for(j = 0; j < piglit_width; j++) { + p888 = (pixel_f888 *)(buffer + (((i * piglit_width) + j) * 3)); + if (p888->red != 0x00 && p888->green != 0x00 && + p888->blue != 0x00) + return PIGLIT_FAIL; + } + } + for(i = piglit_height/4; i < piglit_height/4*3; i++) { + for(j = 0; j < piglit_width/4; j++) { + p888=(pixel_f888 *)(buffer + (((i * piglit_width) + j) * 3)); + if (p888->red != 0x00 && p888->green != 0x00 && + p888->blue != 0x00) + return PIGLIT_FAIL; + } + } + for(i = piglit_height/4; i < piglit_height/4*3; i++) { + for(j = piglit_width/4*3; j < piglit_width; j++) { + p888 = (pixel_f888 *)(buffer + (((i * piglit_width) + j) * 3)); + if (p888->red != 0x00 && p888->green != 0x00 && + p888->blue != 0x00) + return PIGLIT_FAIL; + } + } + + return PIGLIT_PASS; +} + + +enum piglit_result +check_buffer_RGBA(GLubyte *buffer) +{ + int i,j; + + /* check that the rectangle was rendered correctly */ + for (i = piglit_height/4; i < piglit_height/4*3; i++) { + for (j = piglit_width/4; j < piglit_width/4*3; j++) { + if (*(buffer + (i * j)) != 0xff && + *(buffer + ((i * j) + 1)) != 0x00 && + *(buffer + ((i * j) + 2)) != 0x00 && + *(buffer + ((i * j) + 3)) != 0xff) + return PIGLIT_FAIL; + } + } + /* check that the remaining area is black */ + for(i = 0; i < piglit_height/4; i++) { + for(j = 0; j < piglit_width; j++) { + if (*(buffer + (i * j)) != 0x00 && + *(buffer + ((i * j) + 1)) != 0x00 && + *(buffer + ((i * j) + 2)) != 0x00 && + *(buffer + ((i * j) + 3)) != 0xff) + return PIGLIT_FAIL; + } + } + for(i = (piglit_height/4)*3; i < piglit_height; i++) { + for(j = 0; j < piglit_width; j++) { + if (*(buffer + (i * j)) != 0x00 && + *(buffer + ((i * j) + 1)) != 0x00 && + *(buffer + ((i * j) + 2)) != 0x00 && + *(buffer + ((i * j) + 3)) != 0xff) + return PIGLIT_FAIL; + } + } + for(i = piglit_height/4; i < piglit_height/4*3; i++) { + for(j = 0; j < piglit_width/4; j++) { + if (*(buffer + (i * j)) != 0x00 && + *(buffer + ((i * j) + 1)) != 0x00 && + *(buffer + ((i * j) + 2)) != 0x00 && + *(buffer + ((i * j) + 3)) != 0xff) + return PIGLIT_FAIL; + } + } + for(i = piglit_height/4; i < piglit_height/4*3; i++) { + for(j = 240; j < piglit_width; j++) { + if (*(buffer + (i * j)) != 0x00 && + *(buffer + ((i * j) + 1)) != 0x00 && + *(buffer + ((i * j) + 2)) != 0x00 && + *(buffer + ((i * j) + 3)) != 0xff) + return PIGLIT_FAIL; + } + } + + return PIGLIT_PASS; +} + + +enum piglit_result +check_buffer_ALPHA(GLubyte *buffer) +{ + int i,j; + + for(i = 0; i < piglit_height; i++) { + for(j = 0; j < piglit_width; j++) { + if (*(buffer + (i * piglit_height) + j) != 0xff) + return PIGLIT_FAIL; + } + } + + return PIGLIT_PASS; +} + + +enum piglit_result +check_buffer_is_not_changed(GLubyte *buffer) +{ + int i,j; + + for(i = 0; i < piglit_height; i++) { + for(j = 0; j < (piglit_width + 50); j++) { + if (*(buffer + (i * piglit_height) + j) != TEST_PATTERN_BYTE) + return PIGLIT_FAIL; + } + } + + return PIGLIT_PASS; +} + + +enum piglit_result +check_buffer_RGB_565(GLubyte *buffer) +{ + pixel_f565 *p565; + int i,j; + + /* check that the rectangle was rendered correctly */ + for (i = piglit_height/4; i < piglit_height/4*3; i++) { + for (j = piglit_width/4; j < piglit_width/4*3; j++) { + p565 = (pixel_f565 *)(buffer + (((i * piglit_width) + j) * 2)); + if (p565->red != 0x1f && p565->blue != 0x00 && + p565->green != 0x00) + return PIGLIT_FAIL; + } + } + /* check that the remaining area is black */ + for(i = 0; i < piglit_height/4; i++) { + for(j = 0; j < piglit_width; j++) { + p565 = (pixel_f565 *)(buffer + (((i * piglit_width) + j) * 2)); + if (p565->red != 0x00 && p565->blue != 0x00 && + p565->green != 0x00) + return PIGLIT_FAIL; + } + } + for(i = piglit_height/4*3; i < piglit_height; i++) { + for(j = 0; j < piglit_width; j++) { + p565 = (pixel_f565 *)(buffer + (((i * piglit_width) + j) * 2)); + if (p565->red != 0x00 && p565->blue != 0x00 && + p565->green != 0x00) + return PIGLIT_FAIL; + } + } + for(i = piglit_height/4; i < piglit_height/4*3; i++) { + for(j = 0; j < piglit_width/4; j++) { + p565 = (pixel_f565 *)(buffer + (((i * piglit_width) + j) * 2)); + if (p565->red != 0x00 && p565->green != 0x00 && + p565->blue != 0x00) + return PIGLIT_FAIL; + } + } + for(i = piglit_height/4; i < piglit_height/4*3; i++) { + for(j = piglit_width/4*3; j < piglit_width; j++) { + p565 = (pixel_f565 *)(buffer + (((i * piglit_width) + j) * 2)); + if (p565->red != 0x00 && p565->green != 0x00 && + p565->blue != 0x00) + return PIGLIT_FAIL; + } + } + + return PIGLIT_PASS; +} + + +enum piglit_result +check_buffer_RGBA_5551(GLubyte *buffer) +{ + pixel_f5551 *p5551; + int i,j; + + /* check that the rectangle was rendered correctly */ + for (i = piglit_height/4; i < piglit_height/4*3; i++) { + for (j = piglit_width/4; j < piglit_width/4*3; j++) { + p5551 = (pixel_f5551 *)(buffer + (((i * piglit_width) + j) * 2)); + if (p5551->red != 0x1f && p5551->blue != 0x00 && + p5551->green != 0x00 && p5551->alpha != 0x1) + return PIGLIT_FAIL; + } + } + /* check that the remaining area is black */ + for(i = 0; i < piglit_height/4; i++) { + for(j = 0; j < piglit_width; j++) { + p5551 = (pixel_f5551 *)(buffer + (((i * piglit_width) + j) * 2)); + if (p5551->red!=0x00 && p5551->green!=0x00 && + p5551->blue!=0x00 && p5551->alpha!=0x1) + return PIGLIT_FAIL; + } + } + for(i = piglit_height/4*3; i < piglit_height; i++) { + for(j = 0; j < piglit_width; j++) { + p5551 = (pixel_f5551 *)(buffer + (((i * piglit_width) + j) * 2)); + if (p5551->red != 0x00 && p5551->green != 0x00 && + p5551->blue != 0x00 && p5551->alpha != 0x1) + return PIGLIT_FAIL; + } + } + for(i = piglit_height/4; i < piglit_height/4*3; i++) { + for(j = 0; j < piglit_width/4; j++) { + p5551 = (pixel_f5551 *)(buffer + (((i * piglit_width) + j) * 2)); + if (p5551->red != 0x00 && p5551->green != 0x00 && + p5551->blue != 0x00 && p5551->alpha != 0x1) + return PIGLIT_FAIL; + } + } + for(i = piglit_height/4; i < piglit_height/4*3; i++) { + for(j = piglit_width/4*3; j < piglit_width; j++) { + p5551 = (pixel_f5551 *)(buffer + (((i * piglit_width) + j) * 2)); + if (p5551->red != 0x00 && p5551->green != 0x00 && + p5551->blue != 0x00 && p5551->alpha != 0x1) + return PIGLIT_FAIL; + } + } + + return PIGLIT_PASS; +} + + +enum piglit_result +check_buffer_RGBA_4444(GLubyte *buffer) +{ + pixel_f4444 *p4444; + int i,j; + + /* check that the rectangle was rendered correctly */ + for (i = piglit_height/4; i < piglit_height/4*3; i++) { + for (j = piglit_width/4; j < piglit_width/4*3; j++) { + p4444 = (pixel_f4444 *)(buffer + (((i * piglit_width) + j) * 2)); + if (p4444->red != 0xf && p4444->green != 0x00 && + p4444->blue != 0x00 && p4444->alpha != 0xf) + return PIGLIT_FAIL; + } + } + /* check that the remaining area is black */ + for(i = 0; i < piglit_height/4; i++) { + for(j = 0; j < piglit_width; j++) { + p4444 = (pixel_f4444 *)(buffer + (((i * piglit_width) + j) * 2)); + if (p4444->red != 0x00 && p4444->green != 0x00 && + p4444->blue != 0x00 && p4444->alpha != 0xf) + return PIGLIT_FAIL; + } + } + for(i = piglit_height/4*3; i < piglit_height; i++) { + for(j = 0; j < piglit_width; j++) { + p4444 = (pixel_f4444 *)(buffer + (((i * piglit_width) + j) * 2)); + if (p4444->red != 0x00 && p4444->green != 0x00 && + p4444->blue != 0x00 && p4444->alpha != 0xf) + return PIGLIT_FAIL; + } + } + for(i = piglit_height/4; i < piglit_height/4*3; i++) { + for(j = 0; jred != 0x00 && p4444->green != 0x00 && + p4444->blue != 0x00 && p4444->alpha != 0xf) + return PIGLIT_FAIL; + } + } + for(i=piglit_height/4; i < piglit_height/4*3; i++) { + for(j = piglit_width/4*3; j < piglit_width; j++) { + p4444 = (pixel_f4444 *)(buffer + (((i * piglit_width) + j) * 2)); + if (p4444->red != 0x00 && p4444->green != 0x00 && + p4444->blue != 0x00 && p4444->alpha != 0xf) + return PIGLIT_FAIL; + } + } + + return PIGLIT_PASS; +} diff --git a/tests/spec/gles-2.0/api/glreadpixels-common.h b/tests/spec/gles-2.0/api/glreadpixels-common.h new file mode 100644 index 00000000..2bc17333 --- /dev/null +++ b/tests/spec/gles-2.0/api/glreadpixels-common.h @@ -0,0 +1,77 @@ +/* + * Copyright © 2013 Linaro Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Common functions used by the glReadPixels test exercises. + * + * \author Tom Gall + */ + +#define WIDTH 320 +#define HEIGHT 200 +#define TEST_PATTERN_BYTE 0xA5 + +/* various pixel formats */ +typedef struct { + unsigned short red:5; + unsigned short green:6; + unsigned short blue:5; +} pixel_f565; +typedef struct { + unsigned short red:5; + unsigned short green:5; + unsigned short blue:5; + unsigned short alpha:1; +} pixel_f5551; +typedef struct { + unsigned short red:4; + unsigned short green:4; + unsigned short blue:4; + unsigned short alpha:4; +} pixel_f4444; +typedef struct { + unsigned char red; + unsigned char green; + unsigned char blue; +} pixel_f888; + +/* this is to create a mapping between the format and string + * representation. While both formats and types are GLenum type + * these are actually both typdefed to unsigned instead of being + * real enums. + */ +enum _format_key { _DEPTH_COMPONENT, _ALPHA, _RGB, _RGBA, + _LUMINANCE, _LUMINANCE_ALPHA, _x1800 }; + +enum _type_key { _UNSIGNED_BYTE, _UNSIGNED_SHORT_4444, + _UNSIGNED_SHORT_5551, _UNSIGNED_SHORT_565 }; + +enum piglit_result check_buffer_RGB(GLubyte *buffer); +enum piglit_result check_buffer_RGBA(GLubyte *buffer); +enum piglit_result check_buffer_ALPHA(GLubyte *buffer); +enum piglit_result check_buffer_is_not_changed(GLubyte *buffer); +enum piglit_result check_buffer_RGB_565(GLubyte *buffer); +enum piglit_result check_buffer_RGBA_5551(GLubyte *buffer); +enum piglit_result check_buffer_RGBA_4444(GLubyte *buffer); + +void clear_buffer(GLubyte *buffer); diff --git a/tests/spec/gles-2.0/api/glreadpixels-invalid.c b/tests/spec/gles-2.0/api/glreadpixels-invalid.c new file mode 100644 index 00000000..f113d2be --- /dev/null +++ b/tests/spec/gles-2.0/api/glreadpixels-invalid.c @@ -0,0 +1,284 @@ +/* + * Copyright © 2013 Linaro Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * This is test exercises glReadPixels + * as specified by the OpenGL ES 2.0.25 spec. + * + * \author Tom Gall + */ + +#include +#include +#include "piglit-util-gl-common.h" +#include "glreadpixels-common.h" + + +const char *format_strings [] = { + "GL_DEPTH_COMPONENT", + "GL_ALPHA", + "GL_RGB", + "GL_RGBA", + "GL_LUMINANCE", + "GL_LUMINANCE_ALPHA", + "0x1800" +}; + +const char *type_strings[] = { + "GL_UNSIGNED_BYTE", + "GL_UNSIGNED_SHORT_4444", + "GL_UNSIGNED_SHORT_5551", + "GL_UNSIGNED_SHORT_565" +}; + + +PIGLIT_GL_TEST_CONFIG_BEGIN + + config.supports_gl_es_version = 20; + + config.window_width = 320; + config.window_height = 200; + config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DEPTH; + +PIGLIT_GL_TEST_CONFIG_END + +GLuint prog; +GLuint frag; +GLuint vert; + +char vertex_shader [] = + "attribute vec4 vPosition;\n" + "void main()\n" + "{\n" + " gl_Position = vPosition;\n" + "}"; + +char fragment_shader [] = + "precision mediump float;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" + "}"; + +static const struct { + GLenum format; + GLenum type; + enum piglit_result (*checkfn)(GLubyte *); + struct { + int x, y, width, height; + } coords; + int expected_error; + char *gl_error_msg; + enum _format_key format_idx; + enum _type_key type_idx; +} targets[] = { + { + GL_RGBA, + GL_UNSIGNED_BYTE, + check_buffer_is_not_changed, + { -10, -10, 10, 10 }, + 0, + "Reading from -10 -10 failed", + _RGBA, + _UNSIGNED_BYTE + }, + { + GL_RGBA, + GL_UNSIGNED_BYTE, + check_buffer_is_not_changed, + { 0, 0, 0, 0 }, + 0, + "Reading from 0 0 for 0 bytes should not copy data", + _RGBA, + _UNSIGNED_BYTE + }, + { + GL_RGBA, + GL_UNSIGNED_BYTE, + NULL, + { 0, 0, 1, 1 }, + 0, + "Reading from 0 0 to 1 1 to NULL failed", + _RGBA, + _UNSIGNED_BYTE + }, + { + GL_RGBA, + GL_UNSIGNED_BYTE, + check_buffer_is_not_changed, + { 0, 0, -10, -10 }, + GL_INVALID_VALUE, + "Neg width/height should generate GL_INVALID_VALUE", + _RGBA, + _UNSIGNED_BYTE + }, + { + GL_LUMINANCE, + GL_UNSIGNED_BYTE, + NULL, + { 0, 0, WIDTH, HEIGHT }, + GL_INVALID_OPERATION, + "GL_LUMINANCE should generate GL_INVALID_OPERATION", + _LUMINANCE, + _UNSIGNED_BYTE + }, + { + GL_LUMINANCE_ALPHA, + GL_UNSIGNED_BYTE, + NULL, + { 0, 0, WIDTH, HEIGHT }, + GL_INVALID_OPERATION, + "GL_LUMINANCE_ALPHA should generate GL_INVALID_OPERATION", + _LUMINANCE_ALPHA, + _UNSIGNED_BYTE + }, + { + GL_DEPTH_COMPONENT, + GL_UNSIGNED_BYTE, + NULL, + { 0, 0, WIDTH, HEIGHT }, + GL_INVALID_OPERATION, + "GL_DEPTH_COMPONENT should generate GL_INVALID_OPERATION", + _DEPTH_COMPONENT, + _UNSIGNED_BYTE + }, + { + 0x1800, + GL_UNSIGNED_BYTE, + NULL, + { 0, 0, WIDTH, HEIGHT }, + GL_INVALID_OPERATION, + "Invalid format value 0x1800 should generate GL_INVALID_OPERATION", + _x1800, + _UNSIGNED_BYTE + }, + { + GL_RGBA, + GL_UNSIGNED_SHORT_5_6_5, + NULL, + { 0, 0, WIDTH, HEIGHT }, + GL_INVALID_OPERATION, + "GL_RGBA & 565 should generated a GL_INVALID_OPERATION", + _RGBA, + _UNSIGNED_SHORT_565 + }, + { + GL_RGB, + GL_UNSIGNED_SHORT_5_6_5, + check_buffer_RGB_565, + { 0, 0, WIDTH, HEIGHT }, + GL_INVALID_OPERATION, + "glReadPixels with GL_RGB & GL_UNSIGNED_SHORT_565 failed.", + _RGB, + _UNSIGNED_SHORT_565 + }, +}; + + +enum piglit_result +validate_results(void) +{ + /* pad a bit so we can do a request larger than the viewport */ + GLubyte buffer[HEIGHT+50][WIDTH][4]; + enum piglit_result final_result = PIGLIT_PASS; + int v; + + /* first make sure glError has no issues */ + if (!piglit_check_gl_error(0)) + return PIGLIT_FAIL; + + for (v = 0; v < ARRAY_SIZE(targets); v++) { + clear_buffer((GLubyte *)&buffer); + glReadPixels(targets[v].coords.x, + targets[v].coords.y, + targets[v].coords.width, + targets[v].coords.height, + targets[v].format, + targets[v].type, + &buffer); + if (!piglit_check_gl_error(targets[v].expected_error)) { + fprintf(stderr, "%s\n",targets[v].gl_error_msg); + final_result = PIGLIT_FAIL; + } + if (targets[v].checkfn) { + if (targets[v].checkfn((GLubyte *)&buffer) == PIGLIT_FAIL) { + fprintf(stderr, "%s & %s, buffer has incorrect results\n",format_strings[targets[v].format_idx], type_strings[targets[v].type_idx]); + final_result = PIGLIT_FAIL; + } + } + } + piglit_report_result(final_result); + + return final_result; +} + +void +link_and_use_shaders(void) +{ + prog = glCreateProgram(); + + vert = piglit_compile_shader_text(GL_VERTEX_SHADER, vertex_shader); + frag = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fragment_shader); + + glAttachShader(prog, vert); + glAttachShader(prog, frag); + + prog = piglit_link_simple_program(vert, frag); + if (!prog) { + piglit_report_result(PIGLIT_FAIL); + return; + } + + glDeleteShader(vert); + glDeleteShader(frag); + + glUseProgram(prog); + if (!piglit_check_gl_error(0)) { + piglit_report_result(PIGLIT_FAIL); + return; + } +} + +enum piglit_result +piglit_display(void) +{ + GLfloat vertices[] = { + 0.5, -0.5, 0.0, + 0.5, 0.5, 0.0, + -0.5, 0.5, 0.0, + -0.5, -0.5, 0.0 }; + + glClear(GL_COLOR_BUFFER_BIT); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices); + glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + return validate_results(); +} + +void +piglit_init(int argc, char *argv[]) +{ + link_and_use_shaders(); +} diff --git a/tests/spec/gles-2.0/api/glreadpixels.c b/tests/spec/gles-2.0/api/glreadpixels.c new file mode 100644 index 00000000..0e37d870 --- /dev/null +++ b/tests/spec/gles-2.0/api/glreadpixels.c @@ -0,0 +1,293 @@ +/* + * Copyright © 2013 Linaro Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * This is test exercises glReadPixels + * as specified by the OpenGL ES 2.0.25 spec. + * + * Todo: GL_PACK_ALIGNMENT via glPixelStorei isn't tested + * reading from GL_COLOR_ATTACHMENT0 when the default framebuffer + * isn't bound is not tested + * combo of GL_IMPLEMENTATION_COLOR_READ_FORMAT + * GL_IMPLEMENTATION_COLOR_READ_TYPE is not tested + * add variations for DEPTH_STENCIL_OES and STENCIL_INDEX + * + * \author Tom Gall + */ + +#include +#include +#include "piglit-util-gl-common.h" +#include "glreadpixels-common.h" + + +const char *format_strings [] = { + "GL_DEPTH_COMPONENT", + "GL_ALPHA", + "GL_RGB", + "GL_RGBA", + "GL_LUMINANCE", + "GL_LUMINANCE_ALPHA", + "0x1800" +}; + +const char *type_strings[] = { + "GL_UNSIGNED_BYTE", + "GL_UNSIGNED_SHORT_4444", + "GL_UNSIGNED_SHORT_5551", + "GL_UNSIGNED_SHORT_565" +}; + + +PIGLIT_GL_TEST_CONFIG_BEGIN + + config.supports_gl_es_version = 20; + + config.window_width = 320; + config.window_height = 200; + config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DEPTH; + +PIGLIT_GL_TEST_CONFIG_END + +GLuint prog; +GLuint frag; +GLuint vert; + +char vertex_shader [] = + "attribute vec4 vPosition;\n" + "void main()\n" + "{\n" + " gl_Position = vPosition;\n" + "}"; + +char fragment_shader [] = + "precision mediump float;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" + "}"; + +static const struct { + GLenum format; + GLenum type; + enum piglit_result (*checkfn)(GLubyte *); + struct { + int x, y, width, height; + } coords; + int expected_error; + char *gl_error_msg; + enum _format_key format_idx; + enum _type_key type_idx; +} targets[] = { + { + GL_RGBA, + GL_UNSIGNED_BYTE, + check_buffer_RGBA, + { 0, 0, WIDTH, HEIGHT }, + 0, + "glReadPixels with GL_RGBA & GL_UNSIGNED_BTYE failed", + _RGBA, + _UNSIGNED_BYTE + }, + { + GL_RGBA, + GL_UNSIGNED_SHORT_5_5_5_1, + check_buffer_RGBA_5551, + { 0, 0, WIDTH, HEIGHT }, + 0, + "glReadPixels with GL_RGBA & 5551 failed.", + _RGBA, + _UNSIGNED_SHORT_5551 + }, + { + GL_RGBA, + GL_UNSIGNED_SHORT_4_4_4_4, + check_buffer_RGBA_4444, + { 0, 0, WIDTH, HEIGHT }, + 0, + "glReadPixels with GL_RGBA & GL_UNSIGNED_SHORT 4444 failed.", + _RGBA, + _UNSIGNED_SHORT_4444 + }, + { + GL_ALPHA, + GL_UNSIGNED_BYTE, + check_buffer_ALPHA, + { 0, 0, WIDTH, HEIGHT }, + 0, + "glReadPixels with GL_ALPHA & GL_UNSIGNED_BYTE failed.", + _ALPHA, + _UNSIGNED_BYTE + }, + { + GL_ALPHA, + GL_UNSIGNED_SHORT_5_6_5, + check_buffer_ALPHA, + { 0, 0, WIDTH, HEIGHT }, + 0, + "glReadPixels with GL_ALPHA & GL_UNSIGNED_SHORT_565 failed.", + _ALPHA, + _UNSIGNED_SHORT_565 + }, + { + GL_ALPHA, + GL_UNSIGNED_SHORT_5_5_5_1, + check_buffer_ALPHA, + { 0, 0, WIDTH, HEIGHT }, + 0, + "glReadPixels with GL_ALPHA & GL_UNSIGNED_SHORT_5551 failed.", + _ALPHA, + _UNSIGNED_SHORT_5551 + }, + { + GL_ALPHA, + GL_UNSIGNED_SHORT_4_4_4_4, + check_buffer_ALPHA, + { 0, 0, WIDTH, HEIGHT }, + 0, + "glReadPixels with GL_ALPHA & GL_UNSIGNED_SHORT_4444 failed.", + _ALPHA, + _UNSIGNED_SHORT_4444 + }, + { + GL_RGB, + GL_UNSIGNED_BYTE, + check_buffer_RGB, + { 0, 0, WIDTH, HEIGHT }, + 0, + "glReadPixels with GL_RGB & GL_UNSIGNED_BYTE failed.", + _RGB, + _UNSIGNED_BYTE + }, + { + GL_RGB, + GL_UNSIGNED_SHORT_5_5_5_1, + check_buffer_RGBA_5551, + { 0, 0, WIDTH, HEIGHT }, + 0, + "glReadPixels with GL_RGB & GL_UNSIGNED_SHORT_ 5551 failed.", + _RGB, + _UNSIGNED_SHORT_5551 + }, + { + GL_RGB, + GL_UNSIGNED_SHORT_4_4_4_4, + check_buffer_RGBA_4444, + { 0, 0, WIDTH, HEIGHT }, + 0, + "glReadPixels with GL_RGB & GL_UNSIGNED_SHORT_4444 failed.", + _RGB, + _UNSIGNED_SHORT_4444 + } +}; + + +enum piglit_result +validate_results(void) +{ + /* pad a bit so we can do a request larger than the viewport */ + GLubyte buffer[HEIGHT+50][WIDTH][4]; + enum piglit_result final_result = PIGLIT_PASS; + int v; + + /* first make sure glError has no issues */ + if (!piglit_check_gl_error(0)) + return PIGLIT_FAIL; + + for (v = 0; v < ARRAY_SIZE(targets); v++) { + clear_buffer((GLubyte *)&buffer); + glReadPixels(targets[v].coords.x, + targets[v].coords.y, + targets[v].coords.width, + targets[v].coords.height, + targets[v].format, + targets[v].type, + &buffer); + if (!piglit_check_gl_error(targets[v].expected_error)) { + fprintf(stderr, "%s\n",targets[v].gl_error_msg); + final_result = PIGLIT_FAIL; + } + if (targets[v].checkfn) { + if (targets[v].checkfn((GLubyte *)&buffer) == PIGLIT_FAIL) { + fprintf(stderr, "%s & %s, buffer has incorrect results\n", + format_strings[targets[v].format_idx], + type_strings[targets[v].type_idx]); + final_result = PIGLIT_FAIL; + } + } + } + piglit_report_result(final_result); + + return final_result; +} + +void +link_and_use_shaders(void) +{ + prog = glCreateProgram(); + + vert = piglit_compile_shader_text(GL_VERTEX_SHADER, vertex_shader); + frag = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fragment_shader); + + glAttachShader(prog, vert); + glAttachShader(prog, frag); + + prog = piglit_link_simple_program(vert, frag); + if (!prog) { + piglit_report_result(PIGLIT_FAIL); + return; + } + + glDeleteShader(vert); + glDeleteShader(frag); + + glUseProgram(prog); + if (!piglit_check_gl_error(0)) { + piglit_report_result(PIGLIT_FAIL); + return; + } +} + +enum piglit_result +piglit_display(void) +{ + GLfloat vertices[] = { + 0.5, -0.5, 0.0, + 0.5, 0.5, 0.0, + -0.5, 0.5, 0.0, + -0.5, -0.5, 0.0 }; + + glClear(GL_COLOR_BUFFER_BIT); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices); + glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + return validate_results(); +} + +void +piglit_init(int argc, char *argv[]) +{ + link_and_use_shaders(); +} -- cgit v1.2.3