From: Marek Olšák <marek.ol...@amd.com> This is used when glthread is disabled.
Mesa pretty much chases the app thread on the CPU. The performance is the same as pinning the app thread. --- src/mesa/state_tracker/st_context.h | 2 ++ src/mesa/state_tracker/st_draw.c | 32 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 14b9b018809..95133c7020f 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -186,20 +186,22 @@ struct st_context uint8_t sample_locations[ PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE * PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE * 32]; } state; uint64_t dirty; /**< dirty states */ /** This masks out unused shader resources. Only valid in draw calls. */ uint64_t active_states; + unsigned pin_thread_counter; /* for L3 thread pinning on AMD Zen */ + /* If true, further analysis of states is required to know if something * has changed. Used mainly for shaders. */ bool gfx_shaders_may_be_dirty; bool compute_shader_may_be_dirty; GLboolean vertdata_edgeflags; GLboolean edgeflag_culls_prims; struct st_vertex_program *vp; /**< Currently bound vertex program */ diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index eb52d9505b6..5910ffa5bda 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -51,28 +51,36 @@ #include "st_atom.h" #include "st_cb_bitmap.h" #include "st_cb_bufferobjects.h" #include "st_cb_xformfb.h" #include "st_debug.h" #include "st_draw.h" #include "st_program.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" +#include "util/u_cpu_detect.h" #include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_prim.h" #include "util/u_draw.h" #include "util/u_upload_mgr.h" #include "draw/draw_context.h" #include "cso_cache/cso_context.h" +#ifdef PIPE_OS_LINUX +#include <sched.h> +#define HAVE_SCHED_GETCPU 1 +#else +#define sched_getcpu() 0 +#define HAVE_SCHED_GETCPU 0 +#endif /** * Set the restart index. */ static void setup_primitive_restart(struct gl_context *ctx, struct pipe_draw_info *info) { if (ctx->Array._PrimitiveRestart) { unsigned index_size = info->index_size; @@ -115,20 +123,44 @@ prepare_draw(struct st_context *st, struct gl_context *ctx) if (unlikely(!st->bitmap.cache.empty)) st_flush_bitmap_cache(st); st_invalidate_readpix_cache(st); /* Validate state. */ if ((st->dirty | ctx->NewDriverState) & ST_PIPELINE_RENDER_STATE_MASK || st->gfx_shaders_may_be_dirty) { st_validate_state(st, ST_PIPELINE_RENDER); } + + struct pipe_context *pipe = st->pipe; + + /* Pin threads regularly to the same Zen CCX that the main thread is + * running on. The main thread can move between CCXs. + */ + if (unlikely(HAVE_SCHED_GETCPU && /* Linux */ + /* AMD Zen */ + util_cpu_caps.nr_cpus != util_cpu_caps.cores_per_L3 && + /* no glthread */ + ctx->CurrentClientDispatch != ctx->MarshalExec && + /* driver support */ + pipe->set_context_param && + /* do it occasionally */ + ++st->pin_thread_counter % 512 == 0)) { + int cpu = sched_getcpu(); + if (cpu >= 0) { + unsigned L3_cache = cpu / util_cpu_caps.cores_per_L3; + + pipe->set_context_param(pipe, + PIPE_CONTEXT_PARAM_PIN_THREADS_TO_L3_CACHE, + L3_cache); + } + } } /** * This function gets plugged into the VBO module and is called when * we have something to render. * Basically, translate the information into the format expected by gallium. */ static void st_draw_vbo(struct gl_context *ctx, const struct _mesa_prim *prims, -- 2.17.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev