The limit to the working set of a single batch is the amount we can fit into the GTT. The GTT is a per-context address space, so query the context rather than use an estimate based on the legacy global aperture. Futhermore, we can fine tune our soft-limit based on the knowledge of whether we are sharing the GTT with other clients. --- src/mesa/drivers/dri/i965/intel_screen.c | 55 +++++++++++++++++++++--- 1 file changed, 49 insertions(+), 6 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index e6d49b94268..a7e0c20c9ca 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -1420,15 +1420,58 @@ static const __DRIimageExtension intelImageExtension = { .queryDmaBufFormatModifierAttribs = intel_query_format_modifier_attribs, }; +static int +gem_param(int fd, int name) +{ + int v = -1; /* No param uses (yet) the sign bit, reserve it for errors */ + + struct drm_i915_getparam gp = { .param = name, .value = &v }; + if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp)) + return -1; + + return v; +} + +static int +gem_context_getparam(int fd, uint32_t context, uint64_t param, uint64_t *value) +{ + struct drm_i915_gem_context_param gp = { + .ctx_id = context, + .param = param, + }; + + if (drmIoctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, &gp)) + return -1; + + *value = gp.value; + + return 0; +} + static uint64_t -get_aperture_size(int fd) +get_batch_threshold(int fd) { - struct drm_i915_gem_get_aperture aperture; + uint64_t gtt_size; + + /* I915_CONTEXT_PARAM_GTT_SIZE was introduced in kernel v4.5. Prior to that + * be cautious and assume that we only have the smallest 256MiB GTT. + * This is a soft-limit we use to flush the batch before it grows too large + * and tries to claim the entire system for itself. (It is still allowed + * to use as much as it requires of the GTT for a single primitive call, + * with the caveat that it may fail if we cannot fit it all in.) + */ + if (gem_context_getparam(fd, 0, I915_CONTEXT_PARAM_GTT_SIZE, >t_size)) + gtt_size = 256 << 20; - if (drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture) != 0) - return 0; + /* If we have to share the GTT with other clients, be conservative and + * set ourselves a lower soft-limit so we emit batches more often to avoid + * having multiple clients compete for hogging the entire system to + * themselves. + */ + if (gem_param(fd, I915_PARAM_HAS_ALIASING_PPGTT) < 2) + gtt_size /= 2; - return aperture.aper_size; + return 3 * gtt_size / 4; } static int @@ -2482,7 +2525,7 @@ __DRIconfig **intelInitScreen2(__DRIscreen *dri_screen) screen->max_gtt_map_object_size = gtt_size / 4; } - screen->aperture_threshold = get_aperture_size(dri_screen->fd) * 3 / 4; + screen->aperture_threshold = get_batch_threshold(dri_screen->fd); screen->hw_has_swizzling = intel_detect_swizzling(screen); screen->hw_has_timestamp = intel_detect_timestamp(screen); -- 2.17.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev