[Mesa-dev] [PATCH 5/8] gallium: add pipe_context::pin_threads_to_L3_cache for AMD Zen
Marek Olšák
maraeo at gmail.com
Thu Sep 6 04:02:26 UTC 2018
From: Marek Olšák <marek.olsak at amd.com>
State trackers will not use this directly, but will instead use a helper
in MakeCurrent that does the right thing.
---
.../auxiliary/driver_ddebug/dd_context.c | 10 ++++++++++
src/gallium/auxiliary/driver_noop/noop_pipe.c | 6 ++++++
.../auxiliary/driver_trace/tr_context.c | 18 ++++++++++++++++++
src/gallium/include/pipe/p_context.h | 9 +++++++++
4 files changed, 43 insertions(+)
diff --git a/src/gallium/auxiliary/driver_ddebug/dd_context.c b/src/gallium/auxiliary/driver_ddebug/dd_context.c
index a1b6c971e89..51719b6679b 100644
--- a/src/gallium/auxiliary/driver_ddebug/dd_context.c
+++ b/src/gallium/auxiliary/driver_ddebug/dd_context.c
@@ -752,20 +752,29 @@ dd_context_delete_image_handle(struct pipe_context *_pipe, uint64_t handle)
static void
dd_context_make_image_handle_resident(struct pipe_context *_pipe,
uint64_t handle, unsigned access,
bool resident)
{
struct pipe_context *pipe = dd_context(_pipe)->pipe;
pipe->make_image_handle_resident(pipe, handle, access, resident);
}
+static void
+dd_context_pin_threads_to_L3_cache(struct pipe_context *_pipe,
+ unsigned cache)
+{
+ struct pipe_context *pipe = dd_context(_pipe)->pipe;
+
+ pipe->pin_threads_to_L3_cache(pipe, cache);
+}
+
struct pipe_context *
dd_context_create(struct dd_screen *dscreen, struct pipe_context *pipe)
{
struct dd_context *dctx;
if (!pipe)
return NULL;
dctx = CALLOC_STRUCT(dd_context);
if (!dctx)
@@ -855,20 +864,21 @@ dd_context_create(struct dd_screen *dscreen, struct pipe_context *pipe)
CTX_INIT(get_device_reset_status);
CTX_INIT(set_device_reset_callback);
CTX_INIT(dump_debug_state);
CTX_INIT(emit_string_marker);
CTX_INIT(create_texture_handle);
CTX_INIT(delete_texture_handle);
CTX_INIT(make_texture_handle_resident);
CTX_INIT(create_image_handle);
CTX_INIT(delete_image_handle);
CTX_INIT(make_image_handle_resident);
+ CTX_INIT(pin_threads_to_L3_cache);
dd_init_draw_functions(dctx);
u_log_context_init(&dctx->log);
if (pipe->set_log_context)
pipe->set_log_context(pipe, &dctx->log);
dctx->draw_state.sample_mask = ~0;
list_inithead(&dctx->records);
diff --git a/src/gallium/auxiliary/driver_noop/noop_pipe.c b/src/gallium/auxiliary/driver_noop/noop_pipe.c
index 7de3e882398..a8d7d16a696 100644
--- a/src/gallium/auxiliary/driver_noop/noop_pipe.c
+++ b/src/gallium/auxiliary/driver_noop/noop_pipe.c
@@ -305,20 +305,25 @@ static boolean noop_generate_mipmap(struct pipe_context *ctx,
unsigned last_layer)
{
return true;
}
static void noop_invalidate_resource(struct pipe_context *ctx,
struct pipe_resource *resource)
{
}
+static void noop_pin_threads_to_L3_cache(struct pipe_context *ctx,
+ unsigned L3_cache_index)
+{
+}
+
static struct pipe_context *noop_create_context(struct pipe_screen *screen,
void *priv, unsigned flags)
{
struct pipe_context *ctx = CALLOC_STRUCT(pipe_context);
if (!ctx)
return NULL;
ctx->screen = screen;
ctx->priv = priv;
@@ -344,20 +349,21 @@ static struct pipe_context *noop_create_context(struct pipe_screen *screen,
ctx->begin_query = noop_begin_query;
ctx->end_query = noop_end_query;
ctx->get_query_result = noop_get_query_result;
ctx->set_active_query_state = noop_set_active_query_state;
ctx->transfer_map = noop_transfer_map;
ctx->transfer_flush_region = noop_transfer_flush_region;
ctx->transfer_unmap = noop_transfer_unmap;
ctx->buffer_subdata = noop_buffer_subdata;
ctx->texture_subdata = noop_texture_subdata;
ctx->invalidate_resource = noop_invalidate_resource;
+ ctx->pin_threads_to_L3_cache = noop_pin_threads_to_L3_cache;
noop_init_state_functions(ctx);
return ctx;
}
/*
* pipe_screen
*/
static void noop_flush_frontbuffer(struct pipe_screen *_screen,
diff --git a/src/gallium/auxiliary/driver_trace/tr_context.c b/src/gallium/auxiliary/driver_trace/tr_context.c
index dc091aee2e9..13f147316f3 100644
--- a/src/gallium/auxiliary/driver_trace/tr_context.c
+++ b/src/gallium/auxiliary/driver_trace/tr_context.c
@@ -1569,20 +1569,37 @@ trace_context_invalidate_resource(struct pipe_context *_context,
trace_dump_call_begin("pipe_context", "invalidate_resource");
trace_dump_arg(ptr, context);
trace_dump_arg(ptr, resource);
trace_dump_call_end();
context->invalidate_resource(context, resource);
}
+static void
+trace_context_pin_threads_to_L3_cache(struct pipe_context *_context,
+ unsigned cache)
+{
+ struct trace_context *tr_context = trace_context(_context);
+ struct pipe_context *context = tr_context->pipe;
+
+ trace_dump_call_begin("pipe_context", "pin_threads_to_L3_cache");
+
+ trace_dump_arg(ptr, context);
+ trace_dump_arg(uint, cache);
+
+ trace_dump_call_end();
+
+ context->pin_threads_to_L3_cache(context, cache);
+}
+
static void
trace_context_render_condition(struct pipe_context *_context,
struct pipe_query *query,
boolean condition,
enum pipe_render_cond_flag mode)
{
struct trace_context *tr_context = trace_context(_context);
struct pipe_context *context = tr_context->pipe;
query = trace_query_unwrap(query);
@@ -1941,20 +1958,21 @@ trace_context_create(struct trace_screen *tr_scr,
TR_CTX_INIT(create_image_handle);
TR_CTX_INIT(delete_image_handle);
TR_CTX_INIT(make_image_handle_resident);
TR_CTX_INIT(transfer_map);
TR_CTX_INIT(transfer_unmap);
TR_CTX_INIT(transfer_flush_region);
TR_CTX_INIT(buffer_subdata);
TR_CTX_INIT(texture_subdata);
TR_CTX_INIT(invalidate_resource);
+ TR_CTX_INIT(pin_threads_to_L3_cache);
#undef TR_CTX_INIT
tr_ctx->pipe = pipe;
return &tr_ctx->base;
error1:
return pipe;
}
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index 7cf037f1abd..211812fe1a6 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -920,18 +920,27 @@ struct pipe_context {
/**
* Call the given function from the driver thread.
*
* This is set by threaded contexts for use by debugging wrappers.
*
* \param asap if true, run the callback immediately if there are no pending
* commands to be processed by the driver thread
*/
void (*callback)(struct pipe_context *ctx, void (*fn)(void *), void *data,
bool asap);
+
+ /**
+ * A hint for the driver that it should pin its execution threads to
+ * a group of cores sharing a specific L3 cache if the CPU has multiple
+ * L3 caches. This is needed for good multithreading performance on
+ * AMD Zen CPUs.
+ */
+ void (*pin_threads_to_L3_cache)(struct pipe_context *ctx,
+ unsigned L3_cache_index);
};
#ifdef __cplusplus
}
#endif
#endif /* PIPE_CONTEXT_H */
--
2.17.1
More information about the mesa-dev
mailing list