<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>