[Mesa-dev] [PATCH 1/4] gallium: add pipe_context::set_context_param for tuning perf on AMD Zen (v2)

Marek Olšák maraeo at gmail.com
Fri Sep 7 01:04:39 UTC 2018


From: Marek Olšák <marek.olsak at amd.com>

State trackers will not use the new param directly, but will instead use
a helper in MakeCurrent that does the right thing.

v2: rework the interface
---
 .../auxiliary/driver_ddebug/dd_context.c      | 11 ++++++++++
 src/gallium/auxiliary/driver_noop/noop_pipe.c |  7 +++++++
 .../auxiliary/driver_trace/tr_context.c       | 20 +++++++++++++++++++
 src/gallium/include/pipe/p_context.h          |  7 +++++++
 src/gallium/include/pipe/p_defines.h          | 14 +++++++++++++
 5 files changed, 59 insertions(+)

diff --git a/src/gallium/auxiliary/driver_ddebug/dd_context.c b/src/gallium/auxiliary/driver_ddebug/dd_context.c
index a1b6c971e89..a9ac6ef14ab 100644
--- a/src/gallium/auxiliary/driver_ddebug/dd_context.c
+++ b/src/gallium/auxiliary/driver_ddebug/dd_context.c
@@ -752,20 +752,30 @@ 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_set_context_param(struct pipe_context *_pipe,
+                             enum pipe_context_param param,
+                             unsigned value)
+{
+   struct pipe_context *pipe = dd_context(_pipe)->pipe;
+
+   pipe->set_context_param(pipe, param, value);
+}
+
 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 +865,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(set_context_param);
 
    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..a6497f07677 100644
--- a/src/gallium/auxiliary/driver_noop/noop_pipe.c
+++ b/src/gallium/auxiliary/driver_noop/noop_pipe.c
@@ -305,20 +305,26 @@ 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_set_context_param(struct pipe_context *ctx,
+                                   enum pipe_context_param param,
+                                   unsigned value)
+{
+}
+
 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 +350,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->set_context_param = noop_set_context_param;
    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..7859a3395ca 100644
--- a/src/gallium/auxiliary/driver_trace/tr_context.c
+++ b/src/gallium/auxiliary/driver_trace/tr_context.c
@@ -1569,20 +1569,39 @@ 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_set_context_param(struct pipe_context *_context,
+                                enum pipe_context_param param,
+                                unsigned value)
+{
+   struct trace_context *tr_context = trace_context(_context);
+   struct pipe_context *context = tr_context->pipe;
+
+   trace_dump_call_begin("pipe_context", "set_context_param");
+
+   trace_dump_arg(ptr, context);
+   trace_dump_arg(uint, param);
+   trace_dump_arg(uint, value);
+
+   trace_dump_call_end();
+
+   context->set_context_param(context, param, value);
+}
+
 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 +1960,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(set_context_param);
 
 #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..dd1f5ed192c 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -920,18 +920,25 @@ 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);
+
+   /**
+    * Set a context parameter See enum pipe_context_param for more details.
+    */
+   void (*set_context_param)(struct pipe_context *ctx,
+                             enum pipe_context_param param,
+                             unsigned value);
 };
 
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* PIPE_CONTEXT_H */
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index dc6b089c2bf..b494c759b11 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -945,20 +945,34 @@ enum pipe_compute_cap
    PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE,
    PIPE_COMPUTE_CAP_MAX_INPUT_SIZE,
    PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE,
    PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY,
    PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS,
    PIPE_COMPUTE_CAP_IMAGES_SUPPORTED,
    PIPE_COMPUTE_CAP_SUBGROUP_SIZE,
    PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK,
 };
 
+/**
+ * Types of parameters for pipe_context::set_context_param.
+ */
+enum pipe_context_param
+{
+   /* 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. "value" is the L3 cache index. Drivers that don't have
+    * any internal threads or don't run on affected CPUs can ignore this.
+    */
+   PIPE_CONTEXT_PARAM_PIN_THREADS_TO_L3_CACHE,
+};
+
 /**
  * Composite query types
  */
 
 /**
  * Query result for PIPE_QUERY_SO_STATISTICS.
  */
 struct pipe_query_data_so_statistics
 {
    uint64_t num_primitives_written;
-- 
2.17.1



More information about the mesa-dev mailing list