anv: implement VK_KHR_separate_depth_stencil_layouts
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Thu, 4 Jul 2019 08:17:11 +0000 (11:17 +0300)
committerLionel Landwerlin <lionel.g.landwerlin@intel.com>
Wed, 6 Nov 2019 20:13:30 +0000 (20:13 +0000)
v2: Use ternary to simplify code (Jason)

v3: Reorder switch cases to follow existing section ordering (Nanley)
    Add missing comment in cmd_buffer_end_subpass() about new layout (Nanley)

v4: Fix layout comparison for stencil case (Nanley)
    Update a few more comments (Nanley)
    Move VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR in color
    attachment case for future stencil-CCS support (Nanley)

v5: Missed comments update (Nanley)
    Updated relnotes.txt (Lionel)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
docs/relnotes/new_features.txt
src/intel/vulkan/anv_device.c
src/intel/vulkan/anv_extensions.py
src/intel/vulkan/anv_image.c
src/intel/vulkan/anv_pass.c
src/intel/vulkan/anv_private.h
src/intel/vulkan/genX_cmd_buffer.c

index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..47e0dedaf900a2751b49365c83218862f7f3bc63 100644 (file)
@@ -0,0 +1 @@
+VK_KHR_separate_depth_stencil_layouts on Intel.
index c0b153a0578066cdfeb19a15aa507788a8128f2b..381b7ab3c41fa1139779d8c49e457daea47bec7c 100644 (file)
@@ -1188,6 +1188,13 @@ void anv_GetPhysicalDeviceFeatures2(
          break;
       }
 
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR: {
+         VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR *features =
+            (VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR *)ext;
+         features->separateDepthStencilLayouts = true;
+         break;
+      }
+
       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR: {
          VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *features = (void *)ext;
          features->shaderBufferInt64Atomics =
index 2c2bea1806a8d8236cf1fc2df45e4922dd3ecd04..1e0ab5f71429162f26b1b3795b28703d149d2a36 100644 (file)
@@ -106,6 +106,7 @@ EXTENSIONS = [
     Extension('VK_KHR_relaxed_block_layout',              1, True),
     Extension('VK_KHR_sampler_mirror_clamp_to_edge',      1, True),
     Extension('VK_KHR_sampler_ycbcr_conversion',          1, True),
+    Extension('VK_KHR_separate_depth_stencil_layouts',    1, True),
     Extension('VK_KHR_shader_atomic_int64',               1,
               'device->info.gen >= 9 && device->use_softpin'),
     Extension('VK_KHR_shader_clock',                      1, True),
index b4ed8c098ed6def80a57559b5c4889703d3592e9..e96e04f621b8f1c402add5a11d97f6db3f8fa2f1 100644 (file)
@@ -1146,6 +1146,7 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
 
 
    /* Sampling Layouts */
+   case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR:
    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
    case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
       assert((image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) == 0);
@@ -1160,6 +1161,9 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
          return image->planes[plane].aux_usage;
       }
 
+   case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR:
+      return ISL_AUX_USAGE_NONE;
+
 
    case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: {
       assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
@@ -1180,6 +1184,7 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
    /* Rendering Layouts */
    case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
       assert(aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV);
+   case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR:
       if (image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE) {
          assert(image->samples == 1);
          return ISL_AUX_USAGE_CCS_D;
@@ -1188,6 +1193,7 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
          return image->planes[plane].aux_usage;
       }
 
+   case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR:
    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
    case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
       assert(aspect == VK_IMAGE_ASPECT_DEPTH_BIT);
index ec217abfda077b271f93e1b98ee755fe0b436e3d..94783bb36c429540dd874e5636b972e3a1d58106 100644 (file)
@@ -269,6 +269,9 @@ VkResult anv_CreateRenderPass(
          .stencil_load_op        = pCreateInfo->pAttachments[i].stencilLoadOp,
          .initial_layout         = pCreateInfo->pAttachments[i].initialLayout,
          .final_layout           = pCreateInfo->pAttachments[i].finalLayout,
+
+         .stencil_initial_layout = pCreateInfo->pAttachments[i].initialLayout,
+         .stencil_final_layout   = pCreateInfo->pAttachments[i].finalLayout,
       };
    }
 
@@ -325,9 +328,10 @@ VkResult anv_CreateRenderPass(
          subpass->depth_stencil_attachment = subpass_attachments++;
 
          *subpass->depth_stencil_attachment = (struct anv_subpass_attachment) {
-            .usage =       VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
-            .attachment =  desc->pDepthStencilAttachment->attachment,
-            .layout =      desc->pDepthStencilAttachment->layout,
+            .usage =          VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
+            .attachment =     desc->pDepthStencilAttachment->attachment,
+            .layout =         desc->pDepthStencilAttachment->layout,
+            .stencil_layout = desc->pDepthStencilAttachment->layout,
          };
       }
    }
