svga: Upload user buffers only once.
authorJosé Fonseca <jfonseca@vmware.com>
Mon, 22 Feb 2010 19:24:18 +0000 (19:24 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Mon, 22 Feb 2010 21:47:22 +0000 (21:47 +0000)
src/gallium/drivers/svga/svga_pipe_vertex.c
src/gallium/drivers/svga/svga_screen_buffer.c
src/gallium/drivers/svga/svga_screen_buffer.h
src/gallium/drivers/svga/svga_state_vdecl.c

index ffc0f99565b09cd6e268e7142ec13c8b1184aa2e..836b8441da219f4c56ac9d3ba21e4276d9dca6dd 100644 (file)
@@ -49,7 +49,7 @@ static void svga_set_vertex_buffers(struct pipe_context *pipe,
    /* Adjust refcounts */
    for (i = 0; i < count; i++) {
       pipe_buffer_reference(&svga->curr.vb[i].buffer, buffers[i].buffer);
-      if (svga_buffer(buffers[i].buffer)->user)
+      if (svga_buffer_is_user_buffer(buffers[i].buffer))
          any_user_buffer = TRUE;
    }
 
index e3f4a4626050259b1ff959a93a6cf42ae7f5ca7b..1ff6a3a5b317172dce122055b466ea8e52ce5eb8 100644 (file)
@@ -151,6 +151,8 @@ static INLINE enum pipe_error
 svga_buffer_create_hw_storage(struct svga_screen *ss,
                               struct svga_buffer *sbuf)
 {
+   assert(!sbuf->user);
+
    if(!sbuf->hwbuf) {
       unsigned alignment = sbuf->base.alignment;
       unsigned usage = 0;
@@ -515,6 +517,9 @@ svga_buffer_destroy( struct pipe_buffer *buf )
    if(sbuf->handle)
       svga_buffer_destroy_host_surface(ss, sbuf);
    
+   if(sbuf->uploaded.buffer)
+      pipe_buffer_reference(&sbuf->uploaded.buffer, NULL);
+
    if(sbuf->hwbuf)
       svga_buffer_destroy_hw_storage(ss, sbuf);
    
@@ -613,11 +618,12 @@ svga_screen_init_buffer_functions(struct pipe_screen *screen)
 
 
 /**
- * Copy the contents of the user buffer / malloc buffer to a hardware buffer.
+ * Copy the contents of the malloc buffer to a hardware buffer.
  */
 static INLINE enum pipe_error
 svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf)
 {
+   assert(!sbuf->user);
    if(!sbuf->hwbuf) {
       enum pipe_error ret;
       void *map;
@@ -754,6 +760,7 @@ svga_buffer_handle(struct svga_context *svga,
    sbuf = svga_buffer(buf);
    
    assert(!sbuf->map.count);
+   assert(!sbuf->user);
    
    if(!sbuf->handle) {
       ret = svga_buffer_create_host_surface(ss, sbuf);
index 937cf30478dda69df160ec2679aef5e43e0e71ec..8c862fa62d65b1b231f8dc655027d5f5ca8a05f4 100644 (file)
@@ -134,6 +134,19 @@ struct svga_buffer
       unsigned num_ranges;
    } map;
 
+   /**
+    * Information about uploaded version of user buffers.
+    */
+   struct {
+      struct pipe_buffer *buffer;
+
+      /**
+       * We combine multiple user buffers into the same hardware buffer. This
+       * is the relative offset within that buffer.
+       */
+      unsigned offset;
+   } uploaded;
+
    /**
     * DMA'ble memory.
     *
index d1066ce13b082fb04cd837811f39319d79116719..ded903170b5c25df77c5cd55fe95e302917f4139 100644 (file)
@@ -54,33 +54,30 @@ upload_user_buffers( struct svga_context *svga )
    {
       if (svga_buffer_is_user_buffer(svga->curr.vb[i].buffer))
       {
-         struct pipe_buffer *upload_buffer = NULL;
-         unsigned offset = /*svga->curr.vb[i].buffer_offset*/ 0;
-         unsigned size = svga->curr.vb[i].buffer->size /*- offset*/;
-         unsigned upload_offset;
-
-         ret = u_upload_buffer( svga->upload_vb,
-                                offset,
-                                size,
-                                svga->curr.vb[i].buffer,
-                                &upload_offset,
-                                &upload_buffer );
-         if (ret)
-            return ret;
-
-         if (0)
-            debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n", 
-                         __FUNCTION__, 
-                         i,
-                         svga->curr.vb[i].buffer,
-                         upload_buffer, upload_offset, size);
-
-         /* Make sure we release the old buffer and end up with the
-          * correct refcount on the uploaded buffer.
-          */
-         pipe_buffer_reference( &svga->curr.vb[i].buffer, NULL );
-         svga->curr.vb[i].buffer = upload_buffer;
-         svga->curr.vb[i].buffer_offset = upload_offset;
+         struct svga_buffer *buffer = svga_buffer(svga->curr.vb[i].buffer);
+
+         if (!buffer->uploaded.buffer) {
+            ret = u_upload_buffer( svga->upload_vb,
+                                   0,
+                                   buffer->base.size,
+                                   &buffer->base,
+                                   &buffer->uploaded.offset,
+                                   &buffer->uploaded.buffer );
+            if (ret)
+               return ret;
+
+            if (0)
+               debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n",
+                            __FUNCTION__,
+                            i,
+                            buffer,
+                            buffer->uploaded.buffer,
+                            buffer->uploaded.offset,
+                            buffer->base.size);
+         }
+
+         pipe_buffer_reference( &svga->curr.vb[i].buffer, buffer->uploaded.buffer );
+         svga->curr.vb[i].buffer_offset = buffer->uploaded.offset;
       }
    }