[Piglit] [PATCH v2] arb_internalformat_query2: test for the most generic pname checks

Alejandro Piñeiro apinheiro at igalia.com
Tue Feb 2 09:57:26 PST 2016


The spec includes conditions for all the pnames. On most cases, it is
generic like this:

 "Possible values returned are <set>. If the resource is not
  supported, or if the operation is not supported, NONE is
  returned."

So this test checks that for those pnames:
 * If it is not supported (using INTERNALFORMAT_SUPPORTED), the
   returned value is zero.
 * If it is supported, and there is available a list of possible
   values, the returned value is among one of those values.

Tested on NVIDIA GeForce GTX 950 - NVIDIA 352.55: pass.

v2: IMAGE_TEXEL_SIZE, IMAGE_COMPATIBILITY_CLASS, IMAGE_PIXEL_TYPE,
    IMAGE_PIXEL_FORMAT tested on a specific test (Antía)
---
 tests/all.py                                       |   1 +
 .../arb_internalformat_query2/CMakeLists.gl.txt    |   1 +
 tests/spec/arb_internalformat_query2/common.c      | 599 +++++++++++++++++++++
 tests/spec/arb_internalformat_query2/common.h      |  52 +-
 .../generic-pname-checks.c                         | 160 ++++++
 5 files changed, 812 insertions(+), 1 deletion(-)
 create mode 100644 tests/spec/arb_internalformat_query2/common.c
 create mode 100644 tests/spec/arb_internalformat_query2/generic-pname-checks.c

diff --git a/tests/all.py b/tests/all.py
index 6ea3293..8a9b4ef 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -3642,6 +3642,7 @@ with profile.group_manager(
         PiglitGLTest,
         grouptools.join('spec', 'arb_internalformat_query2')) as g:
     g(['arb_internalformat_query2-api-errors'], 'API error checks')
+    g(['arb_internalformat_query2-generic-pname-checks'], 'Individual most generic pname checks')
 
 with profile.group_manager(
         PiglitGLTest, grouptools.join('spec', 'arb_map_buffer_range')) as g:
diff --git a/tests/spec/arb_internalformat_query2/CMakeLists.gl.txt b/tests/spec/arb_internalformat_query2/CMakeLists.gl.txt
index 7a0e857..cd3b07e 100644
--- a/tests/spec/arb_internalformat_query2/CMakeLists.gl.txt
+++ b/tests/spec/arb_internalformat_query2/CMakeLists.gl.txt
@@ -9,5 +9,6 @@ link_libraries (
 )
 
 piglit_add_executable (arb_internalformat_query2-api-errors api-errors.c)
+piglit_add_executable (arb_internalformat_query2-generic-pname-checks generic-pname-checks.c common.c)
 
 # vim: ft=cmake:
