[Mesa-dev] [PATCH] gallium/u_tests: test sync_file fences
Nicolai Hähnle
nhaehnle at gmail.com
Mon Oct 2 09:43:15 UTC 2017
On 29.09.2017 14:26, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> This should be sufficient for testing all kernel/libdrm/radeonsi codepaths
> that are used by radeonsi.
Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
> ---
> src/gallium/auxiliary/util/u_tests.c | 101 +++++++++++++++++++++++++++++++++++
> 1 file changed, 101 insertions(+)
>
> diff --git a/src/gallium/auxiliary/util/u_tests.c b/src/gallium/auxiliary/util/u_tests.c
> index 60e77b2..2e931c0 100644
> --- a/src/gallium/auxiliary/util/u_tests.c
> +++ b/src/gallium/auxiliary/util/u_tests.c
> @@ -483,30 +483,131 @@ null_fragment_shader(struct pipe_context *ctx)
> /* Cleanup. */
> cso_destroy_context(cso);
> ctx->delete_vs_state(ctx, vs);
> ctx->destroy_query(ctx, query);
> pipe_resource_reference(&cb, NULL);
>
> /* Check PRIMITIVES_GENERATED. */
> util_report_result(qresult.u64 == 2);
> }
>
> +#ifdef PIPE_OS_LINUX
> +#include <libsync.h>
> +#else
> +#define sync_merge(str, fd1, fd2) (-1)
> +#define sync_wait(fd, timeout) (-1)
> +#endif
> +
> +static void
> +test_sync_file_fences(struct pipe_context *ctx)
> +{
> + struct pipe_screen *screen = ctx->screen;
> + bool pass = true;
> +
> + if (!screen->get_param(screen, PIPE_CAP_NATIVE_FENCE_FD))
> + return;
> +
> + struct cso_context *cso = cso_create_context(ctx, 0);
> + struct pipe_resource *buf =
> + pipe_buffer_create(screen, 0, PIPE_USAGE_DEFAULT, 1024 * 1024);
> + struct pipe_resource *tex =
> + util_create_texture2d(screen, 4096, 1024, PIPE_FORMAT_R8_UNORM);
> + struct pipe_fence_handle *buf_fence = NULL, *tex_fence = NULL;
> +
> + /* Run 2 clears, get fencess. */
> + uint32_t value = 0;
> + ctx->clear_buffer(ctx, buf, 0, buf->width0, &value, sizeof(value));
> + ctx->flush(ctx, &buf_fence, PIPE_FLUSH_FENCE_FD);
> +
> + struct pipe_box box;
> + u_box_2d(0, 0, tex->width0, tex->height0, &box);
> + ctx->clear_texture(ctx, tex, 0, &box, &value);
> + ctx->flush(ctx, &tex_fence, PIPE_FLUSH_FENCE_FD);
> + pass = pass && buf_fence && tex_fence;
> +
> + /* Export fences. */
> + int buf_fd = screen->fence_get_fd(screen, buf_fence);
> + int tex_fd = screen->fence_get_fd(screen, tex_fence);
> + pass = pass && buf_fd >= 0 && tex_fd >= 0;
> +
> + /* Merge fences. */
> + int merged_fd = sync_merge("test", buf_fd, tex_fd);
> + pass = pass && merged_fd >= 0;
> +
> + /* (Re)import all fences. */
> + struct pipe_fence_handle *re_buf_fence = NULL, *re_tex_fence = NULL;
> + struct pipe_fence_handle *merged_fence = NULL;
> + ctx->create_fence_fd(ctx, &re_buf_fence, buf_fd);
> + ctx->create_fence_fd(ctx, &re_tex_fence, tex_fd);
> + ctx->create_fence_fd(ctx, &merged_fence, merged_fd);
> + pass = pass && re_buf_fence && re_tex_fence && merged_fence;
> +
> + /* Run another clear after waiting for everything. */
> + struct pipe_fence_handle *final_fence = NULL;
> + ctx->fence_server_sync(ctx, merged_fence);
> + value = 0xff;
> + ctx->clear_buffer(ctx, buf, 0, buf->width0, &value, sizeof(value));
> + ctx->flush(ctx, &final_fence, PIPE_FLUSH_FENCE_FD);
> + pass = pass && final_fence;
> +
> + /* Wait for the last fence. */
> + int final_fd = screen->fence_get_fd(screen, final_fence);
> + pass = pass && final_fd >= 0;
> + pass = pass && sync_wait(final_fd, -1) == 0;
> +
> + /* Check that all fences are signalled. */
> + pass = pass && sync_wait(buf_fd, 0) == 0;
> + pass = pass && sync_wait(tex_fd, 0) == 0;
> + pass = pass && sync_wait(merged_fd, 0) == 0;
> +
> + pass = pass && screen->fence_finish(screen, NULL, buf_fence, 0);
> + pass = pass && screen->fence_finish(screen, NULL, tex_fence, 0);
> + pass = pass && screen->fence_finish(screen, NULL, re_buf_fence, 0);
> + pass = pass && screen->fence_finish(screen, NULL, re_tex_fence, 0);
> + pass = pass && screen->fence_finish(screen, NULL, merged_fence, 0);
> + pass = pass && screen->fence_finish(screen, NULL, final_fence, 0);
> +
> + /* Cleanup. */
> + if (buf_fd >= 0)
> + close(buf_fd);
> + if (tex_fd >= 0)
> + close(tex_fd);
> + if (merged_fd >= 0)
> + close(merged_fd);
> + if (final_fd >= 0)
> + close(final_fd);
> +
> + screen->fence_reference(screen, &buf_fence, NULL);
> + screen->fence_reference(screen, &tex_fence, NULL);
> + screen->fence_reference(screen, &re_buf_fence, NULL);
> + screen->fence_reference(screen, &re_tex_fence, NULL);
> + screen->fence_reference(screen, &merged_fence, NULL);
> + screen->fence_reference(screen, &final_fence, NULL);
> +
> + cso_destroy_context(cso);
> + pipe_resource_reference(&buf, NULL);
> + pipe_resource_reference(&tex, NULL);
> +
> + util_report_result(pass);
> +}
> +
> /**
> * Run all tests. This should be run with a clean context after
> * context_create.
> */
> void
> util_run_tests(struct pipe_screen *screen)
> {
> struct pipe_context *ctx = screen->context_create(screen, NULL, 0);
>
> null_fragment_shader(ctx);
> tgsi_vs_window_space_position(ctx);
> null_sampler_view(ctx, TGSI_TEXTURE_2D);
> null_sampler_view(ctx, TGSI_TEXTURE_BUFFER);
> util_test_constant_buffer(ctx, NULL);
> + test_sync_file_fences(ctx);
>
> ctx->destroy(ctx);
>
> puts("Done. Exiting..");
> exit(0);
> }
>
--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
More information about the mesa-dev
mailing list