Allows verification of texelFetch with all six flavors of MS sampler.

- Put lod/sample_index in the fourth channel of the texture, so we
    can verify that the correct lod/sample was sampled.
- For multisample targets, render the test pattern rather than uploading
  it. GL won't let us do a direct upload into these texture targets, and
  the alternative (upload to a staging texture; copy to target) is
  even messier.
- Accept sample count as an extra parameter after sampler
- Add existing swizzle option to usage string
- Use smaller formats for multisample tests, to avoid running into some
  hardware limits.

This replaces the earlier arb_texture_multisample-texel-fetch-execution
and arb_texture_multisample-texel-fetch-execution-array tests, and is
much more thorough (it showed Gen7 was still messed up :( !)

V3: - Increase window height so we can test 8x.
    - Don't break the format-based extension checks.

Signed-off-by: Chris Forbes <chr...@ijw.co.nz>
---
 tests/all.tests                      |   6 +
 tests/texturing/shaders/common.c     |  34 ++++--
 tests/texturing/shaders/common.h     |   2 +
 tests/texturing/shaders/texelFetch.c | 226 +++++++++++++++++++++++++++++++----
 4 files changed, 238 insertions(+), 30 deletions(-)

diff --git a/tests/all.tests b/tests/all.tests
index 5ab0a2d..a041515 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -867,6 +867,12 @@ for sample_count in MSAA_SAMPLE_COUNTS:
     # fb-completeness
     spec['ARB_texture_multisample/fb-completeness/%d' % (sample_count,)] = \
         concurrent_test('arb_texture_multisample-fb-completeness %d' % 
(sample_count,))
+    # texel-fetch execution
+    for stage in ['vs','fs']:
+        for sampler in samplers_atm:
+                spec['ARB_texture_multisample/texelFetch/%d-%s-%s' % (
+                    sample_count, stage, sampler)] = \
+                    concurrent_test('texelFetch %s %s %d' % (stage, sampler, 
sample_count))
 add_concurrent_test(arb_texture_multisample, 
'arb_texture_multisample-texstate')
 add_concurrent_test(arb_texture_multisample, 
'arb_texture_multisample-sample-mask')
 add_concurrent_test(arb_texture_multisample, 
'arb_texture_multisample-sample-mask-value')
diff --git a/tests/texturing/shaders/common.c b/tests/texturing/shaders/common.c
index 120e424..0b13d47 100644
--- a/tests/texturing/shaders/common.c
+++ b/tests/texturing/shaders/common.c
@@ -151,10 +151,11 @@ compute_miplevel_info()
        miplevels = (int) log2f(max_dimension) + 1;
 
        if (sampler.target == GL_TEXTURE_RECTANGLE ||
-           sampler.target == GL_TEXTURE_BUFFER ||
-               sampler.target == GL_TEXTURE_2D_MULTISAMPLE ||
-               sampler.target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
+           sampler.target == GL_TEXTURE_BUFFER)
                miplevels = 1;
+       if (sampler.target == GL_TEXTURE_2D_MULTISAMPLE ||
+               sampler.target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
+               miplevels = sample_count;
 
        /* Compute the size of each miplevel */
        level_size = malloc(miplevels * sizeof(int *));
@@ -165,7 +166,11 @@ compute_miplevel_info()
                level_size[l] = malloc(3 * sizeof(int));
 
                for (i = 0; i < 3 - is_array; i++)
-                       level_size[l][i] = max2(level_size[l-1][i] / 2, 1);
+                       if (has_samples())
+                               /* same size for all sample planes */
+                               level_size[l][i] = level_size[l-1][i];
+                       else
+                               level_size[l][i] = max2(level_size[l-1][i] / 2, 
1);
 
                if (is_array)
                        level_size[l][2] = base_size[2];
@@ -190,6 +195,13 @@ has_slices()
 }
 
 bool
+has_samples()
+{
+    return sampler.target == GL_TEXTURE_2D_MULTISAMPLE ||
+           sampler.target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
+}
+
+bool
 is_array_sampler()
 {
        return sampler.target == GL_TEXTURE_1D_ARRAY ||
@@ -279,15 +291,20 @@ select_sampler(const char *name)
        sampler.type = samplers[i].type;
        sampler.target = samplers[i].target;
 
+       /* Use 32bpc sized formats where possible; drop down to 16bpc for
+        * testing multisample targets to avoid hitting some hardware limits.
+        * on i965.
+        */
+
        if (name[0] == 'i') {
                sampler.data_type = GL_INT;
                sampler.format = GL_RGBA_INTEGER;
-               sampler.internal_format = GL_RGBA32I;
+               sampler.internal_format = has_samples() ? GL_RGBA16I : 
GL_RGBA32I;
                sampler.return_type = "ivec4";
        } else if (name[0] == 'u') {
                sampler.data_type = GL_UNSIGNED_INT;
                sampler.format = GL_RGBA_INTEGER;
-               sampler.internal_format = GL_RGBA32UI;
+               sampler.internal_format = has_samples() ? GL_RGBA16UI : 
GL_RGBA32UI;
                sampler.return_type = "uvec4";
        } else if (strstr(name, "Shadow")) {
                /* Shadow Sampler */
@@ -298,7 +315,7 @@ select_sampler(const char *name)
        } else {
                sampler.data_type = GL_FLOAT;
                sampler.format = GL_RGBA;
-               sampler.internal_format = GL_RGBA32F;
+               sampler.internal_format = has_samples() ? GL_RGBA16F : 
GL_RGBA32F;
                sampler.return_type = "vec4";
        }
 
@@ -321,12 +338,15 @@ require_GL_features(enum shader_target test_stage)
 
        switch (sampler.internal_format) {
        case GL_RGBA32I:
+       case GL_RGBA16I:
                piglit_require_extension("GL_EXT_texture_integer");
                break;
        case GL_RGBA32UI:
+       case GL_RGBA16UI:
                piglit_require_gl_version(30);
                break;
        case GL_RGBA32F:
+       case GL_RGBA16F:
                piglit_require_extension("GL_ARB_texture_float");
                break;
        }
diff --git a/tests/texturing/shaders/common.h b/tests/texturing/shaders/common.h
index a4e8cd7..878faec 100644
--- a/tests/texturing/shaders/common.h
+++ b/tests/texturing/shaders/common.h
@@ -81,6 +81,7 @@ struct sampler_info
 
 /** Whether or not we're using GL_EXT_texture_swizzle */
 bool swizzling;
+int sample_count;
 extern int shader_version;
 
 /**
@@ -97,6 +98,7 @@ float max2(float x, float y);
 
 bool has_height();
 bool has_slices();
+bool has_samples();
 
 bool is_array_sampler();
 bool is_shadow_sampler();
diff --git a/tests/texturing/shaders/texelFetch.c 
b/tests/texturing/shaders/texelFetch.c
index 50e91a6..ebfdfe0 100644
--- a/tests/texturing/shaders/texelFetch.c
+++ b/tests/texturing/shaders/texelFetch.c
@@ -84,11 +84,13 @@ PIGLIT_GL_TEST_CONFIG_BEGIN
        config.supports_gl_core_version = 31;
 
        config.window_width = 355;
-       config.window_height = 250;
+       config.window_height = 350;
        config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
 
 PIGLIT_GL_TEST_CONFIG_END
 
+#define MAX_LOD_OR_SAMPLES  8.0
+
 /** Vertex shader attribute locations */
 const int pos_loc = 0;
 const int texcoord_loc = 1;
@@ -121,7 +123,7 @@ compute_divisors(int lod, float *divisors)
        divisors[0] = max2(level_size[lod][0] - 1, 1);
        divisors[1] = max2(level_size[lod][1] - 1, 1);
        divisors[2] = max2(level_size[lod][2] - 1, 1);
-       divisors[3] = 1.0;
+       divisors[3] = MAX_LOD_OR_SAMPLES;
 
        if (sampler.data_type != GL_UNSIGNED_INT)
                divisors[0] = -divisors[0];
@@ -133,6 +135,8 @@ piglit_display()
        int i, l, z;
        bool pass = true;
 
+   glViewport(0, 0, piglit_width, piglit_height);
+
        glClearColor(0.1, 0.1, 0.1, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
 
@@ -261,6 +265,150 @@ generate_VBOs()
        glEnableVertexAttribArray(texcoord_loc);
 }
 
+/* like piglit_draw_rect(), but works in a core context too.
+ * pretty silly and wasteful (binds a throwaway VAO and BO) */
+static void
+draw_rect_core(int x, int y, int w, int h)
+{
+    float verts[4][4];
+    GLuint bo, vao;
+
+    verts[0][0] = x;
+    verts[0][1] = y;
+    verts[0][2] = 0.0;
+    verts[0][3] = 1.0;
+    verts[1][0] = x + w;
+    verts[1][1] = y;
+    verts[1][2] = 0.0;
+    verts[1][3] = 1.0;
+    verts[2][0] = x + w;
+    verts[2][1] = y + h;
+    verts[2][2] = 0.0;
+    verts[2][3] = 1.0;
+    verts[3][0] = x;
+    verts[3][1] = y + h;
+    verts[3][2] = 0.0;
+    verts[3][3] = 1.0;
+
+    glGenVertexArrays(1, &vao);
+    glBindVertexArray(vao);
+
+    glGenBuffers(1, &bo);
+    glBindBuffer(GL_ARRAY_BUFFER, bo);
+    glBufferData(GL_ARRAY_BUFFER, 4 * 4 * sizeof(float),
+            verts, GL_STATIC_DRAW);
+    glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
+    glEnableVertexAttribArray(0);
+
+    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+    glBindVertexArray(0);
+    glDeleteBuffers(1, &bo);
+    glDeleteVertexArrays(1, &vao);
+}
+
+/**
+ * Generate the same test pattern as generate_texture() does, but do it in the 
shader.
+ * This is a silly workaround for not being able to just upload directly.
+ */
+static void
+upload_multisample_data(GLuint tex, int width, int height,
+        int layers, int samples)
+{
+    GLuint oldFBO, FBO;
+    int si;
+    char *fs_code;
+    int vs, fs;
+    int staging_program = 0;
+    int layer_loc = 0;
+    int si_loc = 0;
+
+    glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint *) &oldFBO);
+    if (is_array_sampler())
+        glTexImage3DMultisample(sampler.target,
+                samples, sampler.internal_format,
+                width, height, layers, GL_TRUE);
+    else
+        glTexImage2DMultisample(sampler.target,
+                samples, sampler.internal_format,
+                width, height, GL_TRUE);
+    if (!piglit_check_gl_error(GL_NO_ERROR)) {
+        printf("Error creating multisample texture\n");
+        piglit_report_result(PIGLIT_FAIL);
+    }
+
+    vs = piglit_compile_shader_text(GL_VERTEX_SHADER,
+            "#version 130\n"
+            "#extension GL_ARB_explicit_attrib_location: require\n"
+            "layout(location=0) in vec4 pos;\n"
+            "void main() {\n"
+            "   gl_Position = pos;\n"
+            "}\n");
+    asprintf(&fs_code,
+            "#version 130\n"
+            "#extension GL_ARB_explicit_attrib_location: require\n"
+            "#extension GL_ARB_fragment_coord_conventions: require\n"
+            "uniform int layer;\n"
+            "uniform int si;\n"
+            "layout(pixel_center_integer) in vec4 gl_FragCoord;\n"
+            "layout(location=0) out %s o;\n"
+            "void main() {\n"
+            "  o = %s(%sgl_FragCoord.x, gl_FragCoord.y, layer, si);\n"
+            "}\n",
+            sampler.return_type,
+            sampler.return_type,
+            sampler.data_type == GL_UNSIGNED_INT ? "" : "-");
+    fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_code);
+    if (!fs) {
+        printf("Failed to compile staging program.\n");
+        piglit_report_result(PIGLIT_FAIL);
+    }
+    staging_program = piglit_link_simple_program(vs,fs);
+    if (!piglit_link_check_status(staging_program))
+        piglit_report_result(PIGLIT_FAIL);
+
+    layer_loc = glGetUniformLocation(staging_program, "layer");
+    si_loc = glGetUniformLocation(staging_program, "si");
+
+    glUseProgram(staging_program);
+    if (!piglit_check_gl_error(GL_NO_ERROR)) {
+        printf("glUseProgram failed\n");
+        piglit_report_result(PIGLIT_FAIL);
+    }
+
+    glGenFramebuffers(1, &FBO);
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO);
+    glViewport(0, 0, width, height);
+
+    glEnable(GL_SAMPLE_MASK);
+
+    for (si=0; si < samples; si++) {
+        glUniform1i(si_loc, si);
+        glSampleMaski(0, 1<<si);
+
+        if (is_array_sampler()) {
+            int layer;
+            for(layer = 0; layer < layers; layer++) {
+                glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, 
GL_COLOR_ATTACHMENT0,
+                    tex, 0, layer);
+                glUniform1i(layer_loc, layer);
+                draw_rect_core(-1, -1, 2, 2);
+            }
+        }
+        else {
+            glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                   sampler.target, tex, 0);
+
+            glUniform1i(layer_loc, 0);
+            draw_rect_core(-1, -1, 2, 2);
+        }
+    }
+
+    glDisable(GL_SAMPLE_MASK);
+
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oldFBO);
+}
+
 /**
  * Create texel data.
  */
