[Mesa-dev] [PATCH 1/2] util/u_upload_mgr: Allow to also use it for downloads

Niels Ole Salscheider niels_ole at salscheider-online.de
Mon Mar 3 12:29:32 PST 2014


Signed-off-by: Niels Ole Salscheider <niels_ole at salscheider-online.de>
---
 src/gallium/auxiliary/hud/hud_context.c       |  3 +-
 src/gallium/auxiliary/util/u_blitter.c        |  3 +-
 src/gallium/auxiliary/util/u_upload_mgr.c     | 49 +++++++++++++++++++--------
 src/gallium/auxiliary/util/u_upload_mgr.h     | 13 +++++--
 src/gallium/auxiliary/util/u_vbuf.c           |  3 +-
 src/gallium/auxiliary/vl/vl_compositor.c      |  3 +-
 src/gallium/drivers/ilo/ilo_context.c         |  3 +-
 src/gallium/drivers/r300/r300_context.c       |  3 +-
 src/gallium/drivers/radeon/r600_pipe_common.c |  3 +-
 src/mesa/state_tracker/st_context.c           |  9 +++--
 10 files changed, 64 insertions(+), 28 deletions(-)

diff --git a/src/gallium/auxiliary/hud/hud_context.c b/src/gallium/auxiliary/hud/hud_context.c
index 465013c..567ec99 100644
--- a/src/gallium/auxiliary/hud/hud_context.c
+++ b/src/gallium/auxiliary/hud/hud_context.c
@@ -938,7 +938,8 @@ hud_create(struct pipe_context *pipe, struct cso_context *cso)
    hud->pipe = pipe;
    hud->cso = cso;
    hud->uploader = u_upload_create(pipe, 256 * 1024, 16,
-                                   PIPE_BIND_VERTEX_BUFFER);
+                                   PIPE_BIND_VERTEX_BUFFER,
+                                   UPLOAD_MGR_UPLOAD);
 
    /* font */
    if (!util_font_create(pipe, UTIL_FONT_FIXED_8X13, &hud->font)) {
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index 95e7fb6..fb606ee 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -333,7 +333,8 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
    for (i = 0; i < 4; i++)
       ctx->vertices[i][0][3] = 1; /*v.w*/
 
-   ctx->upload = u_upload_create(pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER);
+   ctx->upload = u_upload_create(pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER,
+                                 UPLOAD_MGR_UPLOAD);
 
    return &ctx->base;
 }
diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c
index 744ea2e..3205cd1 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.c
+++ b/src/gallium/auxiliary/util/u_upload_mgr.c
@@ -41,11 +41,14 @@
 struct u_upload_mgr {
    struct pipe_context *pipe;
 
-   unsigned default_size;  /* Minimum size of the upload buffer, in bytes. */
-   unsigned alignment;     /* Alignment of each sub-allocation. */
-   unsigned bind;          /* Bitmask of PIPE_BIND_* flags. */
-   unsigned map_flags;     /* Bitmask of PIPE_TRANSFER_* flags. */
-   boolean map_persistent; /* If persistent mappings are supported. */
+   unsigned default_size;          /* Minimum size of the upload buffer,
+                                    * in bytes. */
+   unsigned alignment;             /* Alignment of each sub-allocation. */
+   unsigned bind;                  /* Bitmask of PIPE_BIND_* flags. */
+   unsigned map_flags;             /* Bitmask of PIPE_TRANSFER_* flags. */
+   boolean map_persistent;         /* If persistent mappings are supported. */
+   enum u_upload_mgr_usage usage;  /* Usage of the upload manager
+                                    * (for uploads or downloads) */
 
    struct pipe_resource *buffer;   /* Upload buffer. */
    struct pipe_transfer *transfer; /* Transfer object for the upload buffer. */
@@ -58,7 +61,8 @@ struct u_upload_mgr {
 struct u_upload_mgr *u_upload_create( struct pipe_context *pipe,
                                       unsigned default_size,
                                       unsigned alignment,
-                                      unsigned bind )
+                                      unsigned bind,
+                                      enum u_upload_mgr_usage usage )
 {
    struct u_upload_mgr *upload = CALLOC_STRUCT( u_upload_mgr );
    if (!upload)
@@ -68,20 +72,29 @@ struct u_upload_mgr *u_upload_create( struct pipe_context *pipe,
    upload->default_size = default_size;
    upload->alignment = alignment;
    upload->bind = bind;
+   upload->usage = usage;
 
    upload->map_persistent =
       pipe->screen->get_param(pipe->screen,
                               PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT);
 
    if (upload->map_persistent) {
-      upload->map_flags = PIPE_TRANSFER_WRITE |
-                          PIPE_TRANSFER_PERSISTENT |
+      upload->map_flags = PIPE_TRANSFER_PERSISTENT |
                           PIPE_TRANSFER_COHERENT;
+      if (usage == UPLOAD_MGR_UPLOAD) {
+          upload->map_flags |= PIPE_TRANSFER_WRITE;
+      } else {
+          upload->map_flags |= PIPE_TRANSFER_READ;
+      }
    }
    else {
-      upload->map_flags = PIPE_TRANSFER_WRITE |
-                          PIPE_TRANSFER_UNSYNCHRONIZED |
-                          PIPE_TRANSFER_FLUSH_EXPLICIT;
+      if (usage == UPLOAD_MGR_UPLOAD) {
+          upload->map_flags = PIPE_TRANSFER_WRITE |
+                              PIPE_TRANSFER_UNSYNCHRONIZED |
+                              PIPE_TRANSFER_FLUSH_EXPLICIT;
+      } else {
+          upload->map_flags = PIPE_TRANSFER_READ;
+      }
    }
 
    return upload;
@@ -96,7 +109,8 @@ static void upload_unmap_internal(struct u_upload_mgr *upload, boolean destroyin
    if (upload->transfer) {
       struct pipe_box *box = &upload->transfer->box;
 
-      if (!upload->map_persistent && (int) upload->offset > box->x) {
+      if (upload->usage == UPLOAD_MGR_UPLOAD && !upload->map_persistent &&
+          (int) upload->offset > box->x) {
          pipe_buffer_flush_mapped_range(upload->pipe, upload->transfer,
                                         box->x, upload->offset - box->x);
       }
@@ -244,9 +258,12 @@ enum pipe_error u_upload_data( struct u_upload_mgr *upload,
                                struct pipe_resource **outbuf)
 {
    uint8_t *ptr;
-   enum pipe_error ret = u_upload_alloc(upload, min_out_offset, size,
-                                        out_offset, outbuf,
-                                        (void**)&ptr);
+   enum pipe_error ret;
+
+   assert (upload->usage == UPLOAD_MGR_UPLOAD);
+
+   ret= u_upload_alloc(upload, min_out_offset, size, out_offset, outbuf,
+                       (void**)&ptr);
    if (ret != PIPE_OK)
       return ret;
 
@@ -272,6 +289,8 @@ enum pipe_error u_upload_buffer( struct u_upload_mgr *upload,
    struct pipe_transfer *transfer = NULL;
    const char *map = NULL;
 
+   assert (upload->usage == UPLOAD_MGR_UPLOAD);
+
    map = (const char *)pipe_buffer_map_range(upload->pipe,
                                              inbuf,
                                              offset, size,
diff --git a/src/gallium/auxiliary/util/u_upload_mgr.h b/src/gallium/auxiliary/util/u_upload_mgr.h
index 63bf30e..8af282f 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.h
+++ b/src/gallium/auxiliary/util/u_upload_mgr.h
@@ -38,6 +38,11 @@ struct pipe_context;
 struct pipe_resource;
 
 
+enum u_upload_mgr_usage {
+    UPLOAD_MGR_UPLOAD,
+    UPLOAD_MGR_DOWNLOAD
+};
+
 /**
  * Create the upload manager.
  *
@@ -45,11 +50,13 @@ struct pipe_resource;
  * \param default_size  Minimum size of the upload buffer, in bytes.
  * \param alignment     Alignment of each suballocation in the upload buffer.
  * \param bind          Bitmask of PIPE_BIND_* flags.
+ * \param usage         Usage of the upload manager (for uploads or downloads).
  */
 struct u_upload_mgr *u_upload_create( struct pipe_context *pipe,
                                       unsigned default_size,
                                       unsigned alignment,
-                                      unsigned bind );
+                                      unsigned bind,
+                                      enum u_upload_mgr_usage usage );
 
 /**
  * Destroy the upload manager.
@@ -90,7 +97,7 @@ enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
  * Allocate and write data to the upload buffer.
  *
  * Same as u_upload_alloc, but in addition to that, it copies "data"
- * to the pointer returned from u_upload_alloc.
+ * to the pointer returned from u_upload_alloc. Can only be used for uploads.
  */
 enum pipe_error u_upload_data( struct u_upload_mgr *upload,
                                unsigned min_out_offset,
@@ -104,7 +111,7 @@ enum pipe_error u_upload_data( struct u_upload_mgr *upload,
  * Allocate space in an upload buffer and copy an input buffer to it.
  *
  * Same as u_upload_data, except that the input data comes from a buffer
- * instead of a user pointer.
+ * instead of a user pointer. Can only be used for uploads.
  */
 enum pipe_error u_upload_buffer( struct u_upload_mgr *upload,
                                  unsigned min_out_offset,
diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c
index 0c9c349..23018f0 100644
--- a/src/gallium/auxiliary/util/u_vbuf.c
+++ b/src/gallium/auxiliary/util/u_vbuf.c
@@ -248,7 +248,8 @@ u_vbuf_create(struct pipe_context *pipe,
    memset(mgr->fallback_vbs, ~0, sizeof(mgr->fallback_vbs));
 
    mgr->uploader = u_upload_create(pipe, 1024 * 1024, 4,
-                                   PIPE_BIND_VERTEX_BUFFER);
+                                   PIPE_BIND_VERTEX_BUFFER,
+                                   UPLOAD_MGR_UPLOAD);
 
    return mgr;
 }
diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c
index 3cea044..9c2ff2c 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.c
+++ b/src/gallium/auxiliary/vl/vl_compositor.c
@@ -1015,7 +1015,8 @@ vl_compositor_init(struct vl_compositor *c, struct pipe_context *pipe)
 
    c->pipe = pipe;
 
-   c->upload = u_upload_create(pipe, 128 * 1024, 4, PIPE_BIND_VERTEX_BUFFER);
+   c->upload = u_upload_create(pipe, 128 * 1024, 4, PIPE_BIND_VERTEX_BUFFER,
+                               UPLOAD_MGR_UPLOAD);
 
    if (!c->upload)
       return false;
diff --git a/src/gallium/drivers/ilo/ilo_context.c b/src/gallium/drivers/ilo/ilo_context.c
index faf29c2..b5dbe31 100644
--- a/src/gallium/drivers/ilo/ilo_context.c
+++ b/src/gallium/drivers/ilo/ilo_context.c
@@ -169,7 +169,8 @@ ilo_context_create(struct pipe_screen *screen, void *priv)
     * context.
     */
    ilo->uploader = u_upload_create(&ilo->base, 1024 * 1024, 16,
-         PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_INDEX_BUFFER);
+         PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_INDEX_BUFFER,
+         UPLOAD_MGR_UPLOAD);
    if (!ilo->uploader) {
       ilo_context_destroy(&ilo->base);
       return NULL;
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index e28dbfb..5d05971 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -413,7 +413,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
     r300->context.create_video_buffer = vl_video_buffer_create;
 
     r300->uploader = u_upload_create(&r300->context, 256 * 1024, 4,
-                                     PIPE_BIND_CUSTOM);
+                                     PIPE_BIND_CUSTOM,
+                                     UPLOAD_MGR_UPLOAD);
 
     r300->blitter = util_blitter_create(&r300->context);
     if (r300->blitter == NULL)
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
index 3aa718d..fc81dcf 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.c
+++ b/src/gallium/drivers/radeon/r600_pipe_common.c
@@ -73,7 +73,8 @@ bool r600_common_context_init(struct r600_common_context *rctx,
 
 	rctx->uploader = u_upload_create(&rctx->b, 1024 * 1024, 256,
 					PIPE_BIND_INDEX_BUFFER |
-					PIPE_BIND_CONSTANT_BUFFER);
+					PIPE_BIND_CONSTANT_BUFFER,
+					UPLOAD_MGR_UPLOAD);
 	if (!rctx->uploader)
 		return false;
 
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 0ffc762..d7a0bca 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -129,11 +129,13 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
    /* Create upload manager for vertex data for glBitmap, glDrawPixels,
     * glClear, etc.
     */
-   st->uploader = u_upload_create(st->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER);
+   st->uploader = u_upload_create(st->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER,
+                                  UPLOAD_MGR_UPLOAD);
 
    if (!screen->get_param(screen, PIPE_CAP_USER_INDEX_BUFFERS)) {
       st->indexbuf_uploader = u_upload_create(st->pipe, 128 * 1024, 4,
-                                              PIPE_BIND_INDEX_BUFFER);
+                                              PIPE_BIND_INDEX_BUFFER,
+                                              UPLOAD_MGR_UPLOAD);
    }
 
    if (!screen->get_param(screen, PIPE_CAP_USER_CONSTANT_BUFFERS)) {
@@ -141,7 +143,8 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
          screen->get_param(screen, PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT);
 
       st->constbuf_uploader = u_upload_create(pipe, 128 * 1024, alignment,
-                                              PIPE_BIND_CONSTANT_BUFFER);
+                                              PIPE_BIND_CONSTANT_BUFFER,
+                                              UPLOAD_MGR_UPLOAD);
    }
 
    st->cso_context = cso_create_context(pipe);
-- 
1.9.0



More information about the mesa-dev mailing list