[Piglit] [PATCH] ARB_texture_gather: add initial execution test

Chris Forbes chrisf at ijw.co.nz
Mon Aug 12 16:24:07 PDT 2013


Sorry, there's some assorted lame whitespace in here. Assume I'll fix that :)

On Sat, Aug 10, 2013 at 10:10 PM, Chris Forbes <chrisf at ijw.co.nz> wrote:
> This test exercises combinations of:
> - Shader stage vs/fs
> - Offsetting
> - Component count, up to implementation-defined limit
> - Swizzling
> - Unsigned normalized vs float type
>
> The test works by numbering the texels, and ensuring that the four
> texels sampled by textureGather*() are those we expect.
>
> Not exercised yet:
> - Integer textures
> - Samplers other than sampler2D
> - Other interesting internalformats [DEPTH_COMPONENT, etc]
> - Addressing modes other than WRAP.
>
> Signed-off-by: Chris Forbes <chrisf at ijw.co.nz>
> ---
>  tests/all.tests                           |  19 ++
>  tests/texturing/shaders/CMakeLists.gl.txt |   1 +
>  tests/texturing/shaders/textureGather.c   | 309 ++++++++++++++++++++++++++++++
>  3 files changed, 329 insertions(+)
>  create mode 100644 tests/texturing/shaders/textureGather.c
>
> diff --git a/tests/all.tests b/tests/all.tests
> index a914a2a..68e89e2 100644
> --- a/tests/all.tests
> +++ b/tests/all.tests
> @@ -969,6 +969,25 @@ for stage in ['vs', 'gs', 'fs']:
>         for sampler in samplers_atm:
>                 spec['ARB_texture_multisample/textureSize/' + stage + '-textureSize-' + sampler] = concurrent_test('textureSize ' + stage + ' ' + sampler)
>
> +# Group ARB_texture_gather
> +arb_texture_gather = Group()
> +spec['ARB_texture_gather'] = arb_texture_gather
> +for stage in ['vs', 'fs']:
> +    for comps in ['r', 'rg', 'rgb', 'rgba']:
> +        for swiz in ['red', 'green', 'blue', 'alpha'][:len(comps)] + ['', 'zero', 'one']:
> +            for type in ['', 'float']:
> +                for func in ['textureGather', 'textureGatherOffset']:
> +                    testname = '%s/%s-%s-%s-%s' % (
> +                        func, stage, comps,
> +                        swiz if len(swiz) else 'none',
> +                        type if len(type) else 'unorm')
> +                    cmd = 'textureGather %s %s %s %s %s' % (
> +                        stage,
> +                        'offset' if func == 'textureGatherOffset' else '',
> +                        comps, swiz, type
> +                        )
> +                    arb_texture_gather[testname] = concurrent_test(cmd)
> +
>  # Group AMD_shader_stencil_export
>  spec['AMD_shader_stencil_export'] = Group()
>  import_glsl_parser_tests(spec['AMD_shader_stencil_export'],
> diff --git a/tests/texturing/shaders/CMakeLists.gl.txt b/tests/texturing/shaders/CMakeLists.gl.txt
> index 7210c1c..6e4e9a7 100644
> --- a/tests/texturing/shaders/CMakeLists.gl.txt
> +++ b/tests/texturing/shaders/CMakeLists.gl.txt
> @@ -12,3 +12,4 @@ link_libraries (
>
>  piglit_add_executable (textureSize textureSize.c common.c)
>  piglit_add_executable (texelFetch texelFetch.c common.c)
> +piglit_add_executable (textureGather textureGather.c)
> diff --git a/tests/texturing/shaders/textureGather.c b/tests/texturing/shaders/textureGather.c
> new file mode 100644
> index 0000000..9a92fd9
> --- /dev/null
> +++ b/tests/texturing/shaders/textureGather.c
> @@ -0,0 +1,309 @@
> +#include "piglit-util-gl-common.h"
> +
> +PIGLIT_GL_TEST_CONFIG_BEGIN
> +
> +       config.supports_gl_compat_version = 11;
> +       config.supports_gl_core_version = 31;
> +
> +       config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
> +
> +PIGLIT_GL_TEST_CONFIG_END
> +
> +#define TEXTURE_WIDTH 32
> +#define TEXTURE_HEIGHT 32
> +
> +enum { NONE, VS, FS } stage = NONE;
> +bool use_offset = false;
> +int components = 0;
> +int swizzle = -1;
> +bool use_float = false;
> +
> +GLenum internalformat_for_components[] = { GL_R16, GL_RG16, GL_RGB16, GL_RGBA16 };
> +GLenum internalformat_for_components_f[] = { GL_R32F, GL_RG32F, GL_RGB32F, GL_RGBA32F };
> +GLenum format_for_components[] = { GL_RED, GL_RG, GL_RGB, GL_RGBA };
> +GLenum swizzles[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_ZERO, GL_ONE };
> +
> +unsigned char *pixels;
> +float *expected;
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +       int i, j;
> +       bool pass = true;
> +
> +       glViewport(0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT);
> +
> +       if (swizzle >= 0) {
> +               GLint sw[] = { swizzles[swizzle], GL_ZERO, GL_ZERO, GL_ZERO };
> +               glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, sw);
> +       }
> +
> +       if (stage == FS)
> +               glDrawArrays(GL_TRIANGLES, 0, 6);
> +       else
> +               glDrawArrays(GL_POINTS, 0, TEXTURE_WIDTH * TEXTURE_HEIGHT);
> +
> +       for (j = 0; j < TEXTURE_HEIGHT; j++)
> +               for (i = 0; i < TEXTURE_WIDTH; i++) {
> +                       float *pe = &expected[4 * (j * TEXTURE_WIDTH + i)];
> +                       pass = piglit_probe_pixel_rgba(i, j, pe) && pass;
> +               }
> +
> +       piglit_present_results();
> +
> +       return pass ? PIGLIT_PASS : PIGLIT_FAIL;
> +}
> +
> +/* TODO:
> + * Test mipmap selection (always selects base level)
> + * Test invariance under sampler weirdness
> + * Test other sampler types: gsampler2D|gsampler2DArray|gsamplerCube|gsamplerCubeArray
> + * Test GS texturing too -- Paul?
> + */
> +
> +static unsigned char
> +pixel_value(int i, int j)
> +{
> +       if (swizzle == 4)
> +               return 0;
> +       if (swizzle == 5)
> +               return 255;
> +
> +       if (use_offset) {
> +               /* apply texel offset */
> +               i += TEXTURE_WIDTH + -8;
> +               j += TEXTURE_HEIGHT + 7;
> +       }
> +
> +       /* WRAP at border */
> +       i %= TEXTURE_WIDTH;
> +       j %= TEXTURE_HEIGHT;
> +
> +       return i + j * TEXTURE_WIDTH;
> +}
> +
> +static float
> +norm_value(int x)
> +{
> +       return (float)x / 255.0f;
> +}
> +
> +static void
> +make_image(int num_channels, int use_channel)
> +{
> +       unsigned char *pp = pixels;
> +       int i, j, ch;
> +
> +       for (j = 0; j < TEXTURE_HEIGHT; j++)
> +               for (i = 0; i < TEXTURE_WIDTH; i++)
> +                       for (ch = 0; ch < num_channels; ch++)
> +                               *pp++ = (ch == use_channel) ? (i+j*TEXTURE_WIDTH) : 128;
> +}
> +
> +static void
> +make_expected(void)
> +{
> +       float *pe = expected;
> +       int i, j;
> +
> +       for (j = 0; j < TEXTURE_HEIGHT; j++)
> +               for (i = 0; i < TEXTURE_WIDTH; i++) {
> +                       *pe++ = norm_value(pixel_value(i, j + 1));
> +                       *pe++ = norm_value(pixel_value(i + 1, j + 1));
> +                       *pe++ = norm_value(pixel_value(i + 1, j));
> +                       *pe++ = norm_value(pixel_value(i, j));
> +               }
> +}
> +
> +static void
> +upload_verts(void)
> +{
> +       if (stage == VS) {
> +               float v[4 * TEXTURE_WIDTH * TEXTURE_HEIGHT], *pv = v;
> +               int i, j;
> +               for (j = 0; j < TEXTURE_HEIGHT; j++)
> +                       for (i = 0; i < TEXTURE_WIDTH; i++) {
> +                               *pv++ = (i + 0.5f) * 2 / TEXTURE_WIDTH - 1;
> +                               *pv++ = (j + 0.5f) * 2 / TEXTURE_HEIGHT - 1;
> +                               *pv++ = 0;
> +                               *pv++ = 1;
> +                       }
> +               glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
> +       }
> +       else {
> +               static const float verts[] = {
> +                       -1, -1, 0, 1,           -1, 1, 0, 1,    1, 1, 0, 1,
> +                       -1, -1, 0, 1,           1, 1, 0, 1,             1, -1, 0, 1,
> +               };
> +               glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
> +       }
> +}
> +
> +void
> +do_requires(void)
> +{
> +       int max_components;
> +       piglit_require_GLSL_version(130);
> +       piglit_require_extension("GL_ARB_texture_gather");
> +
> +       /* check whether component count will actually work */
> +       glGetIntegerv(GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB, &max_components);
> +       if (components > max_components) {
> +               printf("Test requires gather from texture with %d components;"
> +                      "This implementation only supports %d\n",
> +                          components, max_components);
> +               piglit_report_result(PIGLIT_SKIP);
> +       }
> +
> +       /* if we are trying to swizzle, check that we can! */
> +       if (swizzle != -1)
> +               piglit_require_extension("GL_EXT_texture_swizzle");
> +}
> +
> +void
> +do_setup(void)
> +{
> +       GLuint tex;
> +       GLint vs, fs, prog;
> +       GLint sampler_loc;
> +       GLuint vbo;
> +       char *vs_code, *fs_code;
> +
> +       pixels = malloc(components * sizeof(unsigned char) * TEXTURE_WIDTH * TEXTURE_HEIGHT);
> +       expected = malloc(4 * sizeof(float) * TEXTURE_WIDTH * TEXTURE_HEIGHT);
> +
> +       glGenTextures(1, &tex);
> +       glBindTexture(GL_TEXTURE_2D, tex);
> +
> +       make_image(components, swizzle >= 0 ? swizzle : 0);
> +       make_expected();
> +
> +       glTexImage2D(GL_TEXTURE_2D, 0,
> +                    use_float
> +                                    ? internalformat_for_components_f[components-1]
> +                                        : internalformat_for_components[components-1],
> +                    TEXTURE_WIDTH, TEXTURE_HEIGHT,
> +                    0, format_for_components[components-1],
> +                                GL_UNSIGNED_BYTE, pixels);
> +       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> +       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
> +
> +       if (stage == VS) {
> +               asprintf(&vs_code, "#version 130\n"
> +                               "#extension GL_ARB_explicit_attrib_location: require\n"
> +                               "#extension GL_ARB_texture_gather: require\n"
> +                               "\n"
> +                               "layout(location=0) in vec4 pos;\n"
> +                               "uniform sampler2D s;\n"
> +                               "out vec4 c;\n"
> +                               "\n"
> +                               "void main() {\n"
> +                               "       gl_Position = pos;\n"
> +                               "       c = textureGather%s(s, 0.5 * pos.xy + vec2(0.5) %s);\n"
> +                               "}\n",
> +                               use_offset ? "Offset" : "",
> +                               use_offset ? ", ivec2(-8,7)" : "");
> +               asprintf(&fs_code,
> +                               "#version 130\n"
> +                               "\n"
> +                               "in vec4 c;\n"
> +                               "\n"
> +                               "void main() {\n"
> +                               "       gl_FragColor = c;\n"
> +                               "}\n");
> +       }
> +       else {
> +               asprintf(&vs_code,
> +                               "#version 130\n"
> +                               "#extension GL_ARB_explicit_attrib_location: require\n"
> +                               "layout(location=0) in vec4 pos;\n"
> +                               "\n"
> +                               "void main() {\n"
> +                               "       gl_Position = pos;\n"
> +                               "}\n");
> +               asprintf(&fs_code,
> +                               "#version 130\n"
> +                               "#extension GL_ARB_texture_gather: require\n"
> +                               "\n"
> +                               "uniform sampler2D s;\n"
> +                               "\n"
> +                               "void main() {\n"
> +                               "       gl_FragColor = textureGather%s(s, gl_FragCoord.xy / vec2(32, 32) %s);\n"
> +                               "}\n",
> +                               use_offset ? "Offset" : "",
> +                               use_offset ? ", ivec2(-8,7)" : "");
> +       }
> +
> +       vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_code);
> +       fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_code);
> +
> +       if (!vs || !fs) {
> +               printf("Failed compiling shader.\n");
> +               piglit_report_result(PIGLIT_FAIL);
> +       }
> +
> +       prog = piglit_link_simple_program(vs, fs);
> +
> +       if (!prog) {
> +               printf("Failed linking shader.\n");
> +               piglit_report_result(PIGLIT_FAIL);
> +       }
> +
> +       glUseProgram(prog);
> +    sampler_loc = glGetUniformLocation(prog, "s");
> +       glUniform1i(sampler_loc, 0);
> +
> +       if (!piglit_check_gl_error(GL_NO_ERROR)) {
> +               printf("Error in init\n");
> +               piglit_report_result(PIGLIT_FAIL);
> +       }
> +
> +       if (piglit_get_gl_version() >= 31) {
> +               GLuint vao;
> +               glGenVertexArrays(1, &vao);
> +               glBindVertexArray(vao);
> +       }
> +
> +       glGenBuffers(1, &vbo);
> +       glBindBuffer(GL_ARRAY_BUFFER, vbo);
> +       upload_verts();
> +       glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
> +       glEnableVertexAttribArray(0);
> +}
> +
> +void
> +fail_with_usage(void)
> +{
> +       printf("Usage: textureGather vs|fs [offset] r|rg|rgb|rgba [red|green|blue|alpha|zero|one] [float]\n");
> +       piglit_report_result(PIGLIT_SKIP);
> +}
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +       int i;
> +       for (i = 1; i < argc; i++) {
> +               char *opt = argv[i];
> +               if (!strcmp(opt, "vs")) stage = VS;
> +               else if (!strcmp(opt, "fs")) stage = FS;
> +               else if (!strcmp(opt, "offset")) use_offset = true;
> +               else if (!strcmp(opt, "r")) components = 1;
> +               else if (!strcmp(opt, "rg")) components = 2;
> +               else if (!strcmp(opt, "rgb")) components = 3;
> +               else if (!strcmp(opt, "rgba")) components = 4;
> +               else if (!strcmp(opt, "red")) swizzle = 0;
> +               else if (!strcmp(opt, "green")) swizzle = 1;
> +               else if (!strcmp(opt, "blue")) swizzle = 2;
> +               else if (!strcmp(opt, "alpha")) swizzle = 3;
> +               else if (!strcmp(opt, "zero")) swizzle = 4;
> +               else if (!strcmp(opt, "one")) swizzle = 5;
> +               else if (!strcmp(opt, "float")) use_float = true;
> +       }
> +
> +       if (stage == NONE) fail_with_usage();
> +       if (components == 0) fail_with_usage();
> +
> +       do_requires();
> +       do_setup();
> +}
> --
> 1.8.3.4
>


More information about the Piglit mailing list