OSDN Git Service

intel: Improve bo_references performance by skipping the tree walk.
authorEric Anholt <eric@anholt.net>
Tue, 20 Oct 2009 20:20:55 +0000 (13:20 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 20 Oct 2009 20:31:55 +0000 (13:31 -0700)
If the target we're asking about hasn't ever been used as a relocation
target, then it obviously hasn't been used as a target by the batch's reloc
tree.  This is the common case for good GL programming where you only map
fresh buffers, and gives us a 5% win in cairo-gl.

[ # ]  backend                         test   min(s) median(s) stddev. count
before:
[  0]       gl            firefox-talos-gfx   64.680   64.756   0.06%    3/3
after:
[  0]       gl            firefox-talos-gfx   60.816   60.970   0.29%    3/3

libdrm/intel/intel_bufmgr_gem.c

index b8be96d..739c99b 100644 (file)
@@ -1571,23 +1571,16 @@ drm_intel_gem_bo_disable_reuse(drm_intel_bo *bo)
        return 0;
 }
 
-/**
- * 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.
- */
 static int
-drm_intel_gem_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo)
+_drm_intel_gem_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo)
 {
        drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
        int i;
 
-       if (bo == NULL || target_bo == NULL)
-               return 0;
-
        for (i = 0; i < bo_gem->reloc_count; i++) {
                if (bo_gem->reloc_target_bo[i] == target_bo)
                        return 1;
-               if (drm_intel_gem_bo_references(bo_gem->reloc_target_bo[i],
+               if (_drm_intel_gem_bo_references(bo_gem->reloc_target_bo[i],
                                                target_bo))
                        return 1;
        }
@@ -1595,6 +1588,19 @@ drm_intel_gem_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo)
        return 0;
 }
 
+/** Return true if target_bo is referenced by bo's relocation tree. */
+static int
+drm_intel_gem_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo)
+{
+       drm_intel_bo_gem *target_bo_gem = (drm_intel_bo_gem *) target_bo;
+
+       if (bo == NULL || target_bo == NULL)
+               return 0;
+       if (target_bo_gem->used_as_reloc_target)
+               return _drm_intel_gem_bo_references(bo, target_bo);
+       return 0;
+}
+
 /**
  * Initializes the GEM buffer manager, which uses the kernel to allocate, map,
  * and manage map buffer objections.