diff options
author | José Fonseca <jfonseca@vmware.com> | 2010-02-22 19:24:18 +0000 |
---|---|---|
committer | José Fonseca <jfonseca@vmware.com> | 2010-02-22 19:38:10 +0000 |
commit | b5fa76097223ba1d07e4c3feb6d266a2e9b81b7f (patch) | |
tree | 09d83b8f62b72e5b7e53dfa12e906f47fdf9fb88 | |
parent | 69cf45cdae25c5676394d014fff904b466279a28 (diff) |
svga: Upload user buffers only once.
-rw-r--r-- | src/gallium/drivers/svga/svga_pipe_vertex.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_screen_buffer.c | 9 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_screen_buffer.h | 13 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_state_vdecl.c | 51 |
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; } } |