Module: Mesa
Branch: main
Commit: 73ed019bec3bfe54a06269c0ea5d59158ab856de
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=73ed019bec3bfe54a06269c0ea5d59158ab856de

Author: Iván Briano <[email protected]>
Date:   Thu Nov  4 12:26:26 2021 -0700

anv: add functions to set up fake render passes

There's two of them because they can be created from three points in the
code that provide different details and this is the least ugly way I
could think of for now.

v2: Avoid allocations (Lionel)

v3: Move definition closer to its usage (Lionel)

v4: (Lionel)
 - Simplify anv_dynamic_pass_init_full
 - Zero out pass/subpass to avoid stall pointers

Reviewed-by: Lionel Landwerlin <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13980>

---

 src/intel/vulkan/anv_pass.c    | 193 +++++++++++++++++++++++++++++++++++++++++
 src/intel/vulkan/anv_private.h | 193 ++++++++++++++++++++++++-----------------
 2 files changed, 306 insertions(+), 80 deletions(-)

diff --git a/src/intel/vulkan/anv_pass.c b/src/intel/vulkan/anv_pass.c
index 91e4efd4533..19a839850c0 100644
--- a/src/intel/vulkan/anv_pass.c
+++ b/src/intel/vulkan/anv_pass.c
@@ -445,3 +445,196 @@ void anv_GetRenderAreaGranularity(
 
    *pGranularity = (VkExtent2D) { 1, 1 };
 }
