<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<meta name="Generator" content="Microsoft Exchange Server">
<!-- converted from text --><style><!-- .EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; } --></style>
</head>
<body>
<meta content="text/html; charset=UTF-8">
<style type="text/css" style="">
<!--
p
        {margin-top:0;
        margin-bottom:0}
-->
</style>
<div dir="ltr">
<div id="x_divtagdefaultwrapper" dir="ltr" style="font-size:12pt; color:#000000; font-family:Calibri,Arial,Helvetica,sans-serif">
<p>Hi Lyude,</p>
<p><br>
</p>
<p>I approve this for inclusion in 12.0.x.</p>
<p><br>
</p>
<p>Marek<br>
</p>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="x_divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> Lyude <lyude@redhat.com><br>
<b>Sent:</b> Wednesday, November 30, 2016 9:06:08 PM<br>
<b>To:</b> mesa-stable@lists.freedesktop.org<br>
<b>Cc:</b> Olsak, Marek<br>
<b>Subject:</b> [PATCH] gallium/radeon: add support for sharing textures with DCC between processes</font>
<div> </div>
</div>
</div>
<font size="2"><span style="font-size:10pt;">
<div class="PlainText">From: Marek Olšák <marek.olsak@amd.com><br>
<br>
v2: use a function for calculating WORD1 of bo metadata<br>
<br>
[Lyude]<br>
On Fedora 24 and 25, I ended up noticing some rather nasty graphical<br>
glitches on my desktop (using an R9 380 w/ amdgpu, Mesa version 12.0.4)<br>
while I was in Wayland where the content of windows was garbled, as seen<br>
here:<br>
<br>
<a href="https://people.freedesktop.org/~lyudess/archive/11-30-2017/amdgpu-fix-example.png">https://people.freedesktop.org/~lyudess/archive/11-30-2017/amdgpu-fix-example.png</a><br>
<br>
After doing some reverse bisecting with Mesa v13, I ended up tracking<br>
down the fix to this patch, which seems to fix the problem entirely on<br>
all of the systems I've tested.<br>
<br>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com><br>
Tested-by: Lyude <lyude@redhat.com><br>
CC: "12.0" <mesa-stable@lists.freedesktop.org><br>
(cherry picked from commit 095803a37aa67361fc68604e81f858f31ae59b1b)<br>
---<br>
 src/gallium/drivers/radeon/r600_pipe_common.h |  4 +++<br>
 src/gallium/drivers/radeon/r600_texture.c     | 16 +++++++++---<br>
 src/gallium/drivers/radeonsi/si_state.c       | 35 ++++++++++++++++++++++++++-<br>
 3 files changed, 51 insertions(+), 4 deletions(-)<br>
<br>
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h<br>
index 3e54534..a236910 100644<br>
--- a/src/gallium/drivers/radeon/r600_pipe_common.h<br>
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h<br>
@@ -366,6 +366,10 @@ struct r600_common_screen {<br>
         void (*query_opaque_metadata)(struct r600_common_screen *rscreen,<br>
                                       struct r600_texture *rtex,<br>
                                       struct radeon_bo_metadata *md);<br>
+<br>
+       void (*apply_opaque_metadata)(struct r600_common_screen *rscreen,<br>
+                                   struct r600_texture *rtex,<br>
+                                   struct radeon_bo_metadata *md);<br>
 };<br>
 <br>
 /* This encapsulates a state or an operation which can emitted into the GPU<br>
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c<br>
index 8de3b18..74c0cbe 100644<br>
--- a/src/gallium/drivers/radeon/r600_texture.c<br>
+++ b/src/gallium/drivers/radeon/r600_texture.c<br>
@@ -965,8 +965,12 @@ r600_texture_create_object(struct pipe_screen *screen,<br>
                         }<br>
                 }<br>
 <br>
-               if (!buf && rtex->surface.dcc_size &&<br>
-                   !(rscreen->debug_flags & DBG_NO_DCC)) {<br>
+               /* Shared textures must always set up DCC here.<br>
+                * If it's not present, it will be disabled by<br>
+                * apply_opaque_metadata later.<br>
+                */<br>
+               if (rtex->surface.dcc_size &&<br>
+                   (buf || !(rscreen->debug_flags & DBG_NO_DCC))) {<br>
                         /* Reserve space for the DCC buffer. */<br>
                         rtex->dcc_offset = align64(rtex->size, rtex->surface.dcc_alignment);<br>
                         rtex->size = rtex->dcc_offset + rtex->surface.dcc_size;<br>
@@ -993,7 +997,9 @@ r600_texture_create_object(struct pipe_screen *screen,<br>
                                          rtex->cmask.offset, rtex->cmask.size,<br>
                                          0xCCCCCCCC, R600_COHERENCY_NONE);<br>
         }<br>
