<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Sep 25, 2016 at 9:59 AM, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This enables lossless render target compression but only for first mip level<br>
of the first slice and only within a render pass.  At the end of the render<br>
pass it always does a full resolve.<br>
<br>
Signed-off-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br>
---<br>
 src/intel/vulkan/anv_blorp.c       | 30 ++++++++++++++++++++++++++++<br>
 src/intel/vulkan/anv_device.c      | 40 ++++++++++++++++++++++++++++++<wbr>++------<br>
 src/intel/vulkan/anv_image.c       |  9 +++++++++<br>
 src/intel/vulkan/anv_private.h     |  2 ++<br>
 src/intel/vulkan/genX_cmd_<wbr>buffer.c | 17 ++++++++++++++++<br>
 5 files changed, 92 insertions(+), 6 deletions(-)<br>
<br>
diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c<br>
index 5cc19eb..74f1d80 100644<br>
--- a/src/intel/vulkan/anv_blorp.c<br>
+++ b/src/intel/vulkan/anv_blorp.c<br>
@@ -929,3 +929,33 @@ anv_cmd_buffer_resolve_<wbr>subpass(struct anv_cmd_buffer *cmd_buffer)<br>
<br>
    blorp_batch_finish(&batch);<br>
 }<br>
+<br>
+void<br>
+anv_cmd_buffer_resolve_<wbr>framebuffer(struct anv_cmd_buffer *cmd_buffer,<br>
+                                   struct anv_framebuffer *fb)<br>
+{<br>
+   struct blorp_batch batch;<br>
+   blorp_batch_init(&cmd_buffer-><wbr>device->blorp, &batch, cmd_buffer);<br>
+<br>
+   for (uint32_t i = 0; i < fb->attachment_count; i++) {<br>
+      struct anv_framebuffer_attachment *fb_att = &fb->attachments[i];<br>
+      const struct anv_image *image = fb_att->view->image;<br>
+<br>
+      if (fb_att->aux_usage != ISL_AUX_USAGE_CCS_E &&<br>
+          fb_att->aux_usage != ISL_AUX_USAGE_CCS_D)<br>
+         continue;<br>
+<br>
+      struct blorp_surf surf;<br>
+      get_blorp_surf_for_anv_image(<wbr>image, VK_IMAGE_ASPECT_COLOR_BIT, &surf);<br>
+      surf.aux_surf = &image->aux_surface.isl;<br>
+      surf.aux_addr = (struct blorp_address) {<br>
+         .buffer = image->bo,<br>
+         .offset = image->offset + image->aux_surface.offset,<br>
+      };<br>
+      surf.aux_usage = fb_att->aux_usage;<br>
+<br>
+      blorp_ccs_resolve(&batch, &surf, fb_att->view->isl.format);<br>
+   }<br>
+<br>
+   blorp_batch_finish(&batch);<br>
+}<br>
diff --git a/src/intel/vulkan/anv_device.<wbr>c b/src/intel/vulkan/anv_device.<wbr>c<br>
index 3d4b783..8c68e94 100644<br>
--- a/src/intel/vulkan/anv_device.<wbr>c<br>
+++ b/src/intel/vulkan/anv_device.<wbr>c<br>
@@ -1765,6 +1765,30 @@ void anv_DestroySampler(<br>
    anv_free2(&device->alloc, pAllocator, sampler);<br>
 }<br>
