v3dv: support depth blits

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
diff --git a/src/broadcom/vulkan/v3dv_meta_copy.c b/src/broadcom/vulkan/v3dv_meta_copy.c
index adcc9cd..1e1968b 100644
--- a/src/broadcom/vulkan/v3dv_meta_copy.c
+++ b/src/broadcom/vulkan/v3dv_meta_copy.c
@@ -1942,6 +1942,8 @@
                         VkFormat format,
                         VkRenderPass *pass)
 {
+   const bool is_color_blit = !vk_format_is_depth_or_stencil(format);
+
    /* FIXME: if blitting to tile boundaries or to the whole image, we could
     * use LOAD_DONT_CARE, but then we would have to include that in the
     * pipeline hash key. Or maybe we should just create both render passes and
@@ -1965,10 +1967,10 @@
    VkSubpassDescription subpass = {
       .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
       .inputAttachmentCount = 0,
-      .colorAttachmentCount = 1,
-      .pColorAttachments = &att_ref,
+      .colorAttachmentCount = is_color_blit ? 1 : 0,
+      .pColorAttachments = is_color_blit ? &att_ref : NULL,
       .pResolveAttachments = NULL,
-      .pDepthStencilAttachment = NULL,
+      .pDepthStencilAttachment = is_color_blit ? NULL : &att_ref,
       .preserveAttachmentCount = 0,
       .pPreserveAttachments = NULL,
    };
@@ -2134,9 +2136,9 @@
 }
 
 static nir_shader *
-get_blit_fs(struct v3dv_device *device,
-            VkFormat dst_format,
-            VkFormat src_format)
+get_color_blit_fs(struct v3dv_device *device,
+                  VkFormat dst_format,
+                  VkFormat src_format)
 {
    nir_builder b;
    const nir_shader_compiler_options *options = v3dv_pipeline_get_nir_options();
@@ -2207,6 +2209,36 @@
    return b.shader;
 }
 
+static nir_shader *
+get_depth_blit_fs(struct v3dv_device *device, VkFormat format)
+{
+   assert(vk_format_has_depth(format));
+
+   nir_builder b;
+   const nir_shader_compiler_options *options = v3dv_pipeline_get_nir_options();
+   nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, options);
+   b.shader->info.name = ralloc_strdup(b.shader, "meta blit fs");
+
+   const struct glsl_type *vec4 = glsl_vec4_type();
+
+   nir_variable *fs_in_tex_coord =
+      nir_variable_create(b.shader, nir_var_shader_in, vec4, "in_tex_coord");
+   fs_in_tex_coord->data.location = VARYING_SLOT_VAR0;
+
+   nir_variable *fs_out_depth =
+      nir_variable_create(b.shader, nir_var_shader_out, vec4, "out_depth");
+   fs_out_depth->data.location = FRAG_RESULT_DEPTH;
+
+   nir_ssa_def *tex_coord = nir_load_var(&b, fs_in_tex_coord);
+   nir_ssa_def *tex_coord_xy = nir_channels(&b, tex_coord, 0x3);
+
+   nir_ssa_def *depth = build_nir_tex_op(&b, device, tex_coord_xy,
+                                         GLSL_TYPE_FLOAT);
+
+   nir_store_var(&b, fs_out_depth, depth, 0x1);
+   return b.shader;
+}
+
 static bool
 create_pipeline(struct v3dv_device *device,
                 struct v3dv_render_pass *pass,
@@ -2333,8 +2365,16 @@
 {
    struct v3dv_render_pass *pass = v3dv_render_pass_from_handle(_pass);
 
+   const bool has_depth = vk_format_has_depth(dst_format);
+   assert(!has_depth || src_format == dst_format);
+
+   /* FIXME: */
+   assert(!vk_format_has_stencil(dst_format));
+
    nir_shader *vs_nir = get_blit_vs();
-   nir_shader *fs_nir = get_blit_fs(device, dst_format, src_format);
+   nir_shader *fs_nir = has_depth ?
+      get_depth_blit_fs(device, dst_format) :
+      get_color_blit_fs(device, dst_format, src_format);
 
    const VkPipelineVertexInputStateCreateInfo vi_state = {
       .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
@@ -2342,13 +2382,14 @@
       .vertexAttributeDescriptionCount = 0,
    };
 
-   const VkPipelineDepthStencilStateCreateInfo ds_state = {
+   VkPipelineDepthStencilStateCreateInfo ds_state = {
       .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
-      .depthTestEnable = false,
-      .depthWriteEnable = false,
-      .depthBoundsTestEnable = false,
-      .stencilTestEnable = false,
    };
+   if (has_depth) {
+      ds_state.depthTestEnable = true;
+      ds_state.depthWriteEnable = true;
+      ds_state.depthCompareOp = VK_COMPARE_OP_ALWAYS;
+   }
 
    VkPipelineColorBlendAttachmentState blend_att_state[1] = { 0 };
    blend_att_state[0] = (VkPipelineColorBlendAttachmentState) {
@@ -2478,8 +2519,6 @@
             VkFilter filter)
 {
    /* FIXME: we only support 2D color blits for now */
-   if (region->dstSubresource.aspectMask != VK_IMAGE_ASPECT_COLOR_BIT)
-      return false;
    if (dst->type != VK_IMAGE_TYPE_2D || src->type != VK_IMAGE_TYPE_2D)
       return false;
 
diff --git a/src/broadcom/vulkan/vk_format_info.h b/src/broadcom/vulkan/vk_format_info.h
index e473e3d..990e3e7 100644
--- a/src/broadcom/vulkan/vk_format_info.h
+++ b/src/broadcom/vulkan/vk_format_info.h
@@ -115,6 +115,13 @@
    return aspects & VK_IMAGE_ASPECT_DEPTH_BIT;
 }
 
+static inline bool
+vk_format_has_stencil(VkFormat format)
+{
+   const VkImageAspectFlags aspects = vk_format_aspects(format);
+   return aspects & VK_IMAGE_ASPECT_STENCIL_BIT;
+}
+
 static inline unsigned
 vk_format_get_blocksize(VkFormat format)
 {