-       if (rtex->dcc_offset) {<br>
+<br>
+       /* Initialize DCC only if the texture is not being imported. */<br>
+       if (!buf && rtex->dcc_offset) {<br>
                 r600_screen_clear_buffer(rscreen, &rtex->resource.b.b,<br>
                                          rtex->dcc_offset,<br>
                                          rtex->surface.dcc_size,<br>
@@ -1159,6 +1165,10 @@ static struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen<br>
 <br>
         rtex->resource.is_shared = true;<br>
         rtex->resource.external_usage = usage;<br>
+<br>
+       if (rscreen->apply_opaque_metadata)<br>
+               rscreen->apply_opaque_metadata(rscreen, rtex, &metadata);<br>
+<br>
         return &rtex->resource.b.b;<br>
 }<br>
 <br>
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c<br>
index a641b5d..575c789 100644<br>
--- a/src/gallium/drivers/radeonsi/si_state.c<br>
+++ b/src/gallium/drivers/radeonsi/si_state.c<br>
@@ -3427,6 +3427,11 @@ void si_init_state_functions(struct si_context *sctx)<br>
         si_init_config(sctx);<br>
 }<br>
 <br>
+static uint32_t si_get_bo_metadata_word1(struct r600_common_screen *rscreen)<br>
+{<br>
+       return (ATI_VENDOR_ID << 16) | rscreen->info.pci_id;<br>
+}<br>
+<br>
 static void si_query_opaque_metadata(struct r600_common_screen *rscreen,<br>
                                      struct r600_texture *rtex,<br>
                                      struct radeon_bo_metadata *md)<br>
@@ -3461,7 +3466,7 @@ static void si_query_opaque_metadata(struct r600_common_screen *rscreen,<br>
         md->metadata[0] = 1; /* metadata image format version 1 */<br>
 <br>
         /* TILE_MODE_INDEX is ambiguous without a PCI ID. */<br>
-       md->metadata[1] = (ATI_VENDOR_ID << 16) | rscreen->info.pci_id;<br>
+       md->metadata[1] = si_get_bo_metadata_word1(rscreen);<br>
 <br>
         si_make_texture_descriptor(sscreen, rtex, true,<br>
                                    res->target, res->format,<br>
@@ -3485,9 +3490,37 @@ static void si_query_opaque_metadata(struct r600_common_screen *rscreen,<br>
         md->size_metadata = (11 + res->last_level) * 4;<br>
 }<br>
 <br>
+static void si_apply_opaque_metadata(struct r600_common_screen *rscreen,<br>
+                                    struct r600_texture *rtex,<br>
+                                    struct radeon_bo_metadata *md)<br>
+{<br>
+       uint32_t *desc = &md->metadata[2];<br>
+<br>
+       if (rscreen->chip_class < VI)<br>
+               return;<br>
+<br>
+       /* Return if DCC is enabled. The texture should be set up with it<br>
+        * already.<br>
+        */<br>
+       if (md->size_metadata >= 11 * 4 &&<br>
+           md->metadata[0] != 0 &&<br>
+           md->metadata[1] == si_get_bo_metadata_word1(rscreen) &&<br>
+           G_008F28_COMPRESSION_EN(desc[6])) {<br>
+               assert(rtex->dcc_offset == ((uint64_t)desc[7] << 8));<br>
+               return;<br>
+       }<br>
+<br>
+       /* Disable DCC. These are always set by texture_from_handle and must<br>
+        * be cleared here.<br>
+        */<br>
+       rtex->dcc_offset = 0;<br>
+       rtex->cb_color_info &= ~VI_S_028C70_DCC_ENABLE(1);<br>
+}<br>
+<br>
 void si_init_screen_state_functions(struct si_screen *sscreen)<br>
 {<br>
         sscreen->b.query_opaque_metadata = si_query_opaque_metadata;<br>
+       sscreen->b.apply_opaque_metadata = si_apply_opaque_metadata;<br>
 }<br>
 <br>
 static void<br>
-- <br>
2.9.3<br>
<br>
</div>
</span></font>
</body>
</html>