intel: combine short memcpy using a temporary allocated buffer
authorChris Wilson <chris@chris-wilson.co.uk>
Fri, 11 Feb 2011 19:40:08 +0000 (19:40 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Mon, 21 Feb 2011 12:59:36 +0000 (12:59 +0000)
Using a temporary buffer for large discontiguous uploads into the common
buffer and a single buffered upload is faster than performing the
discontiguous copies through a mapping into the GTT.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
src/mesa/drivers/dri/i965/brw_draw_upload.c
src/mesa/drivers/dri/intel/intel_buffer_objects.c
src/mesa/drivers/dri/intel/intel_buffer_objects.h

index 8952e97674cabe1760462c95ee9796b3bb624449..62e43e83bb8ac8567c7e6bd45b34a3aae0924d92 100644 (file)
@@ -253,8 +253,7 @@ copy_array_to_vbo_array( struct brw_context *brw,
                        &buffer->bo, &buffer->offset);
    } else {
       const unsigned char *src = element->glarray->Ptr;
-      char *dst = intel_upload_map(&brw->intel, size,
-                                  &buffer->bo, &buffer->offset);
+      char *dst = intel_upload_map(&brw->intel, size);
       int i;
 
       for (i = 0; i < element->count; i++) {
@@ -262,6 +261,8 @@ copy_array_to_vbo_array( struct brw_context *brw,
         src += element->glarray->StrideB;
         dst += dst_stride;
       }
+      intel_upload_unmap(&brw->intel, dst, size,
+                        &buffer->bo, &buffer->offset);
    }
 }
 
@@ -421,9 +422,7 @@ static void brw_prepare_vertices(struct brw_context *brw)
         int count = upload[0]->count, offset;
         char *map;
 
-        map = intel_upload_map(&brw->intel, total_size * count,
-                               &buffer->bo, &buffer->offset);
-
+        map = intel_upload_map(&brw->intel, total_size * count);
         for (i = offset = 0; i < nr_uploads; i++) {
            const unsigned char *src = upload[i]->glarray->Ptr;
            int size = upload[i]->element_size;
@@ -442,6 +441,8 @@ static void brw_prepare_vertices(struct brw_context *brw)
 
            offset += size;
         }
+        intel_upload_unmap(&brw->intel, map, total_size * count,
+                           &buffer->bo, &buffer->offset);
         buffer->stride = offset;
         j++;
 
index 4edf29ec7594c3425001ed0cde7cecc6b66ae27c..9d54f47fead5b5d6e195b51bad43a3d7995ccc86 100644 (file)
@@ -619,7 +619,7 @@ void intel_upload_data(struct intel_context *intel,
    *return_offset = intel->upload.offset;
 
    if (intel->upload.buffer_len &&
-       intel->upload.buffer_len + asize > sizeof(intel->upload.buffer))
+       intel->upload.buffer_len + size > sizeof(intel->upload.buffer))
    {
       drm_intel_bo_subdata(intel->upload.bo,
                           intel->upload.buffer_offset,
@@ -646,25 +646,12 @@ void intel_upload_data(struct intel_context *intel,
    intel->upload.offset += asize;
 }
 
-void *intel_upload_map(struct intel_context *intel,
-                      GLuint size,
-                      drm_intel_bo **return_bo,
-                      GLuint *return_offset)
+void *intel_upload_map(struct intel_context *intel, GLuint size)
 {
-   GLuint asize = ALIGN(size, 64);
    char *ptr;
 
-   if (intel->upload.bo == NULL ||
-       intel->upload.offset + size > intel->upload.bo->size) {
-      wrap_buffers(intel, size);
-   }
-
-   drm_intel_bo_reference(intel->upload.bo);
-   *return_bo = intel->upload.bo;
-   *return_offset = intel->upload.offset;
-
    if (intel->upload.buffer_len &&
-       intel->upload.buffer_len + asize > sizeof(intel->upload.buffer))
+       intel->upload.buffer_len + size > sizeof(intel->upload.buffer))
    {
       drm_intel_bo_subdata(intel->upload.bo,
                           intel->upload.buffer_offset,
@@ -673,26 +660,25 @@ void *intel_upload_map(struct intel_context *intel,
       intel->upload.buffer_len = 0;
    }
 
-   if (size < sizeof(intel->upload.buffer))
-   {
-      if (intel->upload.buffer_len == 0)
-        intel->upload.buffer_offset = intel->upload.offset;
-
+   if (size <= sizeof(intel->upload.buffer))
       ptr = intel->upload.buffer + intel->upload.buffer_len;
-      intel->upload.buffer_len += asize;
-   }
    else
-   {
-      drm_intel_gem_bo_map_gtt(intel->upload.bo);
-      ptr = intel->upload.bo->virtual;
-      ptr += intel->upload.offset;
-   }
-
-   intel->upload.offset += asize;
+      ptr = malloc(size);
 
    return ptr;
 }
 
+void intel_upload_unmap(struct intel_context *intel,
+                       const void *ptr, GLuint size,
+                       drm_intel_bo **return_bo,
+                       GLuint *return_offset)
+{
+   intel_upload_data(intel, ptr, size, return_bo, return_offset);
+
+   if (size > sizeof(intel->upload.buffer))
+      free((void*)ptr);
+}
+
 drm_intel_bo *
 intel_bufferobj_source(struct intel_context *intel,
                        struct intel_buffer_object *intel_obj,
index 4b66bf7d5939e209c6a30ff3f70e9486756bfc0d..2d86becdf3e72d4eef3b1d835023848710671792 100644 (file)
@@ -76,9 +76,11 @@ void intel_upload_data(struct intel_context *intel,
                       GLuint *return_offset);
 
 void *intel_upload_map(struct intel_context *intel,
-                      GLuint size,
-                      drm_intel_bo **return_bo,
-                      GLuint *return_offset);
+                      GLuint size);
+void intel_upload_unmap(struct intel_context *intel,
+                       const void *ptr, GLuint size,
+                       drm_intel_bo **return_bo,
+                       GLuint *return_offset);
 
 void intel_upload_finish(struct intel_context *intel);