[Intel-gfx] [PATCH] libdrm support for tiled rendering

Jesse Barnes jbarnes at virtuousgeek.org
Fri Jan 23 23:13:45 CET 2009


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).

-- 
Jesse Barnes, Intel Open Source Technology Center


diff --git a/libdrm/intel/intel_bufmgr_gem.c b/libdrm/intel/intel_bufmgr_gem.c
index 7b821de..dd8d6e4 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;
+    unsigned int available_fences;
 } drm_intel_bufmgr_gem;
 
 struct _drm_intel_bo_gem {
@@ -1129,6 +1130,26 @@ 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.
+ */
+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->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 +1227,19 @@ 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;
+    unsigned 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) {
+		    fprintf(stderr, "out of fences\n");
+		    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 +1265,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 +1289,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;



More information about the Intel-gfx mailing list