summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/state_tracker/st_context.h2
-rw-r--r--src/mesa/state_tracker/st_draw.c32
2 files changed, 34 insertions, 0 deletions
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
@@ -193,6 +193,8 @@ struct st_context
/** 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.
*/
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
@@ -58,6 +58,7 @@
#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"
@@ -66,6 +67,13 @@
#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.
@@ -122,6 +130,30 @@ prepare_draw(struct st_context *st, struct gl_context *ctx)
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);
+ }
+ }
}
/**