[Mesa-dev] [PATCH 6/6] svga: Support ARB_buffer_storage

Thomas Hellström (VMware) thomas at shipmail.org
Wed Jun 19 08:34:45 UTC 2019


From: Thomas Hellstrom <thellstrom at vmware.com>

This basically boils down to supporting persistent and coherent buffer
storage.
We chose to use coherent buffer storage for all persistent buffers
even if it's not explicitly specified, since using glMemoryBarrier to
obtain coherency would be particularly expensive in our driver stack,
and require a lot of additional bookkeeping.

Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
Reviewed-by: Brian Paul <brianp at vmware.com>
---
 src/gallium/drivers/svga/svga_context.c         |  6 ++++++
 src/gallium/drivers/svga/svga_resource_buffer.c | 13 +++++++++----
 .../drivers/svga/svga_resource_buffer_upload.c  | 17 +++++++++++++----
 .../drivers/svga/svga_resource_texture.c        |  3 +++
 src/gallium/drivers/svga/svga_screen.c          |  3 ++-
 5 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
index 57c0dc49957..104a551356d 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -148,12 +148,16 @@ svga_context_create(struct pipe_screen *screen, void *priv, unsigned flags)
    if (!svga->pipe.stream_uploader)
       goto cleanup;
 
+   u_upload_disable_persistent(svga->pipe.stream_uploader);
+
    svga->pipe.const_uploader = u_upload_create(&svga->pipe, 128 * 1024,
                                                PIPE_BIND_CONSTANT_BUFFER,
                                                PIPE_USAGE_STREAM, 0);
    if (!svga->pipe.const_uploader)
       goto cleanup;
 
+   u_upload_disable_persistent(svga->pipe.const_uploader);
+
    svga->swc = svgascreen->sws->context_create(svgascreen->sws);
    if (!svga->swc)
       goto cleanup;
@@ -236,6 +240,8 @@ svga_context_create(struct pipe_screen *screen, void *priv, unsigned flags)
    if (!svga->const0_upload)
       goto cleanup;
 
+   u_upload_disable_persistent(svga->const0_upload);
+
    if (!svga_texture_transfer_map_upload_create(svga))
       goto cleanup;
 
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c
index 234d825d5a2..712fffc83d3 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer.c
@@ -71,6 +71,9 @@ svga_buffer_needs_hw_storage(const struct svga_screen *ss,
          bind_mask |= PIPE_BIND_CONSTANT_BUFFER;
    }
 
+   if (template->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)
+      return TRUE;
+
    return !!(template->bind & bind_mask);
 }
 
@@ -126,7 +129,8 @@ svga_buffer_transfer_map(struct pipe_context *pipe,
       pipe_resource_reference(&sbuf->translated_indices.buffer, NULL);
    }
 
