From 36d4939343d8789d9066f7245fa2d4fe69119dd8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 14 Feb 2011 09:39:06 +0000 Subject: intel: Remember named bo ... and if asked to open a bo by the same global name, return a fresh reference to the previously allocated buffer. Signed-off-by: Chris Wilson --- intel/intel_bufmgr_gem.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c index 092b56a3..3cdffce1 100644 --- a/intel/intel_bufmgr_gem.c +++ b/intel/intel_bufmgr_gem.c @@ -95,6 +95,8 @@ typedef struct _drm_intel_bufmgr_gem { int num_buckets; time_t time; + drmMMListHead named; + uint64_t gtt_size; int available_fences; int pci_device; @@ -124,6 +126,7 @@ struct _drm_intel_bo_gem { * Kenel-assigned global name for this object */ unsigned int global_name; + drmMMListHead name_list; /** * Index of the buffer within the validation list while preparing a @@ -690,6 +693,8 @@ retry: drm_intel_gem_bo_free(&bo_gem->bo); return NULL; } + + DRMINITLISTHEAD(&bo_gem->name_list); } bo_gem->name = name; @@ -792,6 +797,23 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr, int ret; struct drm_gem_open open_arg; struct drm_i915_gem_get_tiling get_tiling; + drmMMListHead *list; + + /* At the moment most applications only have a few named bo. + * For instance, in a DRI client only the render buffers passed + * between X and the client are named. And since X returns the + * alternating names for the front/back buffer a linear search + * provides a sufficiently fast match. + */ + for (list = bufmgr_gem->named.next; + list != &bufmgr_gem->named; + list = list->next) { + bo_gem = DRMLISTENTRY(drm_intel_bo_gem, list, name_list); + if (bo_gem->global_name == handle) { + drm_intel_gem_bo_reference(&bo_gem->bo); + return &bo_gem->bo; + } + } bo_gem = calloc(1, sizeof(*bo_gem)); if (!bo_gem) @@ -834,6 +856,7 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr, /* XXX stride is unknown */ drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem); + DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named); DBG("bo_create_from_handle: %d (%s)\n", handle, bo_gem->name); return &bo_gem->bo; @@ -925,6 +948,8 @@ drm_intel_gem_bo_unreference_final(drm_intel_bo *bo, time_t time) bo_gem->relocs = NULL; } + DRMLISTDEL(&bo_gem->name_list); + bucket = drm_intel_gem_bo_bucket_for_size(bufmgr_gem, bo->size); /* Put the buffer into our internal cache for reuse if we can. */ if (bufmgr_gem->bo_reuse && bo_gem->reusable && bucket != NULL && @@ -1771,6 +1796,8 @@ drm_intel_gem_bo_flink(drm_intel_bo *bo, uint32_t * name) return -errno; bo_gem->global_name = flink.name; bo_gem->reusable = 0; + + DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named); } *name = bo_gem->global_name; @@ -2217,6 +2244,7 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size) drm_intel_gem_get_pipe_from_crtc_id; bufmgr_gem->bufmgr.bo_references = drm_intel_gem_bo_references; + DRMINITLISTHEAD(&bufmgr_gem->named); init_cache_buckets(bufmgr_gem); return &bufmgr_gem->bufmgr; -- cgit v1.2.3