summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2010-02-22 19:24:18 +0000
committerJosé Fonseca <jfonseca@vmware.com>2010-02-22 19:38:10 +0000
commitb5fa76097223ba1d07e4c3feb6d266a2e9b81b7f (patch)
tree09d83b8f62b72e5b7e53dfa12e906f47fdf9fb88
parent69cf45cdae25c5676394d014fff904b466279a28 (diff)
svga: Upload user buffers only once.
-rw-r--r--src/gallium/drivers/svga/svga_pipe_vertex.c2
-rw-r--r--src/gallium/drivers/svga/svga_screen_buffer.c9
-rw-r--r--src/gallium/drivers/svga/svga_screen_buffer.h13
-rw-r--r--src/gallium/drivers/svga/svga_state_vdecl.c51
4 files changed, 46 insertions, 29 deletions
diff --git a/src/gallium/drivers/svga/svga_pipe_vertex.c b/src/gallium/drivers/svga/svga_pipe_vertex.c
index 87ac9231d5..adc23c6a48 100644
--- a/src/gallium/drivers/svga/svga_pipe_vertex.c
+++ b/src/gallium/drivers/svga/svga_pipe_vertex.c
@@ -50,7 +50,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;
}
diff --git a/src/gallium/drivers/svga/svga_screen_buffer.c b/src/gallium/drivers/svga/svga_screen_buffer.c
index 639ca1a32d..83431c95cc 100644
--- a/src/gallium/drivers/svga/svga_screen_buffer.c
+++ b/src/gallium/drivers/svga/svga_screen_buffer.c
@@ -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;
@@ -514,6 +516,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);
@@ -612,11 +617,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;
@@ -753,6 +759,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);
diff --git a/src/gallium/drivers/svga/svga_screen_buffer.h b/src/gallium/drivers/svga/svga_screen_buffer.h
index 937cf30478..8c862fa62d 100644
--- a/src/gallium/drivers/svga/svga_screen_buffer.h
+++ b/src/gallium/drivers/svga/svga_screen_buffer.h
@@ -135,6 +135,19 @@ struct svga_buffer
} 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.
*
* A piece of GMR memory, with the same size of the buffer. It is created
diff --git a/src/gallium/drivers/svga/svga_state_vdecl.c b/src/gallium/drivers/svga/svga_state_vdecl.c
index c534308f50..2c1d140c80 100644
--- a/src/gallium/drivers/svga/svga_state_vdecl.c
+++ b/src/gallium/drivers/svga/svga_state_vdecl.c
@@ -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;
}
}