+
+void
+anv_dynamic_pass_init(struct anv_dynamic_render_pass *dyn_render_pass,
+                      const struct anv_dynamic_pass_create_info *info)
+{
+   uint32_t att_count;
+
+   att_count = info->colorAttachmentCount;
+   if ((info->depthAttachmentFormat != VK_FORMAT_UNDEFINED) ||
+       (info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED))
+      att_count++;
+
+   struct anv_render_pass *pass = &dyn_render_pass->pass;
+   pass->attachment_count = att_count;
+   pass->subpass_count = 1;
+   pass->attachments = dyn_render_pass->rp_attachments;
+
+   struct anv_subpass *subpass = &dyn_render_pass->subpass;
+   subpass->attachment_count = att_count;
+   subpass->attachments = dyn_render_pass->sp_attachments;
+   if (info->colorAttachmentCount > 0) {
+      subpass->color_count = info->colorAttachmentCount;
+      subpass->color_attachments = dyn_render_pass->sp_attachments;
+   }
+   subpass->view_mask = info->viewMask;
+
+   uint32_t att;
+   for (att = 0; att < info->colorAttachmentCount; att++) {
+      if (info->pColorAttachmentFormats[att] == VK_FORMAT_UNDEFINED)
+         continue;
+      pass->attachments[att].format = info->pColorAttachmentFormats[att];
+      pass->attachments[att].samples = info->rasterizationSamples;
+      subpass->attachments[att].attachment = att;
+      subpass->attachments[att].usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+   }
+
+   if ((info->depthAttachmentFormat != VK_FORMAT_UNDEFINED) ||
+       (info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED)) {
+      pass->attachments[att].format = (info->depthAttachmentFormat != 
VK_FORMAT_UNDEFINED) ? info->depthAttachmentFormat : 
info->stencilAttachmentFormat;
+      pass->attachments[att].samples = info->rasterizationSamples;
+      subpass->attachments[att].attachment = att;
+      subpass->attachments[att].usage = 
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+      subpass->depth_stencil_attachment = &subpass->attachments[att];
+
+      att++;
+   }
+}
+
+void
+anv_dynamic_pass_init_full(struct anv_dynamic_render_pass *dyn_render_pass,
+                           const VkRenderingInfoKHR *info)
+{
+   uint32_t att_count;
+   uint32_t color_count = 0, ds_count = 0;
+   uint32_t color_resolve_idx, ds_idx;
+   bool has_color_resolve, has_ds_resolve;
+
+   struct anv_render_pass *pass = &dyn_render_pass->pass;
+   struct anv_subpass *subpass = &dyn_render_pass->subpass;
+
+   /* We set some of the fields conditionally below, like
+    * subpass->ds_resolve_attachment. But the value of this field is used to
+    * trigger depth/stencil resolve, so clear things to make sure we don't
+    * leave stale values.
+    */
+   memset(pass, 0, sizeof(*pass));
+   memset(subpass, 0, sizeof(*subpass));
+
+   dyn_render_pass->suspending = info->flags & VK_RENDERING_SUSPENDING_BIT_KHR;
+   dyn_render_pass->resuming = info->flags & VK_RENDERING_RESUMING_BIT_KHR;
+
+   color_count = info->colorAttachmentCount;
+   if ((info->pDepthAttachment && info->pDepthAttachment->imageView) ||
+       (info->pStencilAttachment && info->pStencilAttachment->imageView))
+      ds_count = 1;
+
+   has_color_resolve = false;
+   has_ds_resolve = false;
+   for (uint32_t i = 0; i < info->colorAttachmentCount; i++) {
+      if (info->pColorAttachments[i].resolveMode != VK_RESOLVE_MODE_NONE) {
+         has_color_resolve = true;
+         break;
+      }
+   }
+   if (has_color_resolve)
+      color_count *= 2;
+
+   has_ds_resolve =
+      ((info->pDepthAttachment &&
+        info->pDepthAttachment->resolveMode != VK_RESOLVE_MODE_NONE) ||
+       (info->pStencilAttachment &&
+        info->pStencilAttachment->resolveMode != VK_RESOLVE_MODE_NONE));
+   if (has_ds_resolve)
+      ds_count *= 2;
+
+   att_count = color_count + ds_count;
+   color_resolve_idx = info->colorAttachmentCount;
+   ds_idx = color_count;
+
+   pass->subpass_count = 1;
+   pass->attachments = dyn_render_pass->rp_attachments;
+   pass->attachment_count = att_count;
+
+   struct anv_subpass_attachment *subpass_attachments =
+      dyn_render_pass->sp_attachments;
+   subpass->attachment_count = att_count;
+   subpass->attachments = subpass_attachments;
+   subpass->color_count = info->colorAttachmentCount;
+   subpass->color_attachments = subpass_attachments;
+   subpass->has_color_resolve = has_color_resolve;
+   subpass->resolve_attachments =
+      subpass_attachments + subpass->color_count;
+   /* The depth field presence is used to trigger resolve/shadow-buffer-copy,
+    * only set them if needed.
+    */
+   if (ds_count > 0) {
+      subpass->depth_stencil_attachment = &subpass_attachments[ds_idx];
+      if (has_ds_resolve)
+         subpass->ds_resolve_attachment = &subpass_attachments[ds_idx + 1];
+   }
+   subpass->view_mask = info->viewMask;
+
+   for (uint32_t att = 0; att < info->colorAttachmentCount; att++) {
+      if (info->pColorAttachments[att].imageView == VK_NULL_HANDLE) {
+         subpass->color_attachments[att].attachment = VK_ATTACHMENT_UNUSED;
+         continue;
+      }
+
+      ANV_FROM_HANDLE(anv_image_view, iview, 
info->pColorAttachments[att].imageView);
+
+      pass->attachments[att]     = (struct anv_render_pass_attachment) {
+         .format                 = iview->vk.format,
+         .samples                = iview->vk.image->samples,
+      };
+
+      subpass->color_attachments[att] = (struct anv_subpass_attachment) {
+         .usage      = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+         .attachment = att,
+      };
+
+      if (has_color_resolve) {
+         if (info->pColorAttachments[att].resolveMode == VK_RESOLVE_MODE_NONE) 
{
+            subpass->resolve_attachments[att].attachment = 
VK_ATTACHMENT_UNUSED;
+            continue;
+         }
+
+         subpass->resolve_attachments[att] = (struct anv_subpass_attachment) {
+            .usage      = VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+            .attachment = att + color_resolve_idx,
+         };
+      }
+   }
+
+   if (ds_count) {
+      /* Easier to reference for the stuff both have in common. */
+      const VkRenderingAttachmentInfoKHR *d_att = info->pDepthAttachment;
+      const VkRenderingAttachmentInfoKHR *s_att = info->pStencilAttachment;
+      const VkRenderingAttachmentInfoKHR *d_or_s_att = d_att ? d_att : s_att;
+      VkResolveModeFlagBits depth_resolve_mode = VK_RESOLVE_MODE_NONE;
+      VkResolveModeFlagBits stencil_resolve_mode = VK_RESOLVE_MODE_NONE;
+
+      ANV_FROM_HANDLE(anv_image_view, iview, d_or_s_att->imageView);
+
+      pass->attachments[ds_idx]  = (struct anv_render_pass_attachment) {
+         .format                 = iview->vk.format,
+         .samples                = iview->vk.image->samples,
+      };
+
+      *subpass->depth_stencil_attachment = (struct anv_subpass_attachment) {
+         .usage            = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
+         .attachment       = ds_idx,
+      };
+
+      if (d_att && d_att->imageView) {
+         depth_resolve_mode = d_att->resolveMode;
+      }
+      if (s_att && s_att->imageView) {
+         stencil_resolve_mode = s_att->resolveMode;
+      }
+
+      if (has_ds_resolve) {
+         uint32_t ds_res_idx = ds_idx + 1;
+
+         *subpass->ds_resolve_attachment = (struct anv_subpass_attachment) {
+            .usage            = VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+            .attachment       = ds_res_idx,
+         };
+
+         subpass->depth_resolve_mode = depth_resolve_mode;
+         subpass->stencil_resolve_mode = stencil_resolve_mode;
+      }
+   }
+}
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index bdb5391c157..fede8d6e531 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -2912,6 +2912,103 @@ struct anv_cmd_ray_tracing_state {
    } scratch;
 };
 
