<div dir="ltr">Anyone?<br></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Jan 7, 2019 at 9:39 AM Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">---<br>
 src/intel/vulkan/anv_device.c      |  28 ++++++<br>
 src/intel/vulkan/anv_extensions.py |   1 +<br>
 src/intel/vulkan/anv_pass.c        |  37 +++++++-<br>
 src/intel/vulkan/anv_private.h     |   3 +<br>
 src/intel/vulkan/genX_cmd_buffer.c | 136 +++++++++++++++++++++++++++++<br>
 5 files changed, 204 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c<br>
index 2a3919d2949..3761846bb7f 100644<br>
--- a/src/intel/vulkan/anv_device.c<br>
+++ b/src/intel/vulkan/anv_device.c<br>
@@ -1138,6 +1138,34 @@ void anv_GetPhysicalDeviceProperties2(<br>
          break;<br>
       }<br>
<br>
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR: {<br>
+         VkPhysicalDeviceDepthStencilResolvePropertiesKHR *props =<br>
+            (VkPhysicalDeviceDepthStencilResolvePropertiesKHR *)ext;<br>
+<br>
+         /* We support all of the depth resolve modes */<br>
+         props->supportedDepthResolveModes =<br>
+            VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR |<br>
+            VK_RESOLVE_MODE_AVERAGE_BIT_KHR |<br>
+            VK_RESOLVE_MODE_MIN_BIT_KHR |<br>
+            VK_RESOLVE_MODE_MAX_BIT_KHR;<br>
+<br>
+         /* Average doesn't make sense for stencil so we don't support that */<br>
+         props->supportedStencilResolveModes =<br>
+            VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR;<br>
+         if (pdevice->info.gen >= 8) {<br>
+            /* The advanced stencil resolve modes currently require stencil<br>
+             * sampling be supported by the hardware.<br>
+             */<br>
+            props->supportedStencilResolveModes |=<br>
+               VK_RESOLVE_MODE_MIN_BIT_KHR |<br>
+               VK_RESOLVE_MODE_MAX_BIT_KHR;<br>
+         }<br>
+<br>
+         props->independentResolveNone = VK_TRUE;<br>
+         props->independentResolve = VK_TRUE;<br>
+         break;<br>
+      }<br>
+<br>
       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR: {<br>
          VkPhysicalDeviceDriverPropertiesKHR *driver_props =<br>
             (VkPhysicalDeviceDriverPropertiesKHR *) ext;<br>
diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py<br>
index 388845003aa..2ea4cab0e97 100644<br>
--- a/src/intel/vulkan/anv_extensions.py<br>
+++ b/src/intel/vulkan/anv_extensions.py<br>
@@ -76,6 +76,7 @@ EXTENSIONS = [<br>
     Extension('VK_KHR_bind_memory2',                      1, True),<br>
     Extension('VK_KHR_create_renderpass2',                1, True),<br>
     Extension('VK_KHR_dedicated_allocation',              1, True),<br>
+    Extension('VK_KHR_depth_stencil_resolve',             1, True),<br>
     Extension('VK_KHR_descriptor_update_template',        1, True),<br>
     Extension('VK_KHR_device_group',                      1, True),<br>
     Extension('VK_KHR_device_group_creation',             1, True),<br>
diff --git a/src/intel/vulkan/anv_pass.c b/src/intel/vulkan/anv_pass.c<br>
index 7b17cc06935..196cf3ff8fd 100644<br>
--- a/src/intel/vulkan/anv_pass.c<br>
+++ b/src/intel/vulkan/anv_pass.c<br>
@@ -74,6 +74,10 @@ anv_render_pass_compile(struct anv_render_pass *pass)<br>
           subpass->depth_stencil_attachment->attachment == VK_ATTACHMENT_UNUSED)<br>
          subpass->depth_stencil_attachment = NULL;<br>
<br>
+      if (subpass->ds_resolve_attachment &&<br>
+          subpass->ds_resolve_attachment->attachment == VK_ATTACHMENT_UNUSED)<br>
+         subpass->ds_resolve_attachment = NULL;<br>
+<br>
       for (uint32_t j = 0; j < subpass->attachment_count; j++) {<br>
          struct anv_subpass_attachment *subpass_att = &subpass->attachments[j];<br>
          if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)<br>
@@ -116,6 +120,16 @@ anv_render_pass_compile(struct anv_render_pass *pass)<br>
             color_att->usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;<br>
          }<br>
       }<br>
