diff options
author | José Fonseca <jfonseca@vmware.com> | 2010-01-21 12:12:33 -0800 |
---|---|---|
committer | José Fonseca <jfonseca@vmware.com> | 2010-01-21 15:18:40 -0800 |
commit | 0ae076bf40782c48b1b26ca63ed2c349532dd81e (patch) | |
tree | c47c315f753c09746d80680bf382ee53fb38729d /src/gallium | |
parent | efc08bddb7622e4acfa795b58e1264b64b78ab4f (diff) |
svga: Follow buffer usage semantics properly.
It's necessary to download buffers from the host always, except if the
buffer is undefined, because:
- just PIPE_BUFFER_USAGE_CPU_WRITE doesn't guarantee all data is written
-- old contents may still pierce through
- PIPE_BUFFER_USAGE_DISCARD refers to a range, not the whole buffer, so
unless we track which parts have been modified and not we still need
to download the data.
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/svga/svga_screen_buffer.c | 10 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_screen_buffer.h | 5 |
2 files changed, 11 insertions, 4 deletions
diff --git a/src/gallium/drivers/svga/svga_screen_buffer.c b/src/gallium/drivers/svga/svga_screen_buffer.c index c014f2ee20..cc2d3cd9e9 100644 --- a/src/gallium/drivers/svga/svga_screen_buffer.c +++ b/src/gallium/drivers/svga/svga_screen_buffer.c @@ -355,6 +355,8 @@ svga_buffer_upload_flush(struct svga_context *svga, sbuf->hw.svga = NULL; sbuf->hw.boxes = NULL; + sbuf->host_written = TRUE; + /* Decrement reference count */ pipe_buffer_reference((struct pipe_buffer **)&sbuf, NULL); } @@ -436,17 +438,17 @@ svga_buffer_map_range( struct pipe_screen *screen, } else { if(!sbuf->hw.buf) { - struct svga_winsys_surface *handle = sbuf->handle; - if(svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK) return NULL; /* Populate the hardware storage if the host surface pre-existed */ - if((usage & PIPE_BUFFER_USAGE_CPU_READ) && handle) { + if(sbuf->host_written) { SVGA3dSurfaceDMAFlags flags; enum pipe_error ret; struct pipe_fence_handle *fence = NULL; + assert(sbuf->handle); + SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "dma from sid %p (buffer), bytes %u - %u\n", sbuf->handle, 0, sbuf->base.size); @@ -478,7 +480,7 @@ svga_buffer_map_range( struct pipe_screen *screen, } } else { - if((usage & PIPE_BUFFER_USAGE_CPU_READ) && !sbuf->needs_flush) { + if(!(usage & PIPE_BUFFER_USAGE_DISCARD) && !sbuf->needs_flush) { /* We already had the hardware storage but we would have to issue * a download if we hadn't, so move the buffer to the begginning * of the LRU list. diff --git a/src/gallium/drivers/svga/svga_screen_buffer.h b/src/gallium/drivers/svga/svga_screen_buffer.h index 5d7af5a7c5..c9bbe37f32 100644 --- a/src/gallium/drivers/svga/svga_screen_buffer.h +++ b/src/gallium/drivers/svga/svga_screen_buffer.h @@ -135,6 +135,11 @@ struct svga_buffer */ struct svga_winsys_surface *handle; + /** + * Whether the host has been ever written. + */ + boolean host_written; + struct { unsigned count; boolean writing; |