Use previous buffer offsets to compute proposed relocations
authorKeith Packard <keithp@keithp.com>
Thu, 6 Dec 2007 22:11:34 +0000 (14:11 -0800)
committerKeith Packard <keithp@keithp.com>
Wed, 12 Dec 2007 04:27:42 +0000 (20:27 -0800)
This takes advantage of the DRM_BO_HINT_PRESUMED_OFFSET change and allows
the kernel to avoid mapping and re-writing buffers when relocations occur.

src/mesa/drivers/dri/intel/intel_batchbuffer.c
src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c

index 21db0e7dcd6ef0f59bb260883839b7c74fa1a676..1deca8ca1d50cd6ff6275d916c84d95598ba1262 100644 (file)
@@ -246,7 +246,12 @@ intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
                              GLuint flags, GLuint delta)
 {
    dri_emit_reloc(batch->buf, flags, delta, batch->ptr - batch->map, buffer);
-   batch->ptr += 4;
+   /*
+    * Using the old buffer offset, write in what the right data would be, in case
+    * the buffer doesn't move and we can short-circuit the relocation processing
+    * in the kernel
+    */
+   intel_batchbuffer_emit_dword (batch, buffer->offset + delta);
 
    return GL_TRUE;
 }
index 3e0d818a0cc9ae6e4572da4fdd41fae4635c65b2..ab52efca372faff008c01cf42e10e3f6cf72e047 100644 (file)
@@ -193,6 +193,10 @@ intel_setup_validate_list(dri_bufmgr_ttm *bufmgr_ttm, GLuint *count_p)
        req->op = drm_bo_validate;
        req->bo_req.flags = node->flags;
        req->bo_req.hint = 0;
+#ifdef DRM_BO_HINT_PRESUMED_OFFSET
+       req->bo_req.hint |= DRM_BO_HINT_PRESUMED_OFFSET;
+       req->bo_req.presumed_offset = ((dri_bo *) node->priv)->offset;
+#endif
        req->bo_req.mask = node->mask;
        req->bo_req.fence_class = 0; /* Backwards compat. */
        arg->reloc_handle = 0;
@@ -838,11 +842,29 @@ dri_ttm_process_reloc(dri_bo *batch_buf, GLuint *count)
     return ptr;
 }
 
+static void
+intel_update_buffer_offsets (dri_bufmgr_ttm *bufmgr_ttm)
+{
+    struct intel_bo_list *list = &bufmgr_ttm->list;
+    struct intel_bo_node *node;
+    drmMMListHead *l;
+    struct drm_i915_op_arg *arg;
+    struct drm_bo_arg_rep *rep;
+    
+    for (l = list->list.next; l != &list->list; l = l->next) {
+        node = DRMLISTENTRY(struct intel_bo_node, l, head);
+       arg = &node->bo_arg;
+       rep = &arg->d.rep;
+       ((dri_bo *) node->priv)->offset = rep->bo_info.offset;
+    }
+}
+
 static void
 dri_ttm_post_submit(dri_bo *batch_buf, dri_fence **last_fence)
 {
     dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)batch_buf->bufmgr;
 
+    intel_update_buffer_offsets (bufmgr_ttm);
     intel_free_validate_list(bufmgr_ttm);
     intel_free_reloc_list(bufmgr_ttm);