-   if ((usage & PIPE_TRANSFER_READ) && sbuf->dirty) {
+   if ((usage & PIPE_TRANSFER_READ) && sbuf->dirty &&
+       !sbuf->key.coherent && !svga->swc->force_coherent) {
       enum pipe_error ret;
 
       /* Host-side buffers can only be dirtied with vgpu10 features
@@ -160,7 +164,8 @@ svga_buffer_transfer_map(struct pipe_context *pipe,
    }
 
    if (usage & PIPE_TRANSFER_WRITE) {
-      if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
+      if ((usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) &&
+          !(resource->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)) {
          /*
           * Flush any pending primitives, finish writing any pending DMA
           * commands, and tell the host to discard the buffer contents on
@@ -317,7 +322,7 @@ svga_buffer_transfer_flush_region(struct pipe_context *pipe,
    assert(transfer->usage & PIPE_TRANSFER_WRITE);
    assert(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT);
 
-   if (!svga->swc->force_coherent || sbuf->swbuf) {
+   if (!(svga->swc->force_coherent || sbuf->key.coherent) || sbuf->swbuf) {
       mtx_lock(&ss->swc_mutex);
       svga_buffer_add_range(sbuf, offset, offset + length);
       mtx_unlock(&ss->swc_mutex);
@@ -361,7 +366,7 @@ svga_buffer_transfer_unmap(struct pipe_context *pipe,
 
          sbuf->dma.flags.discard = TRUE;
 
-         if (!svga->swc->force_coherent || sbuf->swbuf)
+         if (!(svga->swc->force_coherent || sbuf->key.coherent) || sbuf->swbuf)
             svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0);
       }
    }
diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.c b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
index 64f75231a65..1bb7431abf4 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer_upload.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
@@ -183,6 +183,14 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
          sbuf->key.flags = SVGA3D_SURFACE_TRANSFER_FROM_BUFFER;
       }
 
+      if (sbuf->b.b.flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) {
+         /* This surface can be mapped persistently. We use
+          * coherent memory to avoid implementing memory barriers for
+          * persistent non-coherent memory for now.
+          */
+         sbuf->key.coherent = 1;
+      }
+
       sbuf->key.size.width = sbuf->b.b.width0;
       sbuf->key.size.height = 1;
       sbuf->key.size.depth = 1;
@@ -448,7 +456,7 @@ svga_buffer_upload_gb_command(struct svga_context *svga,
    struct pipe_resource *dummy;
    unsigned i;
 
-   if (swc->force_coherent)
+   if (swc->force_coherent || sbuf->key.coherent)
       return PIPE_OK;
 
    assert(svga_have_gb_objects(svga));
@@ -648,7 +656,8 @@ svga_buffer_upload_flush(struct svga_context *svga, struct svga_buffer *sbuf)
    unsigned i;
    struct pipe_resource *dummy;
 
-   if (!sbuf->dma.pending || svga->swc->force_coherent) {
+   if (!sbuf->dma.pending || svga->swc->force_coherent ||
+       sbuf->key.coherent) {
       //debug_printf("no dma pending on buffer\n");
       return;
    }
@@ -875,7 +884,7 @@ svga_buffer_update_hw(struct svga_context *svga, struct svga_buffer *sbuf,
          memcpy((uint8_t *) map + start, (uint8_t *) sbuf->swbuf + start, len);
       }
 
-      if (svga->swc->force_coherent)
+      if (svga->swc->force_coherent || sbuf->key.coherent)
          sbuf->map.num_ranges = 0;
 
       svga_buffer_hw_storage_unmap(svga, sbuf);
@@ -1036,7 +1045,7 @@ svga_buffer_handle(struct svga_context *svga, struct pipe_resource *buf,
    }
 
    assert(sbuf->handle);
-   if (svga->swc->force_coherent)
+   if (svga->swc->force_coherent || sbuf->key.coherent)
       return sbuf->handle;
 
    if (sbuf->map.num_ranges) {
diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c
index 0b872da3ed2..bfedbee7a48 100644
--- a/src/gallium/drivers/svga/svga_resource_texture.c
+++ b/src/gallium/drivers/svga/svga_resource_texture.c
@@ -1354,6 +1354,9 @@ svga_texture_transfer_map_upload_create(struct svga_context *svga)
 {
    svga->tex_upload = u_upload_create(&svga->pipe, TEX_UPLOAD_DEFAULT_SIZE,
                                       PIPE_BIND_CUSTOM, PIPE_USAGE_STAGING, 0);
+   if (svga->tex_upload)
+      u_upload_disable_persistent(svga->tex_upload);
+
    return svga->tex_upload != NULL;
 }
 
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 5300fada9ff..c76d77f1bc2 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -351,6 +351,8 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return sws->have_sm4_1 ? 1 : 0; /* only single-channel textures */
    case PIPE_CAP_MAX_VARYINGS:
       return sws->have_vgpu10 ? VGPU10_MAX_FS_INPUTS : 10;
+   case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
+      return sws->have_coherent;
 
    /* Unsupported features */
    case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
@@ -366,7 +368,6 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
    case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
    case PIPE_CAP_TEXTURE_GATHER_SM5:
-   case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
    case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
    case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
    case PIPE_CAP_DRAW_INDIRECT:
-- 
2.20.1



More information about the mesa-dev mailing list