OSDN Git Service

intel: libdrm support for fence management in execbuf
authorJesse Barnes <jbarnes@virtuousgeek.org>
Fri, 23 Jan 2009 22:13:45 +0000 (14:13 -0800)
committerEric Anholt <eric@anholt.net>
Wed, 28 Jan 2009 01:23:42 +0000 (17:23 -0800)
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>
libdrm/intel/intel_bufmgr_gem.c
shared-core/i915_drm.h

index 7b821de..7199cc1 100644 (file)
@@ -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).
index 04ab4cf..5456e91 100644 (file)
@@ -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;