gallium: add flag PIPE_TRANSFER_MAP_PERMANENTLY
authorMarek Olšák <maraeo@gmail.com>
Mon, 2 Jan 2012 00:13:15 +0000 (01:13 +0100)
committerMarek Olšák <maraeo@gmail.com>
Thu, 5 Jan 2012 17:29:11 +0000 (18:29 +0100)
Please see the diff for further info.

This paves the way for moving user buffer uploads out of drivers and should
allow to clean up the mess in u_upload_mgr in the meantime.

For now only allowed for buffers on r300 and r600.

Acked-by: Christian König <deathsimple@vodafone.de>
12 files changed:
src/gallium/drivers/i915/i915_resource_buffer.c
src/gallium/drivers/i915/i915_resource_texture.c
src/gallium/drivers/llvmpipe/lp_texture.c
src/gallium/drivers/nouveau/nouveau_buffer.c
src/gallium/drivers/nv50/nv50_transfer.c
src/gallium/drivers/nvc0/nvc0_transfer.c
src/gallium/drivers/nvfx/nvfx_transfer.c
src/gallium/drivers/r300/r300_transfer.c
src/gallium/drivers/r600/r600_texture.c
src/gallium/drivers/svga/svga_resource_buffer.c
src/gallium/drivers/svga/svga_resource_texture.c
src/gallium/include/pipe/p_defines.h

index 77c03450b3a24b81449838c82d2cca95a8e1bdcf..c54e481698e5e0dd542e7d946ce50d6746910b3d 100644 (file)
@@ -68,8 +68,13 @@ i915_get_transfer(struct pipe_context *pipe,
                   const struct pipe_box *box)
 {
    struct i915_context *i915 = i915_context(pipe);
-   struct pipe_transfer *transfer = util_slab_alloc(&i915->transfer_pool);
+   struct pipe_transfer *transfer;
 
+   if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) {
+      return NULL;
+   }
+
+   transfer = util_slab_alloc(&i915->transfer_pool);
    if (transfer == NULL)
       return NULL;
 
