summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/intel
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2008-01-02 16:55:21 -0800
committerEric Anholt <eric@anholt.net>2008-01-03 15:46:16 -0800
commit8abffada70fcd62e3c2dcbcdc6d00d258805326b (patch)
treed04daf5de22d6bbdb97beda35da6b33f4f1bc6c1 /src/mesa/drivers/dri/intel
parent0ff3eb637bac9e100aab0a109a46e81bea9203a3 (diff)
[intel] Convert relocations to not be cleared out on buffer submit.
We have two consumers of relocations. One is static state buffers, which want the same relocation every time. The other is the batchbuffer, which gets thrown out immediately after submit. This lets us reduce repeated computation for static state buffers, and clean up the code by moving relocations nearer to where the state buffer is computed.
Diffstat (limited to 'src/mesa/drivers/dri/intel')
-rw-r--r--src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c125
1 files changed, 92 insertions, 33 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c b/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c
index b9eabb42c0..a5307f1939 100644
--- a/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c
+++ b/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c
@@ -81,6 +81,15 @@ typedef struct _dri_bufmgr_ttm {
struct intel_bo_list list; /* list of buffers to be validated */
} dri_bufmgr_ttm;
+/**
+ * Private information associated with a relocation that isn't already stored
+ * in the relocation buffer to be passed to the kernel.
+ */
+struct dri_ttm_reloc {
+ dri_bo *target_buf;
+ uint64_t validate_flags;
+};
+
typedef struct _dri_bo_ttm {
dri_bo bo;
@@ -88,9 +97,15 @@ typedef struct _dri_bo_ttm {
drmBO drm_bo;
const char *name;
+ /* Index of the buffer within the validation list while preparing a
+ * batchbuffer execution.
+ */
+ int validate_index;
+
/** DRM buffer object containing relocation list */
drmBO *reloc_buf;
- uint32_t *relocs;
+ uint32_t *reloc_buf_data;
+ struct dri_ttm_reloc *relocs;
} dri_bo_ttm;
typedef struct _dri_fence_ttm
@@ -130,14 +145,9 @@ intel_free_validate_list(dri_bufmgr_ttm *bufmgr_ttm)
for (l = list->list.next; l != &list->list; l = list->list.next) {
struct intel_bo_node *node =
DRMLISTENTRY(struct intel_bo_node, l, head);
- dri_bo_ttm *bo_ttm = (dri_bo_ttm *)node->bo;
DRMLISTDEL(l);
- /* Clear relocation list */
- if (bo_ttm->relocs != NULL)
- bo_ttm->relocs[0] = bo_ttm->relocs[0] & ~0xffff;
-
dri_bo_unreference(node->bo);
drmFree(node);
@@ -157,9 +167,10 @@ static void dri_ttm_dump_validation_list(dri_bufmgr_ttm *bufmgr_ttm)
DRMLISTENTRY(struct intel_bo_node, l, head);
dri_bo_ttm *bo_ttm = (dri_bo_ttm *)node->bo;
- if (bo_ttm->relocs != NULL) {
- for (j = 0; j < (bo_ttm->relocs[0] & 0xffff); j++) {
- uint32_t *reloc_entry = bo_ttm->relocs + I915_RELOC_HEADER +
+ if (bo_ttm->reloc_buf_data != NULL) {
+ for (j = 0; j < (bo_ttm->reloc_buf_data[0] & 0xffff); j++) {
+ uint32_t *reloc_entry = bo_ttm->reloc_buf_data +
+ I915_RELOC_HEADER +
j * I915_RELOC0_STRIDE;
DBG("%2d: %s@0x%08x -> %d + 0x%08x\n",
@@ -234,11 +245,10 @@ intel_setup_validate_list(dri_bufmgr_ttm *bufmgr_ttm, GLuint *count_p)
* access flags.
*/
static struct intel_bo_node *
-intel_add_validate_buffer(dri_bufmgr_ttm *bufmgr_ttm,
- dri_bo *buf,
- uint64_t flags,
- int *itemLoc)
+intel_add_validate_buffer(dri_bo *buf,
+ uint64_t flags)
{
+ dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
struct intel_bo_list *list = &bufmgr_ttm->list;
struct intel_bo_node *cur;
dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
@@ -289,7 +299,8 @@ intel_add_validate_buffer(dri_bufmgr_ttm *bufmgr_ttm,
}
cur->flags = memFlags | modeFlags;
}
- *itemLoc = count;
+
+ ttm_buf->validate_index = count;
return cur;
}
@@ -312,6 +323,8 @@ intel_setup_reloc_list(dri_bo *bo)
return 0;
bo_ttm->reloc_buf = malloc(sizeof(bo_ttm->drm_bo));
+ bo_ttm->relocs = malloc(sizeof(struct dri_ttm_reloc) *
+ bufmgr_ttm->max_relocs);
ret = drmBOCreate(bufmgr_ttm->fd,
RELOC_BUF_SIZE(bufmgr_ttm->max_relocs), 0,
@@ -330,7 +343,7 @@ intel_setup_reloc_list(dri_bo *bo)
ret = drmBOMap(bufmgr_ttm->fd, bo_ttm->reloc_buf,
DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE,
- 0, (void **)&bo_ttm->relocs);
+ 0, (void **)&bo_ttm->reloc_buf_data);
if (ret) {
fprintf(stderr, "Failed to map relocation BO: %s\n",
strerror(-ret));
@@ -343,10 +356,10 @@ intel_setup_reloc_list(dri_bo *bo)
* DWORD 2: unused
* DWORD 3: unused
*/
- bo_ttm->relocs[0] = I915_RELOC_TYPE_0 << 16;
- bo_ttm->relocs[1] = 0;
- bo_ttm->relocs[2] = 0;
- bo_ttm->relocs[3] = 0;
+ bo_ttm->reloc_buf_data[0] = I915_RELOC_TYPE_0 << 16;
+ bo_ttm->reloc_buf_data[1] = 0;
+ bo_ttm->reloc_buf_data[2] = 0;
+ bo_ttm->reloc_buf_data[3] = 0;
return 0;
}
@@ -404,6 +417,7 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name,
ttm_buf->name = name;
ttm_buf->refcount = 1;
ttm_buf->reloc_buf = NULL;
+ ttm_buf->reloc_buf_data = NULL;
ttm_buf->relocs = NULL;
DBG("bo_create: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
@@ -455,6 +469,7 @@ intel_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name,
ttm_buf->name = name;
ttm_buf->refcount = 1;
ttm_buf->reloc_buf = NULL;
+ ttm_buf->reloc_buf_data = NULL;
ttm_buf->relocs = NULL;
DBG("bo_create_from_handle: %p %08x (%s)\n",
@@ -484,6 +499,14 @@ dri_ttm_bo_unreference(dri_bo *buf)
int ret;
if (ttm_buf->reloc_buf) {
+ int i;
+
+ /* Unreference all the target buffers */
+ for (i = 0; i < (ttm_buf->reloc_buf_data[0] & 0xffff); i++)
+ dri_bo_unreference(ttm_buf->relocs[i].target_buf);
+ free(ttm_buf->relocs);
+
+ /* Free the kernel BO containing relocation entries */
drmBOUnmap(bufmgr_ttm->fd, ttm_buf->reloc_buf);
drmBOUnreference(bufmgr_ttm->fd, ttm_buf->reloc_buf);
free(ttm_buf->reloc_buf);
@@ -653,47 +676,83 @@ dri_ttm_emit_reloc(dri_bo *reloc_buf, uint64_t flags, GLuint delta,
{
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)reloc_buf->bufmgr;
dri_bo_ttm *reloc_buf_ttm = (dri_bo_ttm *)reloc_buf;
- struct intel_bo_node *node;
- int index;
int num_relocs;
uint32_t *this_reloc;
- node = intel_add_validate_buffer(bufmgr_ttm, target_buf, flags, &index);
-
intel_setup_reloc_list(reloc_buf);
- num_relocs = (reloc_buf_ttm->relocs[0] & 0xffff);
+ num_relocs = (reloc_buf_ttm->reloc_buf_data[0] & 0xffff);
/* Check overflow */
- assert((reloc_buf_ttm->relocs[0] & 0xffff) < bufmgr_ttm->max_relocs);
+ assert((reloc_buf_ttm->reloc_buf_data[0] & 0xffff) <
+ bufmgr_ttm->max_relocs);
- this_reloc = reloc_buf_ttm->relocs + I915_RELOC_HEADER +
+ this_reloc = reloc_buf_ttm->reloc_buf_data + I915_RELOC_HEADER +
num_relocs * I915_RELOC0_STRIDE;
this_reloc[0] = offset;
this_reloc[1] = delta;
- this_reloc[2] = index;
+ this_reloc[2] = -1; /* To be filled in at exec time */
this_reloc[3] = 0;
- reloc_buf_ttm->relocs[0]++; /* Increment relocation count */
+ reloc_buf_ttm->relocs[num_relocs].validate_flags = flags;
+ reloc_buf_ttm->relocs[num_relocs].target_buf = target_buf;
+ dri_bo_reference(target_buf);
+
+ reloc_buf_ttm->reloc_buf_data[0]++; /* Increment relocation count */
/* Check wraparound */
- assert((reloc_buf_ttm->relocs[0] & 0xffff) != 0);
+ assert((reloc_buf_ttm->reloc_buf_data[0] & 0xffff) != 0);
}
+/**
+ * Walk the tree of relocations rooted at BO and accumulate the list of
+ * validations to be performed and update the relocation buffers with
+ * index values into the validation list.
+ */
+static void
+dri_ttm_bo_process_reloc(dri_bo *bo)
+{
+ dri_bo_ttm *bo_ttm = (dri_bo_ttm *)bo;
+ unsigned int nr_relocs;
+ int i;
+
+ if (bo_ttm->reloc_buf_data == NULL)
+ return;
+
+ nr_relocs = bo_ttm->reloc_buf_data[0] & 0xffff;
+
+ for (i = 0; i < nr_relocs; i++) {
+ struct dri_ttm_reloc *r = &bo_ttm->relocs[i];
+ dri_bo_ttm *target_ttm = (dri_bo_ttm *)r->target_buf;
+ uint32_t *reloc_entry;
+
+ /* Continue walking the tree depth-first. */
+ dri_ttm_bo_process_reloc(r->target_buf);
+
+ /* Add the target to the validate list */
+ intel_add_validate_buffer(r->target_buf, r->validate_flags);
+
+ /* Update the index of the target in the relocation entry */
+ reloc_entry = bo_ttm->reloc_buf_data + I915_RELOC_HEADER +
+ i * I915_RELOC0_STRIDE;
+ reloc_entry[2] = target_ttm->validate_index;
+ }
+}
static void *
dri_ttm_process_reloc(dri_bo *batch_buf, GLuint *count)
{
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)batch_buf->bufmgr;
void *ptr;
- int index;
+
+ /* Update indices and set up the validate list. */
+ dri_ttm_bo_process_reloc(batch_buf);
/* Add the batch buffer to the validation list. There are no relocations
* pointing to it.
*/
- intel_add_validate_buffer(bufmgr_ttm, batch_buf,
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE,
- &index);
+ intel_add_validate_buffer(batch_buf,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE);
ptr = intel_setup_validate_list(bufmgr_ttm, count);