Mesa (master): intel: Reset the buffer offset after releasing reference to packed upload

Chris Wilson ickle at kemper.freedesktop.org
Thu Feb 24 12:31:38 UTC 2011


Module: Mesa
Branch: master
Commit: 5ce0f7f10908a0636900bae783cb426a6c607673
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5ce0f7f10908a0636900bae783cb426a6c607673

Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Feb 24 12:29:51 2011 +0000

intel: Reset the buffer offset after releasing reference to packed upload

Fixes oglc/vbo(basic.bufferdata)

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=34603
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

---

 src/mesa/drivers/dri/i965/brw_draw_upload.c       |    1 +
 src/mesa/drivers/dri/intel/intel_buffer_objects.c |  134 ++++++++++++---------
 2 files changed, 77 insertions(+), 58 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index 4efb3cd..7234ce2 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -338,6 +338,7 @@ static void brw_prepare_vertices(struct brw_context *brw)
 	 }
 	 if (k == i) {
 	    struct brw_vertex_buffer *buffer = &brw->vb.buffers[j];
+
 	    /* Named buffer object: Just reference its contents directly. */
 	    buffer->bo = intel_bufferobj_source(intel, intel_buffer,
 						&buffer->offset);
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
index bc57803..2f750a7 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
@@ -53,6 +53,15 @@ intel_bufferobj_alloc_buffer(struct intel_context *intel,
 					  intel_obj->Base.Size, 64);
 }
 
