From: Jesse Barnes Date: Fri, 23 Jan 2009 22:13:45 +0000 (-0800) Subject: intel: libdrm support for fence management in execbuf X-Git-Tag: libdrm-2.4.5~41 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2fa5f28eeef4ce13a48c1998856a115c7e4161ac;p=platform%2Fupstream%2Flibdrm.git intel: libdrm support for fence management in execbuf This patch tries to use the available fence count to figure out whether a given batch can succeed or not (just like the aperture check). Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt --- diff --git a/libdrm/intel/intel_bufmgr_gem.c b/libdrm/intel/intel_bufmgr_gem.c index 7b821de..7199cc1 100644 --- a/libdrm/intel/intel_bufmgr_gem.c +++ b/libdrm/intel/intel_bufmgr_gem.c @@ -99,6 +99,7 @@ typedef struct _drm_intel_bufmgr_gem { struct drm_intel_gem_bo_bucket cache_bucket[DRM_INTEL_GEM_BO_BUCKETS]; uint64_t gtt_size; + int available_fences; } drm_intel_bufmgr_gem; struct _drm_intel_bo_gem { @@ -1129,6 +1130,34 @@ drm_intel_gem_bo_get_aperture_space(drm_intel_bo *bo) } /** + * Count the number of buffers in this list that need a fence reg + * + * If the count is greater than the number of available regs, we'll have + * to ask the caller to resubmit a batch with fewer tiled buffers. + * + * This function under-counts buffers referenced from other buffers + * (such as the targets of the batchbuffer), and over-counts if the same + * buffer appears twice in the array. + */ +static unsigned int +drm_intel_gem_total_fences(drm_intel_bo **bo_array, int count) +{ + int i; + unsigned int total = 0; + + for (i = 0; i < count; i++) { + drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo_array[i]; + + if (bo_gem == NULL) + continue; + + if (bo_gem->tiling_mode != I915_TILING_NONE) + total++; + } + return total; +} + +/** * Clear the flag set by drm_intel_gem_bo_get_aperture_space() so we're ready * for the next drm_intel_bufmgr_check_aperture_space() call. */ @@ -1206,9 +1235,17 @@ drm_intel_gem_check_aperture_space(drm_intel_bo **bo_array, int count) drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo_array[0]->bufmgr; unsigned int total = 0; unsigned int threshold = bufmgr_gem->gtt_size * 3 / 4; + int total_fences; + + /* Check for fence reg constraints if necessary */ + if (bufmgr_gem->available_fences) { + total_fences = drm_intel_gem_total_fences(bo_array, count); + if (total_fences > bufmgr_gem->available_fences) + return -1; + } total = drm_intel_gem_estimate_batch_space(bo_array, count); - + if (total > threshold) total = drm_intel_gem_compute_batch_space(bo_array, count); @@ -1234,6 +1271,7 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size) { drm_intel_bufmgr_gem *bufmgr_gem; struct drm_i915_gem_get_aperture aperture; + drm_i915_getparam_t gp; int ret, i; bufmgr_gem = calloc(1, sizeof(*bufmgr_gem)); @@ -1257,6 +1295,15 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size) (int)bufmgr_gem->gtt_size / 1024); } + gp.param = I915_PARAM_NUM_FENCES_AVAIL; + gp.value = &bufmgr_gem->available_fences; + ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp); + if (ret) { + fprintf(stderr, "get fences failed: %d\n", ret); + fprintf(stderr, "param: %d, val: %d\n", gp.param, *gp.value); + bufmgr_gem->available_fences = 0; + } + /* Let's go with one relocation per every 2 dwords (but round down a bit * since a power of two will mean an extra page allocation for the reloc * buffer). diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h index 04ab4cf..5456e91 100644 --- a/shared-core/i915_drm.h +++ b/shared-core/i915_drm.h @@ -296,6 +296,7 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_LAST_DISPATCH 3 #define I915_PARAM_CHIPSET_ID 4 #define I915_PARAM_HAS_GEM 5 +#define I915_PARAM_NUM_FENCES_AVAIL 6 typedef struct drm_i915_getparam { int param; @@ -307,6 +308,7 @@ typedef struct drm_i915_getparam { #define I915_SETPARAM_USE_MI_BATCHBUFFER_START 1 #define I915_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 #define I915_SETPARAM_ALLOW_BATCHBUFFER 3 +#define I915_SETPARAM_NUM_USED_FENCES 4 typedef struct drm_i915_setparam { int param;