[Piglit] [PATCH 2/8] GL3.2 GL_ARB_sync: Test for valid return values from ClientWaitSync

Chad Versace chad.versace at linux.intel.com
Mon Oct 14 23:23:39 CEST 2013


On 10/07/2013 08:46 AM, Nicholas Mack wrote:
> v2: Fix comments, initialize variables.  Still need to figure out if GPU commands
>      needed before testing these.
>
> v3: Rewrite test cases, fix comment and config block and add to all.tests
> ---
>   tests/all.tests                              |   1 +
>   tests/spec/arb_sync/CMakeLists.gl.txt        |   3 +-
>   tests/spec/arb_sync/ClientWaitSync-returns.c | 195 +++++++++++++++++++++++++++
>   3 files changed, 198 insertions(+), 1 deletion(-)
>   create mode 100644 tests/spec/arb_sync/ClientWaitSync-returns.c
>
> diff --git a/tests/all.tests b/tests/all.tests
> index 4aa77f4..0118cc9 100644
> --- a/tests/all.tests
> +++ b/tests/all.tests
> @@ -1100,6 +1100,7 @@ import_glsl_parser_tests(spec['ARB_shader_stencil_export'],
>   arb_sync = Group()
>   spec['ARB_sync'] = arb_sync
>   arb_sync['ClientWaitSync-errors'] = concurrent_test('arb_sync-ClientWaitSync-errors')
> +arb_sync['ClientWaitSync-returns'] = concurrent_test('arb_sync-ClientWaitSync-returns')

The actual executable name in the CMake is arb_sync-client-wait-returns.

Before submitting a patch series, it's always a good idea to do something like this
to check that the Python and CMake agree, and that all the expected tests show
up in the results file.

   make clean && (make help | grep arb_sync | cut -d: -f1 | xargs make) && ./piglit-run.py -t arb_sync



I submitted a patch, with you CC'd, that introduces the needed CMake magic to
detect if the system supports Posix clocks. Please wait until that patch lands
before committing this one. The CMake snippet in this patch should look like
below to ensure that this test gets built only on systems with Posix clocks.

	if(PIGLIT_HAS_POSIX_CLOCKS)
		piglit_add_executable(my-test-name ...)
	endif()

After that, you can remove all the "requires Posix" comments in the test.

> +/* One second in nanoseconds */
> +#define ONE_SECOND 1000000000
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +	bool pass = true;
> +	GLsync fence1,  fence2,  fence3;
> +	GLenum status1, status2, status3;
> +	/* requires Posix clock API
> +	timespec startTime, endTime;
> +	int timeStatus = -1, seconds_elapsed = -1;
> +	*/
> +
> +	if (piglit_get_gl_version() < 32) {
> +		piglit_require_extension("GL_ARB_sync");
> +	}
> +
> +	/* Test Case 1: Verify that fence times out correctly after set time */
> +
> +	/* queue a draw command */
> +	piglit_draw_rect(-1, -1, 2, 2);
> +
> +	/* create fence sync */
> +	fence1 = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
> +
> +	/* check fence status */
> +	status1 = glClientWaitSync(fence1, GL_SYNC_FLUSH_COMMANDS_BIT,
> +					ONE_SECOND);
> +
> +	/* requires Posix clock API
> +	timeStatus = clock_gettime(CLOCK_MONOTONIC, &startTime);
> +	if (timeStatus != 0) {
> +		printf("Intial clock time not set correctly\n");
> +		piglit_report_result(PIGLIT_FAIL);
> +	}
> +	*/

The test must get the start timestamp immediately before calling glClientWaitSync!
The way this patch is currently written, startTime and endTime will always be
*very* close, because there is no blocking before the first call to clock_gettime()
and the second call.

> +
> +	/* draw call should not be complete since glFlush() wasn't called */
> +	if (status1 != GL_TIMEOUT_EXPIRED) {
> +		printf("Expected: status1 == GL_TIMEOUT_EXPIRED\n"
> +			"Actual: status1 == %s\n",
> +			piglit_get_gl_enum_name(status1));
> +		pass = false;
> +	}
> +
> +	/* requires Posix clock API
> +	timeStatus = clock_gettime(CLOCK_MONOTONIC, &endTime);
> +	if (timeStatus != 0) {
> +		printf("End clock time not set correctly\n");
> +		piglit_report_result(PIGLIT_FAIL);
> +	}
> +	seconds_elapsed = endTime.tv_sec - startTime.tv_sec;
> +	if (seconds_elapsed < 1) { //TODO: how to check for significantly greater?
> +		printf("Expected: wait = 1 second\n"
> +			"Actual: wait = %d seconds", seconds_elapsed);
> +	}
> +	*/
> +
> +	/* clean up */
> +	glFlush();
> +	glDeleteSync(fence1);
> +
> +	/* Test Case 2: Verify that fence times out correctly with no timeout */
> +
> +	/* queue a draw command */
> +	piglit_draw_rect(-1, -1, 2, 2);
> +
> +	/* create fence sync */
> +	fence2 = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
> +
> +	/* check fence status */
> +	status2 = glClientWaitSync(fence2, GL_SYNC_FLUSH_COMMANDS_BIT,
> +					0);
> +
> +	/* requires Posix clock API
> +	timeStatus = clock_gettime(CLOCK_MONOTONIC, &startTime);
> +	if (timeStatus != 0) {
> +		printf("Intial clock time not set correctly\n");
> +		piglit_report_result(PIGLIT_FAIL);
> +	}
> +	*/

Same problem for testcase 2. Get startTime immediately before calling glClientWaitSync.

> +
> +	/* ClientWaitSync() should have returned immediately */
> +	if (status2 != GL_TIMEOUT_EXPIRED) {
> +		printf("Expected: status2 == GL_TIMEOUT_EXPIRED\n"
> +			"Actual: status2 == %s\n",
> +			piglit_get_gl_enum_name(status2));
> +		pass = false;
> +	}
> +
> +	/* requires Posix clock API
> +	timeStatus = clock_gettime(CLOCK_MONOTONIC, &endTime);
> +	if (timeStatus != 0) {
> +		printf("End clock time not set correctly\n");
> +		piglit_report_result(PIGLIT_FAIL);
> +	}
> +	seconds_elapsed = endTime.tv_sec - startTime.tv_sec;
> +	if (seconds_elapsed < .001) {

This comparison doesn't work as expected. The value tv_sec is an integral
number of seconds, according to this snippet from the clock_gettime manpage.

            struct timespec {
                time_t   tv_sec;        /* seconds */
                long     tv_nsec;       /* nanoseconds */
            };

So, if 0.9999 seconds elapsed, the test should fail but endTime.tv_sec - startTime.tv_sec
will be 0. I think the cleanest way to fix the arithmetic problem is to
define this small utility function, and use it whenever you need to subtract times.

static void timespec_sub(struct timespec *result, struct timespec a, struct timespec b)
{
	// Convert a and b to struct timeval, call timersub(3), then convert result
	// back to struct timespec.
}

> +		printf("Expected: wait < .001 second\n"
> +			"Actual: wait = %d seconds", seconds_elapsed);
> +	}
> +	*/
> +
> +	/* clean up */
> +	glFlush();
> +	glDeleteSync(fence2);
> +
> +	/* Test Case 3: Verify fence was already signaled after glFinish() */
> +
> +	/* queue a draw command */
> +	piglit_draw_rect(-1, -1, 2, 2);
> +
> +	/* create fence sync */
> +	fence3 = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
> +
> +	/* flush the command stream */
> +	glFinish();
> +
> +	/* check fence status */
> +	status3 = glClientWaitSync(fence2, GL_SYNC_FLUSH_COMMANDS_BIT,
> +					0);
> +
> +	/* fence should have been already signaled */
> +	if (status3 != GL_ALREADY_SIGNALED) {
> +		printf("Expected: status3 == GL_ALREADY_SIGNALED\n"
> +			"Actual: status3 == %s\n",
> +			piglit_get_gl_enum_name(status3));
> +		pass = false;
> +	}
> +
> +	/* clean up */
> +	glFlush();
> +	glDeleteSync(fence3);
> +
> +	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
> +}
>



More information about the Piglit mailing list