[Mesa-dev] [PATCH 13/13] anv: Enable CCS for basic cases

Pohjolainen, Topi topi.pohjolainen at gmail.com
Mon Sep 26 05:39:34 UTC 2016


On Sun, Sep 25, 2016 at 10:11:55AM -0700, Jason Ekstrand wrote:
>    On Sun, Sep 25, 2016 at 9:59 AM, Jason Ekstrand
>    <[1]jason at jlekstrand.net> wrote:
> 
>      This enables lossless render target compression but only for first
>      mip level
>      of the first slice and only within a render pass.  At the end of the
>      render
>      pass it always does a full resolve.
>      Signed-off-by: Jason Ekstrand <[2]jason at jlekstrand.net>
>      ---
>       src/intel/vulkan/anv_blorp.c       | 30
>      ++++++++++++++++++++++++++++
>       src/intel/vulkan/anv_device.c      | 40
>      ++++++++++++++++++++++++++++++++------
>       src/intel/vulkan/anv_image.c       |  9 +++++++++
>       src/intel/vulkan/anv_private.h     |  2 ++
>       src/intel/vulkan/genX_cmd_buffer.c | 17 ++++++++++++++++
>       5 files changed, 92 insertions(+), 6 deletions(-)
>      diff --git a/src/intel/vulkan/anv_blorp.c
>      b/src/intel/vulkan/anv_blorp.c
>      index 5cc19eb..74f1d80 100644
>      --- a/src/intel/vulkan/anv_blorp.c
>      +++ b/src/intel/vulkan/anv_blorp.c
>      @@ -929,3 +929,33 @@ anv_cmd_buffer_resolve_subpass(struct
>      anv_cmd_buffer *cmd_buffer)
>          blorp_batch_finish(&batch);
>       }
>      +
>      +void
>      +anv_cmd_buffer_resolve_framebuffer(struct anv_cmd_buffer
>      *cmd_buffer,
>      +                                   struct anv_framebuffer *fb)
>      +{
>      +   struct blorp_batch batch;
>      +   blorp_batch_init(&cmd_buffer->device->blorp, &batch,
>      cmd_buffer);
>      +
>      +   for (uint32_t i = 0; i < fb->attachment_count; i++) {
>      +      struct anv_framebuffer_attachment *fb_att =
>      &fb->attachments[i];
>      +      const struct anv_image *image = fb_att->view->image;
>      +
>      +      if (fb_att->aux_usage != ISL_AUX_USAGE_CCS_E &&
>      +          fb_att->aux_usage != ISL_AUX_USAGE_CCS_D)
>      +         continue;
>      +
>      +      struct blorp_surf surf;
>      +      get_blorp_surf_for_anv_image(image,
>      VK_IMAGE_ASPECT_COLOR_BIT, &surf);
>      +      surf.aux_surf = &image->aux_surface.isl;
>      +      surf.aux_addr = (struct blorp_address) {
>      +         .buffer = image->bo,
>      +         .offset = image->offset + image->aux_surface.offset,
>      +      };
>      +      surf.aux_usage = fb_att->aux_usage;
>      +
>      +      blorp_ccs_resolve(&batch, &surf, fb_att->view->isl.format);
>      +   }
>      +
>      +   blorp_batch_finish(&batch);
>      +}
>      diff --git a/src/intel/vulkan/anv_device.c
>      b/src/intel/vulkan/anv_device.c
>      index 3d4b783..8c68e94 100644
>      --- a/src/intel/vulkan/anv_device.c
>      +++ b/src/intel/vulkan/anv_device.c
>      @@ -1765,6 +1765,30 @@ void anv_DestroySampler(
>          anv_free2(&device->alloc, pAllocator, sampler);
>       }
>      +static enum isl_aux_usage
>      +get_fb_attachment_aux_usage(struct anv_device *device,
>      +                            struct anv_framebuffer *fb,
>      +                            struct anv_framebuffer_attachment
>      *fb_att)
>      +{
>      +   if (fb_att->view->image->aux_surface.isl.size == 0)
>      +      return ISL_AUX_USAGE_NONE; /* No aux surface */
>      +
>      +   /* This is a color buffer, it had better be CCS */
>      +   assert(fb_att->view->image->aux_surface.isl.usage &
>      ISL_SURF_USAGE_CCS_BIT);
>      +
>      +   if (!isl_format_supports_lossless_compression(&device->info,
>      +
>      fb_att->view->isl.format))
>      +      return ISL_AUX_USAGE_NONE; /* Unsupported format */
>      +
>      +   if (fb->layers > 1 || fb_att->view->isl.base_array_layer > 0)
>      +      return ISL_AUX_USAGE_NONE; /* Multi-layered CCS not yet
>      supported */
>      +
>      +   if (fb_att->view->isl.base_level > 0)
>      +      return ISL_AUX_USAGE_NONE; /* Multi-LOD CCS not yet supported
>      */
>      +
>      +   return ISL_AUX_USAGE_CCS_E;
>      +}
>      +
>       VkResult anv_CreateFramebuffer(
>           VkDevice                                    _device,
>           const VkFramebufferCreateInfo*              pCreateInfo,
>      @@ -1783,6 +1807,10 @@ VkResult anv_CreateFramebuffer(
>          if (framebuffer == NULL)
>             return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
>      +   framebuffer->width = pCreateInfo->width;
>      +   framebuffer->height = pCreateInfo->height;
>      +   framebuffer->layers = pCreateInfo->layers;
>      +
>          framebuffer->attachment_count = pCreateInfo->attachmentCount;
>          unsigned color_count = 0;
>          for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
>      @@ -1802,10 +1830,14 @@ VkResult anv_CreateFramebuffer(
>                                  device->isl_dev.ss.align);
>          unsigned color_idx = 0;
>          for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
>      -      struct anv_image_view *iview = framebuffer->attachments[i].
>      view;
>      +      struct anv_framebuffer_attachment *fb_att =
>      &framebuffer->attachments[i];
>      +      struct anv_image_view *iview = fb_att->view;
>      +
>             if (iview->image->aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
>                const uint16_t offset = (color_idx++) *
>      device->isl_dev.ss.align;
>      -         framebuffer->attachments[i].rt_state_offset = offset;
>      +         fb_att->rt_state_offset = offset;
>      +         fb_att->aux_usage =
>      +            get_fb_attachment_aux_usage(device, framebuffer,
>      fb_att);
>                struct isl_view isl_view = iview->isl;
>                isl_view.usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
>      @@ -1822,10 +1854,6 @@ VkResult anv_CreateFramebuffer(
>          if (device->info.has_llc)
>             anv_state_clflush(framebuffer->surface_states);
>      -   framebuffer->width = pCreateInfo->width;
>      -   framebuffer->height = pCreateInfo->height;
>      -   framebuffer->layers = pCreateInfo->layers;
>      -
>          *pFramebuffer = anv_framebuffer_to_handle(framebuffer);
>          return VK_SUCCESS;
>      diff --git a/src/intel/vulkan/anv_image.c
>      b/src/intel/vulkan/anv_image.c
>      index 405b923..ff99126 100644
>      --- a/src/intel/vulkan/anv_image.c
>      +++ b/src/intel/vulkan/anv_image.c
>      @@ -169,6 +169,15 @@ make_surface(const struct anv_device *dev,
>          add_surface(image, anv_surf);
>      +   if (aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
>      +      if (dev->info.gen >= 9 && vk_info->samples == 1) {
>      +         ok = isl_surf_get_ccs_surf(&dev->isl_dev, &anv_surf->isl,
>      +                                    &image->aux_surface.isl);
>      +         if (ok)
>      +            add_surface(image, &image->aux_surface);
>      +      }
>      +   }
>      +
>          return VK_SUCCESS;
>       }
>      diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_
>      private.h
>      index 5c24c37..5f03ae0 100644
>      --- a/src/intel/vulkan/anv_private.h
>      +++ b/src/intel/vulkan/anv_private.h
>      @@ -1405,6 +1405,8 @@ anv_cmd_buffer_cs_push_constants(struct
>      anv_cmd_buffer *cmd_buffer);
>       void anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer
>      *cmd_buffer);
>       void anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer
>      *cmd_buffer);
>      +void anv_cmd_buffer_resolve_framebuffer(struct anv_cmd_buffer
>      *cmd_buffer,
>      +                                        struct anv_framebuffer
>      *fb);
>       const struct anv_image_view *
>       anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer
>      *cmd_buffer);
>      diff --git a/src/intel/vulkan/genX_cmd_buffer.c
>      b/src/intel/vulkan/genX_cmd_buffer.c
>      index 90700e7..0962118 100644
>      --- a/src/intel/vulkan/genX_cmd_buffer.c
>      +++ b/src/intel/vulkan/genX_cmd_buffer.c
>      @@ -1346,6 +1346,23 @@ void genX(CmdEndRenderPass)(
>          anv_cmd_buffer_resolve_subpass(cmd_buffer);
>      +   /* From the Sky Lake PRM Vol. 7, "Render Target Resolve":
>      +    *
>      +    *    "When performing a render target resolve, PIPE_CONTROL
>      with end of
>      +    *    pipe sync must be delivered."
>      +    *
>      +    * By "end of pipe sync" it appears that they mean a pixel
>      scoreboard stall
>      +    * This makes sense because the resolve operation probably needs
>      the CCS to
>      +    * be fully valid before it looks at it.
>      +    */
>      +   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
>      +      pc.StallAtPixelScoreboard     = true;
>      +      pc.CommandStreamerStallEnable = true;
>      +   }
> 
>    Topi,
>    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?

Looks like something I need to look into in any case. Unfortunately, I don't
think it will help me at the moment. The test case I'm looking blits from the
problematic compressed buffer to uncompressed framebuffer and then does
pixel read against the uncompressed. Therefore there are no resolves involved.

>    --Jason
> 
>      +
>      +   anv_cmd_buffer_resolve_framebuffer(cmd_buffer,
>      +
>      cmd_buffer->state.framebuffer);
>      +
>       #ifndef NDEBUG
>          anv_dump_add_framebuffer(cmd_buffer,
>      cmd_buffer->state.framebuffer);
>       #endif
>      --
>      2.5.0.400.gff86faf
> 
> References
> 
>    1. mailto:jason at jlekstrand.net
>    2. mailto:jason at jlekstrand.net


More information about the mesa-dev mailing list