svga: Follow buffer usage semantics properly.
authorJosé Fonseca <jfonseca@vmware.com>
Thu, 21 Jan 2010 20:12:33 +0000 (12:12 -0800)
committerJosé Fonseca <jfonseca@vmware.com>
Thu, 21 Jan 2010 23:18:40 +0000 (15:18 -0800)
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.

src/gallium/drivers/svga/svga_screen_buffer.c
src/gallium/drivers/svga/svga_screen_buffer.h

index c014f2ee203fce41e736f392a66b8e3df38d0b2a..cc2d3cd9e9759be0a30d60e75a45029e09c49b47 100644 (file)
@@ -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.
index 5d7af5a7c5049ef0cba2a16f14f49c5d8251948b..c9bbe37f32c3176619b1865818408a1385269f17 100644 (file)
@@ -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;