From: Nicolai Hähnle <nicolai.haeh...@amd.com> Test polygon stipple and its interaction with a simple fragment program. Exposes a bug that lived in Gallium's stipple emulation for a very long time until it was hit by Kodi (reported by Christian König). --- tests/all.py | 1 + tests/general/CMakeLists.gl.txt | 1 + tests/general/polygon-stipple-fs.c | 186 +++++++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+) create mode 100644 tests/general/polygon-stipple-fs.c
diff --git a/tests/all.py b/tests/all.py index 3184b6e..1b0e2f8 100644 --- a/tests/all.py +++ b/tests/all.py @@ -1178,6 +1178,7 @@ with profile.group_manager( g(['array-depth-roundtrip'], run_concurrent=False) g(['depth-cube-map'], run_concurrent=False) g(['sampler-cube-shadow'], run_concurrent=False) + g(['polygon-stipple-fs']) g(['generatemipmap-cubemap']) with profile.group_manager( diff --git a/tests/general/CMakeLists.gl.txt b/tests/general/CMakeLists.gl.txt index 3a46fb0..23b8258 100644 --- a/tests/general/CMakeLists.gl.txt +++ b/tests/general/CMakeLists.gl.txt @@ -90,6 +90,7 @@ piglit_add_executable (polygon-mode-offset polygon-mode-offset.c) piglit_add_executable (polygon-mode-facing polygon-mode-facing.c) piglit_add_executable (polygon-mode polygon-mode.c) piglit_add_executable (polygon-offset polygon-offset.c) +piglit_add_executable (polygon-stipple-fs polygon-stipple-fs.c) piglit_add_executable (primitive-restart primitive-restart.c) piglit_add_executable (primitive-restart-draw-mode primitive-restart-draw-mode.c) piglit_add_executable (provoking-vertex provoking-vertex.c) diff --git a/tests/general/polygon-stipple-fs.c b/tests/general/polygon-stipple-fs.c new file mode 100644 index 0000000..211a7e2 --- /dev/null +++ b/tests/general/polygon-stipple-fs.c @@ -0,0 +1,186 @@ +/* + * Copyright 2016 Advanced Micro Devices, 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 + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS 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. + * + * Authors: + * Nicolai Hähnle <nicolai.haeh...@amd.com> + */ + +/* + * Test that polygon stipple works and interacts reasonably with a simple + * fragment shader. + */ + +#include "piglit-util-gl.h" + +#define STR(x) #x +#define STRINGIFY(x) STR(x) + +PIGLIT_GL_TEST_CONFIG_BEGIN + + config.supports_gl_compat_version = 30; + + config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE; + + config.window_width = 512; + config.window_height = 512; + +PIGLIT_GL_TEST_CONFIG_END + +#define TEX_WIDTH 64 +#define TEX_HEIGHT 64 + +#define BLUE 0x87 +#define ALPHA 0x45 + +/* Use a texture, uniforms, and immediate constants. */ +static const char fragment_shader[] = + "uniform sampler2D tex;\n" + "uniform float b;\n" + "void\n" + "main()\n" + "{\n" + " vec4 color = texture2D(tex, gl_TexCoord[0].xy);\n" + " gl_FragColor.xy = color.xy;\n" + " gl_FragColor.z = b;\n" + " gl_FragColor.w = float(" STRINGIFY(ALPHA) ") / 255.;\n" + "}\n"; + +static GLuint program; + +static bool +equal_images(const GLubyte *texture, + const GLubyte *stipple, + const GLubyte *testImg) +{ + unsigned x, y; + GLubyte ref[4]; + + for (y = 0; y < TEX_HEIGHT; ++y) { + for (x = 0; x < TEX_WIDTH; ++x) { + unsigned idx = (y % 32) * 32 + x % 32; + bool shown = stipple[idx / 8] & (1 << (7 - idx % 8)); + if (shown) { + ref[0] = texture[0]; + ref[1] = texture[1]; + ref[2] = BLUE; + ref[3] = ALPHA; + } else { + ref[0] = ref[1] = ref[2] = ref[3] = 0; + } + + bool fail = memcmp(ref, testImg, 4) != 0; + if (fail) { + printf("%u,%u: test = %u,%u,%u,%u " + "ref = %u,%u,%u,%u\n", + x, y, + testImg[0], testImg[1], testImg[2], testImg[3], + ref[0], ref[1], ref[2], ref[3]); + return false; + } + + testImg += 4; + texture += 4; + } + } + + return true; +} + +static bool +test_stipple() +{ + GLuint uniform_tex, uniform_b; + GLubyte *texture_img; + GLubyte *stipple; + GLubyte *test_img; + GLuint tex; + unsigned i; + bool pass = true; + + texture_img = malloc(TEX_WIDTH * TEX_HEIGHT * 4); + test_img = malloc(TEX_WIDTH * TEX_HEIGHT * 4); + stipple = malloc(32 * 32 / 8); + + for (i = 0; i < TEX_WIDTH * TEX_HEIGHT * 4; ++i) + texture_img[i] = rand(); + for (i = 0; i < 32 * 32 / 8; ++i) + stipple[i] = rand(); + + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texture_img); + + glPolygonStipple(stipple); + glEnable(GL_POLYGON_STIPPLE); + + glUseProgram(program); + + uniform_tex = glGetUniformLocation(program, "tex"); + glUniform1i(uniform_tex, 0); + + uniform_b = glGetUniformLocation(program, "b"); + glUniform1f(uniform_b, BLUE / 255.); + + piglit_draw_rect_tex(0, 0, TEX_WIDTH, TEX_HEIGHT, 0, 0, 1.0, 1.0); + glUseProgram(0); + + glReadPixels(0, 0, TEX_WIDTH, TEX_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, test_img); + + pass = equal_images(texture_img, stipple, test_img); + + glDisable(GL_POLYGON_STIPPLE); + glDeleteTextures(1, &tex); + + free(stipple); + free(test_img); + free(texture_img); + + return pass; +} + +enum piglit_result +piglit_display(void) +{ + bool pass = true; + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + + pass = test_stipple(); + + piglit_present_results(); + + return pass ? PIGLIT_PASS : PIGLIT_FAIL; +} + +void +piglit_init(int argc, char **argv) +{ + srand(0); /* reproducibility of the first error */ + + piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); + + program = piglit_build_simple_program(NULL, fragment_shader); +} -- 2.5.0 _______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/piglit