[Piglit] [PATCH] ARB_texture_gather: add initial execution test
Ian Romanick
idr at freedesktop.org
Tue Aug 13 13:09:31 PDT 2013
On 08/10/2013 03:10 AM, Chris Forbes 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']:
Since ARB_texture_gather will land in Mesa around the same time geometry
shaders land, should this also test gs? I see you also have that
question in the test code...
> + 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
These two would probably be separate tests.
> + * Test other sampler types: gsampler2D|gsampler2DArray|gsamplerCube|gsamplerCubeArray
yeah. :(
> + * 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"
Use textureSize() instead of hardcoded vec(32,32).
> + "}\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);
> + }
piglit_build_simple_program
> +
> + 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();
> +}
>
More information about the Piglit
mailing list