+static void
+release_buffer(struct intel_buffer_object *intel_obj)
+{
+   drm_intel_bo_unreference(intel_obj->buffer);
+   intel_obj->buffer = NULL;
+   intel_obj->offset = 0;
+   intel_obj->source = 0;
+}
+
 /**
  * There is some duplication between mesa's bufferobjects and our
  * bufmgr buffers.  Both have an integer handle and a hashtable to
@@ -81,8 +90,7 @@ intel_bufferobj_release_region(struct intel_context *intel,
    intel_obj->region->pbo = NULL;
    intel_obj->region = NULL;
 
-   drm_intel_bo_unreference(intel_obj->buffer);
-   intel_obj->buffer = NULL;
+   release_buffer(intel_obj);
 }
 
 /* Break the COW tie to the region.  Both the pbo and the region end
@@ -152,11 +160,9 @@ intel_bufferobj_data(struct gl_context * ctx,
    if (intel_obj->region)
       intel_bufferobj_release_region(intel, intel_obj);
 
-   if (intel_obj->buffer != NULL) {
-      drm_intel_bo_unreference(intel_obj->buffer);
-      intel_obj->buffer = NULL;
-      intel_obj->source = 0;
-   }
+   if (intel_obj->buffer != NULL)
+      release_buffer(intel_obj);
+
    free(intel_obj->sys_buffer);
    intel_obj->sys_buffer = NULL;
 
@@ -204,6 +210,7 @@ intel_bufferobj_subdata(struct gl_context * ctx,
 {
    struct intel_context *intel = intel_context(ctx);
    struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
+   bool busy;
 
    if (size == 0)
       return;
@@ -213,47 +220,53 @@ intel_bufferobj_subdata(struct gl_context * ctx,
    if (intel_obj->region)
       intel_bufferobj_cow(intel, intel_obj);
 
+   /* If we have a single copy in system memory, update that */
    if (intel_obj->sys_buffer) {
-      if (intel_obj->buffer) {
-	 drm_intel_bo_unreference(intel_obj->buffer);
-	 intel_obj->buffer = NULL;
-	 intel_obj->source = 0;
+      if (intel_obj->source)
+	 release_buffer(intel_obj);
+
+      if (intel_obj->buffer == NULL) {
+	 memcpy((char *)intel_obj->sys_buffer + offset, data, size);
+	 return;
       }
-      memcpy((char *)intel_obj->sys_buffer + offset, data, size);
-   } else {
-      bool busy =
-	 drm_intel_bo_busy(intel_obj->buffer) ||
-	 drm_intel_bo_references(intel->batch.bo, intel_obj->buffer);
 
-      /* replace the current busy bo with fresh data */
-      if (busy && size == intel_obj->Base.Size) {
-	 drm_intel_bo_unreference(intel_obj->buffer);
-	 intel_bufferobj_alloc_buffer(intel, intel_obj);
-	 drm_intel_bo_subdata(intel_obj->buffer, 0, size, data);
-      } else if (intel->gen < 6) {
-	 if (busy) {
-	    drm_intel_bo *temp_bo;
+      free(intel_obj->sys_buffer);
+      intel_obj->sys_buffer = NULL;
+   }
 
-	    temp_bo = drm_intel_bo_alloc(intel->bufmgr, "subdata temp", size, 64);
+   /* Otherwise we need to update the copy in video memory. */
+   busy =
+      drm_intel_bo_busy(intel_obj->buffer) ||
+      drm_intel_bo_references(intel->batch.bo, intel_obj->buffer);
 
-	    drm_intel_bo_subdata(temp_bo, 0, size, data);
+   /* replace the current busy bo with fresh data */
+   if (busy && size == intel_obj->Base.Size) {
+      drm_intel_bo_unreference(intel_obj->buffer);
+      intel_bufferobj_alloc_buffer(intel, intel_obj);
+      drm_intel_bo_subdata(intel_obj->buffer, 0, size, data);
+   } else if (intel->gen < 6) {
+      if (busy) {
+	 drm_intel_bo *temp_bo;
 
-	    intel_emit_linear_blit(intel,
-				   intel_obj->buffer, offset,
-				   temp_bo, 0,
-				   size);
+	 temp_bo = drm_intel_bo_alloc(intel->bufmgr, "subdata temp", size, 64);
 
-	    drm_intel_bo_unreference(temp_bo);
-	 } else {
-	    drm_intel_bo_subdata(intel_obj->buffer, offset, size, data);
-	 }
+	 drm_intel_bo_subdata(temp_bo, 0, size, data);
+
+	 intel_emit_linear_blit(intel,
+				intel_obj->buffer, offset,
+				temp_bo, 0,
+				size);
+
+	 drm_intel_bo_unreference(temp_bo);
       } else {
-	 /* Can't use the blit to modify the buffer in the middle of batch. */
-	 if (drm_intel_bo_references(intel->batch.bo, intel_obj->buffer)) {
-	    intel_batchbuffer_flush(intel);
-	 }
 	 drm_intel_bo_subdata(intel_obj->buffer, offset, size, data);
       }
+   } else {
+      /* Can't use the blit to modify the buffer in the middle of batch. */
+      if (drm_intel_bo_references(intel->batch.bo, intel_obj->buffer)) {
+	 intel_batchbuffer_flush(intel);
+      }
+      drm_intel_bo_subdata(intel_obj->buffer, offset, size, data);
    }
 }
 
@@ -295,15 +308,19 @@ intel_bufferobj_map(struct gl_context * ctx,
    assert(intel_obj);
 
    if (intel_obj->sys_buffer) {
-      if (!read_only && intel_obj->buffer) {
-	 drm_intel_bo_unreference(intel_obj->buffer);
-	 intel_obj->buffer = NULL;
-	 intel_obj->source = 0;
+      if (!read_only && intel_obj->source) {
+	 release_buffer(intel_obj);
       }
-      obj->Pointer = intel_obj->sys_buffer;
-      obj->Length = obj->Size;
-      obj->Offset = 0;
-      return obj->Pointer;
+
+      if (!intel_obj->buffer || intel_obj->source) {
+	 obj->Pointer = intel_obj->sys_buffer;
+	 obj->Length = obj->Size;
+	 obj->Offset = 0;
+	 return obj->Pointer;
+      }
+
+      free(intel_obj->sys_buffer);
+      intel_obj->sys_buffer = NULL;
    }
 
    /* Flush any existing batchbuffer that might reference this data. */
@@ -356,6 +373,7 @@ intel_bufferobj_map_range(struct gl_context * ctx,
 {
    struct intel_context *intel = intel_context(ctx);
    struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
+   GLboolean read_only = (access == GL_READ_ONLY_ARB);
 
    assert(intel_obj);
 
@@ -367,13 +385,16 @@ intel_bufferobj_map_range(struct gl_context * ctx,
    obj->AccessFlags = access;
 
    if (intel_obj->sys_buffer) {
-      if (access != GL_READ_ONLY_ARB && intel_obj->buffer) {
-	 drm_intel_bo_unreference(intel_obj->buffer);
-	 intel_obj->buffer = NULL;
-	 intel_obj->source = 0;
+      if (!read_only && intel_obj->source)
+	 release_buffer(intel_obj);
+
+      if (!intel_obj->buffer || intel_obj->source) {
+	 obj->Pointer = intel_obj->sys_buffer + offset;
+	 return obj->Pointer;
       }
-      obj->Pointer = intel_obj->sys_buffer + offset;
-      return obj->Pointer;
+
+      free(intel_obj->sys_buffer);
+      intel_obj->sys_buffer = NULL;
    }
 
    if (intel_obj->region)
@@ -549,11 +570,8 @@ intel_bufferobj_buffer(struct intel_context *intel,
       }
    }
 
-   if (intel_obj->source) {
-      drm_intel_bo_unreference(intel_obj->buffer);
-      intel_obj->buffer = NULL;
-      intel_obj->source = 0;
-   }
+   if (intel_obj->source)
+      release_buffer(intel_obj);
 
    if (intel_obj->buffer == NULL) {
       intel_bufferobj_alloc_buffer(intel, intel_obj);
@@ -742,7 +760,7 @@ intel_bufferobj_copy_subdata(struct gl_context *ctx,
       if (src == dst) {
 	 char *ptr = intel_bufferobj_map(ctx, GL_COPY_WRITE_BUFFER,
 					 GL_READ_WRITE, dst);
-	 memcpy(ptr + write_offset, ptr + read_offset, size);
+	 memmove(ptr + write_offset, ptr + read_offset, size);
 	 intel_bufferobj_unmap(ctx, GL_COPY_WRITE_BUFFER, dst);
       } else {
 	 const char *src_ptr;




More information about the mesa-commit mailing list