[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