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.
This commit is contained in:
José Fonseca
2010-01-21 12:12:33 -08:00
parent efc08bddb7
commit 0ae076bf40
2 changed files with 11 additions and 4 deletions
@@ -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.
@@ -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;