@@ -281,18 +429,21 @@ generate_texture()
 
        glGenTextures(1, &tex);
        glBindTexture(target, tex);
-       if (sampler.target == GL_TEXTURE_RECTANGLE) {
-               glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-               glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-       } else {
-               glTexParameteri(target, GL_TEXTURE_MIN_FILTER, 
GL_NEAREST_MIPMAP_NEAREST);
-               glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+       if (!has_samples()) {
+               if (sampler.target == GL_TEXTURE_RECTANGLE) {
+                       glTexParameteri(target, GL_TEXTURE_MIN_FILTER, 
GL_NEAREST);
+                       glTexParameteri(target, GL_TEXTURE_MAG_FILTER, 
GL_NEAREST);
+               } else {
+                       glTexParameteri(target, GL_TEXTURE_MIN_FILTER, 
GL_NEAREST_MIPMAP_NEAREST);
+                       glTexParameteri(target, GL_TEXTURE_MAG_FILTER, 
GL_NEAREST);
+               }
+               glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+               glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+               if (swizzling)
+                       glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA,
+                                        (GLint *) sampler.swizzle);
        }
-       glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-       glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-       if (swizzling)
-               glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA,
-                                (GLint *) sampler.swizzle);
 
        expected_colors = calloc(miplevels, sizeof(float **));
 
