On Thu, Apr 21, 2016 at 10:01 PM, Jordan Justen <[email protected]> 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 <[email protected]> > --- > 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 > [email protected] > https://lists.freedesktop.org/mailman/listinfo/piglit _______________________________________________ Piglit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/piglit
