Tapani Pälli <tapani.pa...@intel.com> writes: > Test includes: > - texture uploads > - mipmap generation > - framebuffer creation > - rendering to > - reading from > - interaction with GL_EXT_copy_image > > v2: code cleanup > > Signed-off-by: Tapani Pälli <tapani.pa...@intel.com> > --- > tests/all.py | 5 + > tests/spec/CMakeLists.txt | 1 + > tests/spec/ext_texture_norm16/CMakeLists.gles2.txt | 7 + > tests/spec/ext_texture_norm16/CMakeLists.txt | 1 + > tests/spec/ext_texture_norm16/render.c | 374 > +++++++++++++++++++++ > 5 files changed, 388 insertions(+) > create mode 100644 tests/spec/ext_texture_norm16/CMakeLists.gles2.txt > create mode 100644 tests/spec/ext_texture_norm16/CMakeLists.txt > create mode 100644 tests/spec/ext_texture_norm16/render.c > > diff --git a/tests/all.py b/tests/all.py > index 26638cd82..101a6c149 100644 > --- a/tests/all.py > +++ b/tests/all.py > @@ -3187,6 +3187,11 @@ with profile.test_list.group_manager( > > with profile.test_list.group_manager( > PiglitGLTest, > + grouptools.join('spec', 'ext_texture_norm16')) as g: > + g(['ext_texture_norm16-render'], 'render') > + > +with profile.test_list.group_manager( > + PiglitGLTest, > grouptools.join('spec', 'ext_frag_depth')) as g: > g(['fragdepth_gles2']) > > diff --git a/tests/spec/CMakeLists.txt b/tests/spec/CMakeLists.txt > index dc14beb4e..405d35a53 100644 > --- a/tests/spec/CMakeLists.txt > +++ b/tests/spec/CMakeLists.txt > @@ -178,3 +178,4 @@ add_subdirectory (arb_fragment_shader_interlock) > add_subdirectory (ext_occlusion_query_boolean) > add_subdirectory (ext_disjoint_timer_query) > add_subdirectory (intel_blackhole_render) > +add_subdirectory (ext_texture_norm16) > diff --git a/tests/spec/ext_texture_norm16/CMakeLists.gles2.txt > b/tests/spec/ext_texture_norm16/CMakeLists.gles2.txt > new file mode 100644 > index 000000000..e9cebd101 > --- /dev/null > +++ b/tests/spec/ext_texture_norm16/CMakeLists.gles2.txt > @@ -0,0 +1,7 @@ > +link_libraries ( > + piglitutil_${piglit_target_api} > +) > + > +piglit_add_executable (ext_texture_norm16-render render.c) > + > +# vim: ft=cmake: > diff --git a/tests/spec/ext_texture_norm16/CMakeLists.txt > b/tests/spec/ext_texture_norm16/CMakeLists.txt > new file mode 100644 > index 000000000..144a306f4 > --- /dev/null > +++ b/tests/spec/ext_texture_norm16/CMakeLists.txt > @@ -0,0 +1 @@ > +piglit_include_target_api() > diff --git a/tests/spec/ext_texture_norm16/render.c > b/tests/spec/ext_texture_norm16/render.c > new file mode 100644 > index 000000000..f99b1fd9c > --- /dev/null > +++ b/tests/spec/ext_texture_norm16/render.c > @@ -0,0 +1,374 @@ > +/* > + * Copyright © 2018 Intel Corporation > + * > + * 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. > + */ > + > +/** > + * @file > + * Basic tests for formats added by GL_EXT_texture_norm16 extension > + * > + * > https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_texture_norm16.txt > + * > + * Test includes: > + * - texture uploads > + * - mipmap generation > + * - framebuffer creation > + * - rendering to > + * - reading from > + * - interaction with GL_EXT_copy_image > + */ > + > +#include "piglit-util-gl.h" > + > +PIGLIT_GL_TEST_CONFIG_BEGIN > + config.supports_gl_es_version = 31; > + config.window_visual = PIGLIT_GL_VISUAL_RGBA; > +PIGLIT_GL_TEST_CONFIG_END > + > +static const char vs_source[] = > + "#version 310 es\n" > + "layout(location = 0) in highp vec4 vertex;\n" > + "layout(location = 1) in highp vec4 uv;\n" > + "out highp vec2 tex_coord;\n" > + "\n" > + "void main()\n" > + "{\n" > + " gl_Position = vertex;\n" > + " tex_coord = uv.st;\n" > + "}\n"; > + > +static const char fs_source[] = > + "#version 310 es\n" > + "layout(location = 0) uniform sampler2D texture;\n" > + "in highp vec2 tex_coord;\n" > + "out highp vec4 color;\n" > + "void main()\n" > + "{\n" > + " color = texture2D(texture, tex_coord);\n" > + "}\n"; > + > +/* trianglestrip, interleaved vertices + texcoords */ > +static const GLfloat vertex_data[] = { > + -1.0f, 1.0f, > + 0.0f, 1.0f, > + 1.0f, 1.0f, > + 1.0f, 1.0f, > + -1.0f, -1.0f, > + 0.0f, 0.0f, > + 1.0f, -1.0f, > + 1.0f, 0.0f > +}; > + > +static const struct fmt_test { > + GLenum iformat; > + GLenum base_format; > + unsigned bpp; > + GLenum type; > + bool req_render; > + bool can_read; > +} tests[] = { > + { GL_R16_EXT, GL_RED, 2, GL_UNSIGNED_SHORT, > true, true, }, > + { GL_RG16_EXT, GL_RG, 4, GL_UNSIGNED_SHORT, > true, true, }, > + { GL_RGB16_EXT, GL_RGB, 6, GL_UNSIGNED_SHORT, > false, true, }, > + { GL_RGBA16_EXT, GL_RGBA, 8, GL_UNSIGNED_SHORT, > true, true, }, > + { GL_R16_SNORM_EXT, GL_RED, 2, GL_SHORT, > false, false, }, > + { GL_RG16_SNORM_EXT, GL_RG, 4, GL_SHORT, > false, false, }, > + { GL_RGB16_SNORM_EXT, GL_RGB, 6, GL_SHORT, > false, false, }, > + { GL_RGBA16_SNORM_EXT, GL_RGBA, 8, GL_SHORT, > false, false, }, > +}; > + > +static void > +upload(const struct fmt_test *test, void *data) > +{ > + /* glGenerateMipmap only for color renderable formats. */ > + if (test->req_render) { > + glTexStorage2D(GL_TEXTURE_2D, 4, test->iformat, piglit_width, > + piglit_height); > + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, piglit_width, > + piglit_height, test->base_format, test->type, > + data); > + glGenerateMipmap(GL_TEXTURE_2D); > + return; > + } > + glTexImage2D(GL_TEXTURE_2D, 0, test->iformat, piglit_width, > + piglit_height, 0, test->base_format, test->type, data); > +} > + > +static unsigned > +get_max_value(GLenum type) > +{ > + return type == GL_SHORT ? SHRT_MAX : USHRT_MAX; > +} > + > +static void > +value_for_format(const struct fmt_test *test, unsigned short *value) > +{ > + unsigned short val = get_max_value(test->type); > + > + /* red */ > + value[0] = val; > + /* yellow */ > + if (test->bpp > 2) > + value[1] = val; > + /* pink */ > + if (test->bpp > 4) { > + value[2] = val; > + value[1] = 0; > + } > + /* blue */ > + if (test->bpp > 6) { > + value[3] = val; > + value[0] = 0; > + } > +} > + > +static void > +generate_data(const struct fmt_test *test) > +{ > + unsigned pixels = piglit_width * piglit_height; > + char *data = malloc (pixels * test->bpp); > + unsigned short *p = (unsigned short *) data; > + > + for (unsigned i = 0; i < pixels; i++, p += test->bpp / 2) > + value_for_format(test, p); > + > + upload(test, data); > + free(data); > +} > + > +static GLuint > +create_texture(const struct fmt_test *test) > +{ > + GLuint tex; > + glGenTextures(1, &tex); > + glBindTexture(GL_TEXTURE_2D, tex); > + > + generate_data(test); > + > + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); > + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); > + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); > + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); > + > + return tex; > +} > + > +static GLuint > +create_fbo(const struct fmt_test *test, GLuint *tex) > +{ > + GLuint fbo; > + GLuint fbo_tex = create_texture(test); > + > + *tex = fbo_tex; > + > + glGenFramebuffers(1, &fbo); > + glBindFramebuffer(GL_FRAMEBUFFER, fbo); > + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, > + GL_TEXTURE_2D, fbo_tex, 0); > + return fbo; > +} > + > +static void > +render_texture(GLuint texture, GLuint target) > +{ > + glBindTexture(GL_TEXTURE_2D, texture); > + glBindFramebuffer(GL_FRAMEBUFFER, target); > + > + glViewport(0, 0, piglit_width, piglit_height); > + > + glClear(GL_COLOR_BUFFER_BIT); > + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); > +} > + > +static bool > +verify_contents(const struct fmt_test *test) > +{ > + bool result = true; > + unsigned amount = piglit_width * piglit_height; > + unsigned short *pix = malloc (amount * 8); > + glReadPixels(0, 0, piglit_width, piglit_height, GL_RGBA, > + GL_UNSIGNED_SHORT, pix); > + > + /* Setup expected value, alpha is always max in the test. */ > + unsigned short value[4] = { 0 }; > + value_for_format(test, value); > + value[3] = get_max_value(test->type); > + > + unsigned short *p = pix; > + for (unsigned i = 0; i < amount; i++, p += 4) { > + if (memcmp(p, value, sizeof(value)) == 0) > + continue; > + > + piglit_report_subtest_result(PIGLIT_FAIL, > + "format 0x%x read fail", > + test->iformat); > + result = false; > + break; > + } > + > + free(pix); > + return result; > +} > + > +static bool > +verify_contents_float(const struct fmt_test *test) > +{ > + /* Setup expected value, alpha is always max in the test. */ > + unsigned short value[4] = { 0 }; > + unsigned short max = get_max_value(test->type); > + value_for_format(test, value); > + value[3] = max; > + > + const float expected[4] = { > + value[0] / max, > + value[1] / max, > + value[2] / max, > + value[3] / max, > + }; > + > + bool res = piglit_probe_rect_rgba(0, 0, piglit_width, piglit_height, > + expected); > + > + if (!res) > + piglit_report_subtest_result(PIGLIT_FAIL, > + "format 0x%x read fail", > + test->iformat); > + return res; > +} > + > +static bool > +test_copy_image(const struct fmt_test *test, GLuint src, GLuint *texture) > +{ > + bool result = true; > + GLuint tex = create_texture(test); > + *texture = tex; > + glCopyImageSubData(src, GL_TEXTURE_2D, 0, 0, 0, 0, tex, GL_TEXTURE_2D, > + 0, 0, 0, 0, piglit_width, piglit_height, 0); > + > + if (!piglit_check_gl_error(GL_NO_ERROR)) { > + piglit_report_subtest_result(PIGLIT_FAIL, > + "format 0x%x copyimage fail", > + test->iformat); > + result = false; > + } > + return result; > +} > + > +enum piglit_result > +piglit_display(void) > +{ > + GLint prog = piglit_build_simple_program(vs_source, fs_source); > + glUseProgram(prog); > + > + glEnableVertexAttribArray(0); > + glEnableVertexAttribArray(1); > + > + glActiveTexture(GL_TEXTURE0); > + glUniform1i(0 /* explicit loc */, 0); > + > + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), > + vertex_data); > + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), > + (void*) (vertex_data + (2 * sizeof(float)))); > + > + bool pass = true; > + > + /* Loop over each format. */ > + const struct fmt_test *test = tests; > + for (unsigned i = 0; i < ARRAY_SIZE(tests); i++, test++) { > + > + /* Create a texture, upload data */ > + const GLuint texture = create_texture(test); > + > + glBindTexture(GL_TEXTURE_2D, texture); > + > + /* Can only texture from. */ > + if (!test->req_render) { > + /* Render texture to window and verify contents. */ > + render_texture(texture, 0); > + pass &= verify_contents_float(test); > + piglit_present_results(); > + if (pass) > + piglit_report_subtest_result(PIGLIT_PASS, > + "format 0x%x", > + test->iformat); > + glDeleteTextures(1, &texture); > + continue; > + } > + > + GLuint fbo_tex; > + const GLuint fbo = create_fbo(test, &fbo_tex); > + > + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != > + GL_FRAMEBUFFER_COMPLETE) { > + piglit_report_subtest_result(PIGLIT_FAIL, > + "format 0x%x fbo fail", > + test->iformat); > + pass &= false; > + } > + > + render_texture(texture, fbo); > + > + /* If GL_EXT_copy_image is supported then create another > + * texture, copy contents and render result to fbo. > + */ > + GLuint texture_copy = 0; > + if (piglit_is_extension_supported("GL_EXT_copy_image")) { > + pass &= test_copy_image(test, texture, &texture_copy); > + render_texture(texture_copy, fbo); > + } else { > + piglit_report_subtest_result(PIGLIT_SKIP, > + "copy test skipped"); > + } > + > + /* If format can be read, verify contents. */ > + if (test->can_read) > + pass &= verify_contents(test); > + > + /* Render fbo contents to window. */ > + render_texture(fbo_tex, 0); > + > + piglit_present_results(); > + > + glDeleteFramebuffers(1, &fbo); > + glDeleteTextures(1, &texture); > + glDeleteTextures(1, &texture_copy); > + > + if (pass) > + piglit_report_subtest_result(PIGLIT_PASS, > + "format 0x%x", > + test->iformat);
If one of the early formats fails, then pass will be false for the rest of the formats even if they passed, giving bogus subtest results. I would recommend moving most of the body of the loop out to a helper function to test the format that returns a bool, and then you can piglit_report_subtest_result() and update the global pass state from the loop. Other than that, I'm really happy with how much API coverage you've got here.
signature.asc
Description: PGP signature
_______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/piglit