From: Marek Olšák <marek.ol...@amd.com> --- src/gallium/drivers/radeon/radeon_winsys.h | 8 ++++++++ src/gallium/drivers/radeonsi/si_pipe.c | 8 ++++++++ src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c | 10 ++++++++++ src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 13 +++++++++++++ 4 files changed, 39 insertions(+)
diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h index b75a2331b95..5ac75b70e77 100644 --- a/src/gallium/drivers/radeon/radeon_winsys.h +++ b/src/gallium/drivers/radeon/radeon_winsys.h @@ -251,20 +251,28 @@ struct radeon_winsys { /** * Query an info structure from winsys. * * \param ws The winsys this function is called from. * \param info Return structure */ void (*query_info)(struct radeon_winsys *ws, struct radeon_info *info); + /** + * A hint for the winsys 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 radeon_winsys *ws, unsigned cache); + /************************************************************************** * Buffer management. Buffer attributes are mostly fixed over its lifetime. * * Remember that gallium gets to choose the interface it needs, and the * window systems must then implement that interface (rather than the * other way around...). *************************************************************************/ /** * Create a buffer object. diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 9156f3e708c..f8e5df9b382 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -345,40 +345,48 @@ static void si_set_debug_callback(struct pipe_context *ctx, static void si_set_log_context(struct pipe_context *ctx, struct u_log_context *log) { struct si_context *sctx = (struct si_context *)ctx; sctx->log = log; if (log) u_log_add_auto_logger(log, si_auto_log_cs, sctx); } +static void si_pin_threads_to_L3_cache(struct pipe_context *ctx, unsigned cache) +{ + struct radeon_winsys *ws = ((struct si_context *)ctx)->ws; + + ws->pin_threads_to_L3_cache(ws, cache); +} + static struct pipe_context *si_create_context(struct pipe_screen *screen, unsigned flags) { struct si_context *sctx = CALLOC_STRUCT(si_context); struct si_screen* sscreen = (struct si_screen *)screen; struct radeon_winsys *ws = sscreen->ws; int shader, i; if (!sctx) return NULL; if (flags & PIPE_CONTEXT_DEBUG) sscreen->record_llvm_ir = true; /* racy but not critical */ sctx->b.screen = screen; /* this must be set first */ sctx->b.priv = NULL; sctx->b.destroy = si_destroy_context; sctx->b.emit_string_marker = si_emit_string_marker; sctx->b.set_debug_callback = si_set_debug_callback; sctx->b.set_log_context = si_set_log_context; + sctx->b.pin_threads_to_L3_cache = si_pin_threads_to_L3_cache; sctx->screen = sscreen; /* Easy accessing of screen/winsys. */ sctx->is_debug = (flags & PIPE_CONTEXT_DEBUG) != 0; slab_create_child(&sctx->pool_transfers, &sscreen->pool_transfers); slab_create_child(&sctx->pool_transfers_unsync, &sscreen->pool_transfers); sctx->ws = sscreen->ws; sctx->family = sscreen->info.family; sctx->chip_class = sscreen->info.chip_class; diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c index dcbc075e3c5..f32bbd9d086 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c @@ -23,20 +23,21 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. */ #include "amdgpu_cs.h" #include "amdgpu_public.h" +#include "util/u_cpu_detect.h" #include "util/u_hash_table.h" #include "util/hash_table.h" #include "util/xmlconfig.h" #include <amdgpu_drm.h> #include <xf86drm.h> #include <stdio.h> #include <sys/stat.h> #include "amd/common/sid.h" #include "amd/common/gfx9d.h" @@ -228,20 +229,28 @@ static bool amdgpu_winsys_unref(struct radeon_winsys *rws) simple_mtx_unlock(&dev_tab_mutex); return destroy; } static const char* amdgpu_get_chip_name(struct radeon_winsys *ws) { amdgpu_device_handle dev = ((struct amdgpu_winsys *)ws)->dev; return amdgpu_get_marketing_name(dev); } +static void amdgpu_pin_threads_to_L3_cache(struct radeon_winsys *rws, + unsigned cache) +{ + struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws; + + util_pin_thread_to_L3(ws->cs_queue.threads[0], cache, + util_cpu_caps.cores_per_L3); +} PUBLIC struct radeon_winsys * amdgpu_winsys_create(int fd, const struct pipe_screen_config *config, radeon_screen_create_t screen_create) { struct amdgpu_winsys *ws; drmVersionPtr version = drmGetVersion(fd); amdgpu_device_handle dev; uint32_t drm_major, drm_minor, r; @@ -307,20 +316,21 @@ amdgpu_winsys_create(int fd, const struct pipe_screen_config *config, pipe_reference_init(&ws->reference, 1); /* Set functions. */ ws->base.unref = amdgpu_winsys_unref; ws->base.destroy = amdgpu_winsys_destroy; ws->base.query_info = amdgpu_winsys_query_info; ws->base.cs_request_feature = amdgpu_cs_request_feature; ws->base.query_value = amdgpu_query_value; ws->base.read_registers = amdgpu_read_registers; ws->base.get_chip_name = amdgpu_get_chip_name; + ws->base.pin_threads_to_L3_cache = amdgpu_pin_threads_to_L3_cache; amdgpu_bo_init_functions(ws); amdgpu_cs_init_functions(ws); amdgpu_surface_init_functions(ws); LIST_INITHEAD(&ws->global_bo_list); ws->bo_export_table = util_hash_table_create(hash_pointer, compare_pointers); (void) simple_mtx_init(&ws->global_bo_list_lock, mtx_plain); (void) simple_mtx_init(&ws->bo_fence_lock, mtx_plain); diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c index 0c41e1397c7..cf07a8d8e26 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c @@ -22,20 +22,21 @@ * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. */ #include "radeon_drm_bo.h" #include "radeon_drm_cs.h" #include "radeon_drm_public.h" +#include "util/u_cpu_detect.h" #include "util/u_memory.h" #include "util/u_hash_table.h" #include <xf86drm.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <radeon_surface.h> @@ -796,20 +797,31 @@ static bool radeon_winsys_unref(struct radeon_winsys *ws) static unsigned handle_hash(void *key) { return PTR_TO_UINT(key); } static int handle_compare(void *key1, void *key2) { return PTR_TO_UINT(key1) != PTR_TO_UINT(key2); } +static void radeon_pin_threads_to_L3_cache(struct radeon_winsys *ws, + unsigned cache) +{ + struct radeon_drm_winsys *rws = (struct radeon_drm_winsys*)ws; + + if (util_queue_is_initialized(&rws->cs_queue)) { + util_pin_thread_to_L3(rws->cs_queue.threads[0], cache, + util_cpu_caps.cores_per_L3); + } +} + PUBLIC struct radeon_winsys * radeon_drm_winsys_create(int fd, const struct pipe_screen_config *config, radeon_screen_create_t screen_create) { struct radeon_drm_winsys *ws; mtx_lock(&fd_tab_mutex); if (!fd_tab) { fd_tab = util_hash_table_create(hash_fd, compare_fd); } @@ -863,20 +875,21 @@ radeon_drm_winsys_create(int fd, const struct pipe_screen_config *config, goto fail_slab; } /* init reference */ pipe_reference_init(&ws->reference, 1); /* Set functions. */ ws->base.unref = radeon_winsys_unref; ws->base.destroy = radeon_winsys_destroy; ws->base.query_info = radeon_query_info; + ws->base.pin_threads_to_L3_cache = radeon_pin_threads_to_L3_cache; ws->base.cs_request_feature = radeon_cs_request_feature; ws->base.query_value = radeon_query_value; ws->base.read_registers = radeon_read_registers; radeon_drm_bo_init_functions(ws); radeon_drm_cs_init_functions(ws); radeon_surface_init_functions(ws); (void) mtx_init(&ws->hyperz_owner_mutex, mtx_plain); (void) mtx_init(&ws->cmask_owner_mutex, mtx_plain); -- 2.17.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev