[Mesa-stable] [PATCH] gallium/radeon: add support for sharing textures with DCC between processes

Olsak, Marek Marek.Olsak at amd.com
Thu Dec 1 17:41:15 UTC 2016


Hi Lyude,


I approve this for inclusion in 12.0.x.


Marek

________________________________
From: Lyude <lyude at redhat.com>
Sent: Wednesday, November 30, 2016 9:06:08 PM
To: mesa-stable at lists.freedesktop.org
Cc: Olsak, Marek
Subject: [PATCH] gallium/radeon: add support for sharing textures with DCC between processes

From: Marek Olšák <marek.olsak at amd.com>

v2: use a function for calculating WORD1 of bo metadata

[Lyude]
On Fedora 24 and 25, I ended up noticing some rather nasty graphical
glitches on my desktop (using an R9 380 w/ amdgpu, Mesa version 12.0.4)
while I was in Wayland where the content of windows was garbled, as seen
here:

https://people.freedesktop.org/~lyudess/archive/11-30-2017/amdgpu-fix-example.png

After doing some reverse bisecting with Mesa v13, I ended up tracking
down the fix to this patch, which seems to fix the problem entirely on
all of the systems I've tested.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
Tested-by: Lyude <lyude at redhat.com>
CC: "12.0" <mesa-stable at lists.freedesktop.org>
(cherry picked from commit 095803a37aa67361fc68604e81f858f31ae59b1b)
---
 src/gallium/drivers/radeon/r600_pipe_common.h |  4 +++
 src/gallium/drivers/radeon/r600_texture.c     | 16 +++++++++---
 src/gallium/drivers/radeonsi/si_state.c       | 35 ++++++++++++++++++++++++++-
 3 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index 3e54534..a236910 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -366,6 +366,10 @@ struct r600_common_screen {
         void (*query_opaque_metadata)(struct r600_common_screen *rscreen,
                                       struct r600_texture *rtex,
                                       struct radeon_bo_metadata *md);
+
+       void (*apply_opaque_metadata)(struct r600_common_screen *rscreen,
+                                   struct r600_texture *rtex,
+                                   struct radeon_bo_metadata *md);
 };

 /* This encapsulates a state or an operation which can emitted into the GPU
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 8de3b18..74c0cbe 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -965,8 +965,12 @@ r600_texture_create_object(struct pipe_screen *screen,
                         }
                 }

-               if (!buf && rtex->surface.dcc_size &&
-                   !(rscreen->debug_flags & DBG_NO_DCC)) {
+               /* Shared textures must always set up DCC here.
+                * If it's not present, it will be disabled by
+                * apply_opaque_metadata later.
+                */
+               if (rtex->surface.dcc_size &&
+                   (buf || !(rscreen->debug_flags & DBG_NO_DCC))) {
                         /* Reserve space for the DCC buffer. */
                         rtex->dcc_offset = align64(rtex->size, rtex->surface.dcc_alignment);
                         rtex->size = rtex->dcc_offset + rtex->surface.dcc_size;
@@ -993,7 +997,9 @@ r600_texture_create_object(struct pipe_screen *screen,
                                          rtex->cmask.offset, rtex->cmask.size,
                                          0xCCCCCCCC, R600_COHERENCY_NONE);
         }
-       if (rtex->dcc_offset) {
+
+       /* Initialize DCC only if the texture is not being imported. */
+       if (!buf && rtex->dcc_offset) {
                 r600_screen_clear_buffer(rscreen, &rtex->resource.b.b,
                                          rtex->dcc_offset,
                                          rtex->surface.dcc_size,
@@ -1159,6 +1165,10 @@ static struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen

         rtex->resource.is_shared = true;
         rtex->resource.external_usage = usage;
+
+       if (rscreen->apply_opaque_metadata)
+               rscreen->apply_opaque_metadata(rscreen, rtex, &metadata);
+
         return &rtex->resource.b.b;
 }

diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index a641b5d..575c789 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -3427,6 +3427,11 @@ void si_init_state_functions(struct si_context *sctx)
         si_init_config(sctx);
 }

+static uint32_t si_get_bo_metadata_word1(struct r600_common_screen *rscreen)
+{
+       return (ATI_VENDOR_ID << 16) | rscreen->info.pci_id;
+}
+
 static void si_query_opaque_metadata(struct r600_common_screen *rscreen,
                                      struct r600_texture *rtex,
                                      struct radeon_bo_metadata *md)
@@ -3461,7 +3466,7 @@ static void si_query_opaque_metadata(struct r600_common_screen *rscreen,
         md->metadata[0] = 1; /* metadata image format version 1 */

         /* TILE_MODE_INDEX is ambiguous without a PCI ID. */
-       md->metadata[1] = (ATI_VENDOR_ID << 16) | rscreen->info.pci_id;
+       md->metadata[1] = si_get_bo_metadata_word1(rscreen);

         si_make_texture_descriptor(sscreen, rtex, true,
                                    res->target, res->format,
@@ -3485,9 +3490,37 @@ static void si_query_opaque_metadata(struct r600_common_screen *rscreen,
         md->size_metadata = (11 + res->last_level) * 4;
 }

+static void si_apply_opaque_metadata(struct r600_common_screen *rscreen,
+                                    struct r600_texture *rtex,
+                                    struct radeon_bo_metadata *md)
+{
+       uint32_t *desc = &md->metadata[2];
+
+       if (rscreen->chip_class < VI)
+               return;
+
+       /* Return if DCC is enabled. The texture should be set up with it
+        * already.
+        */
+       if (md->size_metadata >= 11 * 4 &&
+           md->metadata[0] != 0 &&
+           md->metadata[1] == si_get_bo_metadata_word1(rscreen) &&
+           G_008F28_COMPRESSION_EN(desc[6])) {
+               assert(rtex->dcc_offset == ((uint64_t)desc[7] << 8));
+               return;
+       }
+
+       /* Disable DCC. These are always set by texture_from_handle and must
+        * be cleared here.
+        */
+       rtex->dcc_offset = 0;
+       rtex->cb_color_info &= ~VI_S_028C70_DCC_ENABLE(1);
+}
+
 void si_init_screen_state_functions(struct si_screen *sscreen)
 {
         sscreen->b.query_opaque_metadata = si_query_opaque_metadata;
+       sscreen->b.apply_opaque_metadata = si_apply_opaque_metadata;
 }

 static void
--
2.9.3

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-stable/attachments/20161201/c2205040/attachment-0001.html>


More information about the mesa-stable mailing list