svga: Ignore redefine_user_buffer calls
[mesa.git] / src / gallium / drivers / svga / svga_resource_buffer_upload.c
index acef60f46472d12197955f2848e9c439f728e371..a657a8bc2240ed0c1e4832e9dc095f0c8268fea8 100644 (file)
 #include "svga_debug.h"
 
 
-/* Allocate a winsys_buffer (ie. DMA, aka GMR memory).
+/**
+ * Allocate a winsys_buffer (ie. DMA, aka GMR memory).
+ *
+ * It will flush and retry in case the first attempt to create a DMA buffer
+ * fails, so it should not be called from any function involved in flushing
+ * to avoid recursion.
  */
 struct svga_winsys_buffer *
-svga_winsys_buffer_create( struct svga_screen *ss,
+svga_winsys_buffer_create( struct svga_context *svga,
                            unsigned alignment, 
                            unsigned usage,
                            unsigned size )
 {
-   struct svga_winsys_screen *sws = ss->sws;
+   struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
+   struct svga_winsys_screen *sws = svgascreen->sws;
    struct svga_winsys_buffer *buf;
    
    /* Just try */
    buf = sws->buffer_create(sws, alignment, usage, size);
-   if(!buf) {
-
-      SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "flushing screen to find %d bytes GMR\n", 
+   if (!buf) {
+      SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "flushing context to find %d bytes GMR\n",
                size); 
       
       /* Try flushing all pending DMAs */
-      svga_screen_flush(ss, NULL);
+      svga_context_flush(svga, NULL);
       buf = sws->buffer_create(sws, alignment, usage, size);
-
    }
    
    return buf;
@@ -95,11 +99,12 @@ svga_buffer_create_hw_storage(struct svga_screen *ss,
    assert(!sbuf->user);
 
    if(!sbuf->hwbuf) {
+      struct svga_winsys_screen *sws = ss->sws;
       unsigned alignment = 16;
       unsigned usage = 0;
       unsigned size = sbuf->b.b.width0;
       
-      sbuf->hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
+      sbuf->hwbuf = sws->buffer_create(sws, alignment, usage, size);
       if(!sbuf->hwbuf)
          return PIPE_ERROR_OUT_OF_MEMORY;
       
@@ -115,6 +120,8 @@ enum pipe_error
 svga_buffer_create_host_surface(struct svga_screen *ss,
                                 struct svga_buffer *sbuf)
 {
+   assert(!sbuf->user);
+
    if(!sbuf->handle) {
       sbuf->key.flags = 0;
       
@@ -236,12 +243,17 @@ svga_buffer_upload_command(struct svga_context *svga,
  * Patch up the upload DMA command reserved by svga_buffer_upload_command
  * with the final ranges.
  */
-static void
+void
 svga_buffer_upload_flush(struct svga_context *svga,
                          struct svga_buffer *sbuf)
 {
    SVGA3dCopyBox *boxes;
    unsigned i;
+   struct pipe_resource *dummy;
+
+   if (!sbuf->dma.pending) {
+      return;
+   }
 
    assert(sbuf->handle); 
    assert(sbuf->hwbuf);
@@ -279,17 +291,18 @@ svga_buffer_upload_flush(struct svga_context *svga,
    sbuf->head.next = sbuf->head.prev = NULL; 
 #endif
    sbuf->dma.pending = FALSE;
+   sbuf->dma.flags.discard = FALSE;
+   sbuf->dma.flags.unsynchronized = FALSE;
 
    sbuf->dma.svga = NULL;
    sbuf->dma.boxes = NULL;
 
-   /* Decrement reference count */
-   pipe_reference(&(sbuf->b.b.reference), NULL);
-   sbuf = NULL;
+   /* Decrement reference count (and potentially destroy) */
+   dummy = &sbuf->b.b;
+   pipe_resource_reference(&dummy, NULL);
 }
 
 
-
 /**
  * Note a dirty range.
  *
@@ -320,12 +333,6 @@ svga_buffer_add_range(struct svga_buffer *sbuf,
 
    /*
     * Try to grow one of the ranges.
-    *
-    * Note that it is not this function task to care about overlapping ranges,
-    * as the GMR was already given so it is too late to do anything. Situations
-    * where overlapping ranges may pose a problem should be detected via
-    * pipe_context::is_resource_referenced and the context that refers to the
-    * buffer should be flushed.
     */
 
    for(i = 0; i < sbuf->map.num_ranges; ++i) {
@@ -340,6 +347,11 @@ svga_buffer_add_range(struct svga_buffer *sbuf,
       if (dist <= 0) {
          /*
           * Ranges are contiguous or overlapping -- extend this one and return.
+          *
+          * Note that it is not this function's task to prevent overlapping
+          * ranges, as the GMR was already given so it is too late to do
+          * anything.  If the ranges overlap here it must surely be because
+          * PIPE_TRANSFER_UNSYNCHRONIZED was set.
           */
 
          sbuf->map.ranges[i].start = MIN2(sbuf->map.ranges[i].start, start);
@@ -363,8 +375,7 @@ svga_buffer_add_range(struct svga_buffer *sbuf,
     * pending DMA upload and start clean.
     */
 
-   if(sbuf->dma.pending)
-      svga_buffer_upload_flush(sbuf->dma.svga, sbuf);
+   svga_buffer_upload_flush(sbuf->dma.svga, sbuf);
 
    assert(!sbuf->dma.pending);
    assert(!sbuf->dma.svga);
@@ -476,12 +487,12 @@ svga_buffer_upload_piecewise(struct svga_screen *ss,
          if (offset + size > range->end)
             size = range->end - offset;
 
-         hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
+         hwbuf = sws->buffer_create(sws, alignment, usage, size);
          while (!hwbuf) {
             size /= 2;
             if (!size)
                return PIPE_ERROR_OUT_OF_MEMORY;
-            hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
+            hwbuf = sws->buffer_create(sws, alignment, usage, size);
          }
 
          SVGA_DBG(DEBUG_DMA, "  bytes %u - %u\n",
@@ -632,3 +643,24 @@ svga_context_flush_buffers(struct svga_context *svga)
       next = curr->next;
    }
 }
+
+
+void
+svga_redefine_user_buffer(struct pipe_context *pipe,
+                          struct pipe_resource *resource,
+                          unsigned offset,
+                          unsigned size)
+{
+   struct svga_buffer *sbuf = svga_buffer(resource);
+
+   assert(sbuf->user);
+   assert(!sbuf->dma.pending);
+   assert(!sbuf->handle);
+   assert(!sbuf->hwbuf);
+
+   /*
+    * We always treat the contents of user-buffers as volatile,
+    * so no particular action needed here.
+    */
+
+}