[Piglit] [PATCH V2 3/8] arb_texture_multisample: new test for fb configs

Chris Forbes chrisf at ijw.co.nz
Sun Feb 24 11:37:41 PST 2013


This tests FBO setup with various combinations of multisample textures
and `classic` multisample renderbuffers, and for each, checks:

- That the renderbuffers or textures can be created
- Completeness status

If the configuration is expected to work, additionally:
- Actual sample count >= requested sample count
- Sample positions meet spec requirements (all obtainable, and in [0,1]

Covers the fixedsamplelocations and sample count consistency
requirements in the spec.

V2: - Don't specify window size, we don't care.
    - Add comment about internalformat defaulting.
    - Don't specify dims, sample count per attachment; attachment
      is either multisampled or not, dims are always the same.
    - Report each config result using subtests
    - Support testing different sample counts, and test 2/4/6/8/16
        samples in all.tests. Unsupported sample counts are skipped.
    - Fixup for signature change of piglit_report_subtest_result.
    - Test some multisample array scenarios too.
    - Lookup enum names for some of the output, to make it easier to
        read.
    - Remove the bogus stencil texture case, it's not valid.
    - Skip subtests which can't work with the sample limits exposed
        by the driver, rather than just failing.

Signed-off-by: Chris Forbes <chrisf at ijw.co.nz>
---
 tests/all.tests                                    |   4 +
 .../spec/arb_texture_multisample/CMakeLists.gl.txt |   1 +
 .../spec/arb_texture_multisample/fb-completeness.c | 304 +++++++++++++++++++++
 3 files changed, 309 insertions(+)
 create mode 100644 tests/spec/arb_texture_multisample/fb-completeness.c

diff --git a/tests/all.tests b/tests/all.tests
index 84e2696..184b172 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -861,6 +861,10 @@ add_plain_test(arb_point_sprite, 'point-sprite')
 arb_texture_multisample = Group()
 spec['ARB_texture_multisample'] = arb_texture_multisample
 add_concurrent_test(arb_texture_multisample, 'arb_texture_multisample-minmax')
+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,))
 
 # Group AMD_shader_stencil_export
 spec['AMD_shader_stencil_export'] = Group()
diff --git a/tests/spec/arb_texture_multisample/CMakeLists.gl.txt b/tests/spec/arb_texture_multisample/CMakeLists.gl.txt
index 90dae9e..d793256 100644
--- a/tests/spec/arb_texture_multisample/CMakeLists.gl.txt
+++ b/tests/spec/arb_texture_multisample/CMakeLists.gl.txt
@@ -11,5 +11,6 @@ link_libraries (
 )
 
 piglit_add_executable (arb_texture_multisample-minmax minmax.c)
+piglit_add_executable (arb_texture_multisample-fb-completeness fb-completeness.c)
 
 # vim: ft=cmake:
