radeonsi/nir: fix counting shader inputs & outputs
[mesa.git] / src / gallium / drivers / nouveau / nouveau_buffer.c
index 1695553d793e9e451a5f8716ca076855215f746e..97305d993ff99941b154cb6c6b2896e45e4d6222 100644 (file)
@@ -11,8 +11,6 @@
 #include "nouveau_buffer.h"
 #include "nouveau_mm.h"
 
-#define NOUVEAU_TRANSFER_PUSHBUF_THRESHOLD 192
-
 struct nouveau_transfer {
    struct pipe_transfer base;
 
@@ -147,7 +145,7 @@ nouveau_transfer_staging(struct nouveau_context *nv,
    if (!nv->push_data)
       permit_pb = false;
 
-   if ((size <= NOUVEAU_TRANSFER_PUSHBUF_THRESHOLD) && permit_pb) {
+   if ((size <= nv->screen->transfer_pushbuf_threshold) && permit_pb) {
       tx->map = align_malloc(size, NOUVEAU_MIN_BUFFER_MAP_ALIGN);
       if (tx->map)
          tx->map += adj;
@@ -163,7 +161,7 @@ nouveau_transfer_staging(struct nouveau_context *nv,
    return tx->map;
 }
 
-/* Copies data from the resource into the the transfer's temporary GART
+/* Copies data from the resource into the transfer's temporary GART
  * buffer. Also updates buf->data if present.
  *
  * Maybe just migrate to GART right away if we actually need to do this. */
@@ -406,9 +404,6 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe,
        !util_ranges_intersect(&buf->valid_buffer_range, box->x, box->x + box->width))
       usage |= PIPE_TRANSFER_DISCARD_RANGE | PIPE_TRANSFER_UNSYNCHRONIZED;
 
-   if (usage & PIPE_TRANSFER_PERSISTENT)
-      usage |= PIPE_TRANSFER_UNSYNCHRONIZED;
-
    if (buf->domain == NOUVEAU_BO_VRAM) {
       if (usage & NOUVEAU_TRANSFER_DISCARD) {
          /* Set up a staging area for the user to write to. It will be copied
@@ -476,7 +471,8 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe,
     * complete its operation, or set up a staging area to perform our work in.
     */
    if (nouveau_buffer_busy(buf, usage & PIPE_TRANSFER_READ_WRITE)) {
-      if (unlikely(usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE)) {
+      if (unlikely(usage & (PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE |
+                            PIPE_TRANSFER_PERSISTENT))) {
          /* Discarding was not possible, must sync because
           * subsequent transfers might use UNSYNCHRONIZED. */
          nouveau_buffer_sync(nv, buf, usage & PIPE_TRANSFER_READ_WRITE);
@@ -634,7 +630,6 @@ const struct u_resource_vtbl nouveau_buffer_vtbl =
    nouveau_buffer_transfer_map,          /* transfer_map */
    nouveau_buffer_transfer_flush_region, /* transfer_flush_region */
    nouveau_buffer_transfer_unmap,        /* transfer_unmap */
-   u_default_transfer_inline_write    /* transfer_inline_write */
 };
 
 struct pipe_resource *
@@ -685,10 +680,7 @@ nouveau_buffer_create(struct pipe_screen *pscreen,
       if (buffer->base.bind & screen->sysmem_bindings)
          buffer->domain = NOUVEAU_BO_GART;
    }
-   /* There can be very special situations where we want non-gpu-mapped
-    * buffers, but never through this interface.
-    */
-   assert(buffer->domain);
+
    ret = nouveau_buffer_allocate(screen, buffer, buffer->domain);
 
    if (ret == false)
@@ -843,6 +835,39 @@ nouveau_user_buffer_upload(struct nouveau_context *nv,
    return true;
 }
 
+/* Invalidate underlying buffer storage, reset fences, reallocate to non-busy
+ * buffer.
+ */
+void
+nouveau_buffer_invalidate(struct pipe_context *pipe,
+                          struct pipe_resource *resource)
+{
+   struct nouveau_context *nv = nouveau_context(pipe);
+   struct nv04_resource *buf = nv04_resource(resource);
+   int ref = buf->base.reference.count - 1;
+
+   /* Shared buffers shouldn't get reallocated */
+   if (unlikely(buf->base.bind & PIPE_BIND_SHARED))
+      return;
+
+   /* We can't touch persistent/coherent buffers */
+   if (buf->base.flags & (PIPE_RESOURCE_FLAG_MAP_PERSISTENT |
+                          PIPE_RESOURCE_FLAG_MAP_COHERENT))
+      return;
+
+   /* If the buffer is sub-allocated and not currently being written, just
+    * wipe the valid buffer range. Otherwise we have to create fresh
+    * storage. (We don't keep track of fences for non-sub-allocated BO's.)
+    */
+   if (buf->mm && !nouveau_buffer_busy(buf, PIPE_TRANSFER_WRITE)) {
+      util_range_set_empty(&buf->valid_buffer_range);
+   } else {
+      nouveau_buffer_reallocate(nv->screen, buf, buf->domain);
+      if (ref > 0) /* any references inside context possible ? */
+         nv->invalidate_resource_storage(nv, &buf->base, ref);
+   }
+}
+
 
 /* Scratch data allocation. */