[Mesa-stable] [PATCH 1/2] gallium/drivers: Add threadsafe wrappers for pipe_context v2
Tom Stellard
thomas.stellard at amd.com
Fri Jul 10 18:55:04 PDT 2015
These wrappers can be used by state trackers to ensure threadsafe access
to pipe_context objects.
v2:
- Don't add wrappers for pipe_screen.
- Build system cleanups
CC: 10.6 <mesa-stable at lists.freedesktop.org>
---
configure.ac | 1 +
src/gallium/Makefile.am | 1 +
src/gallium/SConscript | 1 +
src/gallium/drivers/threadsafe/Makefile.am | 11 +
src/gallium/drivers/threadsafe/Makefile.sources | 3 +
src/gallium/drivers/threadsafe/SConscript | 13 +
src/gallium/drivers/threadsafe/threadsafe.h | 37 +++
.../drivers/threadsafe/threadsafe_context.c | 276 +++++++++++++++++++++
8 files changed, 343 insertions(+)
create mode 100644 src/gallium/drivers/threadsafe/Makefile.am
create mode 100644 src/gallium/drivers/threadsafe/Makefile.sources
create mode 100644 src/gallium/drivers/threadsafe/SConscript
create mode 100644 src/gallium/drivers/threadsafe/threadsafe.h
create mode 100644 src/gallium/drivers/threadsafe/threadsafe_context.c
diff --git a/configure.ac b/configure.ac
index d819bef..6f93a2e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2358,6 +2358,7 @@ AC_CONFIG_FILES([Makefile
src/gallium/drivers/rbug/Makefile
src/gallium/drivers/softpipe/Makefile
src/gallium/drivers/svga/Makefile
+ src/gallium/drivers/threadsafe/Makefile
src/gallium/drivers/trace/Makefile
src/gallium/drivers/vc4/Makefile
src/gallium/state_trackers/clover/Makefile
diff --git a/src/gallium/Makefile.am b/src/gallium/Makefile.am
index ede6e21..2290583 100644
--- a/src/gallium/Makefile.am
+++ b/src/gallium/Makefile.am
@@ -12,6 +12,7 @@ SUBDIRS += auxiliary
SUBDIRS += \
drivers/noop \
+ drivers/threadsafe \
drivers/trace \
drivers/rbug
diff --git a/src/gallium/SConscript b/src/gallium/SConscript
index eeb1c78..e6070b6 100644
--- a/src/gallium/SConscript
+++ b/src/gallium/SConscript
@@ -17,6 +17,7 @@ SConscript([
'drivers/softpipe/SConscript',
'drivers/svga/SConscript',
'drivers/trace/SConscript',
+ 'drivers/threadsafe/SConscript',
])
#
diff --git a/src/gallium/drivers/threadsafe/Makefile.am b/src/gallium/drivers/threadsafe/Makefile.am
new file mode 100644
index 0000000..bab64bf
--- /dev/null
+++ b/src/gallium/drivers/threadsafe/Makefile.am
@@ -0,0 +1,11 @@
+include Makefile.sources
+include $(top_srcdir)/src/gallium/Automake.inc
+
+AM_CFLAGS = \
+ $(GALLIUM_DRIVER_CFLAGS)
+
+noinst_LTLIBRARIES = libthreadsafe.la
+
+libthreadsafe_la_SOURCES = $(C_SOURCES)
+
+EXTRA_DIST = SConscript
diff --git a/src/gallium/drivers/threadsafe/Makefile.sources b/src/gallium/drivers/threadsafe/Makefile.sources
new file mode 100644
index 0000000..5e8778e
--- /dev/null
+++ b/src/gallium/drivers/threadsafe/Makefile.sources
@@ -0,0 +1,3 @@
+C_SOURCES := \
+ threadsafe.h \
+ threadsafe_context.c
diff --git a/src/gallium/drivers/threadsafe/SConscript b/src/gallium/drivers/threadsafe/SConscript
new file mode 100644
index 0000000..bc3333e
--- /dev/null
+++ b/src/gallium/drivers/threadsafe/SConscript
@@ -0,0 +1,13 @@
+#######################################################################
+# SConscript for noop convenience library
+
+Import('*')
+
+env = env.Clone()
+
+threadsafe = env.ConvenienceLibrary(
+ target = 'threadsafe',
+ source = env.ParseSourceList('Makefile.sources', 'C_SOURCES')
+ ) + extra
+
+Export('threadsafe')
diff --git a/src/gallium/drivers/threadsafe/threadsafe.h b/src/gallium/drivers/threadsafe/threadsafe.h
new file mode 100644
index 0000000..60614ed
--- /dev/null
+++ b/src/gallium/drivers/threadsafe/threadsafe.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ *
+ * Authors: Tom Stellard <thomas.stellard at amd.com>
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct pipe_context;
+
+struct pipe_context *pipe_threadsafe_context(struct pipe_context *ctx);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/gallium/drivers/threadsafe/threadsafe_context.c b/src/gallium/drivers/threadsafe/threadsafe_context.c
new file mode 100644
index 0000000..070adc5
--- /dev/null
+++ b/src/gallium/drivers/threadsafe/threadsafe_context.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ *
+ * Authors: Tom Stellard <thomas.stellard at amd.com>
+ *
+ */
+
+#include <stdio.h>
+
+/**
+ * \file
+ *
+ * threadsafe_context is a wrapper around a pipe_context to make it thread
+ * safe.
+ *
+ * TODO: Implement all gallium functions. Only the functions required by the
+ * clover state tracker have been implemented.
+ */
+
+#include "os/os_thread.h"
+#include "pipe/p_context.h"
+#include "util/u_memory.h"
+
+#include "threadsafe.h"
+
+
+
+struct threadsafe_context {
+ struct pipe_context base;
+ struct pipe_context *ctx;
+ pipe_mutex mutex;
+};
+
+static struct pipe_context *unwrap(struct pipe_context *ctx) {
+ if (!ctx)
+ return NULL;
+ struct threadsafe_context *ts_ctx = (struct threadsafe_context*)ctx;
+ return ts_ctx->ctx;
+}
+
+#define THREADSAFE_CALL_VOID(ctx, function) \
+ struct threadsafe_context *ts_ctx = (struct threadsafe_context*)(ctx); \
+ pipe_mutex_lock(ts_ctx->mutex); \
+ (unwrap(ctx)->function); \
+ pipe_mutex_unlock(ts_ctx->mutex);
+
+#define THREADSAFE_CALL_RET(ctx, return_type, function) \
+ struct threadsafe_context *ts_ctx = (struct threadsafe_context*)(ctx); \
+ pipe_mutex_lock(ts_ctx->mutex); \
+ return_type ret = (unwrap(ctx)->function); \
+ pipe_mutex_unlock(ts_ctx->mutex); \
+ return ret;
+
+
+static void threadsafe_destroy(struct pipe_context *ctx) {
+ THREADSAFE_CALL_VOID(ctx, destroy(unwrap(ctx)));
+ FREE(ctx);
+}
+
+static void *threadsafe_create_sampler_state(struct pipe_context *ctx,
+ const struct pipe_sampler_state *state) {
+ THREADSAFE_CALL_RET(ctx, void*, create_sampler_state(unwrap(ctx), state));
+}
+
+static struct pipe_query *threadsafe_create_query(struct pipe_context *ctx,
+ unsigned query_type,
+ unsigned index) {
+ THREADSAFE_CALL_RET(ctx, struct pipe_query*,
+ create_query(unwrap(ctx), query_type, index));
+}
+
+static void threadsafe_bind_compute_state(struct pipe_context *ctx,
+ void * state) {
+ THREADSAFE_CALL_VOID(ctx, bind_compute_state(unwrap(ctx), state));
+}
+
+static void threadsafe_bind_sampler_states(struct pipe_context *ctx,
+ unsigned shader, unsigned start_slot,
+ unsigned num_samplers,
+ void **samplers) {
+ THREADSAFE_CALL_VOID(ctx,
+ bind_sampler_states(unwrap(ctx), shader, start_slot, num_samplers,
+ samplers));
+}
+
+static void threadsafe_set_sampler_views(struct pipe_context *ctx,
+ unsigned shader, unsigned start_slot,
+ unsigned num_views,
+ struct pipe_sampler_view ** views) {
+ THREADSAFE_CALL_VOID(ctx,
+ set_sampler_views(unwrap(ctx), shader, start_slot, num_views, views));
+}
+
+
+static void threadsafe_set_compute_resources(struct pipe_context *ctx,
+ unsigned start, unsigned count,
+ struct pipe_surface **resources) {
+ THREADSAFE_CALL_VOID(ctx,
+ set_compute_resources(unwrap(ctx), start, count, resources));
+}
+
+static void threadsafe_set_global_binding(struct pipe_context *ctx,
+ unsigned first, unsigned count,
+ struct pipe_resource **resources,
+ uint32_t **handles) {
+ THREADSAFE_CALL_VOID(ctx,
+ set_global_binding(unwrap(ctx), first, count, resources, handles));
+}
+
+static void threadsafe_launch_grid(struct pipe_context *ctx,
+ const uint *block_layout,
+ const uint *grid_layout,
+ uint32_t pc, const void *input) {
+ THREADSAFE_CALL_VOID(ctx,
+ launch_grid(unwrap(ctx), block_layout, grid_layout, pc, input));
+}
+
+static void threadsafe_delete_compute_state(struct pipe_context *ctx,
+ void *state) {
+ THREADSAFE_CALL_VOID(ctx, delete_compute_state(unwrap(ctx), state));
+}
+
+static void *threadsafe_create_compute_state(struct pipe_context *ctx,
+ const struct pipe_compute_state *state) {
+ THREADSAFE_CALL_RET(ctx, void*, create_compute_state(unwrap(ctx), state));
+}
+
+static void threadsafe_flush(struct pipe_context *ctx,
+ struct pipe_fence_handle **fence,
+ unsigned flags) {
+ THREADSAFE_CALL_VOID(ctx, flush(unwrap(ctx), fence, flags));
+}
+
+static struct pipe_sampler_view *threadsafe_create_sampler_view(
+ struct pipe_context *ctx,
+ struct pipe_resource *texture,
+ const struct pipe_sampler_view *templat) {
+ THREADSAFE_CALL_RET(ctx, struct pipe_sampler_view*,
+ create_sampler_view(unwrap(ctx), texture, templat));
+}
+
+static void threadsafe_resource_copy_region(struct pipe_context *ctx,
+ struct pipe_resource *dst,
+ unsigned dst_level,
+ unsigned dstx, unsigned dsty, unsigned dstz,
+ struct pipe_resource *src,
+ unsigned src_level,
+ const struct pipe_box *src_box) {
+ THREADSAFE_CALL_VOID(ctx,
+ resource_copy_region(unwrap(ctx), dst, dst_level, dstx, dsty, dstz, src,
+ src_level, src_box));
+}
+
+static void threadsafe_sampler_view_destroy(struct pipe_context *ctx,
+ struct pipe_sampler_view *view) {
+ THREADSAFE_CALL_VOID(ctx, sampler_view_destroy(unwrap(ctx), view));
+}
+
+static struct pipe_surface *threadsafe_create_surface(struct pipe_context *ctx,
+ struct pipe_resource *resource,
+ const struct pipe_surface *templat) {
+ THREADSAFE_CALL_RET(ctx, struct pipe_surface*,
+ create_surface(unwrap(ctx), resource, templat));
+}
+
+
+static void threadsafe_surface_destroy(struct pipe_context *ctx,
+ struct pipe_surface *surface) {
+ THREADSAFE_CALL_VOID(ctx, surface_destroy(unwrap(ctx), surface));
+}
+
+static void threadsafe_transfer_inline_write(struct pipe_context *ctx,
+ struct pipe_resource *resource,
+ unsigned level, unsigned usage,
+ const struct pipe_box *pipe_box,
+ const void *data,
+ unsigned stride,
+ unsigned layer_stride) {
+ THREADSAFE_CALL_VOID(ctx,
+ transfer_inline_write(unwrap(ctx), resource, level, usage, pipe_box, data,
+ stride, layer_stride));
+}
+
+static void *threadsafe_transfer_map(struct pipe_context *ctx,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box,
+ struct pipe_transfer **out_transfer) {
+ THREADSAFE_CALL_RET(ctx, void*,
+ transfer_map(unwrap(ctx), resource, level, usage, box, out_transfer));
+}
+
+static void threadsafe_transfer_unmap(struct pipe_context *ctx,
+ struct pipe_transfer *transfer) {
+ THREADSAFE_CALL_VOID(ctx, transfer_unmap(unwrap(ctx), transfer));
+}
+
+static void threadsafe_delete_sampler_state(struct pipe_context *ctx,
+ void *state) {
+ THREADSAFE_CALL_VOID(ctx, delete_sampler_state(unwrap(ctx), state));
+}
+
+static void threadsafe_end_query(struct pipe_context *ctx,
+ struct pipe_query *q) {
+ THREADSAFE_CALL_VOID(ctx, end_query(unwrap(ctx), q));
+}
+
+static void threadsafe_destroy_query(struct pipe_context *ctx,
+ struct pipe_query *q) {
+ THREADSAFE_CALL_VOID(ctx, destroy_query(unwrap(ctx), q));
+}
+
+static boolean threadsafe_get_query_result(struct pipe_context *ctx,
+ struct pipe_query *q,
+ boolean wait,
+ union pipe_query_result *result) {
+ THREADSAFE_CALL_RET(ctx, boolean,
+ get_query_result(unwrap(ctx), q, wait, result));
+}
+
+#define INIT_FUNCTION(name) \
+ ts_ctx->base.name = threadsafe_ ## name;
+
+struct pipe_context *pipe_threadsafe_context(struct pipe_context *ctx) {
+ struct threadsafe_context *ts_ctx = CALLOC_STRUCT(threadsafe_context);
+
+ ts_ctx->ctx = ctx;
+ ts_ctx->base.screen = ctx->screen;
+ pipe_mutex_init(ts_ctx->mutex);
+
+ INIT_FUNCTION(destroy);
+ INIT_FUNCTION(create_query);
+ INIT_FUNCTION(bind_compute_state);
+ INIT_FUNCTION(bind_sampler_states);
+ INIT_FUNCTION(set_sampler_views);
+ INIT_FUNCTION(set_compute_resources);
+ INIT_FUNCTION(set_global_binding);
+ INIT_FUNCTION(launch_grid);
+ INIT_FUNCTION(delete_compute_state);
+ INIT_FUNCTION(create_compute_state);
+ INIT_FUNCTION(flush);
+ INIT_FUNCTION(create_sampler_view);
+ INIT_FUNCTION(resource_copy_region);
+ INIT_FUNCTION(sampler_view_destroy);
+ INIT_FUNCTION(create_surface);
+ INIT_FUNCTION(surface_destroy);
+ INIT_FUNCTION(transfer_inline_write);
+ INIT_FUNCTION(transfer_map);
+ INIT_FUNCTION(transfer_unmap);
+ INIT_FUNCTION(create_sampler_state);
+ INIT_FUNCTION(delete_sampler_state);
+ INIT_FUNCTION(end_query);
+ INIT_FUNCTION(destroy_query);
+ INIT_FUNCTION(get_query_result);
+ return &ts_ctx->base;
+}
--
2.0.4
More information about the mesa-stable
mailing list