@@ -321,24 +472,24 @@ generate_texture()
                                        f_ptr[0] = nx;
                                        f_ptr[1] = y;
                                        f_ptr[2] = z;
-                                       f_ptr[3] = 1.0;
+                                       f_ptr[3] = l;
 
                                        i_ptr[0] = nx;
                                        i_ptr[1] = y;
                                        i_ptr[2] = z;
-                                       i_ptr[3] = 1;
+                                       i_ptr[3] = l;
 
                                        u_ptr[0] = nx;
                                        u_ptr[1] = y;
                                        u_ptr[2] = z;
-                                       u_ptr[3] = 1;
+                                       u_ptr[3] = l;
 
                                        compute_divisors(l, divisors);
 
                                        expected_ptr[0] = f_ptr[0]/divisors[0];
                                        expected_ptr[1] = f_ptr[1]/divisors[1];
                                        expected_ptr[2] = f_ptr[2]/divisors[2];
-                                       expected_ptr[3] = 1.0;
+                                       expected_ptr[3] = f_ptr[3]/divisors[3];
                                        swizzle(expected_ptr);
 
                                        f_ptr += 4;
@@ -365,8 +516,14 @@ generate_texture()
                        break;
                }
 
-               upload_miplevel_data(target, l, level_image);
+               if (!has_samples())
+                       upload_miplevel_data(target, l, level_image);
        }
