gallium/svga: Only upload parts of vertexarrays that are actually used
authorThomas Hellstrom <thellstrom@vmware.com>
Wed, 9 Mar 2011 11:39:14 +0000 (12:39 +0100)
committerThomas Hellstrom <thellstrom@vmware.com>
Thu, 10 Mar 2011 13:30:50 +0000 (14:30 +0100)
Make sure we only upload parts of vertex arrays that are actually used
by a draw command.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
src/gallium/drivers/svga/svga_draw_arrays.c
src/gallium/drivers/svga/svga_draw_elements.c
src/gallium/drivers/svga/svga_resource_buffer.h
src/gallium/drivers/svga/svga_resource_buffer_upload.c
src/gallium/drivers/svga/svga_state_vdecl.c

index a6518042eb9d76e5487e910440f34e101059d2d5..1bb29cc2335206c68e7818b29e0eb104f777fd5d 100644 (file)
@@ -32,6 +32,7 @@
 #include "svga_draw.h"
 #include "svga_draw_private.h"
 #include "svga_context.h"
+#include "svga_resource_buffer.h"
 
 
 #define DBG 0
@@ -191,6 +192,8 @@ simple_draw_arrays( struct svga_hwtnl *hwtnl,
    SVGA3dPrimitiveRange range;
    unsigned hw_prim;
    unsigned hw_count;
+   unsigned i;
+   unsigned src_offs;
 
    hw_prim = svga_translate_prim(prim, count, &hw_count);
    if (hw_count == 0)
@@ -209,6 +212,22 @@ simple_draw_arrays( struct svga_hwtnl *hwtnl,
     * looking at those numbers knows to adjust them by
     * range.indexBias.
     */
+
+   for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
+      struct pipe_resource *vb = hwtnl->cmd.vdecl_vb[i];
+      struct svga_buffer *sbuf = svga_buffer(vb);
+      unsigned stride = hwtnl->cmd.vdecl[i].array.stride;
+      unsigned tmp_src_offs = sbuf->source_offset;
+
+      if (stride)
+         tmp_src_offs /= stride;
+      assert(i == 0 || tmp_src_offs == src_offs);
+      src_offs = tmp_src_offs;
+   }
+
+   range.indexBias = start - src_offs;
+   assert(range.indexBias >= 0);
+
    return svga_hwtnl_prim( hwtnl, &range, 0, count - 1, NULL );
 }
 
index 7d420c6b2954bbf1b9a7e4e1ed969901fcbf4b71..cf61144c9aebfc567a555b249d2dd55ebd598727 100644 (file)
@@ -113,6 +113,7 @@ svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl,
    unsigned hw_count;
    unsigned index_offset = start * index_size;
    int ret = PIPE_OK;
+   unsigned i, src_offs;
 
    hw_prim = svga_translate_prim(prim, count, &hw_count);
    if (hw_count == 0)
@@ -142,6 +143,21 @@ svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl,
       index_buffer = upload_buffer;
    }
 
+   for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
+      struct pipe_resource *vb = hwtnl->cmd.vdecl_vb[i];
+      struct svga_buffer *sbuf = svga_buffer(vb);
+      unsigned stride = hwtnl->cmd.vdecl[i].array.stride;
+      unsigned tmp_src_offs = sbuf->source_offset;
+
+      if (stride)
+        tmp_src_offs /= stride;
+      assert(i == 0 || tmp_src_offs == src_offs);
+      src_offs = tmp_src_offs;
+   }
+
+   index_bias -= src_offs;
+   assert(index_bias >= 0);
+
    range.primType = hw_prim;
    range.primitiveCount = hw_count;
    range.indexArray.offset = index_offset;
index c559f70ec12430f6d8452e58ed9c0d84f955374e..31a6fc6fef13deb4eec71a5adb40ba806bf90dd9 100644 (file)
@@ -143,6 +143,12 @@ struct svga_buffer
       unsigned offset;
    } uploaded;
 
+   /**
+    * The offset in the source user buffer that matches the
+    * uploaded offset
+    */
+   unsigned source_offset;
+
    /**
     * DMA'ble memory.
     *
index b7d54605e665538e10bf4694c23a30071d2ca6c2..601643236a9a28769f522d1f2f3d7a94a515d29b 100644 (file)
@@ -695,6 +695,7 @@ svga_redefine_user_buffer(struct pipe_context *pipe,
       sbuf->key.size.width = sbuf->b.b.width0 = offset + size;
    }
 
+   sbuf->source_offset = offset;
    pipe_mutex_unlock(ss->swc_mutex);
 
    svga->curr.any_user_vertex_buffers = TRUE;
index 2f85f9488f9dda03578d39b15080da7d5152d46c..5bd51ca677d1d623ebd27e0d329f7d14a70e6f56 100644 (file)
@@ -59,8 +59,8 @@ upload_user_buffers( struct svga_context *svga )
          if (!buffer->uploaded.buffer) {
             boolean flushed;
             ret = u_upload_buffer( svga->upload_vb,
-                                   0, 0,
-                                   buffer->b.b.width0,
+                                   0, buffer->source_offset,
+                                   buffer->b.b.width0 - buffer->source_offset,
                                    &buffer->b.b,
                                    &buffer->uploaded.offset,
                                    &buffer->uploaded.buffer,
@@ -69,16 +69,19 @@ upload_user_buffers( struct svga_context *svga )
                return ret;
 
             if (0)
-               debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n",
+               debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sofs %d"
+                            " sz %d\n",
                             __FUNCTION__,
                             i,
                             buffer,
                             buffer->uploaded.buffer,
                             buffer->uploaded.offset,
+                            buffer->source_offset,
                             buffer->b.b.width0);
          }
 
          svga->curr.vb[i].buffer_offset = buffer->uploaded.offset;
+         svga_buffer(buffer->uploaded.buffer)->source_offset = buffer->source_offset;
       }
    }