[Mesa-dev] [PATCH 3/4] anv/pass: Record required pipe flushes

Pohjolainen, Topi topi.pohjolainen at gmail.com
Wed Mar 15 16:51:46 UTC 2017


On Tue, Mar 14, 2017 at 07:55:52AM -0700, Jason Ekstrand wrote:
> ---
>  src/intel/vulkan/anv_pass.c    | 87 ++++++++++++++++++++++++++++++++++++++++++
>  src/intel/vulkan/anv_private.h |  2 +
>  2 files changed, 89 insertions(+)
> 
> diff --git a/src/intel/vulkan/anv_pass.c b/src/intel/vulkan/anv_pass.c
> index 8d1768d..d6d3794 100644
> --- a/src/intel/vulkan/anv_pass.c
> +++ b/src/intel/vulkan/anv_pass.c
> @@ -98,6 +98,7 @@ VkResult anv_CreateRenderPass(
>     if (pass->subpass_attachments == NULL)
>        goto fail_subpass_usages;
>  
> +   bool has_color = false, has_depth = false, has_input = false;
>     p = pass->subpass_attachments;
>     for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
>        const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
> @@ -115,6 +116,7 @@ VkResult anv_CreateRenderPass(
>              uint32_t a = desc->pInputAttachments[j].attachment;
>              subpass->input_attachments[j] = desc->pInputAttachments[j];
>              if (a != VK_ATTACHMENT_UNUSED) {
> +               has_input = true;
>                 pass->attachments[a].usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
>                 pass->attachments[a].subpass_usage[i] |= ANV_SUBPASS_USAGE_INPUT;
>                 pass->attachments[a].last_subpass_idx = i;
> @@ -134,6 +136,7 @@ VkResult anv_CreateRenderPass(
>              uint32_t a = desc->pColorAttachments[j].attachment;
>              subpass->color_attachments[j] = desc->pColorAttachments[j];
>              if (a != VK_ATTACHMENT_UNUSED) {
> +               has_color = true;
>                 pass->attachments[a].usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
>                 pass->attachments[a].subpass_usage[i] |= ANV_SUBPASS_USAGE_DRAW;
>                 pass->attachments[a].last_subpass_idx = i;
> @@ -170,6 +173,7 @@ VkResult anv_CreateRenderPass(
>           *p++ = subpass->depth_stencil_attachment =
>              *desc->pDepthStencilAttachment;
>           if (a != VK_ATTACHMENT_UNUSED) {
> +            has_depth = true;
>              pass->attachments[a].usage |=
>                 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
>              pass->attachments[a].subpass_usage[i] |= ANV_SUBPASS_USAGE_DRAW;
> @@ -181,10 +185,92 @@ VkResult anv_CreateRenderPass(
>        }
>     }
>  
> +   pass->subpass_flushes =
> +      vk_zalloc2(&device->alloc, pAllocator,
> +                 (pass->subpass_count + 1) * sizeof(*pass->subpass_flushes),
> +                 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
> +   if (pass->subpass_flushes == NULL)
> +      goto fail_subpass_attachments;
> +
> +   for (uint32_t i = 0; i < pCreateInfo->dependencyCount; i++) {
> +      const VkSubpassDependency *dep = &pCreateInfo->pDependencies[i];
> +      if (dep->srcSubpass != VK_SUBPASS_EXTERNAL) {

Did you mean to have 'dep->dstSubpass' here and 'dep->srcSubpass' below?

> +         pass->subpass_flushes[dep->dstSubpass] |=
> +            anv_pipe_invalidate_bits_for_access_flags(dep->dstAccessMask);
> +      }
> +
> +      if (dep->dstSubpass != VK_SUBPASS_EXTERNAL) {
> +         pass->subpass_flushes[dep->srcSubpass + 1] |=
> +            anv_pipe_flush_bits_for_access_flags(dep->srcAccessMask);
> +      }
> +   }
> +
> +   /* From the Vulkan 1.0.39 spec:
> +    *
> +    *    If there is no subpass dependency from VK_SUBPASS_EXTERNAL to the
> +    *    first subpass that uses an attachment, then an implicit subpass
> +    *    dependency exists from VK_SUBPASS_EXTERNAL to the first subpass it is
> +    *    used in. The subpass dependency operates as if defined with the
> +    *    following parameters:
> +    *
> +    *    VkSubpassDependency implicitDependency = {
> +    *        .srcSubpass = VK_SUBPASS_EXTERNAL;
> +    *        .dstSubpass = firstSubpass; // First subpass attachment is used in
> +    *        .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
> +    *        .dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
> +    *        .srcAccessMask = 0;
> +    *        .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
> +    *                         VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
> +    *                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
> +    *                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
> +    *                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
> +    *        .dependencyFlags = 0;
> +    *    };
> +    *
> +    *    Similarly, if there is no subpass dependency from the last subpass
> +    *    that uses an attachment to VK_SUBPASS_EXTERNAL, then an implicit
> +    *    subpass dependency exists from the last subpass it is used in to
> +    *    VK_SUBPASS_EXTERNAL. The subpass dependency operates as if defined
> +    *    with the following parameters:
> +    *
> +    *    VkSubpassDependency implicitDependency = {
> +    *        .srcSubpass = lastSubpass; // Last subpass attachment is used in
> +    *        .dstSubpass = VK_SUBPASS_EXTERNAL;
> +    *        .srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
> +    *        .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
> +    *        .srcAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
> +    *                         VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
> +    *                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
> +    *                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
> +    *                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
> +    *        .dstAccessMask = 0;
> +    *        .dependencyFlags = 0;
> +    *    };
> +    *
> +    * We could implement this by walking over all of the attachments and
> +    * subpasses and checking to see if any of them don't have an external
> +    * dependency.  Or, we could just be lazy and add a couple extra flushes.
> +    * We choose to be lazy.
> +    */
> +   if (has_input) {
> +      pass->subpass_flushes[0] |=
> +         ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT;
> +   }
> +   if (has_color) {
> +      pass->subpass_flushes[pass->subpass_count] |=
> +         ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT;
> +   }
> +   if (has_depth) {
> +      pass->subpass_flushes[pass->subpass_count] |=
> +         ANV_PIPE_DEPTH_CACHE_FLUSH_BIT;
> +   }
> +
>     *pRenderPass = anv_render_pass_to_handle(pass);
>  
>     return VK_SUCCESS;
>  
> +fail_subpass_attachments:
> +   vk_free2(&device->alloc, pAllocator, pass->subpass_attachments);
>  fail_subpass_usages:
>     vk_free2(&device->alloc, pAllocator, pass->subpass_usages);
>  fail_pass:
> @@ -204,6 +290,7 @@ void anv_DestroyRenderPass(
>     if (!pass)
>        return;
>  
> +   vk_free2(&device->alloc, pAllocator, pass->subpass_flushes);
>     vk_free2(&device->alloc, pAllocator, pass->subpass_attachments);
>     vk_free2(&device->alloc, pAllocator, pass->subpass_usages);
>     vk_free2(&device->alloc, pAllocator, pass);
> diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
> index a0eefe3..53d39ee 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -2038,6 +2038,8 @@ struct anv_render_pass {
>     uint32_t                                     attachment_count;
>     uint32_t                                     subpass_count;
>     VkAttachmentReference *                      subpass_attachments;
> +   /* An array of subpass_count+1 flushes, one per subpass boundary */
> +   enum anv_pipe_bits *                         subpass_flushes;
>     enum anv_subpass_usage *                     subpass_usages;
>     struct anv_render_pass_attachment *          attachments;
>     struct anv_subpass                           subpasses[0];
> -- 
> 2.5.0.400.gff86faf
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list