From: Chris Wilson Date: Wed, 24 Aug 2016 19:35:46 +0000 (+0100) Subject: i965: Embrace "unlimited" GTT mmap support X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f92a87a14068dd17a32b41b1586421cef6eaa37f;p=mesa.git i965: Embrace "unlimited" GTT mmap support From about kernel 4.9, GTT mmaps are virtually unlimited. A new parameter, I915_PARAM_MMAP_GTT_VERSION, is added to advertise the feature so query it and use it to avoid limiting tiled allocations to only fit within the mappable aperture. A couple of caveats: - fence support is still limited by stride to 262144 and the stride needs to be a multiple of tile_width (as before, and same limitation as the current 3D pipeline in hardware) - the max_gtt_map_object_size forcing untiled may be hiding a few bugs in handling of large objects, though none were spotted in piglits. See kernel commit 4cc6907501ed ("drm/i915: Add I915_PARAM_MMAP_GTT_VERSION to advertise unlimited mmaps"). v2: Include some commentary on mmap virtual space vs CPU addressable space. Signed-off-by: Chris Wilson Cc: Kenneth Graunke Reviewed-by: Kenneth Graunke Reviewed-by: Daniel Vetter --- diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index d6f0d7bbcb3..13643930e38 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -1044,21 +1044,6 @@ brwCreateContext(gl_api api, brw->urb.max_ds_entries = devinfo->urb.max_ds_entries; brw->urb.max_gs_entries = devinfo->urb.max_gs_entries; - /* Estimate the size of the mappable aperture into the GTT. There's an - * ioctl to get the whole GTT size, but not one to get the mappable subset. - * It turns out it's basically always 256MB, though some ancient hardware - * was smaller. - */ - uint32_t gtt_size = 256 * 1024 * 1024; - - /* We don't want to map two objects such that a memcpy between them would - * just fault one mapping in and then the other over and over forever. So - * we would need to divide the GTT size by 2. Additionally, some GTT is - * taken up by things like the framebuffer and the ringbuffer and such, so - * be more conservative. - */ - brw->max_gtt_map_object_size = gtt_size / 4; - if (brw->gen == 6) brw->urb.gs_present = false; @@ -1069,6 +1054,8 @@ brwCreateContext(gl_api api, brw->predicate.state = BRW_PREDICATE_STATE_RENDER; + brw->max_gtt_map_object_size = screen->max_gtt_map_object_size; + brw->use_resource_streamer = screen->has_resource_streamer && (env_var_as_boolean("INTEL_USE_HW_BT", false) || env_var_as_boolean("INTEL_USE_GATHER", false)); diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index e0f70007478..1a4efa3cb0c 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -853,7 +853,7 @@ struct brw_context */ bool perf_debug; - uint32_t max_gtt_map_object_size; + uint64_t max_gtt_map_object_size; int gen; int gt; diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 78766524e3c..cb007d7dc21 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -995,6 +995,17 @@ intel_get_boolean(struct intel_screen *screen, int param) return (intel_get_param(screen, param, &value) == 0) && value; } +static int +intel_get_integer(struct intel_screen *screen, int param) +{ + int value = -1; + + if (intel_get_param(screen, param, &value) == 0) + return value; + + return -1; +} + static void intelDestroyScreen(__DRIscreen * sPriv) { @@ -1565,6 +1576,43 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp) if (INTEL_DEBUG & DEBUG_AUB) drm_intel_bufmgr_gem_set_aub_dump(intelScreen->bufmgr, true); +#ifndef I915_PARAM_MMAP_GTT_VERSION +#define I915_PARAM_MMAP_GTT_VERSION 40 /* XXX delete me with new libdrm */ +#endif + if (intel_get_integer(intelScreen, I915_PARAM_MMAP_GTT_VERSION) >= 1) { + /* Theorectically unlimited! At least for individual objects... + * + * Currently the entire (global) address space for all GTT maps is + * limited to 64bits. That is all objects on the system that are + * setup for GTT mmapping must fit within 64bits. An attempt to use + * one that exceeds the limit with fail in drm_intel_bo_map_gtt(). + * + * Long before we hit that limit, we will be practically limited by + * that any single object must fit in physical memory (RAM). The upper + * limit on the CPU's address space is currently 48bits (Skylake), of + * which only 39bits can be physical memory. (The GPU itself also has + * a 48bit addressable virtual space.) We can fit over 32 million + * objects of the current maximum allocable size before running out + * of mmap space. + */ + intelScreen->max_gtt_map_object_size = UINT64_MAX; + } else { + /* Estimate the size of the mappable aperture into the GTT. There's an + * ioctl to get the whole GTT size, but not one to get the mappable subset. + * It turns out it's basically always 256MB, though some ancient hardware + * was smaller. + */ + uint32_t gtt_size = 256 * 1024 * 1024; + + /* We don't want to map two objects such that a memcpy between them would + * just fault one mapping in and then the other over and over forever. So + * we would need to divide the GTT size by 2. Additionally, some GTT is + * taken up by things like the framebuffer and the ringbuffer and such, so + * be more conservative. + */ + intelScreen->max_gtt_map_object_size = gtt_size / 4; + } + intelScreen->hw_has_swizzling = intel_detect_swizzling(intelScreen); intelScreen->hw_has_timestamp = intel_detect_timestamp(intelScreen); diff --git a/src/mesa/drivers/dri/i965/intel_screen.h b/src/mesa/drivers/dri/i965/intel_screen.h index 98f9d24901c..f62b39f7440 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.h +++ b/src/mesa/drivers/dri/i965/intel_screen.h @@ -44,6 +44,8 @@ struct intel_screen __DRIscreen *driScrnPriv; + uint64_t max_gtt_map_object_size; + bool no_hw; bool hw_has_swizzling;