<p dir="ltr"></p>
<p dir="ltr">On Sep 26, 2016 8:39 AM, "Pohjolainen, Topi" <<a href="mailto:topi.pohjolainen@gmail.com">topi.pohjolainen@gmail.com</a>> wrote:<br>
><br>
> On Sun, Sep 25, 2016 at 10:11:55AM -0700, Jason Ekstrand wrote:<br>
> >    On Sun, Sep 25, 2016 at 9:59 AM, Jason Ekstrand<br>
> >    <[1]<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>> wrote:<br>
> ><br>
> >      This enables lossless render target compression but only for first<br>
> >      mip level<br>
> >      of the first slice and only within a render pass.  At the end of the<br>
> >      render<br>
> >      pass it always does a full resolve.<br>
> >      Signed-off-by: Jason Ekstrand <[2]<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br>
> >      ---<br>
> >       src/intel/vulkan/anv_blorp.c       | 30<br>
> >      ++++++++++++++++++++++++++++<br>
> >       src/intel/vulkan/anv_device.c      | 40<br>
> >      ++++++++++++++++++++++++++++++++------<br>
> >       src/intel/vulkan/anv_image.c       |  9 +++++++++<br>
> >       src/intel/vulkan/anv_private.h     |  2 ++<br>
> >       src/intel/vulkan/genX_cmd_buffer.c | 17 ++++++++++++++++<br>
> >       5 files changed, 92 insertions(+), 6 deletions(-)<br>
> >      diff --git a/src/intel/vulkan/anv_blorp.c<br>
> >      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_subpass(struct<br>
> >      anv_cmd_buffer *cmd_buffer)<br>
> >          blorp_batch_finish(&batch);<br>
> >       }<br>
> >      +<br>
> >      +void<br>
> >      +anv_cmd_buffer_resolve_framebuffer(struct anv_cmd_buffer<br>
> >      *cmd_buffer,<br>
> >      +                                   struct anv_framebuffer *fb)<br>
> >      +{<br>
> >      +   struct blorp_batch batch;<br>
> >      +   blorp_batch_init(&cmd_buffer->device->blorp, &batch,<br>
> >      cmd_buffer);<br>
> >      +<br>
> >      +   for (uint32_t i = 0; i < fb->attachment_count; i++) {<br>
> >      +      struct anv_framebuffer_attachment *fb_att =<br>
> >      &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(image,<br>
> >      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.c<br>
> >      b/src/intel/vulkan/anv_device.c<br>
> >      index 3d4b783..8c68e94 100644<br>
> >      --- a/src/intel/vulkan/anv_device.c<br>
> >      +++ b/src/intel/vulkan/anv_device.c<br>
> >      @@ -1765,6 +1765,30 @@ void anv_DestroySampler(<br>
> >          anv_free2(&device->alloc, pAllocator, sampler);<br>
> >       }<br>
> >      +static enum isl_aux_usage<br>
> >      +get_fb_attachment_aux_usage(struct anv_device *device,<br>
> >      +                            struct anv_framebuffer *fb,<br>
> >      +                            struct anv_framebuffer_attachment<br>
> >      *fb_att)<br>
> >      +{<br>
> >      +   if (fb_att->view->image->aux_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->aux_surface.isl.usage &<br>
> >      ISL_SURF_USAGE_CCS_BIT);<br>
> >      +<br>
> >      +   if (!isl_format_supports_lossless_compression(&device->info,<br>
> >      +<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_layer > 0)<br>
> >      +      return ISL_AUX_USAGE_NONE; /* Multi-layered CCS not yet<br>
> >      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>
> >      +<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_MEMORY);<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].<br>
> >      view;<br>
> >      +      struct anv_framebuffer_attachment *fb_att =<br>
> >      &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++) *<br>
> >      device->isl_dev.ss.align;<br>
> >      -         framebuffer->attachments[i].rt_state_offset = offset;<br>
> >      +         fb_att->rt_state_offset = offset;<br>
> >      +         fb_att->aux_usage =<br>
> >      +            get_fb_attachment_aux_usage(device, framebuffer,<br>
> >      fb_att);<br>
> >                struct isl_view isl_view = iview->isl;<br>
> >                isl_view.usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;<br>
> >      @@ -1822,10 +1854,6 @@ VkResult anv_CreateFramebuffer(<br>
> >          if (device->info.has_llc)<br>
> >             anv_state_clflush(framebuffer->surface_states);<br>
> >      -   framebuffer->width = pCreateInfo->width;<br>
> >      -   framebuffer->height = pCreateInfo->height;<br>
> >      -   framebuffer->layers = pCreateInfo->layers;<br>
> >      -<br>
> >          *pFramebuffer = anv_framebuffer_to_handle(framebuffer);<br>
> >          return VK_SUCCESS;<br>
> >      diff --git a/src/intel/vulkan/anv_image.c<br>
> >      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>
> >          add_surface(image, anv_surf);<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->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>
> >      diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_<br>
> >      private.h<br>
> >      index 5c24c37..5f03ae0 100644<br>
> >      --- a/src/intel/vulkan/anv_private.h<br>
> >      +++ b/src/intel/vulkan/anv_private.h<br>
> >      @@ -1405,6 +1405,8 @@ anv_cmd_buffer_cs_push_constants(struct<br>
> >      anv_cmd_buffer *cmd_buffer);<br>
> >       void anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer<br>
> >      *cmd_buffer);<br>
> >       void anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer<br>
> >      *cmd_buffer);<br>
> >      +void anv_cmd_buffer_resolve_framebuffer(struct anv_cmd_buffer<br>
> >      *cmd_buffer,<br>
> >      +                                        struct anv_framebuffer<br>
> >      *fb);<br>
> >       const struct anv_image_view *<br>
> >       anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer<br>
> >      *cmd_buffer);<br>
> >      diff --git a/src/intel/vulkan/genX_cmd_buffer.c<br>
> >      b/src/intel/vulkan/genX_cmd_buffer.c<br>
> >      index 90700e7..0962118 100644<br>
> >      --- a/src/intel/vulkan/genX_cmd_buffer.c<br>
> >      +++ b/src/intel/vulkan/genX_cmd_buffer.c<br>
> >      @@ -1346,6 +1346,23 @@ void genX(CmdEndRenderPass)(<br>
> >          anv_cmd_buffer_resolve_subpass(cmd_buffer);<br>
> >      +   /* From the Sky Lake PRM Vol. 7, "Render Target Resolve":<br>
> >      +    *<br>
> >      +    *    "When performing a render target resolve, PIPE_CONTROL<br>
> >      with end of<br>
> >      +    *    pipe sync must be delivered."<br>
> >      +    *<br>
> >      +    * By "end of pipe sync" it appears that they mean a pixel<br>
> >      scoreboard stall<br>
> >      +    * This makes sense because the resolve operation probably needs<br>
> >      the CCS to<br>
> >      +    * be fully valid before it looks at it.<br>
> >      +    */<br>
> >      +   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {<br>
> >      +      pc.StallAtPixelScoreboard     = true;<br>
> >      +      pc.CommandStreamerStallEnable = true;<br>
> >      +   }<br>
> ><br>
> >    Topi,<br>
> >    I found this little nugget in the PRM.  It doesn't look like we're<br>
> >    doing that in the GL driver.  Maybe it has something to do with your<br>
> >    problem?<br>
><br>
> Looks like something I need to look into in any case. Unfortunately, I don't<br>
> think it will help me at the moment. The test case I'm looking blits from the<br>
> problematic compressed buffer to uncompressed framebuffer and then does<br>
> pixel read against the uncompressed. Therefore there are no resolves involved.</p>
<p dir="ltr">Bummer.  Well, let me know when you figure it out.</p>
<p dir="ltr">--Jason</p>
<p dir="ltr">> >    --Jason<br>
> ><br>
> >      +<br>
> >      +   anv_cmd_buffer_resolve_framebuffer(cmd_buffer,<br>
> >      +<br>
> >      cmd_buffer->state.framebuffer);<br>
> >      +<br>
> >       #ifndef NDEBUG<br>
> >          anv_dump_add_framebuffer(cmd_buffer,<br>
> >      cmd_buffer->state.framebuffer);<br>
> >       #endif<br>
> >      --<br>
> >      2.5.0.400.gff86faf<br>
> ><br>
> > References<br>
> ><br>
> >    1. mailto:<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a><br>
> >    2. mailto:<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a><br></p>