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

Author: Yiwei Zhang <zzyi...@chromium.org>
Date:   Mon Dec 18 19:26:37 2023 -0800

venus: split up the pipeline fix description into self and pnext

prepare for fixing the pipeline pnext chain

Signed-off-by: Yiwei Zhang <zzyi...@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26751>

---

 src/virtio/vulkan/vn_pipeline.c | 300 +++++++++++++++++++++-------------------
 1 file changed, 160 insertions(+), 140 deletions(-)

diff --git a/src/virtio/vulkan/vn_pipeline.c b/src/virtio/vulkan/vn_pipeline.c
index c99b85aade6..121c36730ff 100644
--- a/src/virtio/vulkan/vn_pipeline.c
+++ b/src/virtio/vulkan/vn_pipeline.c
@@ -24,7 +24,7 @@
  * Fields in the VkGraphicsPipelineCreateInfo pNext chain that we must track
  * to determine which fields are valid and which must be erased.
  */
-struct vn_graphics_pipeline_create_info_fields {
+struct vn_graphics_pipeline_info_self {
    union {
       /* Bitmask exists for testing if any field is set. */
       uint32_t mask;
@@ -65,17 +65,45 @@ struct vn_graphics_pipeline_create_info_fields {
 
          /** VkPipelineMultisampleStateCreateInfo::pSampleMask */
          bool multisample_state_sample_mask : 1;
+      };
+   };
+};
+
+static_assert(sizeof(struct vn_graphics_pipeline_info_self) ==
+                 sizeof(((struct vn_graphics_pipeline_info_self){}).mask),
+              "vn_graphics_pipeline_create_info_self::mask is too small");
+
+/**
+ * Fields in the VkGraphicsPipelineCreateInfo pNext chain that we must track
+ * to determine which fields are valid and which must be erased.
+ */
+struct vn_graphics_pipeline_info_pnext {
+   union {
+      /* Bitmask exists for testing if any field is set. */
+      uint32_t mask;
 
+      /* Group the fixes by Vulkan struct. Within each group, sort by struct
+       * order.
+       */
+      struct {
          /** VkPipelineRenderingCreateInfo, all format fields */
          bool rendering_info_formats : 1;
       };
    };
 };
 
-static_assert(
-   sizeof(struct vn_graphics_pipeline_create_info_fields) ==
-      sizeof(((struct vn_graphics_pipeline_create_info_fields){}).mask),
-   "vn_graphics_pipeline_create_info_fields::mask is too small");
+static_assert(sizeof(struct vn_graphics_pipeline_info_pnext) ==
+                 sizeof(((struct vn_graphics_pipeline_info_pnext){}).mask),
+              "vn_graphics_pipeline_create_info_pnext::mask is too small");
+
+/**
+ * Description of fixes needed for a single VkGraphicsPipelineCreateInfo
+ * pNext chain.
+ */
+struct vn_graphics_pipeline_fix_desc {
+   struct vn_graphics_pipeline_info_self self;
+   struct vn_graphics_pipeline_info_pnext pnext;
+};
 
 /**
  * Typesafe bitmask for VkGraphicsPipelineLibraryFlagsEXT. Named members
@@ -180,17 +208,6 @@ struct vn_graphics_pipeline {
    struct vn_graphics_pipeline_state state;
 };
 
-/**
- * Description of fixes needed for a single VkGraphicsPipelineCreateInfo
- * pNext chain.
- */
-struct vn_graphics_pipeline_fix_desc {
-   /** Erase these fields to prevent the Venus encoder from reading invalid
-    * memory.
-    */
-   struct vn_graphics_pipeline_create_info_fields erase;
-};
-
 /**
  * Temporary storage for fixes in vkCreateGraphicsPipelines.
  *
@@ -751,7 +768,7 @@ static void
 vn_graphics_shader_stages_update(
    const VkGraphicsPipelineCreateInfo *info,
    struct vn_graphics_pipeline_library_state direct_gpl,
-   struct vn_graphics_pipeline_create_info_fields *restrict valid,
+   struct vn_graphics_pipeline_fix_desc *restrict valid,
    VkShaderStageFlags *restrict shader_stages)
 {
    /* From the Vulkan 1.3.251 spec:
@@ -767,7 +784,7 @@ vn_graphics_shader_stages_update(
    if (!direct_gpl.pre_raster_shaders && !direct_gpl.fragment_shader)
       return;
 
-   valid->shader_stages = true;
+   valid->self.shader_stages = true;
 
    for (uint32_t i = 0; i < info->stageCount; i++) {
       /* We do not need to ignore the stages irrelevant to the GPL flags.
@@ -792,7 +809,7 @@ static void
 vn_render_pass_state_update(
    const VkGraphicsPipelineCreateInfo *info,
    struct vn_graphics_pipeline_library_state direct_gpl,
-   struct vn_graphics_pipeline_create_info_fields *restrict valid,
+   struct vn_graphics_pipeline_fix_desc *restrict valid,
    struct vn_render_pass_state *restrict state)
 {
    /* We must set validity before early returns, to ensure we don't erase
@@ -813,9 +830,9 @@ vn_render_pass_state_update(
     * renderPass is not VK_NULL_HANDLE, renderPass must be a valid
     * VkRenderPass handle
     */
-   valid->render_pass |= direct_gpl.pre_raster_shaders ||
-                         direct_gpl.fragment_shader ||
-                         direct_gpl.fragment_output;
+   valid->self.render_pass |= direct_gpl.pre_raster_shaders ||
+                              direct_gpl.fragment_shader ||
+                              direct_gpl.fragment_output;
 
    /* VUID-VkGraphicsPipelineCreateInfo-renderPass-06579
     *
@@ -832,7 +849,7 @@ vn_render_pass_state_update(
     * VkPipelineRenderingCreateInfo::pColorAttachmentFormats must be a valid
     * VkFormat value
     */
-   valid->rendering_info_formats |=
+   valid->pnext.rendering_info_formats |=
       direct_gpl.fragment_output && !info->renderPass;
 
    if (state->attachment_aspects != VK_IMAGE_ASPECT_METADATA_BIT) {
@@ -851,7 +868,7 @@ vn_render_pass_state_update(
       return;
    }
 
-   if (valid->render_pass && info->renderPass) {
+   if (valid->self.render_pass && info->renderPass) {
       struct vn_render_pass *pass =
          vn_render_pass_from_handle(info->renderPass);
       state->attachment_aspects =
@@ -859,7 +876,7 @@ vn_render_pass_state_update(
       return;
    }
 
-   if (valid->rendering_info_formats) {
+   if (valid->pnext.rendering_info_formats) {
       state->attachment_aspects = 0;
 
       /* From the Vulkan 1.3.255 spec:
@@ -990,7 +1007,7 @@ vn_graphics_pipeline_state_fill(
     * type, it may be an invalid pointer. If foo has a Vulkan handle type, it
     * may be an invalid handle.
     */
-   struct vn_graphics_pipeline_create_info_fields valid = { 0 };
+   struct vn_graphics_pipeline_fix_desc valid = { 0 };
 
    /* Merge the linked pipeline libraries. */
    for (uint32_t i = 0; i < lib_count; i++) {
@@ -1027,12 +1044,12 @@ vn_graphics_pipeline_state_fill(
     * state because it influences how the other state is collected.
     */
    if (direct_gpl.pre_raster_shaders) {
-      valid.tessellation_state |=
+      valid.self.tessellation_state |=
          (bool)(state->shader_stages &
                 (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT |
                  VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
-      valid.rasterization_state = true;
-      valid.pipeline_layout = true;
+      valid.self.rasterization_state = true;
+      valid.self.pipeline_layout = true;
 
       if (info->pRasterizationState) {
          state->rasterizer_discard_enable =
@@ -1044,12 +1061,12 @@ vn_graphics_pipeline_state_fill(
          state->rasterizer_discard_enable;
 
       if (!is_raster_statically_disabled) {
-         valid.viewport_state = true;
+         valid.self.viewport_state = true;
 
-         valid.viewport_state_viewports =
+         valid.self.viewport_state_viewports =
             !state->dynamic.viewport && !state->dynamic.viewport_with_count;
 
-         valid.viewport_state_scissors =
+         valid.self.viewport_state_scissors =
             !state->dynamic.scissor && !state->dynamic.scissor_with_count;
       }
 
@@ -1066,10 +1083,10 @@ vn_graphics_pipeline_state_fill(
          !state->gpl.pre_raster_shaders ||
          (state->shader_stages & VK_SHADER_STAGE_VERTEX_BIT);
 
-      valid.vertex_input_state |=
+      valid.self.vertex_input_state |=
          may_have_vertex_shader && !state->dynamic.vertex_input;
 
-      valid.input_assembly_state |= may_have_vertex_shader;
+      valid.self.input_assembly_state |= may_have_vertex_shader;
 
       /* Defer setting the flag until all its state is filled. */
       state->gpl.vertex_input = true;
@@ -1113,13 +1130,14 @@ vn_graphics_pipeline_state_fill(
           *    pMultisampleState must be NULL or a valid pointer to a valid
           *    VkPipelineMultisampleStateCreateInfo structure
           */
-         valid.multisample_state = true;
+         valid.self.multisample_state = true;
 
-         valid.multisample_state_sample_mask = !state->dynamic.sample_mask;
+         valid.self.multisample_state_sample_mask =
+            !state->dynamic.sample_mask;
 
          if ((state->render_pass.attachment_aspects &
               (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
-            valid.depth_stencil_state = true;
+            valid.self.depth_stencil_state = true;
          } else if (state->render_pass.attachment_aspects ==
                        VK_IMAGE_ASPECT_METADATA_BIT &&
                     (info->flags & VK_PIPELINE_CREATE_LIBRARY_BIT_KHR)) {
@@ -1132,10 +1150,10 @@ vn_graphics_pipeline_state_fill(
              * VkPipelineDepthStencilStateCreateInfo. Therefore, we must not
              * ignore it.
              */
-            valid.depth_stencil_state = true;
+            valid.self.depth_stencil_state = true;
          }
 
-         valid.pipeline_layout = true;
+         valid.self.pipeline_layout = true;
       }
 
       /* Defer setting the flag until all its state is filled. */
@@ -1153,14 +1171,15 @@ vn_graphics_pipeline_state_fill(
           *    pMultisampleState must be a valid pointer to a valid
           *    VkPipelineMultisampleStateCreateInfo structure
           */
-         valid.multisample_state = true;
+         valid.self.multisample_state = true;
 
-         valid.multisample_state_sample_mask = !state->dynamic.sample_mask;
+         valid.self.multisample_state_sample_mask =
+            !state->dynamic.sample_mask;
 
-         valid.color_blend_state |=
+         valid.self.color_blend_state |=
             (bool)(state->render_pass.attachment_aspects &
                    VK_IMAGE_ASPECT_COLOR_BIT);
-         valid.depth_stencil_state |=
+         valid.self.depth_stencil_state |=
             (bool)(state->render_pass.attachment_aspects &
                    (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
       }
@@ -1170,67 +1189,67 @@ vn_graphics_pipeline_state_fill(
    }
 
    *out_fix_desc = (struct vn_graphics_pipeline_fix_desc) {
-      .erase = {
-         /* clang-format off
-          *
-          * Format this to resemble a table. (clang-format transforms it into
-          * a difficult-to-read wall of text).
-          */
+      .self = {
+         /* clang-format off */
          .shader_stages =
-            !valid.shader_stages &&
+            !valid.self.shader_stages &&
             info->pStages,
          .vertex_input_state =
-            !valid.vertex_input_state &&
+            !valid.self.vertex_input_state &&
             info->pVertexInputState,
          .input_assembly_state =
-            !valid.input_assembly_state &&
+            !valid.self.input_assembly_state &&
             info->pInputAssemblyState,
          .tessellation_state =
-            !valid.tessellation_state &&
+            !valid.self.tessellation_state &&
             info->pTessellationState,
          .viewport_state =
-            !valid.viewport_state &&
+            !valid.self.viewport_state &&
             info->pViewportState,
          .viewport_state_viewports =
-            !valid.viewport_state_viewports &&
-            valid.viewport_state &&
+            !valid.self.viewport_state_viewports &&
+            valid.self.viewport_state &&
             info->pViewportState &&
             info->pViewportState->pViewports &&
             info->pViewportState->viewportCount,
          .viewport_state_scissors =
-            !valid.viewport_state_scissors &&
-            valid.viewport_state &&
+            !valid.self.viewport_state_scissors &&
+            valid.self.viewport_state &&
             info->pViewportState &&
             info->pViewportState->pScissors &&
             info->pViewportState->scissorCount,
          .rasterization_state =
-            !valid.rasterization_state &&
+            !valid.self.rasterization_state &&
             info->pRasterizationState,
          .multisample_state =
-            !valid.multisample_state &&
+            !valid.self.multisample_state &&
             info->pMultisampleState,
          .multisample_state_sample_mask =
-            valid.multisample_state &&
-            !valid.multisample_state_sample_mask &&
+            !valid.self.multisample_state_sample_mask &&
+            valid.self.multisample_state &&
             info->pMultisampleState &&
             info->pMultisampleState->pSampleMask,
          .depth_stencil_state =
-            !valid.depth_stencil_state &&
+            !valid.self.depth_stencil_state &&
             info->pDepthStencilState,
          .color_blend_state =
-            !valid.color_blend_state &&
+            !valid.self.color_blend_state &&
             info->pColorBlendState,
          .pipeline_layout =
-            !valid.pipeline_layout &&
+            !valid.self.pipeline_layout &&
             info->layout,
          .render_pass =
-            !valid.render_pass &&
+            !valid.self.render_pass &&
             info->renderPass,
          .base_pipeline_handle =
-            !valid.base_pipeline_handle &&
+            !valid.self.base_pipeline_handle &&
             info->basePipelineHandle,
+         /* clang-format on */
+      },
+      .pnext = {
+         /* clang-format off */
          .rendering_info_formats =
-            !valid.rendering_info_formats &&
+            !valid.pnext.rendering_info_formats &&
             rendering_info &&
             rendering_info->pColorAttachmentFormats &&
             rendering_info->colorAttachmentCount,
@@ -1250,15 +1269,16 @@ vn_fix_graphics_pipeline_create_infos(
 {
    VN_TRACE_SCOPE("apply_fixes");
 
-   *out_fix_tmp = NULL;
-
-   uint32_t erase_mask = 0;
+   uint32_t self_mask = 0;
+   uint32_t pnext_mask = 0;
    for (uint32_t i = 0; i < info_count; i++) {
-      erase_mask |= fix_descs[i].erase.mask;
+      self_mask |= fix_descs[i].self.mask;
+      pnext_mask |= fix_descs[i].pnext.mask;
    }
 
-   if (!erase_mask) {
+   if (!self_mask && !pnext_mask) {
       /* No fix is needed. */
+      *out_fix_tmp = NULL;
       return infos;
    }
 
@@ -1270,76 +1290,76 @@ vn_fix_graphics_pipeline_create_infos(
    memcpy(fix_tmp->infos, infos, info_count * sizeof(infos[0]));
 
    for (uint32_t i = 0; i < info_count; i++) {
-      if (!fix_descs[i].erase.mask) {
-         /* No fix is needed for this VkGraphicsPipelineCreateInfo chain. */
-         continue;
-      }
-
-      /* VkGraphicsPipelineCreateInfo */
-      if (fix_descs[i].erase.shader_stages) {
-         fix_tmp->infos[i].stageCount = 0;
-         fix_tmp->infos[i].pStages = NULL;
-      }
-      if (fix_descs[i].erase.vertex_input_state)
-         fix_tmp->infos[i].pVertexInputState = NULL;
-      if (fix_descs[i].erase.input_assembly_state)
-         fix_tmp->infos[i].pInputAssemblyState = NULL;
-      if (fix_descs[i].erase.tessellation_state)
-         fix_tmp->infos[i].pTessellationState = NULL;
-      if (fix_descs[i].erase.viewport_state)
-         fix_tmp->infos[i].pViewportState = NULL;
-      if (fix_descs[i].erase.rasterization_state)
-         fix_tmp->infos[i].pRasterizationState = NULL;
-      if (fix_descs[i].erase.multisample_state)
-         fix_tmp->infos[i].pMultisampleState = NULL;
-      if (fix_descs[i].erase.depth_stencil_state)
-         fix_tmp->infos[i].pDepthStencilState = NULL;
-      if (fix_descs[i].erase.color_blend_state)
-         fix_tmp->infos[i].pColorBlendState = NULL;
-      if (fix_descs[i].erase.pipeline_layout)
-         fix_tmp->infos[i].layout = VK_NULL_HANDLE;
-      if (fix_descs[i].erase.base_pipeline_handle)
-         fix_tmp->infos[i].basePipelineHandle = VK_NULL_HANDLE;
-
-      /* VkPipelineMultisampleStateCreateInfo */
-      if (fix_descs[i].erase.multisample_state_sample_mask) {
-         /* Swap original pMultisampleState with temporary state. */
-         fix_tmp->multisample_state_infos[i] = *infos[i].pMultisampleState;
-         fix_tmp->infos[i].pMultisampleState =
-            &fix_tmp->multisample_state_infos[i];
-
-         fix_tmp->multisample_state_infos[i].pSampleMask = NULL;
-      }
+      if (fix_descs[i].self.mask) {
+         /* VkGraphicsPipelineCreateInfo */
+         if (fix_descs[i].self.shader_stages) {
+            fix_tmp->infos[i].stageCount = 0;
+            fix_tmp->infos[i].pStages = NULL;
+         }
+         if (fix_descs[i].self.vertex_input_state)
+            fix_tmp->infos[i].pVertexInputState = NULL;
+         if (fix_descs[i].self.input_assembly_state)
+            fix_tmp->infos[i].pInputAssemblyState = NULL;
+         if (fix_descs[i].self.tessellation_state)
+            fix_tmp->infos[i].pTessellationState = NULL;
+         if (fix_descs[i].self.viewport_state)
+            fix_tmp->infos[i].pViewportState = NULL;
+         if (fix_descs[i].self.rasterization_state)
+            fix_tmp->infos[i].pRasterizationState = NULL;
+         if (fix_descs[i].self.multisample_state)
+            fix_tmp->infos[i].pMultisampleState = NULL;
+         if (fix_descs[i].self.depth_stencil_state)
+            fix_tmp->infos[i].pDepthStencilState = NULL;
+         if (fix_descs[i].self.color_blend_state)
+            fix_tmp->infos[i].pColorBlendState = NULL;
+         if (fix_descs[i].self.pipeline_layout)
+            fix_tmp->infos[i].layout = VK_NULL_HANDLE;
+         if (fix_descs[i].self.base_pipeline_handle)
+            fix_tmp->infos[i].basePipelineHandle = VK_NULL_HANDLE;
+
+         /* VkPipelineMultisampleStateCreateInfo */
+         if (fix_descs[i].self.multisample_state_sample_mask) {
+            /* Swap original pMultisampleState with temporary state. */
+            fix_tmp->multisample_state_infos[i] = *infos[i].pMultisampleState;
+            fix_tmp->infos[i].pMultisampleState =
+               &fix_tmp->multisample_state_infos[i];
+
+            fix_tmp->multisample_state_infos[i].pSampleMask = NULL;
+         }
 
-      /* VkPipelineViewportStateCreateInfo */
-      if (fix_descs[i].erase.viewport_state_viewports ||
-          fix_descs[i].erase.viewport_state_scissors) {
-         /* Swap original pViewportState with temporary state. */
-         fix_tmp->viewport_state_infos[i] = *infos[i].pViewportState;
-         fix_tmp->infos[i].pViewportState = &fix_tmp->viewport_state_infos[i];
-
-         if (fix_descs[i].erase.viewport_state_viewports)
-            fix_tmp->viewport_state_infos[i].pViewports = NULL;
-         if (fix_descs[i].erase.viewport_state_scissors)
-            fix_tmp->viewport_state_infos[i].pScissors = NULL;
+         /* VkPipelineViewportStateCreateInfo */
+         if (fix_descs[i].self.viewport_state_viewports ||
+             fix_descs[i].self.viewport_state_scissors) {
+            /* Swap original pViewportState with temporary state. */
+            fix_tmp->viewport_state_infos[i] = *infos[i].pViewportState;
+            fix_tmp->infos[i].pViewportState =
+               &fix_tmp->viewport_state_infos[i];
+
+            if (fix_descs[i].self.viewport_state_viewports)
+               fix_tmp->viewport_state_infos[i].pViewports = NULL;
+            if (fix_descs[i].self.viewport_state_scissors)
+               fix_tmp->viewport_state_infos[i].pScissors = NULL;
+         }
       }
 
-      /* VkPipelineRenderingCreateInfo */
-      if (fix_descs[i].erase.rendering_info_formats) {
-         /* All format fields are invalid, but the only field that must be
-          * erased is pColorAttachmentFormats because the other
-          * fields are merely VkFormat values. Encoding invalid pointers is
-          * unsafe; encoding invalid VkFormat values is not unsafe.
-          *
-          * However, the fix is difficult because it requires a deep rewrite
-          * of the pNext chain.
-          *
-          * TODO: Fix invalid
-          * VkPipelineRenderingCreateInfo::pColorAttachmentFormats.
-          */
-         vn_log(dev->instance,
-                "venus may encode array from invalid pointer "
-                "VkPipelineRenderingCreateInfo::pColorAttachmentFormats");
+      if (fix_descs[i].pnext.mask) {
+         /* VkPipelineRenderingCreateInfo */
+         if (fix_descs[i].pnext.rendering_info_formats) {
+            /* All format fields are invalid, but the only field that must be
+             * erased is pColorAttachmentFormats because the other
+             * fields are merely VkFormat values. Encoding invalid pointers is
+             * unsafe; encoding invalid VkFormat values is not unsafe.
+             *
+             * However, the fix is difficult because it requires a deep
+             * rewrite of the pNext chain.
+             *
+             * TODO: Fix invalid
+             * VkPipelineRenderingCreateInfo::pColorAttachmentFormats.
+             */
+            vn_log(dev->instance,
+                   "venus may encode array from invalid pointer "
+                   "VkPipelineRenderingCreateInfo::pColorAttachmentFormats");
+         }
       }
    }
 

Reply via email to