+
+       if (has_samples())
+               upload_multisample_data(tex, level_size[0][0],
+                               level_size[0][1], level_size[0][2],
+                               sample_count);
 }
 
 /**
@@ -381,9 +538,11 @@ coordinate_size()
        case GL_TEXTURE_2D:
        case GL_TEXTURE_1D_ARRAY:
        case GL_TEXTURE_RECTANGLE:
+       case GL_TEXTURE_2D_MULTISAMPLE:
                return 2;
        case GL_TEXTURE_3D:
        case GL_TEXTURE_2D_ARRAY:
+       case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
                return 3;
        default:
                assert(!"Should not get here.");
@@ -432,6 +591,7 @@ generate_GLSL(enum shader_target test_stage)
        case VS:
                asprintf(&vs_code,
                         "#version %d\n"
+                        "%s\n"
                         "#define ivec1 int\n"
                         "flat out %s color;\n"
                         "in vec4 pos;\n"
@@ -443,6 +603,7 @@ generate_GLSL(enum shader_target test_stage)
                         "    gl_Position = pos;\n"
                         "}\n",
                         shader_version,
+                        has_samples() ? "#extension 
GL_ARB_texture_multisample: require" : "",
                         sampler.return_type, sampler.name,
                         offset_func,
                         coordinate_size(),
@@ -475,6 +636,7 @@ generate_GLSL(enum shader_target test_stage)
                         shader_version);
                asprintf(&fs_code,
                         "#version %d\n"
+                        "%s\n"
                         "#define ivec1 int\n"
                         "flat in ivec4 tc;\n"
                         "uniform vec4 divisor;\n"
@@ -485,6 +647,7 @@ generate_GLSL(enum shader_target test_stage)
                         "    gl_FragColor = color/divisor;\n"
                         "}\n",
                         shader_version,
+                        has_samples() ? "#extension 
GL_ARB_texture_multisample: require" : "",
                         sampler.name,
                         offset_func,
                         coordinate_size(),
@@ -545,6 +708,8 @@ supported_sampler()
        case GL_TEXTURE_1D_ARRAY:
        case GL_TEXTURE_2D_ARRAY:
        case GL_TEXTURE_RECTANGLE:
+       case GL_TEXTURE_2D_MULTISAMPLE:
+       case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
                return true;
        }
        return false;
@@ -554,7 +719,7 @@ void
 fail_and_show_usage()
 {
        printf("Usage: texelFetch [140] [offset] <vs|fs> <sampler type> "
-              "[piglit args...]\n");
+              "[sample_count] [swizzle] [piglit args...]\n");
        piglit_report_result(PIGLIT_FAIL);
 }
 
@@ -593,6 +758,21 @@ piglit_init(int argc, char **argv)
                if (!sampler_found && (sampler_found = select_sampler(argv[i])))
                        continue;
 
+        /* Maybe it's the sample count? */
+        if (sampler_found && has_samples() && !sample_count) {
+            if ((sample_count = atoi(argv[i]))) {
+                /* check it */
+                GLint max_samples;
+                glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
+                if (sample_count > max_samples) {
+                    printf("Sample count of %d not supported, >MAX_SAMPLES\n",
+                            sample_count);
+                    piglit_report_result(PIGLIT_SKIP);
+                }
+            }
+            continue;
+        }
+
                if (!swizzling && (swizzling = parse_swizzle(argv[i])))
                        continue;
 
@@ -614,14 +794,14 @@ piglit_init(int argc, char **argv)
        tex_location = glGetUniformLocation(prog, "tex");
        divisor_loc = glGetUniformLocation(prog, "divisor");
 
-       glUseProgram(prog);
-
-       glUniform1i(tex_location, 0);
-
        /* Create textures and set miplevel info */
        set_base_size();
        compute_miplevel_info();
        generate_texture();
 
        generate_VBOs();
+
+       glUseProgram(prog);
+
+       glUniform1i(tex_location, 0);
 }
-- 
1.8.1.4

_______________________________________________
Piglit mailing list
Piglit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/piglit

Reply via email to