+<br>
+      if (subpass->ds_resolve_attachment) {<br>
+         struct anv_subpass_attachment *ds_att =<br>
+            subpass->depth_stencil_attachment;<br>
+         UNUSED struct anv_subpass_attachment *resolve_att =<br>
+            subpass->ds_resolve_attachment;<br>
+<br>
+         assert(resolve_att->usage == VK_IMAGE_USAGE_TRANSFER_DST_BIT);<br>
+         ds_att->usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;<br>
+      }<br>
    }<br>
<br>
    /* From the Vulkan 1.0.39 spec:<br>
@@ -342,10 +356,15 @@ VkResult anv_CreateRenderPass(<br>
 static unsigned<br>
 num_subpass_attachments2(const VkSubpassDescription2KHR *desc)<br>
 {<br>
+   const VkSubpassDescriptionDepthStencilResolveKHR *ds_resolve =<br>
+      vk_find_struct_const(desc->pNext,<br>
+                           SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR);<br>
+<br>
    return desc->inputAttachmentCount +<br>
           desc->colorAttachmentCount +<br>
           (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +<br>
-          (desc->pDepthStencilAttachment != NULL);<br>
+          (desc->pDepthStencilAttachment != NULL) +<br>
+          (ds_resolve && ds_resolve->pDepthStencilResolveAttachment);<br>
 }<br>
<br>
 VkResult anv_CreateRenderPass2KHR(<br>
@@ -460,6 +479,22 @@ VkResult anv_CreateRenderPass2KHR(<br>
             .layout =      desc->pDepthStencilAttachment->layout,<br>
          };<br>
       }<br>
+<br>
+      const VkSubpassDescriptionDepthStencilResolveKHR *ds_resolve =<br>
+         vk_find_struct_const(desc->pNext,<br>
+                              SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR);<br>
+<br>
+      if (ds_resolve && ds_resolve->pDepthStencilResolveAttachment) {<br>
+         subpass->ds_resolve_attachment = subpass_attachments++;<br>
+<br>
+         *subpass->ds_resolve_attachment = (struct anv_subpass_attachment) {<br>
+            .usage =       VK_IMAGE_USAGE_TRANSFER_DST_BIT,<br>
+            .attachment =  ds_resolve->pDepthStencilResolveAttachment->attachment,<br>
+            .layout =      ds_resolve->pDepthStencilResolveAttachment->layout,<br>
+         };<br>
+         subpass->depth_resolve_mode = ds_resolve->depthResolveMode;<br>
+         subpass->stencil_resolve_mode = ds_resolve->stencilResolveMode;<br>
+      }<br>
    }<br>
<br>
    for (uint32_t i = 0; i < pCreateInfo->dependencyCount; i++)<br>
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h<br>
index 6992db277fc..e16de7a7a45 100644<br>
--- a/src/intel/vulkan/anv_private.h<br>
+++ b/src/intel/vulkan/anv_private.h<br>
@@ -3215,6 +3215,9 @@ struct anv_subpass {<br>
    struct anv_subpass_attachment *              resolve_attachments;<br>
<br>
    struct anv_subpass_attachment *              depth_stencil_attachment;<br>
+   struct anv_subpass_attachment *              ds_resolve_attachment;<br>
+   VkResolveModeFlagBitsKHR                     depth_resolve_mode;<br>
+   VkResolveModeFlagBitsKHR                     stencil_resolve_mode;<br>
<br>
    uint32_t                                     view_mask;<br>
<br>
diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c<br>
index b0b56472e57..7aadafd687e 100644<br>
--- a/src/intel/vulkan/genX_cmd_buffer.c<br>
+++ b/src/intel/vulkan/genX_cmd_buffer.c<br>
@@ -3876,6 +3876,23 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,<br>
    cmd_buffer_emit_depth_stencil(cmd_buffer);<br>
 }<br>
<br>
+static enum blorp_filter<br>
+vk_to_blorp_resolve_mode(VkResolveModeFlagBitsKHR vk_mode)<br>
+{<br>
+   switch (vk_mode) {<br>
+   case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR:<br>
+      return BLORP_FILTER_SAMPLE_0;<br>
+   case VK_RESOLVE_MODE_AVERAGE_BIT_KHR:<br>
+      return BLORP_FILTER_AVERAGE;<br>
+   case VK_RESOLVE_MODE_MIN_BIT_KHR:<br>
+      return BLORP_FILTER_MIN_SAMPLE;<br>
+   case VK_RESOLVE_MODE_MAX_BIT_KHR:<br>
+      return BLORP_FILTER_MAX_SAMPLE;<br>
+   default:<br>
+      return BLORP_FILTER_NONE;<br>
+   }<br>
+}<br>
+<br>
 static void<br>
 cmd_buffer_end_subpass(struct anv_cmd_buffer *cmd_buffer)<br>
 {<br>
@@ -3943,6 +3960,125 @@ cmd_buffer_end_subpass(struct anv_cmd_buffer *cmd_buffer)<br>
       }<br>
    }<br>
<br>
+   if (subpass->ds_resolve_attachment) {<br>
+      /* We are about to do some MSAA resolves.  We need to flush so that the<br>
+       * result of writes to the MSAA color attachments show up in the sampler<br>
+       * when we blit to the single-sampled resolve target.<br>
+       */<br>
+      cmd_buffer->state.pending_pipe_bits |=<br>
+         ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT |<br>
+         ANV_PIPE_DEPTH_CACHE_FLUSH_BIT;<br>
+<br>
+      uint32_t src_att = subpass->depth_stencil_attachment->attachment;<br>
+      uint32_t dst_att = subpass->ds_resolve_attachment->attachment;<br>
+<br>
+      assert(src_att < cmd_buffer->state.pass->attachment_count);<br>
+      assert(dst_att < cmd_buffer->state.pass->attachment_count);<br>
+<br>
+      if (cmd_buffer->state.attachments[dst_att].pending_clear_aspects) {<br>
+         /* From the Vulkan 1.0 spec:<br>
+          *<br>
+          *    If the first use of an attachment in a render pass is as a<br>
+          *    resolve attachment, then the loadOp is effectively ignored<br>
+          *    as the resolve is guaranteed to overwrite all pixels in the<br>
+          *    render area.<br>
+          */<br>
+         cmd_buffer->state.attachments[dst_att].pending_clear_aspects = 0;<br>
+      }<br>
+<br>
+      struct anv_image_view *src_iview = fb->attachments[src_att];<br>
+      struct anv_image_view *dst_iview = fb->attachments[dst_att];<br>
+<br>
+      const VkRect2D render_area = cmd_buffer->state.render_area;<br>
+<br>
+      if ((src_iview->image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) &&<br>
+          subpass->depth_resolve_mode != VK_RESOLVE_MODE_NONE_KHR) {<br>
+<br>
+         struct anv_attachment_state *src_state =<br>
+            &cmd_state->attachments[src_att];<br>
+         struct anv_attachment_state *dst_state =<br>
+            &cmd_state->attachments[dst_att];<br>
+<br>
+         /* MSAA resolves sample from the source attachment.  Transition the<br>
+          * depth attachment first to get rid of any HiZ that we may not be<br>
+          * able to handle.<br>
+          */<br>
+         transition_depth_buffer(cmd_buffer, src_iview->image,<br>
+                                 src_state->current_layout,<br>
+                                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);<br>
+         src_state->aux_usage =<br>
+            anv_layout_to_aux_usage(&cmd_buffer->device->info, src_iview->image,<br>
+                                    VK_IMAGE_ASPECT_DEPTH_BIT,<br>
+                                    VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);<br>
+         src_state->current_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;<br>
+<br>
+         /* MSAA resolves write to the resolve attachment as if it were any<br>
+          * other transfer op.  Transition the resolve attachment accordingly.<br>
+          */<br>
+         VkImageLayout dst_initial_layout = dst_state->current_layout;<br>
+<br>
+         /* If our render area is the entire size of the image, we're going to<br>
+          * blow it all away so we can claim the initial layout is UNDEFINED<br>
+          * and we'll get a HiZ ambiguate instead of a resolve.<br>
+          */<br>
+         if (dst_iview->image->type != VK_IMAGE_TYPE_3D &&<br>
+             render_area.offset.x == 0 && render_area.offset.y == 0 &&<br>
+             render_area.extent.width == dst_iview->extent.width &&<br>
+             render_area.extent.height == dst_iview->extent.height)<br>
+            dst_initial_layout = VK_IMAGE_LAYOUT_UNDEFINED;<br>
+<br>
+         transition_depth_buffer(cmd_buffer, dst_iview->image,<br>
+                                 dst_initial_layout,<br>
+                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);<br>
+         dst_state->aux_usage =<br>
+            anv_layout_to_aux_usage(&cmd_buffer->device->info, dst_iview->image,<br>
+                                    VK_IMAGE_ASPECT_DEPTH_BIT,<br>
+                                    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);<br>
+         dst_state->current_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;<br>
+<br>
+         enum blorp_filter filter =<br>
+            vk_to_blorp_resolve_mode(subpass->depth_resolve_mode);<br>
+<br>
+         anv_image_msaa_resolve(cmd_buffer,<br>
+                                src_iview->image, src_state->aux_usage,<br>
+                                src_iview->planes[0].isl.base_level,<br>
+                                src_iview->planes[0].isl.base_array_layer,<br>
+                                dst_iview->image, dst_state->aux_usage,<br>
+                                dst_iview->planes[0].isl.base_level,<br>
+                                dst_iview->planes[0].isl.base_array_layer,<br>
+                                VK_IMAGE_ASPECT_DEPTH_BIT,<br>
+                                render_area.offset.x, render_area.offset.y,<br>
+                                render_area.offset.x, render_area.offset.y,<br>
+                                render_area.extent.width,<br>
+                                render_area.extent.height,<br>
+                                fb->layers, filter);<br>
+      }<br>
+<br>
+      if ((src_iview->image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&<br>
+          subpass->stencil_resolve_mode != VK_RESOLVE_MODE_NONE_KHR) {<br>
+<br>
+         enum isl_aux_usage src_aux_usage = ISL_AUX_USAGE_NONE;<br>
+         enum isl_aux_usage dst_aux_usage = ISL_AUX_USAGE_NONE;<br>
+<br>
+         enum blorp_filter filter =<br>
+            vk_to_blorp_resolve_mode(subpass->stencil_resolve_mode);<br>
+<br>
+         anv_image_msaa_resolve(cmd_buffer,<br>
+                                src_iview->image, src_aux_usage,<br>
+                                src_iview->planes[0].isl.base_level,<br>
+                                src_iview->planes[0].isl.base_array_layer,<br>
+                                dst_iview->image, dst_aux_usage,<br>
+                                dst_iview->planes[0].isl.base_level,<br>
+                                dst_iview->planes[0].isl.base_array_layer,<br>
+                                VK_IMAGE_ASPECT_STENCIL_BIT,<br>
+                                render_area.offset.x, render_area.offset.y,<br>
+                                render_area.offset.x, render_area.offset.y,<br>
+                                render_area.extent.width,<br>
+                                render_area.extent.height,<br>
+                                fb->layers, filter);<br>
+      }<br>
+   }<br>
+<br>
    for (uint32_t i = 0; i < subpass->attachment_count; ++i) {<br>
       const uint32_t a = subpass->attachments[i].attachment;<br>
       if (a == VK_ATTACHMENT_UNUSED)<br>
-- <br>
2.20.1<br>
<br>
</blockquote></div>