i915: Don't put VBOs in graphics memory unless required for an operation.
authorEric Anholt <eric@anholt.net>
Tue, 2 Jun 2009 13:53:40 +0000 (06:53 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 17 Jun 2009 18:08:36 +0000 (11:08 -0700)
This saves doing swtnl from uncached memory, which is painful.  Improves
clutter test-text performance by 10% since it started using VBOs.
(cherry picked from commit a945e203d4fe254593bc0c5c5d6caca45e65f9f7)

src/mesa/drivers/dri/intel/intel_buffer_objects.c
src/mesa/drivers/dri/intel/intel_buffer_objects.h

index 1b64c68157172b90832e9380f45cabed9228d7fa..c31fe91ad62d9e7d8d1910e677e80b68a7dfc6ae 100644 (file)
@@ -102,6 +102,7 @@ intel_bufferobj_free(GLcontext * ctx, struct gl_buffer_object *obj)
    assert(intel_obj);
    assert(!obj->Pointer); /* Mesa should have unmapped it */
 
+   _mesa_free(intel_obj->sys_buffer);
    if (intel_obj->region) {
       intel_bufferobj_release_region(intel, intel_obj);
    }
@@ -142,7 +143,23 @@ intel_bufferobj_data(GLcontext * ctx,
       dri_bo_unreference(intel_obj->buffer);
       intel_obj->buffer = NULL;
    }
+   _mesa_free(intel_obj->sys_buffer);
+   intel_obj->sys_buffer = NULL;
+
    if (size != 0) {
+#ifdef I915
+      /* On pre-965, stick VBOs in system memory, as we're always doing swtnl
+       * with their contents anyway.
+       */
+      if (target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER) {
+        intel_obj->sys_buffer = _mesa_malloc(size);
+        if (intel_obj->sys_buffer != NULL) {
+           if (data != NULL)
+              memcpy(intel_obj->sys_buffer, data, size);
+           return;
+        }
+      }
+#endif
       intel_bufferobj_alloc_buffer(intel, intel_obj);
 
       if (data != NULL)
@@ -172,7 +189,10 @@ intel_bufferobj_subdata(GLcontext * ctx,
    if (intel_obj->region)
       intel_bufferobj_cow(intel, intel_obj);
 
-   dri_bo_subdata(intel_obj->buffer, offset, size, data);
+   if (intel_obj->sys_buffer)
+      memcpy((char *)intel_obj->sys_buffer + offset, data, size);
+   else
+      dri_bo_subdata(intel_obj->buffer, offset, size, data);
 }
 
 
@@ -209,6 +229,11 @@ intel_bufferobj_map(GLcontext * ctx,
 
    assert(intel_obj);
 
+   if (intel_obj->sys_buffer) {
+      obj->Pointer = intel_obj->sys_buffer;
+      return obj->Pointer;
+   }
+
    if (intel_obj->region)
       intel_bufferobj_cow(intel, intel_obj);
 
@@ -265,6 +290,18 @@ intel_bufferobj_buffer(struct intel_context *intel,
       }
    }
 
+   if (intel_obj->buffer == NULL) {
+      intel_bufferobj_alloc_buffer(intel, intel_obj);
+      intel_bufferobj_subdata(&intel->ctx,
+                             GL_ARRAY_BUFFER_ARB,
+                             0,
+                             intel_obj->Base.Size,
+                             intel_obj->sys_buffer,
+                             &intel_obj->Base);
+      _mesa_free(intel_obj->sys_buffer);
+      intel_obj->sys_buffer = NULL;
+   }
+
    return intel_obj->buffer;
 }
 
index 7ef723833c0481ef43cde99414b0f59fa04db493..0431015631976276604b79836a38cb9ef0495246 100644 (file)
@@ -42,6 +42,8 @@ struct intel_buffer_object
 {
    struct gl_buffer_object Base;
    dri_bo *buffer;     /* the low-level buffer manager's buffer handle */
+   /** System memory buffer data, if not using a BO to store the data. */
+   void *sys_buffer;
 
    struct intel_region *region; /* Is there a zero-copy texture
                                    associated with this (pixel)