aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965/intel_screen.c
diff options
context:
space:
mode:
authorChris Wilson <[email protected]>2016-08-24 20:35:46 +0100
committerChris Wilson <[email protected]>2016-08-26 09:09:34 +0100
commitf92a87a14068dd17a32b41b1586421cef6eaa37f (patch)
treeb047683597a18ab4c5983004ad0042e94ba45459 /src/mesa/drivers/dri/i965/intel_screen.c
parentbc5be5323f14c4f790ecaf29991158be1f5435b0 (diff)
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 <[email protected]> Cc: Kenneth Graunke <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]> Reviewed-by: Daniel Vetter <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri/i965/intel_screen.c')
-rw-r--r--src/mesa/drivers/dri/i965/intel_screen.c48
1 files changed, 48 insertions, 0 deletions
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);