mesa/gallium: add MESA_MAP_ONCE / PIPE_MAP_ONCE
authorPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Thu, 22 Oct 2020 13:46:08 +0000 (15:46 +0200)
committerPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Tue, 17 Nov 2020 09:53:06 +0000 (10:53 +0100)
If set, this bit tells the driver that the buffer will only be
mapped once.

radeonsi uses it to disable its "never unmap buffers" optimisations.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3660
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7428>

src/gallium/drivers/radeonsi/si_buffer.c
src/gallium/include/pipe/p_defines.h
src/mesa/main/dd.h
src/mesa/state_tracker/st_cb_bufferobjects.c
src/mesa/vbo/vbo_save_api.c

index f44f3fd..463a9fe 100644 (file)
@@ -388,6 +388,8 @@ static void *si_buffer_transfer_map(struct pipe_context *ctx, struct pipe_resour
     */
    if (buf->b.is_user_ptr)
       usage |= PIPE_MAP_PERSISTENT;
+   if (usage & PIPE_MAP_ONCE)
+      usage |= RADEON_MAP_TEMPORARY;
 
    /* See if the buffer range being mapped has never been initialized,
     * in which case it can be mapped unsynchronized. */
@@ -594,6 +596,10 @@ static void si_buffer_transfer_unmap(struct pipe_context *ctx, struct pipe_trans
    if (transfer->usage & PIPE_MAP_WRITE && !(transfer->usage & PIPE_MAP_FLUSH_EXPLICIT))
       si_buffer_do_flush_region(ctx, transfer, &transfer->box);
 
+   if (transfer->usage & (PIPE_MAP_ONCE | RADEON_MAP_TEMPORARY) &&
+       !stransfer->staging)
+      sctx->ws->buffer_unmap(si_resource(stransfer->b.b.resource)->buf);
+
    si_resource_reference(&stransfer->staging, NULL);
    assert(stransfer->b.staging == NULL); /* for threaded context only */
    pipe_resource_reference(&transfer->resource, NULL);
index efc5bec..38bc6fb 100644 (file)
@@ -363,6 +363,11 @@ enum pipe_map_flags
    PIPE_MAP_STENCIL_ONLY = 1 << 17,
 
    /**
+    * Mapping will be used only once (never remapped).
+    */
+   PIPE_MAP_ONCE = 1 << 18,
+
+   /**
     * This and higher bits are reserved for private use by drivers. Drivers
     * should use this as (PIPE_MAP_DRV_PRV << i).
     */
index eb3c14e..506a182 100644 (file)
@@ -74,6 +74,9 @@ struct _mesa_index_buffer;
 /* Mapping a buffer is allowed from any thread. */
 #define MESA_MAP_THREAD_SAFE_BIT  0x8000
 
+/* This buffer will only be mapped/unmapped once */
+#define MESA_MAP_ONCE            0x10000
+
 
 /**
  * Device driver function table.
index e7550cc..ad4a838 100644 (file)
@@ -496,6 +496,8 @@ st_access_flags_to_transfer_flags(GLbitfield access, bool wholeBuffer)
       flags |= PIPE_MAP_DONTBLOCK;
    if (access & MESA_MAP_THREAD_SAFE_BIT)
       flags |= PIPE_MAP_THREAD_SAFE;
+   if (access & MESA_MAP_ONCE)
+      flags |= PIPE_MAP_ONCE;
 
    return flags;
 }
index 0203199..7540da5 100644 (file)
@@ -193,7 +193,8 @@ vbo_save_map_vertex_store(struct gl_context *ctx,
    const GLbitfield access = (GL_MAP_WRITE_BIT |
                               GL_MAP_INVALIDATE_RANGE_BIT |
                               GL_MAP_UNSYNCHRONIZED_BIT |
-                              GL_MAP_FLUSH_EXPLICIT_BIT);
+                              GL_MAP_FLUSH_EXPLICIT_BIT |
+                              MESA_MAP_ONCE);
 
    assert(vertex_store->bufferobj);
    assert(!vertex_store->buffer_map);  /* the buffer should not be mapped */