<br>
+static enum isl_aux_usage<br>
+get_fb_attachment_aux_usage(<wbr>struct anv_device *device,<br>
+                            struct anv_framebuffer *fb,<br>
+                            struct anv_framebuffer_attachment *fb_att)<br>
+{<br>
+   if (fb_att->view->image->aux_<wbr>surface.isl.size == 0)<br>
+      return ISL_AUX_USAGE_NONE; /* No aux surface */<br>
+<br>
+   /* This is a color buffer, it had better be CCS */<br>
+   assert(fb_att->view->image-><wbr>aux_surface.isl.usage & ISL_SURF_USAGE_CCS_BIT);<br>
+<br>
+   if (!isl_format_supports_<wbr>lossless_compression(&device-><wbr>info,<br>
+                                                 fb_att->view->isl.format))<br>
+      return ISL_AUX_USAGE_NONE; /* Unsupported format */<br>
+<br>
+   if (fb->layers > 1 || fb_att->view->isl.base_array_<wbr>layer > 0)<br>
+      return ISL_AUX_USAGE_NONE; /* Multi-layered CCS not yet supported */<br>
+<br>
+   if (fb_att->view->isl.base_level > 0)<br>
+      return ISL_AUX_USAGE_NONE; /* Multi-LOD CCS not yet supported */<br>
+<br>
+   return ISL_AUX_USAGE_CCS_E;<br>
+}<br>
+<br>
 VkResult anv_CreateFramebuffer(<br>
     VkDevice                                    _device,<br>
     const VkFramebufferCreateInfo*              pCreateInfo,<br>
@@ -1783,6 +1807,10 @@ VkResult anv_CreateFramebuffer(<br>
    if (framebuffer == NULL)<br>
       return vk_error(VK_ERROR_OUT_OF_HOST_<wbr>MEMORY);<br>
<br>
+   framebuffer->width = pCreateInfo->width;<br>
+   framebuffer->height = pCreateInfo->height;<br>
+   framebuffer->layers = pCreateInfo->layers;<br>
+<br>
    framebuffer->attachment_count = pCreateInfo->attachmentCount;<br>
    unsigned color_count = 0;<br>
    for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {<br>
@@ -1802,10 +1830,14 @@ VkResult anv_CreateFramebuffer(<br>
                            device->isl_dev.ss.align);<br>
    unsigned color_idx = 0;<br>
    for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {<br>
-      struct anv_image_view *iview = framebuffer->attachments[i].<wbr>view;<br>
+      struct anv_framebuffer_attachment *fb_att = &framebuffer->attachments[i];<br>
+      struct anv_image_view *iview = fb_att->view;<br>
+<br>
       if (iview->image->aspects & VK_IMAGE_ASPECT_COLOR_BIT) {<br>
          const uint16_t offset = (color_idx++) * device->isl_dev.ss.align;<br>
-         framebuffer->attachments[i].<wbr>rt_state_offset = offset;<br>
+         fb_att->rt_state_offset = offset;<br>
+         fb_att->aux_usage =<br>
+            get_fb_attachment_aux_usage(<wbr>device, framebuffer, fb_att);<br>
<br>
          struct isl_view isl_view = iview->isl;<br>
          isl_view.usage |= ISL_SURF_USAGE_RENDER_TARGET_<wbr>BIT;<br>
@@ -1822,10 +1854,6 @@ VkResult anv_CreateFramebuffer(<br>
    if (device->info.has_llc)<br>
       anv_state_clflush(framebuffer-<wbr>>surface_states);<br>
<br>
-   framebuffer->width = pCreateInfo->width;<br>
-   framebuffer->height = pCreateInfo->height;<br>
-   framebuffer->layers = pCreateInfo->layers;<br>
-<br>
    *pFramebuffer = anv_framebuffer_to_handle(<wbr>framebuffer);<br>
<br>
    return VK_SUCCESS;<br>
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c<br>
index 405b923..ff99126 100644<br>
--- a/src/intel/vulkan/anv_image.c<br>
+++ b/src/intel/vulkan/anv_image.c<br>
@@ -169,6 +169,15 @@ make_surface(const struct anv_device *dev,<br>
<br>
    add_surface(image, anv_surf);<br>
<br>
+   if (aspect == VK_IMAGE_ASPECT_COLOR_BIT) {<br>
+      if (dev->info.gen >= 9 && vk_info->samples == 1) {<br>
+         ok = isl_surf_get_ccs_surf(&dev-><wbr>isl_dev, &anv_surf->isl,<br>
+                                    &image->aux_surface.isl);<br>
+         if (ok)<br>
+            add_surface(image, &image->aux_surface);<br>
+      }<br>
+   }<br>
+<br>
    return VK_SUCCESS;<br>
 }<br>
<br>
diff --git a/src/intel/vulkan/anv_<wbr>private.h b/src/intel/vulkan/anv_<wbr>private.h<br>
index 5c24c37..5f03ae0 100644<br>
--- a/src/intel/vulkan/anv_<wbr>private.h<br>
+++ b/src/intel/vulkan/anv_<wbr>private.h<br>
@@ -1405,6 +1405,8 @@ anv_cmd_buffer_cs_push_<wbr>constants(struct anv_cmd_buffer *cmd_buffer);<br>
<br>
 void anv_cmd_buffer_clear_subpass(<wbr>struct anv_cmd_buffer *cmd_buffer);<br>
 void anv_cmd_buffer_resolve_<wbr>subpass(struct anv_cmd_buffer *cmd_buffer);<br>
+void anv_cmd_buffer_resolve_<wbr>framebuffer(struct anv_cmd_buffer *cmd_buffer,<br>
+                                        struct anv_framebuffer *fb);<br>
<br>
 const struct anv_image_view *<br>
 anv_cmd_buffer_get_depth_<wbr>stencil_view(const struct anv_cmd_buffer *cmd_buffer);<br>
diff --git a/src/intel/vulkan/genX_cmd_<wbr>buffer.c b/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
index 90700e7..0962118 100644<br>
--- a/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
+++ b/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
@@ -1346,6 +1346,23 @@ void genX(CmdEndRenderPass)(<br>
<br>
    anv_cmd_buffer_resolve_<wbr>subpass(cmd_buffer);<br>
<br>
+   /* From the Sky Lake PRM Vol. 7, "Render Target Resolve":<br>
+    *<br>
+    *    "When performing a render target resolve, PIPE_CONTROL with end of<br>
+    *    pipe sync must be delivered."<br>
+    *<br>
+    * By "end of pipe sync" it appears that they mean a pixel scoreboard stall<br>
+    * This makes sense because the resolve operation probably needs the CCS to<br>
+    * be fully valid before it looks at it.<br>
+    */<br>
+   anv_batch_emit(&cmd_buffer-><wbr>batch, GENX(PIPE_CONTROL), pc) {<br>
+      pc.StallAtPixelScoreboard     = true;<br>
+      pc.CommandStreamerStallEnable = true;<br>
+   }<br></blockquote><div><br></div><div>Topi,<br></div><div><br></div><div>I found this little nugget in the PRM.  It doesn't look like we're doing that in the GL driver.  Maybe it has something to do with your problem?<br><br></div><div>--Jason<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+   anv_cmd_buffer_resolve_<wbr>framebuffer(cmd_buffer,<br>
+                                      cmd_buffer->state.framebuffer)<wbr>;<br>
+<br>
 #ifndef NDEBUG<br>
    anv_dump_add_framebuffer(cmd_<wbr>buffer, cmd_buffer->state.framebuffer)<wbr>;<br>
 #endif<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.5.0.400.gff86faf<br>
<br>
</font></span></blockquote></div><br></div></div>