@@ -430,6 +434,10 @@ VkResult anv_CreateRenderPass2KHR(
    pass->subpass_flushes = subpass_flushes;
 
    for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
+      const VkAttachmentDescriptionStencilLayoutKHR *stencil_layout =
+         vk_find_struct_const(pCreateInfo->pAttachments[i].pNext,
+                              ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR);
+
       pass->attachments[i] = (struct anv_render_pass_attachment) {
          .format                 = pCreateInfo->pAttachments[i].format,
          .samples                = pCreateInfo->pAttachments[i].samples,
@@ -438,6 +446,13 @@ VkResult anv_CreateRenderPass2KHR(
          .stencil_load_op        = pCreateInfo->pAttachments[i].stencilLoadOp,
          .initial_layout         = pCreateInfo->pAttachments[i].initialLayout,
          .final_layout           = pCreateInfo->pAttachments[i].finalLayout,
+
+         .stencil_initial_layout = (stencil_layout ?
+                                    stencil_layout->stencilInitialLayout :
+                                    pCreateInfo->pAttachments[i].initialLayout),
+         .stencil_final_layout   = (stencil_layout ?
+                                    stencil_layout->stencilFinalLayout :
+                                    pCreateInfo->pAttachments[i].finalLayout),
       };
    }
 
@@ -493,10 +508,17 @@ VkResult anv_CreateRenderPass2KHR(
       if (desc->pDepthStencilAttachment) {
          subpass->depth_stencil_attachment = subpass_attachments++;
 
+         const VkAttachmentReferenceStencilLayoutKHR *stencil_attachment =
+            vk_find_struct_const(desc->pDepthStencilAttachment->pNext,
+                                 ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR);
+
          *subpass->depth_stencil_attachment = (struct anv_subpass_attachment) {
-            .usage =       VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
-            .attachment =  desc->pDepthStencilAttachment->attachment,
-            .layout =      desc->pDepthStencilAttachment->layout,
+            .usage =          VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
+            .attachment =     desc->pDepthStencilAttachment->attachment,
+            .layout =         desc->pDepthStencilAttachment->layout,
+            .stencil_layout = stencil_attachment ?
+                              stencil_attachment->stencilLayout :
+                              desc->pDepthStencilAttachment->layout,
          };
       }
 
@@ -507,10 +529,17 @@ VkResult anv_CreateRenderPass2KHR(
       if (ds_resolve && ds_resolve->pDepthStencilResolveAttachment) {
          subpass->ds_resolve_attachment = subpass_attachments++;
 
+         const VkAttachmentReferenceStencilLayoutKHR *stencil_resolve_attachment =
+            vk_find_struct_const(ds_resolve->pDepthStencilResolveAttachment->pNext,
+                                 ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR);
+
          *subpass->ds_resolve_attachment = (struct anv_subpass_attachment) {
-            .usage =       VK_IMAGE_USAGE_TRANSFER_DST_BIT,
-            .attachment =  ds_resolve->pDepthStencilResolveAttachment->attachment,
-            .layout =      ds_resolve->pDepthStencilResolveAttachment->layout,
+            .usage =          VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+            .attachment =     ds_resolve->pDepthStencilResolveAttachment->attachment,
+            .layout =         ds_resolve->pDepthStencilResolveAttachment->layout,
+            .stencil_layout = stencil_resolve_attachment ?
+                              stencil_resolve_attachment->stencilLayout :
+                              ds_resolve->pDepthStencilResolveAttachment->layout,
          };
          subpass->depth_resolve_mode = ds_resolve->depthResolveMode;
          subpass->stencil_resolve_mode = ds_resolve->stencilResolveMode;
index 73cf85881d9889054bce708fe571f19b8d6d51d9..bdbe594a3ba1229d29ea45205ad80e5b78e9a4a5 100644 (file)
@@ -2412,6 +2412,7 @@ struct anv_attachment_state {
    struct anv_surface_state                     input;
 
    VkImageLayout                                current_layout;
+   VkImageLayout                                current_stencil_layout;
    VkImageAspectFlags                           pending_clear_aspects;
    VkImageAspectFlags                           pending_load_aspects;
    bool                                         fast_clear;
@@ -3744,6 +3745,9 @@ struct anv_subpass_attachment {
    VkImageUsageFlagBits usage;
    uint32_t attachment;
    VkImageLayout layout;
+
+   /* Used only with attachment containing stencil data. */
+   VkImageLayout stencil_layout;
 };
 
 struct anv_subpass {
@@ -3794,6 +3798,9 @@ struct anv_render_pass_attachment {
    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;
 };
index 6e42b659f4c89532ad6660b441ff0a6f51a8c80d..a020fa200d4c60289d8cd6b8e2d14ef155f35495 100644 (file)
@@ -505,7 +505,8 @@ static inline bool
 vk_image_layout_stencil_write_optimal(VkImageLayout layout)
 {
    return layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
-          layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
+          layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ||
+          layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR;
 }
 
 /* Transitions a HiZ-enabled depth buffer from one layout to another. Unless
@@ -526,18 +527,19 @@ transition_stencil_buffer(struct anv_cmd_buffer *cmd_buffer,
 
    /* On gen7, we have to store a texturable version of the stencil buffer in
     * a shadow whenever VK_IMAGE_USAGE_SAMPLED_BIT is set and copy back and
-    * forth at strategic points.  Stencil writes are only allowed in three
+    * forth at strategic points. Stencil writes are only allowed in following
     * layouts:
     *
     *  - VK_IMAGE_LAYOUT_GENERAL
     *  - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
     *  - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
     *  - VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
+    *  - VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR
     *
     * For general, we have no nice opportunity to transition so we do the copy
-    * to the shadow unconditionally at the end of the subpass.  For transfer
-    * destinations, we can update it as part of the transfer op.  For the
-    * other two, we delay the copy until a transition into some other layout.
+    * to the shadow unconditionally at the end of the subpass. For transfer
+    * destinations, we can update it as part of the transfer op. For the other
+    * layouts, we delay the copy until a transition into some other layout.
     */
    if (image->planes[plane].shadow_surface.isl.size_B > 0 &&
        vk_image_layout_stencil_write_optimal(initial_layout) &&
@@ -1293,6 +1295,7 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer,
          }
 
          state->attachments[i].current_layout = att->initial_layout;
+         state->attachments[i].current_stencil_layout = att->stencil_initial_layout;
          state->attachments[i].pending_clear_aspects = clear_aspects;
          state->attachments[i].pending_load_aspects = load_aspects;
          if (clear_aspects)
@@ -4271,7 +4274,7 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
             (att_state->fast_clear && !att_state->clear_color_is_zero_one) ||
             att_state->input_aux_usage != att_state->aux_usage;
 
-      VkImageLayout target_layout;
+      VkImageLayout target_layout, target_stencil_layout;
       if (iview->aspect_mask & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV &&
           !input_needs_resolve) {
          /* Layout transitions before the final only help to enable sampling
@@ -4282,6 +4285,7 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
          target_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
       } else {
          target_layout = subpass->attachments[i].layout;
+         target_stencil_layout = subpass->attachments[i].stencil_layout;
       }
 
       uint32_t base_layer, layer_count;
@@ -4314,9 +4318,11 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
          transition_stencil_buffer(cmd_buffer, image,
                                    iview->planes[0].isl.base_level, 1,
                                    base_layer, layer_count,
-                                   att_state->current_layout, target_layout);
+                                   att_state->current_stencil_layout,
+                                   target_stencil_layout);
       }
       att_state->current_layout = target_layout;
+      att_state->current_stencil_layout = target_stencil_layout;
 
       if (att_state->pending_clear_aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
          assert(att_state->pending_clear_aspects == VK_IMAGE_ASPECT_COLOR_BIT);
@@ -4676,14 +4682,14 @@ cmd_buffer_end_subpass(struct anv_cmd_buffer *cmd_buffer)
 
       const VkRect2D render_area = cmd_buffer->state.render_area;
 
+      struct anv_attachment_state *src_state =
+         &cmd_state->attachments[src_att];
+      struct anv_attachment_state *dst_state =
+         &cmd_state->attachments[dst_att];
+
       if ((src_iview->image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) &&
           subpass->depth_resolve_mode != VK_RESOLVE_MODE_NONE_KHR) {
 
-         struct anv_attachment_state *src_state =
-            &cmd_state->attachments[src_att];
-         struct anv_attachment_state *dst_state =
-            &cmd_state->attachments[dst_att];
-
          /* MSAA resolves sample from the source attachment.  Transition the
           * depth attachment first to get rid of any HiZ that we may not be
           * able to handle.
@@ -4742,6 +4748,9 @@ cmd_buffer_end_subpass(struct anv_cmd_buffer *cmd_buffer)
       if ((src_iview->image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
           subpass->stencil_resolve_mode != VK_RESOLVE_MODE_NONE_KHR) {
 
+         src_state->current_stencil_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+         dst_state->current_stencil_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+
          enum isl_aux_usage src_aux_usage = ISL_AUX_USAGE_NONE;
          enum isl_aux_usage dst_aux_usage = ISL_AUX_USAGE_NONE;
 
@@ -4767,18 +4776,19 @@ cmd_buffer_end_subpass(struct anv_cmd_buffer *cmd_buffer)
 #if GEN_GEN == 7
    /* On gen7, we have to store a texturable version of the stencil buffer in
     * a shadow whenever VK_IMAGE_USAGE_SAMPLED_BIT is set and copy back and
-    * forth at strategic points.  Stencil writes are only allowed in three
+    * forth at strategic points. Stencil writes are only allowed in following
     * layouts:
     *
     *  - VK_IMAGE_LAYOUT_GENERAL
     *  - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
     *  - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
     *  - VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
+    *  - VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR
     *
     * For general, we have no nice opportunity to transition so we do the copy
-    * to the shadow unconditionally at the end of the subpass.  For transfer
-    * destinations, we can update it as part of the transfer op.  For the
-    * other two, we delay the copy until a transition into some other layout.
+    * to the shadow unconditionally at the end of the subpass. For transfer
+    * destinations, we can update it as part of the transfer op. For the other
+    * layouts, we delay the copy until a transition into some other layout.
     */
    if (subpass->depth_stencil_attachment) {
       uint32_t a = subpass->depth_stencil_attachment->attachment;
@@ -4793,7 +4803,7 @@ cmd_buffer_end_subpass(struct anv_cmd_buffer *cmd_buffer)
                                                     VK_IMAGE_ASPECT_STENCIL_BIT);
 
          if (image->planes[plane].shadow_surface.isl.size_B > 0 &&
-             att_state->current_layout == VK_IMAGE_LAYOUT_GENERAL) {
+             att_state->current_stencil_layout == VK_IMAGE_LAYOUT_GENERAL) {
             assert(image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT);
             anv_image_copy_to_shadow(cmd_buffer, image,
                                      VK_IMAGE_ASPECT_STENCIL_BIT,
@@ -4870,6 +4880,8 @@ cmd_buffer_end_subpass(struct anv_cmd_buffer *cmd_buffer)
       /* Transition the image into the final layout for this render pass */
       VkImageLayout target_layout =
          cmd_state->pass->attachments[a].final_layout;
+      VkImageLayout target_stencil_layout =
+         cmd_state->pass->attachments[a].stencil_final_layout;
 
       uint32_t base_layer, layer_count;
       if (image->type == VK_IMAGE_TYPE_3D) {
@@ -4898,7 +4910,8 @@ cmd_buffer_end_subpass(struct anv_cmd_buffer *cmd_buffer)
          transition_stencil_buffer(cmd_buffer, image,
                                    iview->planes[0].isl.base_level, 1,
                                    base_layer, layer_count,
-                                   att_state->current_layout, target_layout);
+                                   att_state->current_stencil_layout,
+                                   target_stencil_layout);
       }
    }