index 8ff733a7be530f261d8fe3e54084fe1192a51449..64d071c9d53c04e739a66e66296fbe5d81efffc6 100644 (file)
@@ -720,9 +720,14 @@ i915_texture_get_transfer(struct pipe_context *pipe,
 {
    struct i915_context *i915 = i915_context(pipe);
    struct i915_texture *tex = i915_texture(resource);
-   struct i915_transfer *transfer = util_slab_alloc(&i915->texture_transfer_pool);
+   struct i915_transfer *transfer;
    boolean use_staging_texture = FALSE;
 
+   if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) {
+      return NULL;
+   }
+
+   transfer = util_slab_alloc(&i915->texture_transfer_pool);
    if (transfer == NULL)
       return NULL;
 
index ca38571b2bc273d4a0da37142a2ba2d8fb06c8dc..d86d493a0a21d4c594b071b8d81af369157348f6 100644 (file)
@@ -587,6 +587,10 @@ llvmpipe_get_transfer(struct pipe_context *pipe,
    assert(resource);
    assert(level <= resource->last_level);
 
+   if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) {
+      return NULL;
+   }
+
    /*
     * Transfers, like other pipe operations, must happen in order, so flush the
     * context if necessary.
index f822625af9094977b7ceaba4810f98d09df0c256..02186ba373938532b7c67123bcddaa09d2abedd6 100644 (file)
@@ -172,7 +172,13 @@ nouveau_buffer_transfer_get(struct pipe_context *pipe,
 {
    struct nv04_resource *buf = nv04_resource(resource);
    struct nouveau_context *nv = nouveau_context(pipe);
-   struct nouveau_transfer *xfr = CALLOC_STRUCT(nouveau_transfer);
+   struct nouveau_transfer *xfr;
+
+   if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) {
+      return NULL;
+   }
+
+   xfr = CALLOC_STRUCT(nouveau_transfer);
    if (!xfr)
       return NULL;
 
index 6f860e7334863639c92e96cfc766ba07c9404658..8ddebeb7451f5fb1a6dc428c201ed1ad0d9944ff 100644 (file)
@@ -243,7 +243,7 @@ nv50_miptree_transfer_new(struct pipe_context *pctx,
    uint32_t size;
    int ret;
 
-   if (usage & PIPE_TRANSFER_MAP_DIRECTLY)
+   if (usage & (PIPE_TRANSFER_MAP_DIRECTLY | PIPE_TRANSFER_MAP_PERMANENTLY))
       return NULL;
 
    tx = CALLOC_STRUCT(nv50_transfer);
index f16863733b7c907dffc59e060ca4b76fbd9c698f..c04f41f6ea38b7bfbfece21723520d1e3c61d2b2 100644 (file)
@@ -243,7 +243,7 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx,
    uint32_t size;
    int ret;
 
-   if (usage & PIPE_TRANSFER_MAP_DIRECTLY)
+   if (usage & (PIPE_TRANSFER_MAP_DIRECTLY | PIPE_TRANSFER_MAP_PERMANENTLY))
       return NULL;
 
    tx = CALLOC_STRUCT(nvc0_transfer);
index 7a218b18c6404a636be51181ef921b329d21faa3..605af8efa8ea4230609031e65a1b6d128cf8281f 100644 (file)
@@ -26,6 +26,9 @@ nvfx_transfer_new(struct pipe_context *pipe,
                  unsigned usage,
                  const struct pipe_box *box)
 {
+        if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) {
+                return NULL;
+        }
         if((usage & (PIPE_TRANSFER_UNSYNCHRONIZED | PIPE_TRANSFER_DONTBLOCK)) == PIPE_TRANSFER_DONTBLOCK)
         {
                 struct nouveau_bo* bo = ((struct nvfx_resource*)pt)->bo;
index afdd530d15dd76ef01d11f142bbb855ae0574d87..91e861a4a73327531c45499d3bd8cfc8a05e0264 100644 (file)
@@ -89,6 +89,10 @@ r300_texture_get_transfer(struct pipe_context *ctx,
     struct pipe_resource base;
     boolean referenced_cs, referenced_hw;
 
+    if (usage & (PIPE_TRANSFER_MAP_DIRECTLY | PIPE_TRANSFER_MAP_PERMANENTLY)) {
+        return NULL;
+    }
+
     referenced_cs =
         r300->rws->cs_is_buffer_referenced(r300->cs, tex->cs_buf);
     if (referenced_cs) {
index 8fe54c8a5397a1de2ce1c8178f1fa8f38b7e6d04..decd94152254bd8d06166c9d084b240b6d97b23a 100644 (file)
@@ -630,6 +630,10 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
        int r;
        boolean use_staging_texture = FALSE;
 
+       if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) {
+          return NULL;
+       }
+
        /* We cannot map a tiled texture directly because the data is
         * in a different order, therefore we do detiling using a blit.
         *
index fa713ee88adda16c864983942dcfee6276e6faf1..57ec752bf9b129fcbd29ada8699f74e77c125fe5 100644 (file)
@@ -74,6 +74,10 @@ svga_buffer_get_transfer(struct pipe_context *pipe,
    struct svga_buffer *sbuf = svga_buffer(resource);
    struct pipe_transfer *transfer;
 
+   if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) {
+      return NULL;
+   }
+
    transfer = CALLOC_STRUCT(pipe_transfer);
    if (transfer == NULL) {
       return NULL;
index 697c1d3c5e3e1bf635143d69889832eecb721eb1..4eb1068e2260f7359c0655339a94cf490a775a6e 100644 (file)
@@ -259,7 +259,7 @@ svga_texture_get_transfer(struct pipe_context *pipe,
    unsigned nblocksy = util_format_get_nblocksy(texture->format, box->height);
 
    /* We can't map texture storage directly */
-   if (usage & PIPE_TRANSFER_MAP_DIRECTLY)
+   if (usage & (PIPE_TRANSFER_MAP_DIRECTLY | PIPE_TRANSFER_MAP_PERMANENTLY))
       return NULL;
 
    assert(box->depth == 1);
index 3b3940db89373ba1a535f8af8d6076e1b9444227..91d8b1e4525832f874ea2656e246febad5d97f4e 100644 (file)
@@ -225,6 +225,22 @@ enum pipe_transfer_usage {
     */
    PIPE_TRANSFER_MAP_DIRECTLY = (1 << 2),
 
+   /**
+    * The transfer should map the resource storage directly and the GPU should
+    * be able to see what the CPU has written. Such a storage may stay mapped
+    * while issuing draw commands which use it. The only allowed usage is
+    * non-overlapping writes which are suballocated out of a big buffer.
+    * The minimum allowed alignment of suballocations is 256 bytes (this is
+    * a subject to change).
+    * The flag is intended to be used to avoid mapping and unmapping
+    * resources repeatedly when doing uploads and draws intermixed.
+    *
+    * The driver may return NULL if that isn't possible, and the state
+    * tracker needs to cope with that and use an alternative path
+    * without this flag.
+    */
+   PIPE_TRANSFER_MAP_PERMANENTLY = (1 << 3),
+
    /**
     * Discards the memory within the mapped region.
     *