[Piglit] [PATCH] arb_query_buffer_object: Update and add more test scenarios

Ilia Mirkin imirkin at alum.mit.edu
Fri Apr 22 04:11:02 UTC 2016


On Thu, Apr 21, 2016 at 10:01 PM, Jordan Justen
<jordan.l.justen at intel.com> wrote:
> Bump requirement to OpenGL 3.2 and add OpenGL Core profile support.
>
> Test several other query types. (Previously only GL_SAMPLES_PASSED was
> tested.)
>
> Also test retrieving the result to CPU memory before and after the
> buffer based result.
>
> Don't warn if the async test always has the results available.

Tested on nouveau (with minor fixes for timestamps), and it passes.

>
> Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
> ---
>  tests/spec/arb_query_buffer_object/qbo.c | 324 +++++++++++++++++++------------
>  1 file changed, 205 insertions(+), 119 deletions(-)
>
> diff --git a/tests/spec/arb_query_buffer_object/qbo.c b/tests/spec/arb_query_buffer_object/qbo.c
> index 0cee6c8..847642a 100644
> --- a/tests/spec/arb_query_buffer_object/qbo.c
> +++ b/tests/spec/arb_query_buffer_object/qbo.c
> @@ -28,13 +28,14 @@
>   * Tests ARB_query_buffer_object
>   * - synchronous wait for result
>   * - asynchrounous result, default value is left intact if result unavailable
> + * - asynchrounous result, retrieve result to client memory before & after
>   */
>
>  #include "piglit-util-gl.h"
>
>  PIGLIT_GL_TEST_CONFIG_BEGIN
> -       config.supports_gl_compat_version = 30;
> -//     config.supports_gl_core_version = 32;
> +       config.supports_gl_compat_version = 32;
> +       config.supports_gl_core_version = 32;
>         config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE |
>                 PIGLIT_GL_VISUAL_DEPTH;
>
> @@ -43,200 +44,285 @@ PIGLIT_GL_TEST_CONFIG_END
>  #define BUFFER_OFFSET(i) ((GLint *)((unsigned char*)NULL + (i)))
>
>  static const float green[] = {0, 1, 0, 1};
> -static const float red[] = {1, 0, 0, 1};
>
>  static unsigned query;
>  static unsigned qbo;
>
>  static int prog;
>  static int qbo_prog;
> +static int sync_mode_loc;
> +static int original_count_loc;
> +static int expect_exact_loc;
>  static int expected_count_loc;
> -static int qbo_async_prog;
>
> -enum piglit_result
> -synchronous_query(void)
> +enum sync_mode {
> +       QBO_SYNC,
> +       QBO_ASYNC,
> +       QBO_ASYNC_CPU_READ_BEFORE,
> +       QBO_ASYNC_CPU_READ_AFTER,
> +       NUM_QBO_SYNC_MODES,
> +};
> +
> +static char* sync_mode_names[] = {
> +       "SYNC",
> +       "ASYNC",
> +       "ASYNC_CPU_READ_BEFORE",
> +       "ASYNC_CPU_READ_AFTER",
> +};
> +
> +static enum sync_mode sync_mode;
> +
> +static GLenum query_types[] = {
> +       GL_ANY_SAMPLES_PASSED,
> +       GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
> +       GL_CLIPPING_INPUT_PRIMITIVES_ARB,
> +       GL_CLIPPING_OUTPUT_PRIMITIVES_ARB,

These are only available with GL_ARB_pipeline_statistics_query. You
don't require that anywhere, so I think you need to optionally skip
these if they're not available.

> +       /* GL_COMPUTE_SHADER_INVOCATIONS_ARB, */
> +       GL_FRAGMENT_SHADER_INVOCATIONS_ARB,
> +       /* GL_GEOMETRY_SHADER_INVOCATIONS, */
> +       /* GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB, */
> +       GL_PRIMITIVES_GENERATED,
> +       GL_PRIMITIVES_SUBMITTED_ARB,
> +       GL_SAMPLES_PASSED_ARB,
> +       /* GL_TESS_CONTROL_SHADER_PATCHES_ARB, */
> +       /* GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB, */
> +       GL_TIMESTAMP,
> +       GL_TIME_ELAPSED,
> +       GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN,
> +       GL_VERTEX_SHADER_INVOCATIONS_ARB,
> +       GL_VERTICES_SUBMITTED_ARB,
> +};
> +
> +static GLenum query_type;
> +
> +static void
> +get_query_values(GLenum query_type, uint32_t *original,
> +                bool *exact, uint32_t *expected)
>  {
> -       GLboolean pass;
> -
> -       glClearColor(0.5, 0.5, 0.5, 1.0);
> -       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
> -
> -       // enable query, draw something that should pass
> -       glEnable(GL_DEPTH_TEST);
> -       glUseProgram(prog);
> -       glBeginQuery(GL_SAMPLES_PASSED, query);
> -       piglit_draw_rect_z(0.5, -1, -1, 2, 2);
> -       glEndQuery(GL_SAMPLES_PASSED);
> -
> -       // Stuff query result into qbo
> -       glBindBuffer(GL_QUERY_BUFFER, qbo);
> -       glGetQueryObjectivARB(query, GL_QUERY_RESULT, BUFFER_OFFSET(0));
> -       // Make it available to shader as uniform buffer 0
> -       glBindBufferBase(GL_UNIFORM_BUFFER, 0, qbo);
> -
> -       glUseProgram(qbo_prog);
> +       *original = 0xffffffff;
> +       *exact = true;
> +
> +       switch (query_type) {
> +       case GL_ANY_SAMPLES_PASSED:
> +       case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
> +               *expected = 1;
> +               break;
> +       case GL_CLIPPING_INPUT_PRIMITIVES_ARB:
> +       case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB:
> +               *exact = false;
> +               *expected = 1;
> +               break;
> +       case GL_FRAGMENT_SHADER_INVOCATIONS_ARB:
> +               *exact = false;
> +               *expected = 1;
> +               break;
> +       case GL_PRIMITIVES_GENERATED:
> +       case GL_PRIMITIVES_SUBMITTED_ARB:
> +               *exact = false;
> +               *expected = 1;
> +               break;
> +       case GL_SAMPLES_PASSED_ARB:
> +               *expected = piglit_width * piglit_height;
> +               break;
> +       case GL_TIMESTAMP:
> +       case GL_TIME_ELAPSED:
> +               *exact = false;
> +               *expected = 1;
> +               break;
> +       case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
> +               *expected = 0;
> +               break;
> +       case GL_VERTEX_SHADER_INVOCATIONS_ARB:
> +       case GL_VERTICES_SUBMITTED_ARB:
> +               *exact = false;
> +               *expected = 1;
> +               break;
> +       case GL_COMPUTE_SHADER_INVOCATIONS_ARB:
> +       case GL_GEOMETRY_SHADER_INVOCATIONS:
> +       case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB:
> +       case GL_TESS_CONTROL_SHADER_PATCHES_ARB:
> +       case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB:
> +       default:
> +               abort();
> +       }
> +}
>
> -       // expected count of samples passed
> -       glUniform1ui(expected_count_loc, piglit_width * piglit_height);
> +static enum piglit_result
> +cpu_gather_query(bool exact, uint32_t expected)
> +{
> +       GLint qresult;
>
> -       glDisable(GL_DEPTH_TEST);
> -       // draw green if query successful
> -       piglit_draw_rect(-1, -1, 2, 2);
> +       glBindBuffer(GL_QUERY_BUFFER, 0);
>
> -       pass = piglit_probe_rect_rgba(0, 0, piglit_width, piglit_height, green);
> +       glGetQueryObjectiv(query, GL_QUERY_RESULT, &qresult);
>
> -       piglit_present_results();
> +       glBindBuffer(GL_QUERY_BUFFER, qbo);
>
> -       return pass ? PIGLIT_PASS : PIGLIT_FAIL;
> +       return (exact ? qresult == expected : qresult >= expected)
> +               ? PIGLIT_PASS : PIGLIT_FAIL;
>  }
>
>  enum piglit_result
> -asynchronous_query_with_default(void)
> +run_subtest(void)
>  {
> -       enum piglit_result result;
> -       unsigned default_value[2] = { 42u, 0u };
> -       unsigned char *buffer;
> -       unsigned redcount, greencount, bluecount;
> -       size_t n;
> +       uint32_t original;
> +       bool exact;
> +       uint32_t expected;
> +       uint32_t default_value[2] = { 0u, 0u };
> +       bool is_sync = sync_mode == QBO_SYNC;
> +
> +       get_query_values(query_type, &original, &exact, &expected);
> +       default_value[0] = original;
>
>         glClearColor(0.5, 0.5, 0.5, 1.0);
>         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
>
> -       // Load default value into buffer
> +       /* Load default value into buffer */
>         glBindBuffer(GL_QUERY_BUFFER, qbo);
>         glBufferData(GL_QUERY_BUFFER, 8, default_value, GL_DYNAMIC_COPY);
>
> -       // enable query, draw something that should pass
> +       /* Enable query, draw something that should pass */
>         glEnable(GL_DEPTH_TEST);
>         glUseProgram(prog);
> -       glBeginQuery(GL_SAMPLES_PASSED, query);
> +       glGenQueries(1, &query);
> +       if (query_type != GL_TIMESTAMP)
> +               glBeginQuery(query_type, query);
>         piglit_draw_rect_z(0.5, -1, -1, 2, 2);
> -       glEndQuery(GL_SAMPLES_PASSED);
> +       if (query_type != GL_TIMESTAMP)
> +               glEndQuery(query_type);
> +       else
> +               glQueryCounter(query, query_type);
> +
> +       if (sync_mode == QBO_ASYNC_CPU_READ_BEFORE &&
> +           cpu_gather_query(exact, expected))
> +               return PIGLIT_FAIL;
>
>         glBindBuffer(GL_QUERY_BUFFER, qbo);
> -       // Stuff query result into qbo
> -       glGetQueryObjectivARB(query, GL_QUERY_RESULT_NO_WAIT, BUFFER_OFFSET(0));
> -       // Stuff query availability into qbo
> -       glGetQueryObjectivARB(query, GL_QUERY_RESULT_AVAILABLE, BUFFER_OFFSET(4));
> -       // Make it available to shader as uniform buffer 0
> +       if (is_sync) {
> +               /* Stuff query result into qbo */
> +               glGetQueryObjectivARB(query, GL_QUERY_RESULT,
> +                                     BUFFER_OFFSET(0));
> +       } else {
> +               /* Stuff query result into qbo */
> +               glGetQueryObjectivARB(query, GL_QUERY_RESULT_NO_WAIT, BUFFER_OFFSET(0));
> +               /* Stuff query availability into qbo */
> +               glGetQueryObjectivARB(query, GL_QUERY_RESULT_AVAILABLE, BUFFER_OFFSET(4));
> +       }
> +
> +       if (sync_mode == QBO_ASYNC_CPU_READ_AFTER &&
> +           cpu_gather_query(exact, expected))
> +               return PIGLIT_FAIL;
> +
> +       /* Make it available to shader as uniform buffer 0 */
>         glBindBufferBase(GL_UNIFORM_BUFFER, 0, qbo);
>
> -       glUseProgram(qbo_async_prog);
> +       glUseProgram(qbo_prog);
> +
> +       /* Setup program uniforms */
> +       glUniform1ui(sync_mode_loc, is_sync ? GL_TRUE : GL_FALSE);
> +       glUniform1ui(original_count_loc, original);
> +       glUniform1ui(expect_exact_loc, exact ? GL_TRUE : GL_FALSE);
> +       glUniform1ui(expected_count_loc, expected);
>
>         glDisable(GL_DEPTH_TEST);
> -       // draw green if query successful
> +       /* Draw green if query successful */
>         piglit_draw_rect(-1, -1, 2, 2);
>
> -       // Any red values -> fail
> -       // No blue, we don't know if async result not available works -> warn
> -       buffer = malloc(piglit_width * piglit_height * 4);
> -       glReadPixels(0, 0, piglit_width, piglit_height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
> -       redcount = 0;
> -       bluecount = 0;
> -       greencount = 0;
> -       for (n = 0; n < piglit_width * piglit_height; n++) {
> -               unsigned char r = buffer[n*4 + 0];
> -               unsigned char g = buffer[n*4 + 1];
> -               unsigned char b = buffer[n*4 + 2];
> -               if (r)
> -                       redcount++;
> -               if (b)
> -                       bluecount++;
> -               if (g)
> -                       greencount++;
> -       }
> -       free(buffer);
> +       glDeleteQueries(1, &query);
>
> -       if (redcount || greencount != piglit_width * piglit_height) {
> -               result = PIGLIT_FAIL;
> -       }
> -       else if (bluecount == 0) {
> -               result = PIGLIT_WARN;
> -               printf("no pixels where async query result unavailable, uncertain test result\n");
> -       }
> -       else {
> -               result = PIGLIT_PASS;
> -       }
> +       return piglit_probe_rect_rgba(0, 0, piglit_width,
> +                                     piglit_height, green)
> +               ? PIGLIT_PASS : PIGLIT_FAIL;
> +}
>
> +enum piglit_result
> +run_subtest_and_present(void)
> +{
> +       char *subtest_name;
> +       enum piglit_result r = run_subtest();
>         piglit_present_results();
> -
> -       return result;
> +       asprintf(&subtest_name, "query-%s-%s",
> +                piglit_get_gl_enum_name(query_type),
> +                sync_mode_names[sync_mode]);
> +       piglit_report_subtest_result(r, subtest_name);
> +       free(subtest_name);
> +       return r;
>  }
>
>  enum piglit_result
>  piglit_display(void)
>  {
> -       enum piglit_result r, r2;
> -
> -       r = synchronous_query();
> -       piglit_report_subtest_result(r, "synchronous_query");
> -
> -       r2 = asynchronous_query_with_default();
> -       piglit_report_subtest_result(r2, "asynchronous_query_with_default");
> +       enum piglit_result r = PIGLIT_PASS;
> +       enum piglit_result subtest_result;
> +       int qnum;
> +
> +       for (qnum = 0; qnum < ARRAY_SIZE(query_types); qnum++) {
> +               query_type = query_types[qnum];
> +               for (sync_mode = QBO_SYNC;
> +                    sync_mode < NUM_QBO_SYNC_MODES;
> +                    sync_mode++) {
> +                       subtest_result = run_subtest_and_present();
> +                       r = MAX2(r, subtest_result);
> +               }
> +       }
>
> -       return MAX2(r, r2);
> +       return r;
>  }
>
>  void
>  piglit_init(int argc, char **argv)
>  {
>         char *vsCode;
> -       char *fsCode, *qboFsCode, *qboAsyncFsCode;
> +       char *fsCode, *qboFsCode;
>
>         piglit_require_extension("GL_ARB_query_buffer_object");
>         piglit_require_extension("GL_ARB_uniform_buffer_object");
>
> -       glGenQueries(1, &query);
> -
>         glGenBuffers(1, &qbo);
>         glBindBuffer(GL_QUERY_BUFFER, qbo);
>         glBufferData(GL_QUERY_BUFFER, 4, NULL, GL_DYNAMIC_COPY);
>
>         vsCode =
> -               "#version 130\n"
> +               "#version 150\n"
> +               "in vec4 pos_in;\n"
>                 "void main() {\n"
> -               "       gl_Position = gl_Vertex;\n"
> +               "       gl_Position = pos_in;\n"
>                 "}\n";
>         fsCode =
> -               "#version 130\n"
> +               "#version 150\n"
> +               "out vec4 color;\n"
>                 "void main() {\n"
> -               "       gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);\n"
> +               "       color = vec4(0.0, 0.0, 1.0, 1.0);\n"
>                 "}\n";
>         qboFsCode =
> -               "#version 130\n"
> -               "#extension GL_ARB_uniform_buffer_object : require\n"
> -               "uniform query {\n"
> -               "       uint result;\n"
> -               "};\n"
> -               "uniform uint expected_count;\n"
> -               "void main() {\n"
> -               "   if (result == expected_count) {\n"
> -               "               gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
> -               "       } else {\n"
> -               "               gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
> -               "       }\n"
> -               "}\n";
> -       qboAsyncFsCode =
> -               "#version 130\n"
> +               "#version 150\n"
>                 "#extension GL_ARB_uniform_buffer_object : require\n"
>                 "uniform query {\n"
>                 "       uint result;\n"
>                 "       uint available;\n"
>                 "};\n"
> +               "uniform bool sync_mode;\n"
> +               "uniform uint original_count;\n"
> +               "uniform bool expect_exact;\n"
> +               "uniform uint expected_count;\n"
> +               "out vec4 color;\n"
>                 "void main() {\n"
> -               "       if (available == 0u && result == 42u) {\n"
> -               "               gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0);\n"
> -               "   } else if (available == 0u && result != 42u) {\n"
> -               "               gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);\n"
> -               "       } else if (available != 0u && result > 0u) {\n"
> -               "               gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
> +               "       bool ready = sync_mode || available != 0u;\n"
> +               "       if (!ready && result == original_count) {\n"
> +               "               color = vec4(0.0, 1.0, 0.0, 1.0);\n"
> +               "       } else if (ready &&\n"
> +               "                  (expect_exact ? result == expected_count :\n"
> +               "                                  result >= expected_count)) {\n"
> +               "               color = vec4(0.0, 1.0, 0.0, 1.0);\n"
>                 "       } else {\n"
> -               "               gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);\n"
> +               "               color = vec4(1.0, 0.0, 0.0, 1.0);\n"
>                 "       }\n"
>                 "}\n";
>
>         prog = piglit_build_simple_program(vsCode, fsCode);
>         qbo_prog = piglit_build_simple_program(vsCode, qboFsCode);
> +       sync_mode_loc = glGetUniformLocation(qbo_prog, "sync_mode");
> +       original_count_loc = glGetUniformLocation(qbo_prog, "original_count");
> +       expect_exact_loc = glGetUniformLocation(qbo_prog, "expect_exact");
>         expected_count_loc = glGetUniformLocation(qbo_prog, "expected_count");
> -       qbo_async_prog = piglit_build_simple_program(vsCode, qboAsyncFsCode);
>  }
> --
> 2.8.0.rc3
>
> _______________________________________________
> Piglit mailing list
> Piglit at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/piglit


More information about the Piglit mailing list