anv: Drop pipeline pass/subpass in favor of rendering_info
authorJason Ekstrand <jason.ekstrand@collabora.com>
Fri, 11 Feb 2022 17:40:34 +0000 (11:40 -0600)
committerJason Ekstrand <jason.ekstrand@collabora.com>
Wed, 16 Mar 2022 17:51:16 +0000 (12:51 -0500)
This is about the only "small" change we can make in the process of
converting from render-pass-based to dynamic-rendering-based.  Make
everything in pipeline creation work in terms of dynamic rendering and
create the dynamic rendering structs from the render pass as-needed.

Reviewed-by: Ivan Briano <ivan.briano@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14961>

src/intel/vulkan/anv_nir_lower_multiview.c
src/intel/vulkan/anv_pipeline.c
src/intel/vulkan/anv_private.h
src/intel/vulkan/genX_pipeline.c

index cc6f798..eff13e5 100644 (file)
@@ -170,7 +170,7 @@ anv_nir_lower_multiview(nir_shader *shader,
                         struct anv_graphics_pipeline *pipeline)
 {
    assert(shader->info.stage != MESA_SHADER_COMPUTE);
-   uint32_t view_mask = pipeline->subpass->view_mask;
+   uint32_t view_mask = pipeline->view_mask;
 
    /* If multiview isn't enabled, just lower the ViewIndex builtin to zero. */
    if (view_mask == 0) {
@@ -190,7 +190,7 @@ anv_nir_lower_multiview(nir_shader *shader,
       if (shader->info.stage == MESA_SHADER_FRAGMENT)
          return false;
 
-      bool progress = nir_lower_multiview(shader, pipeline->subpass->view_mask);
+      bool progress = nir_lower_multiview(shader, pipeline->view_mask);
 
       if (progress) {
          nir_builder b;
@@ -315,7 +315,7 @@ anv_check_for_primitive_replication(nir_shader **shaders,
       return false;
    }
 
-   uint32_t view_mask = pipeline->subpass->view_mask;
+   uint32_t view_mask = pipeline->view_mask;
    int view_count = util_bitcount(view_mask);
    if (view_count == 1 || view_count > primitive_replication_max_views)
       return false;
index ca1a215..da35d78 100644 (file)
@@ -463,9 +463,9 @@ static void
 populate_wm_prog_key(const struct anv_graphics_pipeline *pipeline,
                      VkPipelineShaderStageCreateFlags flags,
                      bool robust_buffer_acccess,
-                     const struct anv_subpass *subpass,
                      const VkPipelineMultisampleStateCreateInfo *ms_info,
                      const VkPipelineFragmentShadingRateStateCreateInfoKHR *fsr_info,
+                     const VkPipelineRenderingCreateInfo *rendering_info,
                      struct brw_wm_prog_key *key)
 {
    const struct anv_device *device = pipeline->base.device;
@@ -485,13 +485,13 @@ populate_wm_prog_key(const struct anv_graphics_pipeline *pipeline,
 
    key->ignore_sample_mask_out = false;
 
-   assert(subpass->color_count <= MAX_RTS);
-   for (uint32_t i = 0; i < subpass->color_count; i++) {
-      if (subpass->color_attachments[i].attachment != VK_ATTACHMENT_UNUSED)
+   assert(rendering_info->colorAttachmentCount <= MAX_RTS);
+   for (uint32_t i = 0; i < rendering_info->colorAttachmentCount; i++) {
+      if (rendering_info->pColorAttachmentFormats[i] != VK_FORMAT_UNDEFINED)
          key->color_outputs_valid |= (1 << i);
    }
 
-   key->nr_color_regions = subpass->color_count;
+   key->nr_color_regions = rendering_info->colorAttachmentCount;
 
    /* To reduce possible shader recompilations we would need to know if
     * there is a SampleMask output variable to compute if we should emit
@@ -610,8 +610,8 @@ anv_pipeline_hash_graphics(struct anv_graphics_pipeline *pipeline,
    struct mesa_sha1 ctx;
    _mesa_sha1_init(&ctx);
 
-   _mesa_sha1_update(&ctx, &pipeline->subpass->view_mask,
-                     sizeof(pipeline->subpass->view_mask));
+   _mesa_sha1_update(&ctx, &pipeline->view_mask,
+                     sizeof(pipeline->view_mask));
 
    if (layout)
       _mesa_sha1_update(&ctx, layout->sha1, sizeof(layout->sha1));
@@ -868,7 +868,7 @@ anv_pipeline_compile_vs(const struct brw_compiler *compiler,
     * position slot.
     */
    uint32_t pos_slots = pipeline->use_primitive_replication ?
-      anv_subpass_view_count(pipeline->subpass) : 1;
+      MAX2(1, util_bitcount(pipeline->view_mask)) : 1;
 
    brw_compute_vue_map(compiler->devinfo,
                        &vs_stage->prog_data.vs.base.vue_map,
@@ -1466,7 +1466,8 @@ anv_pipeline_init_from_cached_graphics(struct anv_graphics_pipeline *pipeline)
 static VkResult
 anv_pipeline_compile_graphics(struct anv_graphics_pipeline *pipeline,
                               struct anv_pipeline_cache *cache,
-                              const VkGraphicsPipelineCreateInfo *info)
+                              const VkGraphicsPipelineCreateInfo *info,
+                              const VkPipelineRenderingCreateInfo *rendering_info)
 {
    VkPipelineCreationFeedbackEXT pipeline_feedback = {
       .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
@@ -1539,10 +1540,10 @@ anv_pipeline_compile_graphics(struct anv_graphics_pipeline *pipeline,
             dynamic_states & ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE;
          populate_wm_prog_key(pipeline, subgroup_size_type,
                               pipeline->base.device->robust_buffer_access,
-                              pipeline->subpass,
                               raster_enabled ? info->pMultisampleState : NULL,
                               vk_find_struct_const(info->pNext,
                                                    PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR),
+                              rendering_info,
                               &stages[stage].key.wm);
          break;
       }
@@ -1749,7 +1750,7 @@ anv_pipeline_compile_graphics(struct anv_graphics_pipeline *pipeline,
    }
 
    if (pipeline->base.device->info.ver >= 12 &&
-       pipeline->subpass->view_mask != 0) {
+       pipeline->view_mask != 0) {
       /* For some pipelines HW Primitive Replication can be used instead of
        * instancing to implement Multiview.  This depend on how viewIndex is
        * used in all the active shaders, so this check can't be done per
@@ -2119,10 +2120,10 @@ anv_pipeline_compile_cs(struct anv_compute_pipeline *pipeline,
  */
 static void
 copy_non_dynamic_state(struct anv_graphics_pipeline *pipeline,
-                       const VkGraphicsPipelineCreateInfo *pCreateInfo)
+                       const VkGraphicsPipelineCreateInfo *pCreateInfo,
+                       const VkPipelineRenderingCreateInfo *rendering_info)
 {
    anv_cmd_dirty_mask_t states = ANV_CMD_DIRTY_DYNAMIC_ALL;
-   struct anv_subpass *subpass = pipeline->subpass;
 
    pipeline->dynamic_state = default_dynamic_state;
 
@@ -2223,8 +2224,8 @@ copy_non_dynamic_state(struct anv_graphics_pipeline *pipeline,
     *    created against does not use any color attachments.
     */
    bool uses_color_att = false;
-   for (unsigned i = 0; i < subpass->color_count; ++i) {
-      if (subpass->color_attachments[i].attachment != VK_ATTACHMENT_UNUSED) {
+   for (unsigned i = 0; i < rendering_info->colorAttachmentCount; i++) {
+      if (rendering_info->pColorAttachmentFormats[i] != VK_FORMAT_UNDEFINED) {
          uses_color_att = true;
          break;
       }
@@ -2250,7 +2251,9 @@ copy_non_dynamic_state(struct anv_graphics_pipeline *pipeline,
     *    disabled or if the subpass of the render pass the pipeline is created
     *    against does not use a depth/stencil attachment.
     */
-   if (!raster_discard && subpass->depth_stencil_attachment) {
+   if (!raster_discard &&
+       (rendering_info->depthAttachmentFormat != VK_FORMAT_UNDEFINED ||
+        rendering_info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED)) {
       assert(pCreateInfo->pDepthStencilState);
 
       if (states & ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS) {
@@ -2439,6 +2442,7 @@ anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline,
                            struct anv_device *device,
                            struct anv_pipeline_cache *cache,
                            const VkGraphicsPipelineCreateInfo *pCreateInfo,
+                           const VkPipelineRenderingCreateInfo *rendering_info,
                            const VkAllocationCallbacks *alloc)
 {
    VkResult result;
@@ -2452,38 +2456,6 @@ anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline,
    anv_batch_set_storage(&pipeline->base.batch, ANV_NULL_ADDRESS,
                          pipeline->batch_data, sizeof(pipeline->batch_data));
 
-   ANV_FROM_HANDLE(anv_render_pass, render_pass, pCreateInfo->renderPass);
-
-   if (render_pass) {
-      assert(pCreateInfo->subpass < render_pass->subpass_count);
-      pipeline->subpass = &render_pass->subpasses[pCreateInfo->subpass];
-      pipeline->pass = render_pass;
-   } else {
-      const VkPipelineRenderingCreateInfoKHR *rendering_create_info =
-         vk_find_struct_const(pCreateInfo->pNext, PIPELINE_RENDERING_CREATE_INFO_KHR);
-
-      /* These should be zeroed already. */
-      pipeline->pass = &pipeline->dynamic_render_pass.pass;
-      pipeline->subpass = &pipeline->dynamic_render_pass.subpass;
-
-      if (rendering_create_info) {
-         struct anv_dynamic_pass_create_info info = {
-            .viewMask = rendering_create_info->viewMask,
-            .colorAttachmentCount =
-               rendering_create_info->colorAttachmentCount,
-            .pColorAttachmentFormats =
-               rendering_create_info->pColorAttachmentFormats,
-            .depthAttachmentFormat =
-               rendering_create_info->depthAttachmentFormat,
-            .stencilAttachmentFormat =
-               rendering_create_info->stencilAttachmentFormat,
-         };
-
-         anv_dynamic_pass_init(&pipeline->dynamic_render_pass, &info);
-      }
-   }
-
-
    assert(pCreateInfo->pRasterizationState);
 
    if (pCreateInfo->pDynamicState) {
@@ -2505,9 +2477,10 @@ anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline,
    if (anv_pipeline_is_mesh(pipeline))
       assert(device->physical->vk.supported_extensions.NV_mesh_shader);
 
-   copy_non_dynamic_state(pipeline, pCreateInfo);
+   copy_non_dynamic_state(pipeline, pCreateInfo, rendering_info);
 
    pipeline->depth_clamp_enable = pCreateInfo->pRasterizationState->depthClampEnable;
+   pipeline->view_mask = rendering_info->viewMask;
 
    /* Previously we enabled depth clipping when !depthClampEnable.
     * DepthClipStateCreateInfo now makes depth clipping explicit so if the
@@ -2520,7 +2493,8 @@ anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline,
    pipeline->depth_clip_enable = clip_info ? clip_info->depthClipEnable :
       !(pipeline->depth_clamp_enable || pipeline->negative_one_to_one);
 
-   result = anv_pipeline_compile_graphics(pipeline, cache, pCreateInfo);
+   result = anv_pipeline_compile_graphics(pipeline, cache, pCreateInfo,
+                                          rendering_info);
    if (result != VK_SUCCESS) {
       anv_pipeline_finish(&pipeline->base, device, alloc);
       return result;
@@ -2581,8 +2555,8 @@ anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline,
        * the instance divisor by the number of views ensure that we repeat the
        * client's per-instance data once for each view.
        */
-      if (pipeline->subpass->view_mask && !pipeline->use_primitive_replication) {
-         const uint32_t view_count = anv_subpass_view_count(pipeline->subpass);
+      if (pipeline->view_mask && !pipeline->use_primitive_replication) {
+         const uint32_t view_count = util_bitcount(pipeline->view_mask);
          for (uint32_t vb = 0; vb < MAX_VBS; vb++) {
             if (pipeline->vb[vb].instanced)
                pipeline->vb[vb].instance_divisor *= view_count;
index c5d4853..9038c2a 100644 (file)
@@ -3498,12 +3498,10 @@ struct anv_graphics_pipeline {
    VkPolygonMode                                polygon_mode;
    uint32_t                                     rasterization_samples;
 
-   struct anv_subpass *                         subpass;
-   struct anv_render_pass *                     pass;
-
    struct anv_shader_bin *                      shaders[ANV_GRAPHICS_SHADER_STAGE_COUNT];
 
    VkShaderStageFlags                           active_stages;
+   uint32_t                                     view_mask;
 
    bool                                         writes_depth;
    bool                                         depth_test_enable;
@@ -3684,6 +3682,7 @@ VkResult
 anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline, struct anv_device *device,
                            struct anv_pipeline_cache *cache,
                            const VkGraphicsPipelineCreateInfo *pCreateInfo,
+                           const VkPipelineRenderingCreateInfoKHR *rendering_info,
                            const VkAllocationCallbacks *alloc);
 
 VkResult
index 1e07d79..105e302 100644 (file)
@@ -33,6 +33,7 @@
 #include "vk_util.h"
 #include "vk_format.h"
 #include "vk_log.h"
+#include "vk_render_pass.h"
 
 static uint32_t
 vertex_element_comp_control(enum isl_format format, unsigned comp)
@@ -759,9 +760,8 @@ emit_rs_state(struct anv_graphics_pipeline *pipeline,
               const VkPipelineRasterizationStateCreateInfo *rs_info,
               const VkPipelineMultisampleStateCreateInfo *ms_info,
               const VkPipelineRasterizationLineStateCreateInfoEXT *line_info,
+              const VkPipelineRenderingCreateInfo *rendering_info,
               const uint32_t dynamic_states,
-              const struct anv_render_pass *pass,
-              const struct anv_subpass *subpass,
               enum intel_urb_deref_block_size urb_deref_block_size)
 {
    struct GENX(3DSTATE_SF) sf = {
@@ -895,18 +895,16 @@ emit_rs_state(struct anv_graphics_pipeline *pipeline,
    /* Gfx7 requires that we provide the depth format in 3DSTATE_SF so that it
     * can get the depth offsets correct.
     */
-   if (subpass->depth_stencil_attachment) {
-      VkFormat vk_format =
-         pass->attachments[subpass->depth_stencil_attachment->attachment].format;
-      assert(vk_format_is_depth_or_stencil(vk_format));
-      if (vk_format_aspects(vk_format) & VK_IMAGE_ASPECT_DEPTH_BIT) {
-         enum isl_format isl_format =
-            anv_get_isl_format(&pipeline->base.device->info, vk_format,
-                               VK_IMAGE_ASPECT_DEPTH_BIT,
-                               VK_IMAGE_TILING_OPTIMAL);
-         sf.DepthBufferSurfaceFormat =
-            isl_format_get_depth_format(isl_format, false);
-      }
+   if (rendering_info != NULL &&
+       rendering_info->depthAttachmentFormat != VK_FORMAT_UNDEFINED) {
+      assert(vk_format_has_depth(rendering_info->depthAttachmentFormat));
+      enum isl_format isl_format =
+         anv_get_isl_format(&pipeline->base.device->info,
+                            rendering_info->depthAttachmentFormat,
+                            VK_IMAGE_ASPECT_DEPTH_BIT,
+                            VK_IMAGE_TILING_OPTIMAL);
+      sf.DepthBufferSurfaceFormat =
+         isl_format_get_depth_format(isl_format, false);
    }
 #endif
 
@@ -1206,9 +1204,8 @@ sanitize_ds_state(VkPipelineDepthStencilStateCreateInfo *state,
 static void
 emit_ds_state(struct anv_graphics_pipeline *pipeline,
               const VkPipelineDepthStencilStateCreateInfo *pCreateInfo,
-              const uint32_t dynamic_states,
-              const struct anv_render_pass *pass,
-              const struct anv_subpass *subpass)
+              const VkPipelineRenderingCreateInfo *rendering_info,
+              const uint32_t dynamic_states)
 {
 #if GFX_VER == 7
 #  define depth_stencil_dw pipeline->gfx7.depth_stencil_state
@@ -1232,10 +1229,11 @@ emit_ds_state(struct anv_graphics_pipeline *pipeline,
    }
 
    VkImageAspectFlags ds_aspects = 0;
-   if (subpass->depth_stencil_attachment) {
-      VkFormat depth_stencil_format =
-         pass->attachments[subpass->depth_stencil_attachment->attachment].format;
-      ds_aspects = vk_format_aspects(depth_stencil_format);
+   if (rendering_info != NULL) {
+      if (rendering_info->depthAttachmentFormat != VK_FORMAT_UNDEFINED)
+         ds_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
+      if (rendering_info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED)
+         ds_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
    }
 
    VkPipelineDepthStencilStateCreateInfo info = *pCreateInfo;
@@ -2250,12 +2248,13 @@ has_color_buffer_write_enabled(const struct anv_graphics_pipeline *pipeline,
 }
 
 static void
-emit_3dstate_wm(struct anv_graphics_pipeline *pipeline, struct anv_subpass *subpass,
+emit_3dstate_wm(struct anv_graphics_pipeline *pipeline,
                 const VkPipelineInputAssemblyStateCreateInfo *ia,
                 const VkPipelineRasterizationStateCreateInfo *raster,
                 const VkPipelineColorBlendStateCreateInfo *blend,
                 const VkPipelineMultisampleStateCreateInfo *multisample,
                 const VkPipelineRasterizationLineStateCreateInfoEXT *line,
+                const VkRenderingSelfDependencyInfoMESA *rsd,
                 const uint32_t dynamic_states)
 {
    const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline);
@@ -2322,7 +2321,8 @@ emit_3dstate_wm(struct anv_graphics_pipeline *pipeline, struct anv_subpass *subp
        * may get the depth or stencil value from the current draw rather
        * than the previous one.
        */
-      wm.PixelShaderKillsPixel         = subpass->has_ds_self_dep ||
+      wm.PixelShaderKillsPixel         = rsd->depthSelfDependency ||
+                                         rsd->stencilSelfDependency ||
                                          wm_prog_data->uses_kill;
 
       pipeline->force_fragment_thread_dispatch =
@@ -2495,8 +2495,8 @@ emit_3dstate_ps(struct anv_graphics_pipeline *pipeline,
 #if GFX_VER >= 8
 static void
 emit_3dstate_ps_extra(struct anv_graphics_pipeline *pipeline,
-                      struct anv_subpass *subpass,
-                      const VkPipelineRasterizationStateCreateInfo *rs_info)
+                      const VkPipelineRasterizationStateCreateInfo *rs_info,
+                      const VkRenderingSelfDependencyInfoMESA *rsd_info)
 {
    const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline);
 
@@ -2520,7 +2520,8 @@ emit_3dstate_ps_extra(struct anv_graphics_pipeline *pipeline,
        * around to fetching from the input attachment and we may get the depth
        * or stencil value from the current draw rather than the previous one.
        */
-      ps.PixelShaderKillsPixel         = subpass->has_ds_self_dep ||
+      ps.PixelShaderKillsPixel         = rsd_info->depthSelfDependency ||
+                                         rsd_info->stencilSelfDependency ||
                                          wm_prog_data->uses_kill;
 
 #if GFX_VER >= 9
@@ -2575,7 +2576,7 @@ emit_3dstate_vf_statistics(struct anv_graphics_pipeline *pipeline)
 static void
 compute_kill_pixel(struct anv_graphics_pipeline *pipeline,
                    const VkPipelineMultisampleStateCreateInfo *ms_info,
-                   const struct anv_subpass *subpass)
+                   const VkRenderingSelfDependencyInfoMESA *rsd_info)
 {
    if (!anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT)) {
       pipeline->kill_pixel = false;
@@ -2599,21 +2600,24 @@ compute_kill_pixel(struct anv_graphics_pipeline *pipeline,
     * of an alpha test.
     */
    pipeline->kill_pixel =
-      subpass->has_ds_self_dep || wm_prog_data->uses_kill ||
+      rsd_info->depthSelfDependency ||
+      rsd_info->stencilSelfDependency ||
+      wm_prog_data->uses_kill ||
       wm_prog_data->uses_omask ||
       (ms_info && ms_info->alphaToCoverageEnable);
 }
 
 #if GFX_VER == 12
 static void
-emit_3dstate_primitive_replication(struct anv_graphics_pipeline *pipeline)
+emit_3dstate_primitive_replication(struct anv_graphics_pipeline *pipeline,
+                                   const VkPipelineRenderingCreateInfo *rendering_info)
 {
    if (!pipeline->use_primitive_replication) {
       anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_PRIMITIVE_REPLICATION), pr);
       return;
    }
 
-   uint32_t view_mask = pipeline->subpass->view_mask;
+   uint32_t view_mask = rendering_info != NULL ? rendering_info->viewMask : 0;
    int view_count = util_bitcount(view_mask);
    assert(view_count > 1 && view_count <= MAX_VIEWS_FOR_PRIMITIVE_REPLICATION);
 
@@ -2783,8 +2787,71 @@ genX(graphics_pipeline_create)(
    if (pipeline == NULL)
       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
 
+   /* We'll use these as defaults if we don't have pipeline rendering or
+    * self-dependency structs.  Saves us some NULL checks.
+    */
+   VkRenderingSelfDependencyInfoMESA rsd_info_tmp = {
+      .sType = VK_STRUCTURE_TYPE_RENDERING_SELF_DEPENDENCY_INFO_MESA,
+   };
+   VkPipelineRenderingCreateInfo rendering_info_tmp = {
+      .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
+      .pNext = &rsd_info_tmp,
+   };
+
+   const VkPipelineRenderingCreateInfo *rendering_info;
+   const VkRenderingSelfDependencyInfoMESA *rsd_info;
+   VkFormat color_formats_tmp[MAX_RTS];
+   if (pCreateInfo->renderPass != VK_NULL_HANDLE) {
+      ANV_FROM_HANDLE(anv_render_pass, render_pass, pCreateInfo->renderPass);
+      assert(pCreateInfo->subpass < render_pass->subpass_count);
+      const struct anv_subpass *subpass =
+         &render_pass->subpasses[pCreateInfo->subpass];
+
+      rendering_info_tmp.viewMask = subpass->view_mask;
+
+      assert(subpass->color_count <= MAX_RTS);
+      for (uint32_t i = 0; i < subpass->color_count; i++) {
+         uint32_t att_idx = subpass->color_attachments[i].attachment;
+         if (att_idx < render_pass->attachment_count)
+            color_formats_tmp[i] = render_pass->attachments[att_idx].format;
+         else
+            color_formats_tmp[i] = VK_FORMAT_UNDEFINED;
+      }
+      rendering_info_tmp.colorAttachmentCount = subpass->color_count;
+      rendering_info_tmp.pColorAttachmentFormats = color_formats_tmp;
+
+      if (subpass->depth_stencil_attachment) {
+         uint32_t ds_att_idx = subpass->depth_stencil_attachment->attachment;
+         assert(ds_att_idx < render_pass->attachment_count);
+         VkFormat depth_stencil_format =
+            render_pass->attachments[ds_att_idx].format;
+         if (vk_format_has_depth(depth_stencil_format)) {
+            rendering_info_tmp.depthAttachmentFormat = depth_stencil_format;
+            rsd_info_tmp.depthSelfDependency = subpass->has_ds_self_dep;
+         }
+         if (vk_format_has_stencil(depth_stencil_format)) {
+            rendering_info_tmp.stencilAttachmentFormat = depth_stencil_format;
+            rsd_info_tmp.stencilSelfDependency = subpass->has_ds_self_dep;
+         }
+      }
+
+      rendering_info = &rendering_info_tmp;
+      rsd_info = &rsd_info_tmp;
+   } else {
+      rendering_info = vk_find_struct_const(pCreateInfo->pNext,
+                                            PIPELINE_RENDERING_CREATE_INFO_KHR);
+      if (rendering_info == NULL)
+         rendering_info = &rendering_info_tmp;
+
+      rsd_info = vk_find_struct_const(rendering_info->pNext,
+                                      RENDERING_SELF_DEPENDENCY_INFO_MESA);
+      if (rsd_info == NULL)
+         rsd_info = &rsd_info_tmp;
+   }
+
    result = anv_graphics_pipeline_init(pipeline, device, cache,
-                                       pCreateInfo, pAllocator);
+                                       pCreateInfo, rendering_info,
+                                       pAllocator);
    if (result != VK_SUCCESS) {
       vk_free2(&device->vk.alloc, pAllocator, pipeline);
       if (result == VK_PIPELINE_COMPILE_REQUIRED_EXT)
@@ -2792,9 +2859,6 @@ genX(graphics_pipeline_create)(
       return result;
    }
 
-   struct anv_render_pass *pass = pipeline->pass;
-   struct anv_subpass *subpass = pipeline->subpass;
-
    /* Information on which states are considered dynamic. */
    const VkPipelineDynamicStateCreateInfo *dyn_info =
       pCreateInfo->pDynamicState;
@@ -2835,12 +2899,12 @@ genX(graphics_pipeline_create)(
    assert(pCreateInfo->pRasterizationState);
    emit_rs_state(pipeline, pCreateInfo->pInputAssemblyState,
                            pCreateInfo->pRasterizationState,
-                           ms_info, line_info, dynamic_states, pass, subpass,
-                           urb_deref_block_size);
+                           ms_info, line_info, rendering_info,
+                           dynamic_states, urb_deref_block_size);
    emit_ms_state(pipeline, ms_info, dynamic_states);
-   emit_ds_state(pipeline, ds_info, dynamic_states, pass, subpass);
+   emit_ds_state(pipeline, ds_info, rendering_info, dynamic_states);
    emit_cb_state(pipeline, cb_info, ms_info, dynamic_states);
-   compute_kill_pixel(pipeline, ms_info, subpass);
+   compute_kill_pixel(pipeline, ms_info, rsd_info);
 
    emit_3dstate_clip(pipeline,
                      pCreateInfo->pInputAssemblyState,
@@ -2849,7 +2913,7 @@ genX(graphics_pipeline_create)(
                      dynamic_states);
 
 #if GFX_VER == 12
-   emit_3dstate_primitive_replication(pipeline);
+   emit_3dstate_primitive_replication(pipeline, rendering_info);
 #endif
 
 #if 0
@@ -2906,14 +2970,14 @@ genX(graphics_pipeline_create)(
    }
 
    emit_3dstate_sbe(pipeline);
-   emit_3dstate_wm(pipeline, subpass,
+   emit_3dstate_wm(pipeline,
                    pCreateInfo->pInputAssemblyState,
                    pCreateInfo->pRasterizationState,
-                   cb_info, ms_info, line_info, dynamic_states);
+                   cb_info, ms_info, line_info, rsd_info,
+                   dynamic_states);
    emit_3dstate_ps(pipeline, cb_info, ms_info);
 #if GFX_VER >= 8
-   emit_3dstate_ps_extra(pipeline, subpass,
-                         pCreateInfo->pRasterizationState);
+   emit_3dstate_ps_extra(pipeline, pCreateInfo->pRasterizationState, rsd_info);
 #endif
 
    *pPipeline = anv_pipeline_to_handle(&pipeline->base);