diff --git a/tests/spec/arb_texture_multisample/fb-completeness.c b/tests/spec/arb_texture_multisample/fb-completeness.c
new file mode 100644
index 0000000..0267c21
--- /dev/null
+++ b/tests/spec/arb_texture_multisample/fb-completeness.c
@@ -0,0 +1,304 @@
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+    config.supports_gl_compat_version = 30;
+    config.window_visual = PIGLIT_GL_VISUAL_RGB;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+enum piglit_result
+piglit_display(void)
+{
+    return PIGLIT_FAIL;
+}
+
+#define SURFACE_WIDTH 64
+#define SURFACE_HEIGHT 64
+#define SURFACE_DEPTH 2     // for GL_TEXTURE_2D_MULTISAMPLE_ARRAY
+
+struct attachment_info
+{
+    GLenum target;
+    GLenum attachment;
+    bool multisample;
+    bool fixedsamplelocations;
+    GLuint format;      // override internalformat; if zero, will choose something
+                        // reasonable based on the attachment
+    int layer;          // for GL_TEXTURE_2D_MULTISAMPLE_ARRAY, the layer to attach
+};
+
+struct test_info
+{
+    char const *name;
+    int expected;
+    struct attachment_info attachments[4];
+};
+
+struct test_info tests[] = {
+    {   "single_msaa_color", GL_FRAMEBUFFER_COMPLETE,
+        {   { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE },
+            { 0 },
+        }
+    },
+    {   "msaa_mrt_color", GL_FRAMEBUFFER_COMPLETE,
+        {   { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE },
+            { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT1, GL_TRUE, GL_TRUE },
+            { 0 },
+        }
+    },
+    {   "msaa_mixed_texture_and_renderbuffer", GL_FRAMEBUFFER_COMPLETE,
+        {   { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE },
+            { GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE },
+            { 0 },
+        }
+    },
+    {   "mixed_msaa_and_plain", GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
+        {   { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE },
+            { GL_RENDERBUFFER, GL_COLOR_ATTACHMENT1, GL_FALSE, GL_TRUE },
+            { 0 },
+        }
+    },
+    {   "msaa_mrt_color_nofixed", GL_FRAMEBUFFER_COMPLETE,
+        {   { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_FALSE },
+            { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT1, GL_TRUE, GL_FALSE },
+            { 0 },
+        }
+    },
+    {   "mix_fixedmode", GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
+        {   { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE },
+            { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT1, GL_TRUE, GL_FALSE },
+            { 0 },
+        }
+    },
+    {   "mix_fixedmode_with_renderbuffer", GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
+        {   { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_FALSE },
+            { GL_RENDERBUFFER, GL_COLOR_ATTACHMENT1, GL_TRUE, GL_TRUE },
+            { 0 },
+        }
+    },
+    {   "msaa_depth", GL_FRAMEBUFFER_COMPLETE,
+        {   { GL_TEXTURE_2D_MULTISAMPLE, GL_DEPTH_ATTACHMENT, GL_TRUE, GL_TRUE },
+            { 0 },
+        }
+    },
+    {   "msaa_depth_stencil", GL_FRAMEBUFFER_COMPLETE,
+        {   {   GL_TEXTURE_2D_MULTISAMPLE, GL_DEPTH_ATTACHMENT, GL_TRUE, GL_TRUE,
+                GL_DEPTH_STENCIL
+            },
+            { 0 },
+        }
+    },
+    {   "msaa_classic_stencil", GL_FRAMEBUFFER_COMPLETE,
+        {   { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE },
+            { GL_RENDERBUFFER, GL_STENCIL_ATTACHMENT, GL_TRUE, GL_TRUE },
+            { 0 },
+        }
+    },
+    {   "msaa_color_layer", GL_FRAMEBUFFER_COMPLETE,
+        {   { GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE,
+                .layer=0 },
+            { 0 },
+        }
+    },
+    {   "msaa_color_nonzero_layer", GL_FRAMEBUFFER_COMPLETE,
+        {   { GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE,
+                .layer=1 },
+            { 0 },
+        }
+    },
+    { 0 },
+};
+
+static GLuint
+choose_format(struct attachment_info *att)
+{
+    if (att->format)
+        return att->format;
+
+    switch(att->attachment) {
+    case GL_DEPTH_ATTACHMENT:
+        return GL_DEPTH_COMPONENT;
+    case GL_STENCIL_ATTACHMENT:
+        return GL_STENCIL_INDEX;
+    default:
+        return GL_RGBA;
+    }
+}
+
+static enum piglit_result
+check_sample_positions(int expected_sample_count)
+{
+    GLint samples;
+    int i;
+
+    glGetIntegerv(GL_SAMPLES, &samples);
+    if (!piglit_check_gl_error(GL_NO_ERROR))
+        return PIGLIT_FAIL;
+
+    if (samples < expected_sample_count) {
+        printf("Expected sample count at least %d, got %d\n",
+               expected_sample_count, samples);
+        return PIGLIT_FAIL;
+    }
+
+    for (i = 0; i < samples; i++) {
+        float sample_pos[2];
+
+        glGetMultisamplefv(GL_SAMPLE_POSITION, i, sample_pos);
+
+        if (!piglit_check_gl_error(GL_NO_ERROR))
+            return PIGLIT_FAIL;
+
+        printf("Sample %d position %2.2f %2.2f\n",
+                i, sample_pos[0], sample_pos[1] );
+
+        if (sample_pos[0] < 0 || sample_pos[0] > 1 ||
+                sample_pos[1] < 0 || sample_pos[1] > 1) {
+            printf("Sample %d out of range\n", i );
+            return PIGLIT_FAIL;
+        }
+    }
+
+    return PIGLIT_PASS;
+}
+
+static enum piglit_result
+exec_test(struct test_info *info, int sample_count)
+{
+    GLuint fb, tex, rb;
+    GLint result;
+    struct attachment_info *att;
+    GLint maxColorSamples, maxDepthSamples;
+
+    glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorSamples);
+    glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthSamples);
+
+    glGenFramebuffers(1, &fb);
+    glBindFramebuffer(GL_FRAMEBUFFER, fb);
+
+    printf("Testing fbo completeness for config '%s'\n", info->name);
+
+    for (att=info->attachments; att->target; att++) {
+        int attachment_sample_count = att->multisample ? sample_count : 0;
+        printf("  Att target=%s att=%s samples=%d dims=%d,%d,%d fixed=%d\n",
+               piglit_get_gl_enum_name(att->target),
+               piglit_get_gl_enum_name(att->attachment),
+               attachment_sample_count,
+               SURFACE_WIDTH, SURFACE_HEIGHT,
+               att->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ? SURFACE_DEPTH : 1,
+               att->fixedsamplelocations);
+
+        switch (att->target) {
+        case GL_TEXTURE_2D_MULTISAMPLE:
+        case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+            if (att->attachment == GL_DEPTH_ATTACHMENT && sample_count > maxDepthSamples)
+                return PIGLIT_SKIP;
+            if ((att->attachment == GL_COLOR_ATTACHMENT0 ||
+                att->attachment == GL_COLOR_ATTACHMENT1) && sample_count > maxColorSamples)
+                return PIGLIT_SKIP;
+        }
+
+        switch (att->target) {
+        case GL_TEXTURE_2D_MULTISAMPLE:
+            glGenTextures(1, &tex);
+            glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
+            glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,
+                                    attachment_sample_count, choose_format(att),
+                                    SURFACE_WIDTH, SURFACE_HEIGHT,
+                                    att->fixedsamplelocations);
+
+            if (!piglit_check_gl_error(GL_NO_ERROR))
+                return PIGLIT_FAIL;
+
+            glFramebufferTexture2D(GL_FRAMEBUFFER, att->attachment,
+                                   att->target, tex, 0);
+            break;
+
+        case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+            glGenTextures(1, &tex);
+            glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, tex);
+            glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
+                    attachment_sample_count, choose_format(att),
+                    SURFACE_WIDTH, SURFACE_HEIGHT, SURFACE_DEPTH,
+                    att->fixedsamplelocations);
+
+            if (!piglit_check_gl_error(GL_NO_ERROR))
+                return PIGLIT_FAIL;
+
+            glFramebufferTextureLayer(GL_FRAMEBUFFER, att->attachment,
+                    tex, 0, att->layer);
+            break;
+
+        case GL_RENDERBUFFER:
+            /* RENDERBUFFER has fixedsamplelocations implicitly */
+            assert(att->fixedsamplelocations);
+            glGenRenderbuffers(1, &rb);
+            glBindRenderbuffer(GL_RENDERBUFFER, rb);
+            if (att->multisample) {
+                glRenderbufferStorageMultisample(GL_RENDERBUFFER,
+                                                 attachment_sample_count, choose_format(att),
+                                                 SURFACE_WIDTH, SURFACE_HEIGHT);
+            }
+            else {
+                /* non-MSAA renderbuffer */
+                glRenderbufferStorage(GL_RENDERBUFFER, choose_format(att),
+                                      SURFACE_WIDTH, SURFACE_HEIGHT);
+            }
+
+            glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+                                      att->attachment, att->target, rb);
+
+            if (!piglit_check_gl_error(GL_NO_ERROR))
+                return PIGLIT_FAIL;
+            break;
+
+        default:
+            assert(!"Unsupported target");
+        }
+    }
+
+    result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+    if (result != info->expected) {
+        printf("glCheckFramebufferStatus: expected %s, got %s\n",
+               piglit_get_gl_enum_name(info->expected),
+               piglit_get_gl_enum_name(result));
+        return PIGLIT_FAIL;
+    }
+
+    if (result == GL_FRAMEBUFFER_COMPLETE && info->attachments->multisample)
+        return check_sample_positions(sample_count);
+
+    return PIGLIT_PASS;
+}
+
+void
+usage(int argc, char **argv)
+{
+    printf("usage: %s <sample-count>\n", argv[0]);
+    piglit_report_result(PIGLIT_SKIP);
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+    struct test_info *info;
+    enum piglit_result result = PIGLIT_PASS;
+    int sample_count;
+    int max_samples;
+
+    if (argc != 2)
+        usage(argc, argv);
+
+    sample_count = atoi(argv[1]);
+    glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
+    if (sample_count > max_samples) {
+        printf("Sample count of %d not supported.\n", sample_count);
+        piglit_report_result(PIGLIT_SKIP);
+    }
+
+    for (info = tests; info->name; info++)
+        piglit_report_subtest_result(exec_test(info, sample_count), info->name);
+
+    piglit_report_result(result);
+}
-- 
1.8.1.4



More information about the Piglit mailing list