Module: Mesa
Branch: main
Commit: b46526b7a49253bc4d47932ce01589b45b225a91
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=b46526b7a49253bc4d47932ce01589b45b225a91

Author: Charmaine Lee <[email protected]>
Date:   Mon Aug 29 14:14:30 2022 -0700

svga: fix persistent mapped surface update to constant buffer

Currently when a buffer is mapped with the persistent bit set and is
later bound as a constant buffer, the updated buffer content is not
properly updated to the constant buffer surface as the constant buffer
surface is different from the original buffer surface. Doing
a buffer copy to sync the content of the constant buffer will fix
the problem, but the buffer copy can be costly.
To properly fix the issue, instead of creating a secondary surface
for the constant buffer, the original buffer surface will be accessed as
a raw buffer.

This fixes the rendering issue running yuzu deko_basic.nro

Reviewed-by: Martin Krastev <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25381>

---

 .../drivers/svga/svga_resource_buffer_upload.c     | 23 ++++++++++++++++++----
 src/gallium/drivers/svga/svga_screen_cache.h       |  5 +++--
 src/gallium/drivers/svga/svga_state_constants.c    | 10 +++++++++-
 3 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.c 
b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
index 3a9687cd3ef..b3a34221941 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer_upload.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
@@ -1,5 +1,5 @@
 /**********************************************************
- * Copyright 2008-2009 VMware, Inc.  All rights reserved.
+ * Copyright 2008-2022 VMware, Inc.  All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -204,10 +204,25 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
 
       if (sbuf->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.
+          * coherent memory if available to avoid implementing memory barriers
+          * for persistent non-coherent memory for now.
           */
-         sbuf->key.coherent = 1;
+         sbuf->key.coherent = ss->sws->have_coherent;
+
+         /* Set the persistent bit so if the buffer is to be bound
+          * as constant buffer, we'll access it as raw buffer
+          * instead of copying the content back and forth between the
+          * mapped buffer surface and the constant buffer surface.
+          */
+         sbuf->key.persistent = 1;
+
+         /* Set the raw views bind flag only if the mapped buffer surface
+          * is not already bound as constant buffer since constant buffer
+          * surface cannot have other bind flags.
+          */
+         if ((bind_flags & PIPE_BIND_CONSTANT_BUFFER) == 0) {
+            sbuf->key.flags |= SVGA3D_SURFACE_BIND_RAW_VIEWS;
+         }
       }
 
       sbuf->key.size.width = sbuf->b.width0;
diff --git a/src/gallium/drivers/svga/svga_screen_cache.h 
b/src/gallium/drivers/svga/svga_screen_cache.h
index 0aaee5a921d..4d21407e627 100644
--- a/src/gallium/drivers/svga/svga_screen_cache.h
+++ b/src/gallium/drivers/svga/svga_screen_cache.h
@@ -1,6 +1,6 @@
 
 /**********************************************************
- * Copyright 2008-2009 VMware, Inc.  All rights reserved.
+ * Copyright 2008-2022 VMware, Inc.  All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -70,10 +70,11 @@ struct svga_host_surface_cache_key
    uint32_t sampleCount:5;
    uint32_t scanout:1;
    uint32_t coherent:1;
+   uint32_t persistent:1;
 };
 
 
-struct svga_host_surface_cache_entry 
+struct svga_host_surface_cache_entry
 {
    /** 
     * Head for the LRU list, svga_host_surface_cache::unused, and
diff --git a/src/gallium/drivers/svga/svga_state_constants.c 
b/src/gallium/drivers/svga/svga_state_constants.c
index 3157b9c0078..0e710ff3469 100644
--- a/src/gallium/drivers/svga/svga_state_constants.c
+++ b/src/gallium/drivers/svga/svga_state_constants.c
@@ -1437,6 +1437,14 @@ struct svga_tracked_state svga_hw_cs_constbufs =
 };
 
 
+static inline boolean
+has_raw_buffer_view(struct svga_buffer *sbuf)
+{
+   return (sbuf->uav ||
+           (sbuf->key.persistent &&
+            (sbuf->key.flags & SVGA3D_SURFACE_BIND_RAW_VIEWS) != 0));
+}
+
 /**
  * A helper function to update the rawbuf for constbuf mask
  */
@@ -1454,7 +1462,7 @@ update_rawbuf_mask(struct svga_context *svga, enum 
pipe_shader_type shader)
       struct svga_buffer *sbuf =
          svga_buffer(svga->curr.constbufs[shader][index].buffer);
 
-      if (sbuf && sbuf->uav) {
+      if (sbuf && has_raw_buffer_view(sbuf)) {
          svga->state.raw_constbufs[shader] |= (1 << index);
       } else {
          svga->state.raw_constbufs[shader] &= ~(1 << index);

Reply via email to