diff --git a/tests/spec/arb_internalformat_query2/common.c b/tests/spec/arb_internalformat_query2/common.c
new file mode 100644
index 0000000..83dbd3d
--- /dev/null
+++ b/tests/spec/arb_internalformat_query2/common.c
@@ -0,0 +1,599 @@
+/*
+ * Copyright © 2015 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.
+ */
+
+#include "common.h"
+#include <inttypes.h>  /* for PRIu64 macro */
+
+/* Generic callback type, doing a cast of params to void*, to avoid
+ * having two paths (32 and 64) for each check */
+typedef void (*GetInternalformat)(GLenum target, GLenum internalformat,
+                                  GLenum pname, GLsizei bufsize,
+                                  void *params);
+
+/* This struct is intended to abstract the fact that there are two
+ * really similar methods, and two really similar params (just change
+ * the type). All the castings and decision about which method should
+ * be used would be done here, just to keep the code of the test
+ * cleaner.
+ */
+struct _test_data {
+        /* int instead of a bool to make easier iterate on the
+         * possible values. */
+        int testing64;
+        int params_size;
+        void *params;
+        GetInternalformat callback;
+};
+
+/* Updates the callback and params based on current values of
+ * testing64 and params_size */
+static void
+sync_test_data(test_data *data)
+{
+        if (data->params != NULL)
+                free(data->params);
+
+        if (data->testing64) {
+                data->callback = (GetInternalformat) glGetInternalformati64v;
+                data->params = malloc(sizeof(GLint64) * data->params_size);
+        } else {
+                data->callback = (GetInternalformat) glGetInternalformativ;
+                data->params = malloc(sizeof(GLint) * data->params_size);
+        }
+}
+
+test_data*
+test_data_new(int testing64,
+              int params_size)
+{
+        test_data *result;
+
+        result = (test_data*) malloc(sizeof(test_data));
+        result->testing64 = testing64;
+        result->params_size = params_size;
+        result->params = NULL;
+
+        sync_test_data(result);
+
+        return result;
+}
+
+/*
+ * Frees @data, and sets its value to NULL.
+ */
+void
+test_data_clear(test_data **data)
+{
+        test_data *_data = *data;
+
+        if (_data == NULL)
+                return;
+
+        free(_data->params);
+        _data->params = NULL;
+
+        *data = NULL;
+}
+
+void
+test_data_execute(test_data *data,
+                  const GLenum target,
+                  const GLenum internalformat,
+                  const GLenum pname)
+{
+        data->callback(target, internalformat, pname,
+                       data->params_size, data->params);
+}
+
+void
+test_data_set_testing64(test_data *data,
+                        const int testing64)
+{
+        if (data->testing64 == testing64)
+                return;
+
+        data->testing64 = testing64;
+        sync_test_data(data);
+}
+
+GLint64
+test_data_value_at_index(test_data *data,
+                         const int index)
+{
+        if (index > data->params_size || index < 0) {
+                fprintf(stderr, "ERROR: invalid index while retrieving"
+                        " data from auxiliar test data\n");
+                return -1;
+        }
+
+        return data->testing64 ?
+                ((GLint64*)data->params)[index] :
+                ((GLint*)data->params)[index];
+}
+
+/*
+ * Returns if @target/@internalformat is supported using
+ * INTERNALFORMAT_SUPPORTED for @target and @internalformat.
+ *
+ * @data is only used to known if we are testing the 32-bit or the
+ * 64-bit query, so the content of @data will not be modified due this
+ * call.
+ */
+bool
+test_data_check_supported(const test_data *data,
+                          const GLenum target,
+                          const GLenum internalformat)
+{
+        bool result;
+        test_data *local_data = test_data_new(data->testing64, 1);
+
+        test_data_execute(local_data, target, internalformat,
+                          GL_INTERNALFORMAT_SUPPORTED);
+
+        if (!piglit_check_gl_error(GL_NO_ERROR))
+                result = false;
+        else
+                result = test_data_value_at_index(local_data, 0) == GL_TRUE;
+
+        test_data_clear(&local_data);
+
+        return result;
+}
+
+/* Returns if @value is one of the values among @set */
+bool
+value_on_set(const GLint *set,
+       const unsigned set_size,
+       GLint value)
+{
+        unsigned i;
+
+        for (i = 0; i < set_size; i++) {
+                if (set[i] == value)
+                        return true;
+        }
+
+        return false;
+}
+
+bool
+test_data_check_possible_values(test_data *data,
+                                const GLint *possible_values,
+                                const unsigned num_possible_values)
+{
+        return value_on_set(possible_values, num_possible_values,
+                            test_data_value_at_index(data, 0));
+}
+
+/*
+ * Prints the info of a failing case for a given pname.
+ *
+ * Note that it tries to get the name of the value at @data as if it
+ * were a enum, as it is useful on that case. But there are several
+ * pnames that returns a value. A possible improvement would be that
+ * for those just printing the value.
+ */
+void
+print_failing_case(const GLenum target, const GLenum internalformat,
+                   const GLenum pname, test_data *data)
+{
+        print_failing_case_full(target, internalformat, pname, -1, data);
+}
+
+/*
+ * Prints the info of a failing case. If expected_value is smaller
+ * that 0, it is not printed.
+*/
+void print_failing_case_full(const GLenum target, const GLenum internalformat,
+                             const GLenum pname, GLint64 expected_value,
+                             test_data *data)
+{
+        /* Knowing if it is supported is interesting in order to know
+         * if the test is being too restrictive */
+        bool supported = test_data_check_supported(data, target, internalformat);
+        GLint64 current_value = test_data_value_at_index(data, 0);
+
+        if (data->testing64) {
+                fprintf(stderr,  "    64 bit failing case: ");
+        } else {
+                fprintf(stderr,  "    32 bit failing case: ");
+        }
+
+        fprintf(stderr, "pname = %s, "
+                "target = %s, internalformat = %s, ",
+                piglit_get_gl_enum_name(pname),
+                piglit_get_gl_enum_name(target),
+                piglit_get_gl_enum_name(internalformat));
+
+        if (expected_value >= 0)
+                fprintf(stderr, "expected value = (%" PRIu64 "), ",
+                        expected_value);
+
+        fprintf(stderr, "params[0] = (%" PRIu64 ",%s), "
+                "supported=%i\n",
+                current_value,
+                piglit_get_gl_enum_name(current_value),
+                supported);
+}
+
+/*
+ * The most basic condition. From spec, a lot of pnames has a
+ * condition like this:
+ *
+ * "Possible values returned are <set>. If the resource is not
+ *  supported, or if the operation is not supported, NONE is
+ *  returned."
+ *
+ * So this method, calls the callback defined at @data (that should be
+ * GetInternalformativ or GetInternalformati64v) using @pname, for all
+ * @num_targets at @targets, and all @num_internalformats at
+ * @internalformats, and checks the following conditions:
+ *
+ * * If @pname is not supported (calling INTERNALFORMAT_SUPPORTED),
+ *   checks that the value returned is always the same.
+ * * If @pname is supported, checks that the returned value is among
+ *   one of the values defined at @possible_values
+ *
+ * @possible_values, at num_possible_values is allowed to be NULL,0, for
+ * the cases where the set of returned values is not specified in
+ * detail by the spec (like INTERNALFORMAT_PREFERRED). On that case,
+ * it is not tested the returned value, and just tested that if not
+ * suppported, the returned value is the usupported value defined by
+ * the spec.
+ *
+ */
+bool
+try_basic(const GLenum *targets, unsigned num_targets,
+          const GLenum *internalformats, unsigned num_internalformats,
+          const GLenum pname,
+          const GLint *possible_values, unsigned num_possible_values,
+          test_data *data)
+{
+        bool pass = true;
+        unsigned i;
+        unsigned j;
+
+	for (i = 0; i < num_targets; i++) {
+                for (j = 0; j < num_internalformats; j++) {
+                        bool error_test;
+                        bool value_test;
+                        bool supported;
+
+                        supported = check_query2_dependencies(pname, targets[i])
+                                && test_data_check_supported(data, targets[i],
+                                                             internalformats[j]);
+
+                        test_data_execute(data, targets[i], internalformats[j], pname);
+
+                        if (supported && num_possible_values == 0)
+                                continue;
+
+                        error_test =
+                                piglit_check_gl_error(GL_NO_ERROR);
+
+                        value_test = supported ?
+                                test_data_check_possible_values(data, possible_values,
+                                                                num_possible_values) :
+                                test_data_is_unsupported_response(data, pname);
+
+                        if (error_test && value_test)
+                                continue;
+
+                        print_failing_case(targets[i], internalformats[j],
+                                           pname, data);
+
+                        pass = false;
+                }
+        }
+
+	return pass;
+}
+
+/*
+ * Returns if @pname query2 dependencies are fulfilled. So for
+ * example, FRAMEBUFFER_RENDERABLE needs
+ * ARB/EXT_framebuffer_object. With that pname, if
+ * ARB/EXT_framebuffer_object is not present, it returns false.
+ *
+ * It is assumed that @pname is a valid query2 pname, as would
+ * simplify the implementation of this method.
+ */
+static bool
+check_query2_pname_dependencies(const GLenum pname)
+{
+        switch(pname) {
+        case GL_FRAMEBUFFER_RENDERABLE:
+        case GL_FRAMEBUFFER_BLEND:
+                if (!piglit_is_extension_supported("GL_ARB_framebuffer_object") &&
+                    !piglit_is_extension_supported("GL_EXT_framebuffer_object"))
+                        return false;
+                break;
+
+        case GL_FRAMEBUFFER_RENDERABLE_LAYERED:
+                if (!piglit_is_extension_supported("GL_ARB_framebuffer_object") &&
+                    !piglit_is_extension_supported("GL_EXT_framebuffer_object"))
+                        return false;
+                if (!piglit_is_extension_supported("GL_EXT_texture_array"))
+                        return false;
+                break;
+
+        case GL_MANUAL_GENERATE_MIPMAP:
+                if (!piglit_is_extension_supported("GL_ARB_framebuffer_object") &&
+                    !piglit_is_extension_supported("GL_EXT_framebuffer_object"))
+                        return false;
+                break;
+
+        case GL_MAX_LAYERS:
+                if (!piglit_is_extension_supported("GL_EXT_texture_array"))
+                        return false;
+                break;
+
+        case GL_SRGB_READ:
+                if (!piglit_is_extension_supported("GL_EXT_texture_sRGB"))
+                        return false;
+                break;
+
+        case GL_SRGB_WRITE:
+                if (!piglit_is_extension_supported("GL_ARB_framebuffer_sRGB"))
+                        return false;
+                break;
+
+        case GL_SRGB_DECODE_ARB:
+                /* Note that if the extension is not supported, it
+                 * should return INVALID_ENUM, not unsupported */
+                if (!piglit_is_extension_supported("GL_ARB_texture_sRGB_decode") &&
+                    !piglit_is_extension_supported("GL_EXT_texture_sRGB_decode"))
+                        return false;
+                break;
+
+        case GL_TESS_CONTROL_TEXTURE:
+        case GL_TESS_EVALUATION_TEXTURE:
+                if (!piglit_is_extension_supported("GL_ARB_tesselation_shader"))
+                        return false;
+                break;
+
+        case GL_GEOMETRY_TEXTURE:
+                if (!piglit_is_extension_supported("GL_ARB_geometry_shader4"))
+                        return false;
+                break;
+
+        case GL_COMPUTE_TEXTURE:
+                if (!piglit_is_extension_supported("GL_ARB_compute_shader"))
+                        return false;
+                break;
+
+        case GL_TEXTURE_GATHER:
+                if (!piglit_is_extension_supported("GL_ARB_texture_gather"))
+                        return false;
+                break;
+
+        case GL_SHADER_IMAGE_LOAD:
+        case GL_SHADER_IMAGE_STORE:
+        case GL_SHADER_IMAGE_ATOMIC:
+        case GL_IMAGE_TEXEL_SIZE:
+        case GL_IMAGE_COMPATIBILITY_CLASS:
+        case GL_IMAGE_PIXEL_FORMAT:
+        case GL_IMAGE_PIXEL_TYPE:
+        case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
+                if (!piglit_is_extension_supported("GL_ARB_shader_image_load_store"))
+                        return false;
+                break;
+
+        case GL_CLEAR_BUFFER:
+                if (!piglit_is_extension_supported("GL_ARB_clear_buffer_object"))
+                        return false;
+                break;
+
+        case GL_TEXTURE_VIEW:
+        case GL_VIEW_COMPATIBILITY_CLASS:
+                if (!piglit_is_extension_supported("GL_ARB_texture_view"))
+                        return false;
+                break;
+
+                        case GL_SAMPLES:
+                break;
+
+        default:
+                return true;
+        }
+
+        return true;
+}
+
+/*
+ * Returns if @target query2 dependencies are fulfilled. So for
+ * example, TEXTURE_1D_ARRAY needs
+ * EXT_texture_array. With that pname, if
+ * ARB/EXT_framebuffer_object is not present, it returns false.
+ *
+ * It is assumed that @target is a valid query2 target, as would
+ * simplify the implementation of this method.
+ */
+static bool
+check_query2_target_dependencies(const GLenum target)
+{
+        switch(target) {
+        case GL_TEXTURE_1D_ARRAY:
+        case GL_TEXTURE_2D_ARRAY:
+                if (!piglit_is_extension_supported("GL_EXT_texture_array"))
+                        return false;
+                break;
+
+        case GL_TEXTURE_CUBE_MAP_ARRAY:
+                if (!piglit_is_extension_supported("GL_ARB_texture_cube_map_array"))
+                        return false;
+                break;
+
+        case GL_TEXTURE_2D_MULTISAMPLE:
+        case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+                if (!piglit_is_extension_supported("GL_ARB_texture_multisample"))
+                        return false;
+                break;
+
+        case GL_TEXTURE_RECTANGLE:
+                if (!piglit_is_extension_supported("GL_ARB_texture_rectangle"))
+                        return false;
+                break;
+
+        case GL_RENDERBUFFER:
+                if (!piglit_is_extension_supported("GL_ARB_framebuffer_object") &&
+                    !piglit_is_extension_supported("GL_EXT_framebuffer_object"))
+                        return false;
+                break;
+
+        case GL_TEXTURE_BUFFER:
+                if (!piglit_is_extension_supported("GL_ARB_texture_buffer_object"))
+                        return false;
+                break;
+
+        default:
+                return true;
+        }
+
+        return true;
+}
+
+/* Returns is @pname and @target dependencies are fullfilled */
+bool
+check_query2_dependencies(const GLenum pname,
+                          const GLenum target)
+{
+        return check_query2_target_dependencies(target) &&
+                check_query2_pname_dependencies(pname);
+}
+
+/*
+ * Gets the unsupported response for any given @pname.
+ */
+static GLint
+get_unsupported_response(GLenum pname)
+{
+        switch(pname) {
+        case GL_SAMPLES:
+                /* This one is special as if unsupported, the params
+                 * parameter at GetInternalformativ should not be
+                 * modified. We return 0 for this method, but should
+                 * be took into account by the caller */
+                return 0;
+                break;
+
+        case GL_MAX_COMBINED_DIMENSIONS:
+        case GL_NUM_SAMPLE_COUNTS:
+        case GL_INTERNALFORMAT_RED_SIZE:
+        case GL_INTERNALFORMAT_GREEN_SIZE:
+        case GL_INTERNALFORMAT_BLUE_SIZE:
+        case GL_INTERNALFORMAT_ALPHA_SIZE:
+        case GL_INTERNALFORMAT_DEPTH_SIZE:
+        case GL_INTERNALFORMAT_STENCIL_SIZE:
+        case GL_INTERNALFORMAT_SHARED_SIZE:
+        case GL_MAX_WIDTH:
+        case GL_MAX_HEIGHT:
+        case GL_MAX_DEPTH:
+        case GL_MAX_LAYERS:
+        case GL_IMAGE_TEXEL_SIZE:
+        case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH:
+        case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT:
+        case GL_TEXTURE_COMPRESSED_BLOCK_SIZE:
+                return 0;
+                break;
+
+        case GL_INTERNALFORMAT_PREFERRED:
+        case GL_INTERNALFORMAT_RED_TYPE:
+        case GL_INTERNALFORMAT_GREEN_TYPE:
+        case GL_INTERNALFORMAT_BLUE_TYPE:
+        case GL_INTERNALFORMAT_ALPHA_TYPE:
+        case GL_INTERNALFORMAT_DEPTH_TYPE:
+        case GL_INTERNALFORMAT_STENCIL_TYPE:
+        case GL_FRAMEBUFFER_RENDERABLE:
+        case GL_FRAMEBUFFER_RENDERABLE_LAYERED:
+        case GL_FRAMEBUFFER_BLEND:
+        case GL_READ_PIXELS:
+        case GL_READ_PIXELS_FORMAT:
+        case GL_READ_PIXELS_TYPE:
+        case GL_TEXTURE_IMAGE_FORMAT:
+        case GL_TEXTURE_IMAGE_TYPE:
+        case GL_GET_TEXTURE_IMAGE_FORMAT:
+        case GL_GET_TEXTURE_IMAGE_TYPE:
+        case GL_MANUAL_GENERATE_MIPMAP:
+        case GL_AUTO_GENERATE_MIPMAP:
+        case GL_COLOR_ENCODING:
+        case GL_SRGB_READ:
+        case GL_SRGB_WRITE:
+        case GL_SRGB_DECODE_ARB:
+        case GL_FILTER:
+        case GL_VERTEX_TEXTURE:
+        case GL_TESS_CONTROL_TEXTURE:
+        case GL_TESS_EVALUATION_TEXTURE:
+        case GL_GEOMETRY_TEXTURE:
+        case GL_FRAGMENT_TEXTURE:
+        case GL_COMPUTE_TEXTURE:
+        case GL_TEXTURE_SHADOW:
+        case GL_TEXTURE_GATHER:
+        case GL_TEXTURE_GATHER_SHADOW:
+        case GL_SHADER_IMAGE_LOAD:
+        case GL_SHADER_IMAGE_STORE:
+        case GL_SHADER_IMAGE_ATOMIC:
+        case GL_IMAGE_COMPATIBILITY_CLASS:
+        case GL_IMAGE_PIXEL_FORMAT:
+        case GL_IMAGE_PIXEL_TYPE:
+        case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
+        case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST:
+        case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST:
+        case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE:
+        case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE:
+        case GL_CLEAR_BUFFER:
+        case GL_TEXTURE_VIEW:
+        case GL_VIEW_COMPATIBILITY_CLASS:
+                return GL_NONE;
+                break;
+
+        case GL_INTERNALFORMAT_SUPPORTED:
+        case GL_COLOR_COMPONENTS:
+        case GL_DEPTH_COMPONENTS:
+        case GL_STENCIL_COMPONENTS:
+        case GL_COLOR_RENDERABLE:
+        case GL_DEPTH_RENDERABLE:
+        case GL_STENCIL_RENDERABLE:
+        case GL_MIPMAP:
+        case GL_TEXTURE_COMPRESSED:
+                return GL_FALSE;
+                break;
+
+        default:
+                fprintf(stderr, "Error: %i(%s) is not a valid GetInternalformativ pname",
+                        pname, piglit_get_gl_enum_name(pname));
+        }
+
+        return 0;
+}
+
+/*
+ * Returns if the content of @data contains the unsupported value for
+ * @pname. It is assumed that the pname would return just one value.
+ */
+bool
+test_data_is_unsupported_response(test_data *data,
+                                  GLenum pname)
+{
+        return test_data_value_at_index(data, 0) == get_unsupported_response(pname);
+}
diff --git a/tests/spec/arb_internalformat_query2/common.h b/tests/spec/arb_internalformat_query2/common.h
index 5cce88b..5295c91 100644
--- a/tests/spec/arb_internalformat_query2/common.h
+++ b/tests/spec/arb_internalformat_query2/common.h
@@ -156,7 +156,10 @@ static const GLenum invalid_pnames[] = {
 
 /* From spec:
  *
- *  "<internalformats> that must be supported (in GL 4.2 or later)
+ *  "INTERNALFORMAT_SUPPORTED:
+ *  <skip>
+ *
+ * <internalformats> that must be supported (in GL 4.2 or later)
  *   include the following:
  *    - "sized internal formats" from Table 3.12, 3.13, and 3.15,
  *    - any specific "compressed internal format" from Table 3.14,
@@ -262,4 +265,51 @@ static const GLenum valid_internalformats[] = {
         GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT,
 };
 
+typedef struct _test_data test_data;
+
+test_data* test_data_new(int testing64,
+                         int params_size);
+
+void test_data_clear(test_data **data);
+
+void test_data_execute(test_data *data,
+                       const GLenum target,
+                       const GLenum internalformat,
+                       const GLenum pname);
+
+void test_data_set_testing64(test_data *data,
+                             const int testing64);
+
+bool test_data_check_supported(const test_data *data,
+                               const GLenum target,
+                               const GLenum internalformat);
+
+bool test_data_check_possible_values(test_data *data,
+                                     const GLint *possible_values,
+                                     const unsigned num_possible_values);
+
+GLint64 test_data_value_at_index(test_data *data,
+                                 const int index);
+
+bool try_basic(const GLenum *targets, unsigned num_targets,
+               const GLenum *internalformats, unsigned num_internalformats,
+               const GLenum pname,
+               const GLint *possible_values, unsigned num_possible_values,
+               test_data *data);
+
+void print_failing_case(const GLenum target, const GLenum internalformat,
+                        const GLenum pname, test_data *data);
+
+void print_failing_case_full(const GLenum target, const GLenum internalformat,
+                             const GLenum pname, GLint64 expected_value,
+                             test_data *data);
+
+bool value_on_set(const GLint *set,
+                  const unsigned set_size,
+                  GLint value);
+
+bool check_query2_dependencies(const GLenum pname,
+                               const GLenum target);
 
+bool test_data_is_unsupported_response(test_data *data,
+                                       GLenum pname);
diff --git a/tests/spec/arb_internalformat_query2/generic-pname-checks.c b/tests/spec/arb_internalformat_query2/generic-pname-checks.c
new file mode 100644
index 0000000..e427109
--- /dev/null
+++ b/tests/spec/arb_internalformat_query2/generic-pname-checks.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright © 2015 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 gneric-pname-checks.c
+ *
+ * Verify a handful of conditions required by the spec for a set of
+ * pnames with the most generic conditions. Specifically it tests for the
+ * pnames that only require:
+ *
+ *  a) That if not supported, the returned value is always the same
+ *  b) If supported, the returned value is among a fixed set of
+ *     possible values.
+ *
+ */
+
+#include "common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_compat_version = 10;
+	config.window_visual = PIGLIT_GL_VISUAL_RGB;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const GLenum pnames_common_outcome[] = {
+        GL_FRAMEBUFFER_RENDERABLE,
+        GL_FRAMEBUFFER_RENDERABLE_LAYERED,
+        GL_FRAMEBUFFER_BLEND,
+        GL_READ_PIXELS,
+        GL_MANUAL_GENERATE_MIPMAP,
+        GL_AUTO_GENERATE_MIPMAP,
+        GL_SRGB_READ,
+        GL_SRGB_WRITE,
+        GL_SRGB_DECODE_ARB,
+        GL_VERTEX_TEXTURE,
+        GL_TESS_CONTROL_TEXTURE,
+        GL_TESS_EVALUATION_TEXTURE,
+        GL_GEOMETRY_TEXTURE,
+        GL_FRAGMENT_TEXTURE,
+        GL_COMPUTE_TEXTURE,
+        GL_TEXTURE_SHADOW,
+        GL_TEXTURE_GATHER,
+        GL_TEXTURE_GATHER_SHADOW,
+        GL_SHADER_IMAGE_LOAD,
+        GL_SHADER_IMAGE_STORE,
+        GL_SHADER_IMAGE_ATOMIC,
+        GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST,
+        GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST,
+        GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE,
+        GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE,
+        GL_CLEAR_BUFFER,
+        GL_TEXTURE_VIEW,
+};
+
+static const GLint possible_values_common[] = {
+        GL_NONE,
+        GL_CAVEAT_SUPPORT,
+        GL_FULL_SUPPORT,
+};
+
+static const GLenum pnames_true_false[] = {
+        GL_COLOR_RENDERABLE,
+        GL_DEPTH_RENDERABLE,
+        GL_STENCIL_RENDERABLE,
+        GL_TEXTURE_COMPRESSED,
+};
+
+static const GLint possible_values_true_false[] = {
+        GL_TRUE,
+        GL_FALSE
+};
+
+enum piglit_result
+piglit_display(void)
+{
+	return PIGLIT_FAIL;
+}
+
+/*
+ * Executes try_basic on a list of pnames/possible values.
+ *
+ * check_basic and try_basic are splitted because for some pnames, we
+ * would need to check more than just try_basic.
+ */
+static bool
+check_basic(const GLenum *pnames, unsigned num_pnames,
+            const GLint *possible_values, unsigned num_possible_values)
+{
+        bool check_pass = true;
+        test_data *data = test_data_new(0, 1);
+        unsigned i;
+        int testing64;
+
+        for (i = 0; i < num_pnames; i++) {
+                bool pass = true;
+
+                for (testing64 = 0; testing64 <= 1; testing64++) {
+                        test_data_set_testing64(data, testing64);
+
+                        pass = try_basic(valid_targets, ARRAY_SIZE(valid_targets),
+                                         valid_internalformats, ARRAY_SIZE(valid_internalformats),
+                                         pnames[i],
+                                         possible_values, num_possible_values,
+                                         data)
+                                && pass;
+                }
+
+                piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL,
+                                             "%s", piglit_get_gl_enum_name(pnames[i]));
+
+                check_pass = check_pass && pass;
+        }
+
+        test_data_clear(&data);
+
+        return check_pass;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+        bool pass = true;
+        GLenum pname;
+
+	piglit_require_extension("GL_ARB_internalformat_query2");
+
+        pname = GL_INTERNALFORMAT_PREFERRED;
+        pass = check_basic(&pname, 1, NULL, 0) && pass;
+
+        pass = check_basic(pnames_common_outcome, ARRAY_SIZE(pnames_common_outcome),
+                           possible_values_common, ARRAY_SIZE(possible_values_common))
+                && pass;
+
+        pass = check_basic(pnames_true_false, ARRAY_SIZE(pnames_true_false),
+                           possible_values_true_false, ARRAY_SIZE(possible_values_true_false))
+                && pass;
+
+        piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
+}
-- 
2.1.4



More information about the Piglit mailing list