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