+struct anv_framebuffer {
+   struct vk_object_base                        base;
+
+   uint32_t                                     width;
+   uint32_t                                     height;
+   uint32_t                                     layers;
+
+   uint32_t                                     attachment_count;
+   struct anv_image_view *                      attachments[0];
+};
+
+struct anv_subpass_attachment {
+   VkImageUsageFlagBits usage;
+   uint32_t attachment;
+   VkImageLayout layout;
+
+   /* Used only with attachment containing stencil data. */
+   VkImageLayout stencil_layout;
+};
+
+struct anv_subpass {
+   uint32_t                                     attachment_count;
+
+   /**
+    * A pointer to all attachment references used in this subpass.
+    * Only valid if ::attachment_count > 0.
+    */
+   struct anv_subpass_attachment *              attachments;
+   uint32_t                                     input_count;
+   struct anv_subpass_attachment *              input_attachments;
+   uint32_t                                     color_count;
+   struct anv_subpass_attachment *              color_attachments;
+   struct anv_subpass_attachment *              resolve_attachments;
+
+   struct anv_subpass_attachment *              depth_stencil_attachment;
+   struct anv_subpass_attachment *              ds_resolve_attachment;
+   VkResolveModeFlagBitsKHR                     depth_resolve_mode;
+   VkResolveModeFlagBitsKHR                     stencil_resolve_mode;
+
+   uint32_t                                     view_mask;
+
+   /** Subpass has a depth/stencil self-dependency */
+   bool                                         has_ds_self_dep;
+
+   /** Subpass has at least one color resolve attachment */
+   bool                                         has_color_resolve;
+};
+
+struct anv_render_pass_attachment {
+   /* TODO: Consider using VkAttachmentDescription instead of storing each of
+    * its members individually.
+    */
+   VkFormat                                     format;
+   uint32_t                                     samples;
+   VkImageUsageFlags                            usage;
+   VkAttachmentLoadOp                           load_op;
+   VkAttachmentStoreOp                          store_op;
+   VkAttachmentLoadOp                           stencil_load_op;
+   VkImageLayout                                initial_layout;
+   VkImageLayout                                final_layout;
+   VkImageLayout                                first_subpass_layout;
+
+   VkImageLayout                                stencil_initial_layout;
+   VkImageLayout                                stencil_final_layout;
+
+   /* The subpass id in which the attachment will be used last. */
+   uint32_t                                     last_subpass_idx;
+};
+
+struct anv_render_pass {
+   struct vk_object_base                        base;
+
+   uint32_t                                     attachment_count;
+   uint32_t                                     subpass_count;
+   /* An array of subpass_count+1 flushes, one per subpass boundary */
+   enum anv_pipe_bits *                         subpass_flushes;
+   struct anv_render_pass_attachment *          attachments;
+   struct anv_subpass                           subpasses[0];
+};
+
+/* RTs * 2 (for resolve attachments)
+ * depth/sencil * 2
+ */
+#define MAX_DYN_RENDER_ATTACHMENTS (MAX_RTS * 2 + 2 * 2)
+
+/* And this, kids, is what we call a nasty hack. */
+struct anv_dynamic_render_pass {
+   struct anv_render_pass                    pass;
+   struct anv_subpass                        subpass;
+   struct anv_framebuffer                    framebuffer;
+   struct anv_render_pass_attachment         
rp_attachments[MAX_DYN_RENDER_ATTACHMENTS];
+   struct anv_subpass_attachment             
sp_attachments[MAX_DYN_RENDER_ATTACHMENTS];
+
+   bool suspending;
+   bool resuming;
+};
+
 /** State required while building cmd buffer */
 struct anv_cmd_state {
    /* PIPELINE_SELECT.PipelineSelection */
@@ -4369,92 +4466,12 @@ struct anv_sampler {
    struct anv_state             custom_border_color;
 };
 
-struct anv_framebuffer {
-   struct vk_object_base                        base;
-
-   uint32_t                                     width;
-   uint32_t                                     height;
-   uint32_t                                     layers;
-
-   uint32_t                                     attachment_count;
-   struct anv_image_view *                      attachments[0];
-};
-
-struct anv_subpass_attachment {
-   VkImageUsageFlagBits usage;
-   uint32_t attachment;
-   VkImageLayout layout;
-
-   /* Used only with attachment containing stencil data. */
-   VkImageLayout stencil_layout;
-};
-
-struct anv_subpass {
-   uint32_t                                     attachment_count;
-
-   /**
-    * A pointer to all attachment references used in this subpass.
-    * Only valid if ::attachment_count > 0.
-    */
-   struct anv_subpass_attachment *              attachments;
-   uint32_t                                     input_count;
-   struct anv_subpass_attachment *              input_attachments;
-   uint32_t                                     color_count;
-   struct anv_subpass_attachment *              color_attachments;
-   struct anv_subpass_attachment *              resolve_attachments;
-
-   struct anv_subpass_attachment *              depth_stencil_attachment;
-   struct anv_subpass_attachment *              ds_resolve_attachment;
-   VkResolveModeFlagBitsKHR                     depth_resolve_mode;
-   VkResolveModeFlagBitsKHR                     stencil_resolve_mode;
-
-   uint32_t                                     view_mask;
-
-   /** Subpass has a depth/stencil self-dependency */
-   bool                                         has_ds_self_dep;
-
-   /** Subpass has at least one color resolve attachment */
-   bool                                         has_color_resolve;
-};
-
 static inline unsigned
 anv_subpass_view_count(const struct anv_subpass *subpass)
 {
    return MAX2(1, util_bitcount(subpass->view_mask));
 }
 
-struct anv_render_pass_attachment {
-   /* TODO: Consider using VkAttachmentDescription instead of storing each of
-    * its members individually.
-    */
-   VkFormat                                     format;
-   uint32_t                                     samples;
-   VkImageUsageFlags                            usage;
-   VkAttachmentLoadOp                           load_op;
-   VkAttachmentStoreOp                          store_op;
-   VkAttachmentLoadOp                           stencil_load_op;
-   VkImageLayout                                initial_layout;
-   VkImageLayout                                final_layout;
-   VkImageLayout                                first_subpass_layout;
-
-   VkImageLayout                                stencil_initial_layout;
-   VkImageLayout                                stencil_final_layout;
-
-   /* The subpass id in which the attachment will be used last. */
-   uint32_t                                     last_subpass_idx;
-};
-
-struct anv_render_pass {
-   struct vk_object_base                        base;
-
-   uint32_t                                     attachment_count;
-   uint32_t                                     subpass_count;
-   /* An array of subpass_count+1 flushes, one per subpass boundary */
-   enum anv_pipe_bits *                         subpass_flushes;
-   struct anv_render_pass_attachment *          attachments;
-   struct anv_subpass                           subpasses[0];
-};
-
 #define ANV_PIPELINE_STATISTICS_MASK 0x000007ff
 
 struct anv_query_pool {
@@ -4478,6 +4495,22 @@ struct anv_query_pool {
    struct intel_perf_query_info                 **pass_query;
 };
 
+struct anv_dynamic_pass_create_info {
+   uint32_t                 viewMask;
+   uint32_t                 colorAttachmentCount;
+   const VkFormat*          pColorAttachmentFormats;
+   VkFormat                 depthAttachmentFormat;
+   VkFormat                 stencilAttachmentFormat;
+   VkSampleCountFlagBits    rasterizationSamples;
+};
+
+void
+anv_dynamic_pass_init(struct anv_dynamic_render_pass *dyn_render_pass,
+                      const struct anv_dynamic_pass_create_info *info);
+void
+anv_dynamic_pass_init_full(struct anv_dynamic_render_pass *dyn_render_pass,
+                           const VkRenderingInfoKHR *info);
+
 static inline uint32_t khr_perf_query_preamble_offset(const struct 
anv_query_pool *pool,
                                                       uint32_t pass)
 {

Reply via email to