diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-01-23 14:13:45 -0800 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-01-27 17:23:42 -0800 |
commit | 2fa5f28eeef4ce13a48c1998856a115c7e4161ac (patch) | |
tree | 6537902c7be2e9aa82d3afd7f8480ae0f183b845 | |
parent | 26ca0bca9bd5e23b1d31bc6dfb6d58b62143447b (diff) |
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 <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r-- | libdrm/intel/intel_bufmgr_gem.c | 49 | ||||
-rw-r--r-- | shared-core/i915_drm.h | 2 |
2 files changed, 50 insertions, 1 deletions
diff --git a/libdrm/intel/intel_bufmgr_gem.c b/libdrm/intel/intel_bufmgr_gem.c index 7b821de8..7199cc10 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 04ab4cf5..5456e917 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; |