summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-06-05 15:58:09 -0700
committerKeith Packard <keithp@keithp.com>2008-06-06 13:00:46 -0700
commita919ff5d5ec2fe716cbf5c593be7cc0705499107 (patch)
tree55e88ddbf0430fbf1fae315e4b0d6530b7da0dd8
parent5f5badb26f761eec87b951ce1b7b3a51a5060c50 (diff)
[libdrm/intel] Reuse entire dri_bo_gem structure
The code was discarding the dri_bo_gem structure and saving only the kernel handle. This lost the mmap address, causing pain when the next buffer user wanted to map the buffer.
-rw-r--r--libdrm/intel/intel_bufmgr_gem.c76
1 files changed, 43 insertions, 33 deletions
diff --git a/libdrm/intel/intel_bufmgr_gem.c b/libdrm/intel/intel_bufmgr_gem.c
index 20f39b5f..08cb5d6b 100644
--- a/libdrm/intel/intel_bufmgr_gem.c
+++ b/libdrm/intel/intel_bufmgr_gem.c
@@ -55,15 +55,16 @@
fprintf(stderr, __VA_ARGS__); \
} while (0)
+typedef struct _dri_bo_gem dri_bo_gem;
+
struct intel_validate_entry {
- dri_bo *bo;
+ dri_bo_gem *bo_gem;
struct drm_i915_op_arg bo_arg;
};
struct dri_gem_bo_bucket_entry {
- uint32_t gem_handle;
- uint32_t last_offset;
- struct dri_gem_bo_bucket_entry *next;
+ dri_bo_gem *bo_gem;
+ struct dri_gem_bo_bucket_entry *next;
};
struct dri_gem_bo_bucket {
@@ -103,7 +104,7 @@ typedef struct _dri_bufmgr_gem {
struct drm_i915_gem_execbuffer exec_arg;
} dri_bufmgr_gem;
-typedef struct _dri_bo_gem {
+struct _dri_bo_gem {
dri_bo bo;
int refcount;
@@ -133,7 +134,7 @@ typedef struct _dri_bo_gem {
int reloc_count;
/** Mapped address for the buffer */
void *virtual;
-} dri_bo_gem;
+};
static int
logbase2(int n)
@@ -270,24 +271,21 @@ dri_gem_bo_alloc(dri_bufmgr *bufmgr, const char *name,
int ret;
struct dri_gem_bo_bucket *bucket;
int alloc_from_cache = 0;
-
- bo_gem = calloc(1, sizeof(*bo_gem));
- if (!bo_gem)
- return NULL;
+ unsigned long bo_size;
/* Round the allocated size up to a power of two number of pages. */
- bo_gem->bo.size = 1 << logbase2(size);
- if (bo_gem->bo.size < page_size)
- bo_gem->bo.size = page_size;
- bucket = dri_gem_bo_bucket_for_size(bufmgr_gem, bo_gem->bo.size);
+ bo_size = 1 << logbase2(size);
+ if (bo_size < page_size)
+ bo_size = page_size;
+ bucket = dri_gem_bo_bucket_for_size(bufmgr_gem, bo_size);
/* If we don't have caching at this size, don't actually round the
* allocation up.
*/
if (bucket == NULL || bucket->max_entries == 0) {
- bo_gem->bo.size = size;
- if (bo_gem->bo.size < page_size)
- bo_gem->bo.size = page_size;
+ bo_size = size;
+ if (bo_size < page_size)
+ bo_size = page_size;
}
/* Get a buffer out of the cache if available */
@@ -295,7 +293,9 @@ dri_gem_bo_alloc(dri_bufmgr *bufmgr, const char *name,
struct dri_gem_bo_bucket_entry *entry = bucket->head;
struct drm_i915_gem_busy busy;
- busy.handle = entry->gem_handle;
+ bo_gem = entry->bo_gem;
+ busy.handle = bo_gem->gem_handle;
+
ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
alloc_from_cache = (ret == 0 && busy.busy == 0);
@@ -305,8 +305,6 @@ dri_gem_bo_alloc(dri_bufmgr *bufmgr, const char *name,
bucket->tail = &bucket->head;
bucket->num_entries--;
- bo_gem->gem_handle = entry->gem_handle;
- bo_gem->bo.offset = entry->last_offset;
free(entry);
}
}
@@ -314,8 +312,13 @@ dri_gem_bo_alloc(dri_bufmgr *bufmgr, const char *name,
if (!alloc_from_cache) {
struct drm_gem_create create;
+ bo_gem = calloc(1, sizeof(*bo_gem));
+ if (!bo_gem)
+ return NULL;
+
+ bo_gem->bo.size = bo_size;
memset(&create, 0, sizeof(create));
- create.size = bo_gem->bo.size;
+ create.size = bo_size;
ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CREATE, &create);
bo_gem->gem_handle = create.handle;
@@ -323,10 +326,9 @@ dri_gem_bo_alloc(dri_bufmgr *bufmgr, const char *name,
free(bo_gem);
return NULL;
}
+ bo_gem->bo.bufmgr = bufmgr;
}
- bo_gem->bo.virtual = NULL;
- bo_gem->bo.bufmgr = bufmgr;
bo_gem->name = name;
bo_gem->refcount = 1;
bo_gem->validate_index = -1;
@@ -400,9 +402,6 @@ dri_gem_bo_unreference(dri_bo *bo)
struct dri_gem_bo_bucket *bucket;
int ret;
- if (bo_gem->mapped)
- munmap (bo_gem->virtual, bo->size);
-
if (bo_gem->relocs != NULL) {
int i;
@@ -413,6 +412,9 @@ dri_gem_bo_unreference(dri_bo *bo)
free(bo_gem->relocs);
}
+ DBG("bo_unreference final: %d (%s)\n",
+ bo_gem->gem_handle, bo_gem->name);
+
bucket = dri_gem_bo_bucket_for_size(bufmgr_gem, bo->size);
/* Put the buffer into our internal cache for reuse if we can. */
if (bucket != NULL &&
@@ -422,9 +424,14 @@ dri_gem_bo_unreference(dri_bo *bo)
{
struct dri_gem_bo_bucket_entry *entry;
+ bo_gem->name = 0;
+ bo_gem->validate_index = -1;
+ bo_gem->relocs = NULL;
+ bo_gem->reloc_target_bo = NULL;
+ bo_gem->reloc_count = 0;
+
entry = calloc(1, sizeof(*entry));
- entry->gem_handle = bo_gem->gem_handle;
- entry->last_offset = bo->offset;
+ entry->bo_gem = bo_gem;
entry->next = NULL;
*bucket->tail = entry;
@@ -441,12 +448,9 @@ dri_gem_bo_unreference(dri_bo *bo)
"DRM_IOCTL_GEM_CLOSE %d failed (%s): %s\n",
bo_gem->gem_handle, bo_gem->name, strerror(-ret));
}
+ free(bo);
}
- DBG("bo_unreference final: %d (%s)\n",
- bo_gem->gem_handle, bo_gem->name);
-
- free(bo);
return;
}
}
@@ -604,6 +608,7 @@ dri_bufmgr_gem_destroy(dri_bufmgr *bufmgr)
while ((entry = bucket->head) != NULL) {
struct drm_gem_close close;
+ dri_bo_gem *bo_gem;
int ret;
bucket->head = entry->next;
@@ -611,14 +616,19 @@ dri_bufmgr_gem_destroy(dri_bufmgr *bufmgr)
bucket->tail = &bucket->head;
bucket->num_entries--;
+ bo_gem = entry->bo_gem;
+ if (bo_gem->mapped)
+ munmap (bo_gem->virtual, bo_gem->bo.size);
+
/* Close this object */
- close.handle = entry->gem_handle;
+ close.handle = bo_gem->gem_handle;
ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close);
if (ret != 0) {
fprintf(stderr, "DRM_IOCTL_GEM_CLOSE failed: %s\n",
strerror(-ret));
}
+ free(bo_gem);
free(entry);
}
}