101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2016 Red Hat
301e04c3fSmrg *
401e04c3fSmrg * based on anv driver:
501e04c3fSmrg * Copyright © 2016 Intel Corporation
601e04c3fSmrg *
701e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
801e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
901e04c3fSmrg * to deal in the Software without restriction, including without limitation
1001e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1101e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
1201e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1301e04c3fSmrg *
1401e04c3fSmrg * The above copyright notice and this permission notice (including the next
1501e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1601e04c3fSmrg * Software.
1701e04c3fSmrg *
1801e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1901e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2001e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2101e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2201e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2301e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2401e04c3fSmrg * IN THE SOFTWARE.
2501e04c3fSmrg */
2601e04c3fSmrg
2701e04c3fSmrg#include "nir/nir_builder.h"
287ec681f3Smrg#include "radv_meta.h"
2901e04c3fSmrg#include "vk_format.h"
3001e04c3fSmrg
3101e04c3fSmrgenum blit2d_src_type {
327ec681f3Smrg   BLIT2D_SRC_TYPE_IMAGE,
337ec681f3Smrg   BLIT2D_SRC_TYPE_IMAGE_3D,
347ec681f3Smrg   BLIT2D_SRC_TYPE_BUFFER,
357ec681f3Smrg   BLIT2D_NUM_SRC_TYPES,
3601e04c3fSmrg};
3701e04c3fSmrg
387ec681f3Smrgstatic VkResult blit2d_init_color_pipeline(struct radv_device *device,
397ec681f3Smrg                                           enum blit2d_src_type src_type, VkFormat format,
407ec681f3Smrg                                           uint32_t log2_samples);
4101e04c3fSmrg
427ec681f3Smrgstatic VkResult blit2d_init_depth_only_pipeline(struct radv_device *device,
437ec681f3Smrg                                                enum blit2d_src_type src_type,
447ec681f3Smrg                                                uint32_t log2_samples);
4501e04c3fSmrg
467ec681f3Smrgstatic VkResult blit2d_init_stencil_only_pipeline(struct radv_device *device,
477ec681f3Smrg                                                  enum blit2d_src_type src_type,
487ec681f3Smrg                                                  uint32_t log2_samples);
4901e04c3fSmrg
5001e04c3fSmrgstatic void
517ec681f3Smrgcreate_iview(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *surf,
527ec681f3Smrg             struct radv_image_view *iview, VkFormat depth_format, VkImageAspectFlagBits aspects)
5301e04c3fSmrg{
547ec681f3Smrg   VkFormat format;
557ec681f3Smrg   VkImageViewType view_type = cmd_buffer->device->physical_device->rad_info.chip_class < GFX9
567ec681f3Smrg                                  ? VK_IMAGE_VIEW_TYPE_2D
577ec681f3Smrg                                  : radv_meta_get_view_type(surf->image);
587ec681f3Smrg
597ec681f3Smrg   if (depth_format)
607ec681f3Smrg      format = depth_format;
617ec681f3Smrg   else
627ec681f3Smrg      format = surf->format;
637ec681f3Smrg
647ec681f3Smrg   radv_image_view_init(iview, cmd_buffer->device,
657ec681f3Smrg                        &(VkImageViewCreateInfo){
667ec681f3Smrg                           .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
677ec681f3Smrg                           .image = radv_image_to_handle(surf->image),
687ec681f3Smrg                           .viewType = view_type,
697ec681f3Smrg                           .format = format,
707ec681f3Smrg                           .subresourceRange = {.aspectMask = aspects,
717ec681f3Smrg                                                .baseMipLevel = surf->level,
727ec681f3Smrg                                                .levelCount = 1,
737ec681f3Smrg                                                .baseArrayLayer = surf->layer,
747ec681f3Smrg                                                .layerCount = 1},
757ec681f3Smrg                        },
767ec681f3Smrg                        NULL);
7701e04c3fSmrg}
7801e04c3fSmrg
7901e04c3fSmrgstatic void
807ec681f3Smrgcreate_bview(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_buffer *src,
817ec681f3Smrg             struct radv_buffer_view *bview, VkFormat depth_format)
8201e04c3fSmrg{
837ec681f3Smrg   VkFormat format;
847ec681f3Smrg
857ec681f3Smrg   if (depth_format)
867ec681f3Smrg      format = depth_format;
877ec681f3Smrg   else
887ec681f3Smrg      format = src->format;
897ec681f3Smrg   radv_buffer_view_init(bview, cmd_buffer->device,
907ec681f3Smrg                         &(VkBufferViewCreateInfo){
917ec681f3Smrg                            .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
927ec681f3Smrg                            .flags = 0,
937ec681f3Smrg                            .buffer = radv_buffer_to_handle(src->buffer),
947ec681f3Smrg                            .format = format,
957ec681f3Smrg                            .offset = src->offset,
967ec681f3Smrg                            .range = VK_WHOLE_SIZE,
977ec681f3Smrg                         });
9801e04c3fSmrg}
9901e04c3fSmrg
10001e04c3fSmrgstruct blit2d_src_temps {
1017ec681f3Smrg   struct radv_image_view iview;
1027ec681f3Smrg   struct radv_buffer_view bview;
10301e04c3fSmrg};
10401e04c3fSmrg
10501e04c3fSmrgstatic void
1067ec681f3Smrgblit2d_bind_src(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *src_img,
1077ec681f3Smrg                struct radv_meta_blit2d_buffer *src_buf, struct blit2d_src_temps *tmp,
1087ec681f3Smrg                enum blit2d_src_type src_type, VkFormat depth_format, VkImageAspectFlagBits aspects,
10901e04c3fSmrg                uint32_t log2_samples)
11001e04c3fSmrg{
1117ec681f3Smrg   struct radv_device *device = cmd_buffer->device;
1127ec681f3Smrg
1137ec681f3Smrg   if (src_type == BLIT2D_SRC_TYPE_BUFFER) {
1147ec681f3Smrg      create_bview(cmd_buffer, src_buf, &tmp->bview, depth_format);
1157ec681f3Smrg
1167ec681f3Smrg      radv_meta_push_descriptor_set(
1177ec681f3Smrg         cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
1187ec681f3Smrg         device->meta_state.blit2d[log2_samples].p_layouts[src_type], 0, /* set */
1197ec681f3Smrg         1,                                                              /* descriptorWriteCount */
1207ec681f3Smrg         (VkWriteDescriptorSet[]){
1217ec681f3Smrg            {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1227ec681f3Smrg             .dstBinding = 0,
1237ec681f3Smrg             .dstArrayElement = 0,
1247ec681f3Smrg             .descriptorCount = 1,
1257ec681f3Smrg             .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
1267ec681f3Smrg             .pTexelBufferView = (VkBufferView[]){radv_buffer_view_to_handle(&tmp->bview)}}});
1277ec681f3Smrg
1287ec681f3Smrg      radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
1297ec681f3Smrg                            device->meta_state.blit2d[log2_samples].p_layouts[src_type],
1307ec681f3Smrg                            VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4, &src_buf->pitch);
1317ec681f3Smrg   } else {
1327ec681f3Smrg      create_iview(cmd_buffer, src_img, &tmp->iview, depth_format, aspects);
1337ec681f3Smrg
1347ec681f3Smrg      if (src_type == BLIT2D_SRC_TYPE_IMAGE_3D)
1357ec681f3Smrg         radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
1367ec681f3Smrg                               device->meta_state.blit2d[log2_samples].p_layouts[src_type],
1377ec681f3Smrg                               VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4, &src_img->layer);
1387ec681f3Smrg
1397ec681f3Smrg      radv_meta_push_descriptor_set(
1407ec681f3Smrg         cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
1417ec681f3Smrg         device->meta_state.blit2d[log2_samples].p_layouts[src_type], 0, /* set */
1427ec681f3Smrg         1,                                                              /* descriptorWriteCount */
1437ec681f3Smrg         (VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1447ec681f3Smrg                                   .dstBinding = 0,
1457ec681f3Smrg                                   .dstArrayElement = 0,
1467ec681f3Smrg                                   .descriptorCount = 1,
1477ec681f3Smrg                                   .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
1487ec681f3Smrg                                   .pImageInfo = (VkDescriptorImageInfo[]){
1497ec681f3Smrg                                      {
1507ec681f3Smrg                                         .sampler = VK_NULL_HANDLE,
1517ec681f3Smrg                                         .imageView = radv_image_view_to_handle(&tmp->iview),
1527ec681f3Smrg                                         .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
1537ec681f3Smrg                                      },
1547ec681f3Smrg                                   }}});
1557ec681f3Smrg   }
15601e04c3fSmrg}
15701e04c3fSmrg
15801e04c3fSmrgstruct blit2d_dst_temps {
1597ec681f3Smrg   VkImage image;
1607ec681f3Smrg   struct radv_image_view iview;
1617ec681f3Smrg   VkFramebuffer fb;
16201e04c3fSmrg};
16301e04c3fSmrg
16401e04c3fSmrgstatic void
1657ec681f3Smrgblit2d_bind_dst(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *dst,
1667ec681f3Smrg                uint32_t width, uint32_t height, VkFormat depth_format,
1677ec681f3Smrg                struct blit2d_dst_temps *tmp, VkImageAspectFlagBits aspects)
16801e04c3fSmrg{
1697ec681f3Smrg   create_iview(cmd_buffer, dst, &tmp->iview, depth_format, aspects);
1707ec681f3Smrg
1717ec681f3Smrg   radv_CreateFramebuffer(
1727ec681f3Smrg      radv_device_to_handle(cmd_buffer->device),
1737ec681f3Smrg      &(VkFramebufferCreateInfo){.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
1747ec681f3Smrg                                 .attachmentCount = 1,
1757ec681f3Smrg                                 .pAttachments =
1767ec681f3Smrg                                    (VkImageView[]){
1777ec681f3Smrg                                       radv_image_view_to_handle(&tmp->iview),
1787ec681f3Smrg                                    },
1797ec681f3Smrg                                 .width = width,
1807ec681f3Smrg                                 .height = height,
1817ec681f3Smrg                                 .layers = 1},
1827ec681f3Smrg      &cmd_buffer->pool->alloc, &tmp->fb);
18301e04c3fSmrg}
18401e04c3fSmrg
18501e04c3fSmrgstatic void
1867ec681f3Smrgbind_pipeline(struct radv_cmd_buffer *cmd_buffer, enum blit2d_src_type src_type, unsigned fs_key,
18701e04c3fSmrg              uint32_t log2_samples)
18801e04c3fSmrg{
1897ec681f3Smrg   VkPipeline pipeline =
1907ec681f3Smrg      cmd_buffer->device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key];
19101e04c3fSmrg
1927ec681f3Smrg   radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS,
1937ec681f3Smrg                        pipeline);
19401e04c3fSmrg}
19501e04c3fSmrg
19601e04c3fSmrgstatic void
1977ec681f3Smrgbind_depth_pipeline(struct radv_cmd_buffer *cmd_buffer, enum blit2d_src_type src_type,
1987ec681f3Smrg                    uint32_t log2_samples)
19901e04c3fSmrg{
2007ec681f3Smrg   VkPipeline pipeline =
2017ec681f3Smrg      cmd_buffer->device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type];
20201e04c3fSmrg
2037ec681f3Smrg   radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS,
2047ec681f3Smrg                        pipeline);
20501e04c3fSmrg}
20601e04c3fSmrg
20701e04c3fSmrgstatic void
2087ec681f3Smrgbind_stencil_pipeline(struct radv_cmd_buffer *cmd_buffer, enum blit2d_src_type src_type,
2097ec681f3Smrg                      uint32_t log2_samples)
21001e04c3fSmrg{
2117ec681f3Smrg   VkPipeline pipeline =
2127ec681f3Smrg      cmd_buffer->device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type];
21301e04c3fSmrg
2147ec681f3Smrg   radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS,
2157ec681f3Smrg                        pipeline);
21601e04c3fSmrg}
21701e04c3fSmrg
21801e04c3fSmrgstatic void
21901e04c3fSmrgradv_meta_blit2d_normal_dst(struct radv_cmd_buffer *cmd_buffer,
2207ec681f3Smrg                            struct radv_meta_blit2d_surf *src_img,
2217ec681f3Smrg                            struct radv_meta_blit2d_buffer *src_buf,
2227ec681f3Smrg                            struct radv_meta_blit2d_surf *dst, unsigned num_rects,
2237ec681f3Smrg                            struct radv_meta_blit2d_rect *rects, enum blit2d_src_type src_type,
2247ec681f3Smrg                            uint32_t log2_samples)
22501e04c3fSmrg{
2267ec681f3Smrg   struct radv_device *device = cmd_buffer->device;
2277ec681f3Smrg
2287ec681f3Smrg   for (unsigned r = 0; r < num_rects; ++r) {
2297ec681f3Smrg      u_foreach_bit(i, dst->aspect_mask)
2307ec681f3Smrg      {
2317ec681f3Smrg         unsigned aspect_mask = 1u << i;
2327ec681f3Smrg         unsigned src_aspect_mask = aspect_mask;
2337ec681f3Smrg         VkFormat depth_format = 0;
2347ec681f3Smrg         if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
2357ec681f3Smrg            depth_format = vk_format_stencil_only(dst->image->vk_format);
2367ec681f3Smrg         else if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT)
2377ec681f3Smrg            depth_format = vk_format_depth_only(dst->image->vk_format);
2387ec681f3Smrg         else if (src_img)
2397ec681f3Smrg            src_aspect_mask = src_img->aspect_mask;
2407ec681f3Smrg
2417ec681f3Smrg         struct blit2d_src_temps src_temps;
2427ec681f3Smrg         blit2d_bind_src(cmd_buffer, src_img, src_buf, &src_temps, src_type, depth_format,
2437ec681f3Smrg                         src_aspect_mask, log2_samples);
2447ec681f3Smrg
2457ec681f3Smrg         struct blit2d_dst_temps dst_temps;
2467ec681f3Smrg         blit2d_bind_dst(cmd_buffer, dst, rects[r].dst_x + rects[r].width,
2477ec681f3Smrg                         rects[r].dst_y + rects[r].height, depth_format, &dst_temps, aspect_mask);
2487ec681f3Smrg
2497ec681f3Smrg         float vertex_push_constants[4] = {
2507ec681f3Smrg            rects[r].src_x,
2517ec681f3Smrg            rects[r].src_y,
2527ec681f3Smrg            rects[r].src_x + rects[r].width,
2537ec681f3Smrg            rects[r].src_y + rects[r].height,
2547ec681f3Smrg         };
2557ec681f3Smrg
2567ec681f3Smrg         radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
2577ec681f3Smrg                               device->meta_state.blit2d[log2_samples].p_layouts[src_type],
2587ec681f3Smrg                               VK_SHADER_STAGE_VERTEX_BIT, 0, 16, vertex_push_constants);
2597ec681f3Smrg
2607ec681f3Smrg         if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT ||
2617ec681f3Smrg             aspect_mask == VK_IMAGE_ASPECT_PLANE_0_BIT ||
2627ec681f3Smrg             aspect_mask == VK_IMAGE_ASPECT_PLANE_1_BIT ||
2637ec681f3Smrg             aspect_mask == VK_IMAGE_ASPECT_PLANE_2_BIT) {
2647ec681f3Smrg            unsigned fs_key = radv_format_meta_fs_key(device, dst_temps.iview.vk_format);
2657ec681f3Smrg            unsigned dst_layout = radv_meta_dst_layout_from_layout(dst->current_layout);
2667ec681f3Smrg
2677ec681f3Smrg            if (device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key] ==
2687ec681f3Smrg                VK_NULL_HANDLE) {
2697ec681f3Smrg               VkResult ret = blit2d_init_color_pipeline(
2707ec681f3Smrg                  device, src_type, radv_fs_key_format_exemplars[fs_key], log2_samples);
2717ec681f3Smrg               if (ret != VK_SUCCESS) {
2727ec681f3Smrg                  cmd_buffer->record_result = ret;
2737ec681f3Smrg                  goto fail_pipeline;
2747ec681f3Smrg               }
2757ec681f3Smrg            }
2767ec681f3Smrg
2777ec681f3Smrg            radv_cmd_buffer_begin_render_pass(
2787ec681f3Smrg               cmd_buffer,
2797ec681f3Smrg               &(VkRenderPassBeginInfo){
2807ec681f3Smrg                  .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
2817ec681f3Smrg                  .renderPass = device->meta_state.blit2d_render_passes[fs_key][dst_layout],
2827ec681f3Smrg                  .framebuffer = dst_temps.fb,
2837ec681f3Smrg                  .renderArea =
2847ec681f3Smrg                     {
2857ec681f3Smrg                        .offset =
2867ec681f3Smrg                           {
2877ec681f3Smrg                              rects[r].dst_x,
2887ec681f3Smrg                              rects[r].dst_y,
2897ec681f3Smrg                           },
2907ec681f3Smrg                        .extent = {rects[r].width, rects[r].height},
2917ec681f3Smrg                     },
2927ec681f3Smrg                  .clearValueCount = 0,
2937ec681f3Smrg                  .pClearValues = NULL,
2947ec681f3Smrg               },
2957ec681f3Smrg               &(struct radv_extra_render_pass_begin_info){.disable_dcc =
2967ec681f3Smrg                                                              dst->disable_compression});
2977ec681f3Smrg
2987ec681f3Smrg            radv_cmd_buffer_set_subpass(cmd_buffer, &cmd_buffer->state.pass->subpasses[0]);
2997ec681f3Smrg
3007ec681f3Smrg            bind_pipeline(cmd_buffer, src_type, fs_key, log2_samples);
3017ec681f3Smrg         } else if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) {
3027ec681f3Smrg            enum radv_blit_ds_layout ds_layout = radv_meta_blit_ds_to_type(dst->current_layout);
3037ec681f3Smrg
3047ec681f3Smrg            if (device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type] ==
3057ec681f3Smrg                VK_NULL_HANDLE) {
3067ec681f3Smrg               VkResult ret = blit2d_init_depth_only_pipeline(device, src_type, log2_samples);
3077ec681f3Smrg               if (ret != VK_SUCCESS) {
3087ec681f3Smrg                  cmd_buffer->record_result = ret;
3097ec681f3Smrg                  goto fail_pipeline;
3107ec681f3Smrg               }
3117ec681f3Smrg            }
3127ec681f3Smrg
3137ec681f3Smrg            radv_cmd_buffer_begin_render_pass(
3147ec681f3Smrg               cmd_buffer,
3157ec681f3Smrg               &(VkRenderPassBeginInfo){
3167ec681f3Smrg                  .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
3177ec681f3Smrg                  .renderPass = device->meta_state.blit2d_depth_only_rp[ds_layout],
3187ec681f3Smrg                  .framebuffer = dst_temps.fb,
3197ec681f3Smrg                  .renderArea =
3207ec681f3Smrg                     {
3217ec681f3Smrg                        .offset =
3227ec681f3Smrg                           {
3237ec681f3Smrg                              rects[r].dst_x,
3247ec681f3Smrg                              rects[r].dst_y,
3257ec681f3Smrg                           },
3267ec681f3Smrg                        .extent = {rects[r].width, rects[r].height},
3277ec681f3Smrg                     },
3287ec681f3Smrg                  .clearValueCount = 0,
3297ec681f3Smrg                  .pClearValues = NULL,
3307ec681f3Smrg               },
3317ec681f3Smrg               NULL);
3327ec681f3Smrg
3337ec681f3Smrg            radv_cmd_buffer_set_subpass(cmd_buffer, &cmd_buffer->state.pass->subpasses[0]);
3347ec681f3Smrg
3357ec681f3Smrg            bind_depth_pipeline(cmd_buffer, src_type, log2_samples);
3367ec681f3Smrg
3377ec681f3Smrg         } else if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
3387ec681f3Smrg            enum radv_blit_ds_layout ds_layout = radv_meta_blit_ds_to_type(dst->current_layout);
3397ec681f3Smrg
3407ec681f3Smrg            if (device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type] ==
3417ec681f3Smrg                VK_NULL_HANDLE) {
3427ec681f3Smrg               VkResult ret = blit2d_init_stencil_only_pipeline(device, src_type, log2_samples);
3437ec681f3Smrg               if (ret != VK_SUCCESS) {
3447ec681f3Smrg                  cmd_buffer->record_result = ret;
3457ec681f3Smrg                  goto fail_pipeline;
3467ec681f3Smrg               }
3477ec681f3Smrg            }
3487ec681f3Smrg
3497ec681f3Smrg            radv_cmd_buffer_begin_render_pass(
3507ec681f3Smrg               cmd_buffer,
3517ec681f3Smrg               &(VkRenderPassBeginInfo){
3527ec681f3Smrg                  .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
3537ec681f3Smrg                  .renderPass = device->meta_state.blit2d_stencil_only_rp[ds_layout],
3547ec681f3Smrg                  .framebuffer = dst_temps.fb,
3557ec681f3Smrg                  .renderArea =
3567ec681f3Smrg                     {
3577ec681f3Smrg                        .offset =
3587ec681f3Smrg                           {
3597ec681f3Smrg                              rects[r].dst_x,
3607ec681f3Smrg                              rects[r].dst_y,
3617ec681f3Smrg                           },
3627ec681f3Smrg                        .extent = {rects[r].width, rects[r].height},
3637ec681f3Smrg                     },
3647ec681f3Smrg                  .clearValueCount = 0,
3657ec681f3Smrg                  .pClearValues = NULL,
3667ec681f3Smrg               },
3677ec681f3Smrg               NULL);
3687ec681f3Smrg
3697ec681f3Smrg            radv_cmd_buffer_set_subpass(cmd_buffer, &cmd_buffer->state.pass->subpasses[0]);
3707ec681f3Smrg
3717ec681f3Smrg            bind_stencil_pipeline(cmd_buffer, src_type, log2_samples);
3727ec681f3Smrg         } else
3737ec681f3Smrg            unreachable("Processing blit2d with multiple aspects.");
3747ec681f3Smrg
3757ec681f3Smrg         radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
3767ec681f3Smrg                             &(VkViewport){.x = rects[r].dst_x,
3777ec681f3Smrg                                           .y = rects[r].dst_y,
3787ec681f3Smrg                                           .width = rects[r].width,
3797ec681f3Smrg                                           .height = rects[r].height,
3807ec681f3Smrg                                           .minDepth = 0.0f,
3817ec681f3Smrg                                           .maxDepth = 1.0f});
3827ec681f3Smrg
3837ec681f3Smrg         radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1,
3847ec681f3Smrg                            &(VkRect2D){
3857ec681f3Smrg                               .offset = (VkOffset2D){rects[r].dst_x, rects[r].dst_y},
3867ec681f3Smrg                               .extent = (VkExtent2D){rects[r].width, rects[r].height},
3877ec681f3Smrg                            });
3887ec681f3Smrg
3897ec681f3Smrg         radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
3907ec681f3Smrg         radv_cmd_buffer_end_render_pass(cmd_buffer);
3917ec681f3Smrg
3927ec681f3Smrg      fail_pipeline:
3937ec681f3Smrg         /* At the point where we emit the draw call, all data from the
3947ec681f3Smrg          * descriptor sets, etc. has been used.  We are free to delete it.
3957ec681f3Smrg          */
3967ec681f3Smrg         radv_DestroyFramebuffer(radv_device_to_handle(device), dst_temps.fb,
3977ec681f3Smrg                                 &cmd_buffer->pool->alloc);
3987ec681f3Smrg
3997ec681f3Smrg         if (src_type == BLIT2D_SRC_TYPE_BUFFER)
4007ec681f3Smrg            radv_buffer_view_finish(&src_temps.bview);
4017ec681f3Smrg         else
4027ec681f3Smrg            radv_image_view_finish(&dst_temps.iview);
4037ec681f3Smrg
4047ec681f3Smrg         radv_image_view_finish(&dst_temps.iview);
4057ec681f3Smrg      }
4067ec681f3Smrg   }
40701e04c3fSmrg}
40801e04c3fSmrg
40901e04c3fSmrgvoid
4107ec681f3Smrgradv_meta_blit2d(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_blit2d_surf *src_img,
4117ec681f3Smrg                 struct radv_meta_blit2d_buffer *src_buf, struct radv_meta_blit2d_surf *dst,
4127ec681f3Smrg                 unsigned num_rects, struct radv_meta_blit2d_rect *rects)
41301e04c3fSmrg{
4147ec681f3Smrg   bool use_3d = cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9 &&
4157ec681f3Smrg                 (src_img && src_img->image->type == VK_IMAGE_TYPE_3D);
4167ec681f3Smrg   enum blit2d_src_type src_type = src_buf  ? BLIT2D_SRC_TYPE_BUFFER
4177ec681f3Smrg                                   : use_3d ? BLIT2D_SRC_TYPE_IMAGE_3D
4187ec681f3Smrg                                            : BLIT2D_SRC_TYPE_IMAGE;
4197ec681f3Smrg   radv_meta_blit2d_normal_dst(cmd_buffer, src_img, src_buf, dst, num_rects, rects, src_type,
4207ec681f3Smrg                               src_img ? util_logbase2(src_img->image->info.samples) : 0);
42101e04c3fSmrg}
42201e04c3fSmrg
42301e04c3fSmrgstatic nir_shader *
42401e04c3fSmrgbuild_nir_vertex_shader(void)
42501e04c3fSmrg{
4267ec681f3Smrg   const struct glsl_type *vec4 = glsl_vec4_type();
4277ec681f3Smrg   const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
4287ec681f3Smrg   nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_VERTEX, NULL, "meta_blit2d_vs");
4297ec681f3Smrg
4307ec681f3Smrg   nir_variable *pos_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "gl_Position");
4317ec681f3Smrg   pos_out->data.location = VARYING_SLOT_POS;
4327ec681f3Smrg
4337ec681f3Smrg   nir_variable *tex_pos_out = nir_variable_create(b.shader, nir_var_shader_out, vec2, "v_tex_pos");
4347ec681f3Smrg   tex_pos_out->data.location = VARYING_SLOT_VAR0;
4357ec681f3Smrg   tex_pos_out->data.interpolation = INTERP_MODE_SMOOTH;
4367ec681f3Smrg
4377ec681f3Smrg   nir_ssa_def *outvec = radv_meta_gen_rect_vertices(&b);
4387ec681f3Smrg   nir_store_var(&b, pos_out, outvec, 0xf);
4397ec681f3Smrg
4407ec681f3Smrg   nir_ssa_def *src_box = nir_load_push_constant(&b, 4, 32, nir_imm_int(&b, 0), .range = 16);
4417ec681f3Smrg   nir_ssa_def *vertex_id = nir_load_vertex_id_zero_base(&b);
4427ec681f3Smrg
4437ec681f3Smrg   /* vertex 0 - src_x, src_y */
4447ec681f3Smrg   /* vertex 1 - src_x, src_y+h */
4457ec681f3Smrg   /* vertex 2 - src_x+w, src_y */
4467ec681f3Smrg   /* so channel 0 is vertex_id != 2 ? src_x : src_x + w
4477ec681f3Smrg      channel 1 is vertex id != 1 ? src_y : src_y + w */
4487ec681f3Smrg
4497ec681f3Smrg   nir_ssa_def *c0cmp = nir_ine(&b, vertex_id, nir_imm_int(&b, 2));
4507ec681f3Smrg   nir_ssa_def *c1cmp = nir_ine(&b, vertex_id, nir_imm_int(&b, 1));
4517ec681f3Smrg
4527ec681f3Smrg   nir_ssa_def *comp[2];
4537ec681f3Smrg   comp[0] = nir_bcsel(&b, c0cmp, nir_channel(&b, src_box, 0), nir_channel(&b, src_box, 2));
4547ec681f3Smrg
4557ec681f3Smrg   comp[1] = nir_bcsel(&b, c1cmp, nir_channel(&b, src_box, 1), nir_channel(&b, src_box, 3));
4567ec681f3Smrg   nir_ssa_def *out_tex_vec = nir_vec(&b, comp, 2);
4577ec681f3Smrg   nir_store_var(&b, tex_pos_out, out_tex_vec, 0x3);
4587ec681f3Smrg   return b.shader;
45901e04c3fSmrg}
46001e04c3fSmrg
4617ec681f3Smrgtypedef nir_ssa_def *(*texel_fetch_build_func)(struct nir_builder *, struct radv_device *,
46201e04c3fSmrg                                               nir_ssa_def *, bool, bool);
46301e04c3fSmrg
46401e04c3fSmrgstatic nir_ssa_def *
4657ec681f3Smrgbuild_nir_texel_fetch(struct nir_builder *b, struct radv_device *device, nir_ssa_def *tex_pos,
4667ec681f3Smrg                      bool is_3d, bool is_multisampled)
46701e04c3fSmrg{
4687ec681f3Smrg   enum glsl_sampler_dim dim = is_3d             ? GLSL_SAMPLER_DIM_3D
4697ec681f3Smrg                               : is_multisampled ? GLSL_SAMPLER_DIM_MS
4707ec681f3Smrg                                                 : GLSL_SAMPLER_DIM_2D;
4717ec681f3Smrg   const struct glsl_type *sampler_type = glsl_sampler_type(dim, false, false, GLSL_TYPE_UINT);
4727ec681f3Smrg   nir_variable *sampler = nir_variable_create(b->shader, nir_var_uniform, sampler_type, "s_tex");
4737ec681f3Smrg   sampler->data.descriptor_set = 0;
4747ec681f3Smrg   sampler->data.binding = 0;
4757ec681f3Smrg
4767ec681f3Smrg   nir_ssa_def *tex_pos_3d = NULL;
4777ec681f3Smrg   nir_ssa_def *sample_idx = NULL;
4787ec681f3Smrg   if (is_3d) {
4797ec681f3Smrg      nir_ssa_def *layer =
4807ec681f3Smrg         nir_load_push_constant(b, 1, 32, nir_imm_int(b, 0), .base = 16, .range = 4);
4817ec681f3Smrg
4827ec681f3Smrg      nir_ssa_def *chans[3];
4837ec681f3Smrg      chans[0] = nir_channel(b, tex_pos, 0);
4847ec681f3Smrg      chans[1] = nir_channel(b, tex_pos, 1);
4857ec681f3Smrg      chans[2] = layer;
4867ec681f3Smrg      tex_pos_3d = nir_vec(b, chans, 3);
4877ec681f3Smrg   }
4887ec681f3Smrg   if (is_multisampled) {
4897ec681f3Smrg      sample_idx = nir_load_sample_id(b);
4907ec681f3Smrg   }
4917ec681f3Smrg
4927ec681f3Smrg   nir_ssa_def *tex_deref = &nir_build_deref_var(b, sampler)->dest.ssa;
4937ec681f3Smrg
4947ec681f3Smrg   nir_tex_instr *tex = nir_tex_instr_create(b->shader, is_multisampled ? 4 : 3);
4957ec681f3Smrg   tex->sampler_dim = dim;
4967ec681f3Smrg   tex->op = is_multisampled ? nir_texop_txf_ms : nir_texop_txf;
4977ec681f3Smrg   tex->src[0].src_type = nir_tex_src_coord;
4987ec681f3Smrg   tex->src[0].src = nir_src_for_ssa(is_3d ? tex_pos_3d : tex_pos);
4997ec681f3Smrg   tex->src[1].src_type = is_multisampled ? nir_tex_src_ms_index : nir_tex_src_lod;
5007ec681f3Smrg   tex->src[1].src = nir_src_for_ssa(is_multisampled ? sample_idx : nir_imm_int(b, 0));
5017ec681f3Smrg   tex->src[2].src_type = nir_tex_src_texture_deref;
5027ec681f3Smrg   tex->src[2].src = nir_src_for_ssa(tex_deref);
5037ec681f3Smrg   if (is_multisampled) {
5047ec681f3Smrg      tex->src[3].src_type = nir_tex_src_lod;
5057ec681f3Smrg      tex->src[3].src = nir_src_for_ssa(nir_imm_int(b, 0));
5067ec681f3Smrg   }
5077ec681f3Smrg   tex->dest_type = nir_type_uint32;
5087ec681f3Smrg   tex->is_array = false;
5097ec681f3Smrg   tex->coord_components = is_3d ? 3 : 2;
5107ec681f3Smrg
5117ec681f3Smrg   nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
5127ec681f3Smrg   nir_builder_instr_insert(b, &tex->instr);
5137ec681f3Smrg
5147ec681f3Smrg   return &tex->dest.ssa;
51501e04c3fSmrg}
51601e04c3fSmrg
51701e04c3fSmrgstatic nir_ssa_def *
5187ec681f3Smrgbuild_nir_buffer_fetch(struct nir_builder *b, struct radv_device *device, nir_ssa_def *tex_pos,
5197ec681f3Smrg                       bool is_3d, bool is_multisampled)
52001e04c3fSmrg{
5217ec681f3Smrg   const struct glsl_type *sampler_type =
5227ec681f3Smrg      glsl_sampler_type(GLSL_SAMPLER_DIM_BUF, false, false, GLSL_TYPE_UINT);
5237ec681f3Smrg   nir_variable *sampler = nir_variable_create(b->shader, nir_var_uniform, sampler_type, "s_tex");
5247ec681f3Smrg   sampler->data.descriptor_set = 0;
5257ec681f3Smrg   sampler->data.binding = 0;
5267ec681f3Smrg
5277ec681f3Smrg   nir_ssa_def *width = nir_load_push_constant(b, 1, 32, nir_imm_int(b, 0), .base = 16, .range = 4);
5287ec681f3Smrg
5297ec681f3Smrg   nir_ssa_def *pos_x = nir_channel(b, tex_pos, 0);
5307ec681f3Smrg   nir_ssa_def *pos_y = nir_channel(b, tex_pos, 1);
5317ec681f3Smrg   pos_y = nir_imul(b, pos_y, width);
5327ec681f3Smrg   pos_x = nir_iadd(b, pos_x, pos_y);
5337ec681f3Smrg
5347ec681f3Smrg   nir_ssa_def *tex_deref = &nir_build_deref_var(b, sampler)->dest.ssa;
5357ec681f3Smrg
5367ec681f3Smrg   nir_tex_instr *tex = nir_tex_instr_create(b->shader, 2);
5377ec681f3Smrg   tex->sampler_dim = GLSL_SAMPLER_DIM_BUF;
5387ec681f3Smrg   tex->op = nir_texop_txf;
5397ec681f3Smrg   tex->src[0].src_type = nir_tex_src_coord;
5407ec681f3Smrg   tex->src[0].src = nir_src_for_ssa(pos_x);
5417ec681f3Smrg   tex->src[1].src_type = nir_tex_src_texture_deref;
5427ec681f3Smrg   tex->src[1].src = nir_src_for_ssa(tex_deref);
5437ec681f3Smrg   tex->dest_type = nir_type_uint32;
5447ec681f3Smrg   tex->is_array = false;
5457ec681f3Smrg   tex->coord_components = 1;
5467ec681f3Smrg
5477ec681f3Smrg   nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
5487ec681f3Smrg   nir_builder_instr_insert(b, &tex->instr);
5497ec681f3Smrg
5507ec681f3Smrg   return &tex->dest.ssa;
55101e04c3fSmrg}
55201e04c3fSmrg
55301e04c3fSmrgstatic const VkPipelineVertexInputStateCreateInfo normal_vi_create_info = {
5547ec681f3Smrg   .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
5557ec681f3Smrg   .vertexBindingDescriptionCount = 0,
5567ec681f3Smrg   .vertexAttributeDescriptionCount = 0,
55701e04c3fSmrg};
55801e04c3fSmrg
55901e04c3fSmrgstatic nir_shader *
5607ec681f3Smrgbuild_nir_copy_fragment_shader(struct radv_device *device, texel_fetch_build_func txf_func,
5617ec681f3Smrg                               const char *name, bool is_3d, bool is_multisampled)
56201e04c3fSmrg{
5637ec681f3Smrg   const struct glsl_type *vec4 = glsl_vec4_type();
5647ec681f3Smrg   const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
5657ec681f3Smrg   nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, NULL, "%s", name);
56601e04c3fSmrg
5677ec681f3Smrg   nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos");
5687ec681f3Smrg   tex_pos_in->data.location = VARYING_SLOT_VAR0;
56901e04c3fSmrg
5707ec681f3Smrg   nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
5717ec681f3Smrg   color_out->data.location = FRAG_RESULT_DATA0;
57201e04c3fSmrg
5737ec681f3Smrg   nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
5747ec681f3Smrg   nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3);
57501e04c3fSmrg
5767ec681f3Smrg   nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled);
5777ec681f3Smrg   nir_store_var(&b, color_out, color, 0xf);
57801e04c3fSmrg
5797ec681f3Smrg   return b.shader;
58001e04c3fSmrg}
58101e04c3fSmrg
58201e04c3fSmrgstatic nir_shader *
5837ec681f3Smrgbuild_nir_copy_fragment_shader_depth(struct radv_device *device, texel_fetch_build_func txf_func,
5847ec681f3Smrg                                     const char *name, bool is_3d, bool is_multisampled)
58501e04c3fSmrg{
5867ec681f3Smrg   const struct glsl_type *vec4 = glsl_vec4_type();
5877ec681f3Smrg   const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
5887ec681f3Smrg   nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, NULL, "%s", name);
58901e04c3fSmrg
5907ec681f3Smrg   nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos");
5917ec681f3Smrg   tex_pos_in->data.location = VARYING_SLOT_VAR0;
59201e04c3fSmrg
5937ec681f3Smrg   nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
5947ec681f3Smrg   color_out->data.location = FRAG_RESULT_DEPTH;
59501e04c3fSmrg
5967ec681f3Smrg   nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
5977ec681f3Smrg   nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3);
59801e04c3fSmrg
5997ec681f3Smrg   nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled);
6007ec681f3Smrg   nir_store_var(&b, color_out, color, 0x1);
60101e04c3fSmrg
6027ec681f3Smrg   return b.shader;
60301e04c3fSmrg}
60401e04c3fSmrg
60501e04c3fSmrgstatic nir_shader *
6067ec681f3Smrgbuild_nir_copy_fragment_shader_stencil(struct radv_device *device, texel_fetch_build_func txf_func,
6077ec681f3Smrg                                       const char *name, bool is_3d, bool is_multisampled)
60801e04c3fSmrg{
6097ec681f3Smrg   const struct glsl_type *vec4 = glsl_vec4_type();
6107ec681f3Smrg   const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2);
6117ec681f3Smrg   nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, NULL, "%s", name);
61201e04c3fSmrg
6137ec681f3Smrg   nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "v_tex_pos");
6147ec681f3Smrg   tex_pos_in->data.location = VARYING_SLOT_VAR0;
61501e04c3fSmrg
6167ec681f3Smrg   nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color");
6177ec681f3Smrg   color_out->data.location = FRAG_RESULT_STENCIL;
61801e04c3fSmrg
6197ec681f3Smrg   nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
6207ec681f3Smrg   nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3);
62101e04c3fSmrg
6227ec681f3Smrg   nir_ssa_def *color = txf_func(&b, device, tex_pos, is_3d, is_multisampled);
6237ec681f3Smrg   nir_store_var(&b, color_out, color, 0x1);
62401e04c3fSmrg
6257ec681f3Smrg   return b.shader;
62601e04c3fSmrg}
62701e04c3fSmrg
62801e04c3fSmrgvoid
62901e04c3fSmrgradv_device_finish_meta_blit2d_state(struct radv_device *device)
63001e04c3fSmrg{
6317ec681f3Smrg   struct radv_meta_state *state = &device->meta_state;
6327ec681f3Smrg
6337ec681f3Smrg   for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) {
6347ec681f3Smrg      for (unsigned k = 0; k < RADV_META_DST_LAYOUT_COUNT; ++k) {
6357ec681f3Smrg         radv_DestroyRenderPass(radv_device_to_handle(device), state->blit2d_render_passes[j][k],
6367ec681f3Smrg                                &state->alloc);
6377ec681f3Smrg      }
6387ec681f3Smrg   }
6397ec681f3Smrg
6407ec681f3Smrg   for (enum radv_blit_ds_layout j = RADV_BLIT_DS_LAYOUT_TILE_ENABLE; j < RADV_BLIT_DS_LAYOUT_COUNT;
6417ec681f3Smrg        j++) {
6427ec681f3Smrg      radv_DestroyRenderPass(radv_device_to_handle(device), state->blit2d_depth_only_rp[j],
6437ec681f3Smrg                             &state->alloc);
6447ec681f3Smrg      radv_DestroyRenderPass(radv_device_to_handle(device), state->blit2d_stencil_only_rp[j],
6457ec681f3Smrg                             &state->alloc);
6467ec681f3Smrg   }
6477ec681f3Smrg
6487ec681f3Smrg   for (unsigned log2_samples = 0; log2_samples < MAX_SAMPLES_LOG2; ++log2_samples) {
6497ec681f3Smrg      for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES; src++) {
6507ec681f3Smrg         radv_DestroyPipelineLayout(radv_device_to_handle(device),
6517ec681f3Smrg                                    state->blit2d[log2_samples].p_layouts[src], &state->alloc);
6527ec681f3Smrg         radv_DestroyDescriptorSetLayout(radv_device_to_handle(device),
6537ec681f3Smrg                                         state->blit2d[log2_samples].ds_layouts[src],
6547ec681f3Smrg                                         &state->alloc);
6557ec681f3Smrg
6567ec681f3Smrg         for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) {
6577ec681f3Smrg            radv_DestroyPipeline(radv_device_to_handle(device),
6587ec681f3Smrg                                 state->blit2d[log2_samples].pipelines[src][j], &state->alloc);
6597ec681f3Smrg         }
6607ec681f3Smrg
6617ec681f3Smrg         radv_DestroyPipeline(radv_device_to_handle(device),
6627ec681f3Smrg                              state->blit2d[log2_samples].depth_only_pipeline[src], &state->alloc);
6637ec681f3Smrg         radv_DestroyPipeline(radv_device_to_handle(device),
6647ec681f3Smrg                              state->blit2d[log2_samples].stencil_only_pipeline[src],
6657ec681f3Smrg                              &state->alloc);
6667ec681f3Smrg      }
6677ec681f3Smrg   }
66801e04c3fSmrg}
66901e04c3fSmrg
67001e04c3fSmrgstatic VkResult
6717ec681f3Smrgblit2d_init_color_pipeline(struct radv_device *device, enum blit2d_src_type src_type,
6727ec681f3Smrg                           VkFormat format, uint32_t log2_samples)
67301e04c3fSmrg{
6747ec681f3Smrg   VkResult result;
6757ec681f3Smrg   unsigned fs_key = radv_format_meta_fs_key(device, format);
6767ec681f3Smrg   const char *name;
6777ec681f3Smrg
6787ec681f3Smrg   mtx_lock(&device->meta_state.mtx);
6797ec681f3Smrg   if (device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key]) {
6807ec681f3Smrg      mtx_unlock(&device->meta_state.mtx);
6817ec681f3Smrg      return VK_SUCCESS;
6827ec681f3Smrg   }
6837ec681f3Smrg
6847ec681f3Smrg   texel_fetch_build_func src_func;
6857ec681f3Smrg   switch (src_type) {
6867ec681f3Smrg   case BLIT2D_SRC_TYPE_IMAGE:
6877ec681f3Smrg      src_func = build_nir_texel_fetch;
6887ec681f3Smrg      name = "meta_blit2d_image_fs";
6897ec681f3Smrg      break;
6907ec681f3Smrg   case BLIT2D_SRC_TYPE_IMAGE_3D:
6917ec681f3Smrg      src_func = build_nir_texel_fetch;
6927ec681f3Smrg      name = "meta_blit3d_image_fs";
6937ec681f3Smrg      break;
6947ec681f3Smrg   case BLIT2D_SRC_TYPE_BUFFER:
6957ec681f3Smrg      src_func = build_nir_buffer_fetch;
6967ec681f3Smrg      name = "meta_blit2d_buffer_fs";
6977ec681f3Smrg      break;
6987ec681f3Smrg   default:
6997ec681f3Smrg      unreachable("unknown blit src type\n");
7007ec681f3Smrg      break;
7017ec681f3Smrg   }
7027ec681f3Smrg
7037ec681f3Smrg   const VkPipelineVertexInputStateCreateInfo *vi_create_info;
7047ec681f3Smrg   nir_shader *fs = build_nir_copy_fragment_shader(
7057ec681f3Smrg      device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
7067ec681f3Smrg   nir_shader *vs = build_nir_vertex_shader();
7077ec681f3Smrg
7087ec681f3Smrg   vi_create_info = &normal_vi_create_info;
7097ec681f3Smrg
7107ec681f3Smrg   VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
7117ec681f3Smrg      {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
7127ec681f3Smrg       .stage = VK_SHADER_STAGE_VERTEX_BIT,
7137ec681f3Smrg       .module = vk_shader_module_handle_from_nir(vs),
7147ec681f3Smrg       .pName = "main",
7157ec681f3Smrg       .pSpecializationInfo = NULL},
7167ec681f3Smrg      {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
7177ec681f3Smrg       .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
7187ec681f3Smrg       .module = vk_shader_module_handle_from_nir(fs),
7197ec681f3Smrg       .pName = "main",
7207ec681f3Smrg       .pSpecializationInfo = NULL},
7217ec681f3Smrg   };
7227ec681f3Smrg
7237ec681f3Smrg   for (unsigned dst_layout = 0; dst_layout < RADV_META_DST_LAYOUT_COUNT; ++dst_layout) {
7247ec681f3Smrg      if (!device->meta_state.blit2d_render_passes[fs_key][dst_layout]) {
7257ec681f3Smrg         VkImageLayout layout = radv_meta_dst_layout_to_layout(dst_layout);
7267ec681f3Smrg
7277ec681f3Smrg         result = radv_CreateRenderPass2(
7287ec681f3Smrg            radv_device_to_handle(device),
7297ec681f3Smrg            &(VkRenderPassCreateInfo2){
7307ec681f3Smrg               .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
7317ec681f3Smrg               .attachmentCount = 1,
7327ec681f3Smrg               .pAttachments =
7337ec681f3Smrg                  &(VkAttachmentDescription2){
7347ec681f3Smrg                     .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
7357ec681f3Smrg                     .format = format,
7367ec681f3Smrg                     .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
7377ec681f3Smrg                     .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
7387ec681f3Smrg                     .initialLayout = layout,
7397ec681f3Smrg                     .finalLayout = layout,
7407ec681f3Smrg                  },
7417ec681f3Smrg               .subpassCount = 1,
7427ec681f3Smrg               .pSubpasses =
7437ec681f3Smrg                  &(VkSubpassDescription2){
7447ec681f3Smrg                     .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
7457ec681f3Smrg                     .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
7467ec681f3Smrg                     .inputAttachmentCount = 0,
7477ec681f3Smrg                     .colorAttachmentCount = 1,
7487ec681f3Smrg                     .pColorAttachments =
7497ec681f3Smrg                        &(VkAttachmentReference2){
7507ec681f3Smrg                           .sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
7517ec681f3Smrg                           .attachment = 0,
7527ec681f3Smrg                           .layout = layout,
7537ec681f3Smrg                        },
7547ec681f3Smrg                     .pResolveAttachments = NULL,
7557ec681f3Smrg                     .pDepthStencilAttachment =
7567ec681f3Smrg                        &(VkAttachmentReference2){
7577ec681f3Smrg                           .sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
7587ec681f3Smrg                           .attachment = VK_ATTACHMENT_UNUSED,
7597ec681f3Smrg                           .layout = layout,
7607ec681f3Smrg                        },
7617ec681f3Smrg                     .preserveAttachmentCount = 0,
7627ec681f3Smrg                     .pPreserveAttachments = NULL,
7637ec681f3Smrg                  },
7647ec681f3Smrg               .dependencyCount = 2,
7657ec681f3Smrg               .pDependencies =
7667ec681f3Smrg                  (VkSubpassDependency2[]){{.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
7677ec681f3Smrg                                            .srcSubpass = VK_SUBPASS_EXTERNAL,
7687ec681f3Smrg                                            .dstSubpass = 0,
7697ec681f3Smrg                                            .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
7707ec681f3Smrg                                            .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
7717ec681f3Smrg                                            .srcAccessMask = 0,
7727ec681f3Smrg                                            .dstAccessMask = 0,
7737ec681f3Smrg                                            .dependencyFlags = 0},
7747ec681f3Smrg                                           {.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
7757ec681f3Smrg                                            .srcSubpass = 0,
7767ec681f3Smrg                                            .dstSubpass = VK_SUBPASS_EXTERNAL,
7777ec681f3Smrg                                            .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
7787ec681f3Smrg                                            .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
7797ec681f3Smrg                                            .srcAccessMask = 0,
7807ec681f3Smrg                                            .dstAccessMask = 0,
7817ec681f3Smrg                                            .dependencyFlags = 0}},
7827ec681f3Smrg            },
7837ec681f3Smrg            &device->meta_state.alloc,
7847ec681f3Smrg            &device->meta_state.blit2d_render_passes[fs_key][dst_layout]);
7857ec681f3Smrg      }
7867ec681f3Smrg   }
7877ec681f3Smrg
7887ec681f3Smrg   const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
7897ec681f3Smrg      .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
7907ec681f3Smrg      .stageCount = ARRAY_SIZE(pipeline_shader_stages),
7917ec681f3Smrg      .pStages = pipeline_shader_stages,
7927ec681f3Smrg      .pVertexInputState = vi_create_info,
7937ec681f3Smrg      .pInputAssemblyState =
7947ec681f3Smrg         &(VkPipelineInputAssemblyStateCreateInfo){
7957ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
7967ec681f3Smrg            .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
7977ec681f3Smrg            .primitiveRestartEnable = false,
7987ec681f3Smrg         },
7997ec681f3Smrg      .pViewportState =
8007ec681f3Smrg         &(VkPipelineViewportStateCreateInfo){
8017ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
8027ec681f3Smrg            .viewportCount = 1,
8037ec681f3Smrg            .scissorCount = 1,
8047ec681f3Smrg         },
8057ec681f3Smrg      .pRasterizationState =
8067ec681f3Smrg         &(VkPipelineRasterizationStateCreateInfo){
8077ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
8087ec681f3Smrg            .rasterizerDiscardEnable = false,
8097ec681f3Smrg            .polygonMode = VK_POLYGON_MODE_FILL,
8107ec681f3Smrg            .cullMode = VK_CULL_MODE_NONE,
8117ec681f3Smrg            .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE},
8127ec681f3Smrg      .pMultisampleState =
8137ec681f3Smrg         &(VkPipelineMultisampleStateCreateInfo){
8147ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
8157ec681f3Smrg            .rasterizationSamples = 1 << log2_samples,
8167ec681f3Smrg            .sampleShadingEnable = log2_samples > 1,
8177ec681f3Smrg            .minSampleShading = 1.0,
8187ec681f3Smrg            .pSampleMask = (VkSampleMask[]){UINT32_MAX},
8197ec681f3Smrg         },
8207ec681f3Smrg      .pColorBlendState =
8217ec681f3Smrg         &(VkPipelineColorBlendStateCreateInfo){
8227ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
8237ec681f3Smrg            .attachmentCount = 1,
8247ec681f3Smrg            .pAttachments =
8257ec681f3Smrg               (VkPipelineColorBlendAttachmentState[]){
8267ec681f3Smrg                  {.colorWriteMask = VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_R_BIT |
8277ec681f3Smrg                                     VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT},
8287ec681f3Smrg               }},
8297ec681f3Smrg      .pDynamicState =
8307ec681f3Smrg         &(VkPipelineDynamicStateCreateInfo){
8317ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
8327ec681f3Smrg            .dynamicStateCount = 9,
8337ec681f3Smrg            .pDynamicStates =
8347ec681f3Smrg               (VkDynamicState[]){
8357ec681f3Smrg                  VK_DYNAMIC_STATE_VIEWPORT,
8367ec681f3Smrg                  VK_DYNAMIC_STATE_SCISSOR,
8377ec681f3Smrg                  VK_DYNAMIC_STATE_LINE_WIDTH,
8387ec681f3Smrg                  VK_DYNAMIC_STATE_DEPTH_BIAS,
8397ec681f3Smrg                  VK_DYNAMIC_STATE_BLEND_CONSTANTS,
8407ec681f3Smrg                  VK_DYNAMIC_STATE_DEPTH_BOUNDS,
8417ec681f3Smrg                  VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
8427ec681f3Smrg                  VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
8437ec681f3Smrg                  VK_DYNAMIC_STATE_STENCIL_REFERENCE,
8447ec681f3Smrg               },
8457ec681f3Smrg         },
8467ec681f3Smrg      .flags = 0,
8477ec681f3Smrg      .layout = device->meta_state.blit2d[log2_samples].p_layouts[src_type],
8487ec681f3Smrg      .renderPass = device->meta_state.blit2d_render_passes[fs_key][0],
8497ec681f3Smrg      .subpass = 0,
8507ec681f3Smrg   };
8517ec681f3Smrg
8527ec681f3Smrg   const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};
8537ec681f3Smrg
8547ec681f3Smrg   result = radv_graphics_pipeline_create(
8557ec681f3Smrg      radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache),
8567ec681f3Smrg      &vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc,
8577ec681f3Smrg      &device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key]);
8587ec681f3Smrg
8597ec681f3Smrg   ralloc_free(vs);
8607ec681f3Smrg   ralloc_free(fs);
8617ec681f3Smrg
8627ec681f3Smrg   mtx_unlock(&device->meta_state.mtx);
8637ec681f3Smrg   return result;
86401e04c3fSmrg}
86501e04c3fSmrg
86601e04c3fSmrgstatic VkResult
8677ec681f3Smrgblit2d_init_depth_only_pipeline(struct radv_device *device, enum blit2d_src_type src_type,
8687ec681f3Smrg                                uint32_t log2_samples)
86901e04c3fSmrg{
8707ec681f3Smrg   VkResult result;
8717ec681f3Smrg   const char *name;
8727ec681f3Smrg
8737ec681f3Smrg   mtx_lock(&device->meta_state.mtx);
8747ec681f3Smrg   if (device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type]) {
8757ec681f3Smrg      mtx_unlock(&device->meta_state.mtx);
8767ec681f3Smrg      return VK_SUCCESS;
8777ec681f3Smrg   }
8787ec681f3Smrg
8797ec681f3Smrg   texel_fetch_build_func src_func;
8807ec681f3Smrg   switch (src_type) {
8817ec681f3Smrg   case BLIT2D_SRC_TYPE_IMAGE:
8827ec681f3Smrg      src_func = build_nir_texel_fetch;
8837ec681f3Smrg      name = "meta_blit2d_depth_image_fs";
8847ec681f3Smrg      break;
8857ec681f3Smrg   case BLIT2D_SRC_TYPE_IMAGE_3D:
8867ec681f3Smrg      src_func = build_nir_texel_fetch;
8877ec681f3Smrg      name = "meta_blit3d_depth_image_fs";
8887ec681f3Smrg      break;
8897ec681f3Smrg   case BLIT2D_SRC_TYPE_BUFFER:
8907ec681f3Smrg      src_func = build_nir_buffer_fetch;
8917ec681f3Smrg      name = "meta_blit2d_depth_buffer_fs";
8927ec681f3Smrg      break;
8937ec681f3Smrg   default:
8947ec681f3Smrg      unreachable("unknown blit src type\n");
8957ec681f3Smrg      break;
8967ec681f3Smrg   }
8977ec681f3Smrg
8987ec681f3Smrg   const VkPipelineVertexInputStateCreateInfo *vi_create_info;
8997ec681f3Smrg   nir_shader *fs = build_nir_copy_fragment_shader_depth(
9007ec681f3Smrg      device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
9017ec681f3Smrg   nir_shader *vs = build_nir_vertex_shader();
9027ec681f3Smrg
9037ec681f3Smrg   vi_create_info = &normal_vi_create_info;
9047ec681f3Smrg
9057ec681f3Smrg   VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
9067ec681f3Smrg      {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
9077ec681f3Smrg       .stage = VK_SHADER_STAGE_VERTEX_BIT,
9087ec681f3Smrg       .module = vk_shader_module_handle_from_nir(vs),
9097ec681f3Smrg       .pName = "main",
9107ec681f3Smrg       .pSpecializationInfo = NULL},
9117ec681f3Smrg      {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
9127ec681f3Smrg       .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
9137ec681f3Smrg       .module = vk_shader_module_handle_from_nir(fs),
9147ec681f3Smrg       .pName = "main",
9157ec681f3Smrg       .pSpecializationInfo = NULL},
9167ec681f3Smrg   };
9177ec681f3Smrg
9187ec681f3Smrg   for (enum radv_blit_ds_layout ds_layout = RADV_BLIT_DS_LAYOUT_TILE_ENABLE;
9197ec681f3Smrg        ds_layout < RADV_BLIT_DS_LAYOUT_COUNT; ds_layout++) {
9207ec681f3Smrg      if (!device->meta_state.blit2d_depth_only_rp[ds_layout]) {
9217ec681f3Smrg         VkImageLayout layout = radv_meta_blit_ds_to_layout(ds_layout);
9227ec681f3Smrg         result = radv_CreateRenderPass2(
9237ec681f3Smrg            radv_device_to_handle(device),
9247ec681f3Smrg            &(VkRenderPassCreateInfo2){
9257ec681f3Smrg               .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
9267ec681f3Smrg               .attachmentCount = 1,
9277ec681f3Smrg               .pAttachments =
9287ec681f3Smrg                  &(VkAttachmentDescription2){
9297ec681f3Smrg                     .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
9307ec681f3Smrg                     .format = VK_FORMAT_D32_SFLOAT,
9317ec681f3Smrg                     .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
9327ec681f3Smrg                     .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
9337ec681f3Smrg                     .initialLayout = layout,
9347ec681f3Smrg                     .finalLayout = layout,
9357ec681f3Smrg                  },
9367ec681f3Smrg               .subpassCount = 1,
9377ec681f3Smrg               .pSubpasses =
9387ec681f3Smrg                  &(VkSubpassDescription2){
9397ec681f3Smrg                     .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
9407ec681f3Smrg                     .inputAttachmentCount = 0,
9417ec681f3Smrg                     .colorAttachmentCount = 0,
9427ec681f3Smrg                     .pColorAttachments = NULL,
9437ec681f3Smrg                     .pResolveAttachments = NULL,
9447ec681f3Smrg                     .pDepthStencilAttachment =
9457ec681f3Smrg                        &(VkAttachmentReference2){
9467ec681f3Smrg                           .sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
9477ec681f3Smrg                           .attachment = 0,
9487ec681f3Smrg                           .layout = layout,
9497ec681f3Smrg                        },
9507ec681f3Smrg                     .preserveAttachmentCount = 0,
9517ec681f3Smrg                     .pPreserveAttachments = NULL,
9527ec681f3Smrg                  },
9537ec681f3Smrg               .dependencyCount = 2,
9547ec681f3Smrg               .pDependencies =
9557ec681f3Smrg                  (VkSubpassDependency2[]){{.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
9567ec681f3Smrg                                            .srcSubpass = VK_SUBPASS_EXTERNAL,
9577ec681f3Smrg                                            .dstSubpass = 0,
9587ec681f3Smrg                                            .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
9597ec681f3Smrg                                            .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
9607ec681f3Smrg                                            .srcAccessMask = 0,
9617ec681f3Smrg                                            .dstAccessMask = 0,
9627ec681f3Smrg                                            .dependencyFlags = 0},
9637ec681f3Smrg                                           {.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
9647ec681f3Smrg                                            .srcSubpass = 0,
9657ec681f3Smrg                                            .dstSubpass = VK_SUBPASS_EXTERNAL,
9667ec681f3Smrg                                            .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
9677ec681f3Smrg                                            .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
9687ec681f3Smrg                                            .srcAccessMask = 0,
9697ec681f3Smrg                                            .dstAccessMask = 0,
9707ec681f3Smrg                                            .dependencyFlags = 0}},
9717ec681f3Smrg            },
9727ec681f3Smrg            &device->meta_state.alloc, &device->meta_state.blit2d_depth_only_rp[ds_layout]);
9737ec681f3Smrg      }
9747ec681f3Smrg   }
9757ec681f3Smrg
9767ec681f3Smrg   const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
9777ec681f3Smrg      .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
9787ec681f3Smrg      .stageCount = ARRAY_SIZE(pipeline_shader_stages),
9797ec681f3Smrg      .pStages = pipeline_shader_stages,
9807ec681f3Smrg      .pVertexInputState = vi_create_info,
9817ec681f3Smrg      .pInputAssemblyState =
9827ec681f3Smrg         &(VkPipelineInputAssemblyStateCreateInfo){
9837ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
9847ec681f3Smrg            .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
9857ec681f3Smrg            .primitiveRestartEnable = false,
9867ec681f3Smrg         },
9877ec681f3Smrg      .pViewportState =
9887ec681f3Smrg         &(VkPipelineViewportStateCreateInfo){
9897ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
9907ec681f3Smrg            .viewportCount = 1,
9917ec681f3Smrg            .scissorCount = 1,
9927ec681f3Smrg         },
9937ec681f3Smrg      .pRasterizationState =
9947ec681f3Smrg         &(VkPipelineRasterizationStateCreateInfo){
9957ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
9967ec681f3Smrg            .rasterizerDiscardEnable = false,
9977ec681f3Smrg            .polygonMode = VK_POLYGON_MODE_FILL,
9987ec681f3Smrg            .cullMode = VK_CULL_MODE_NONE,
9997ec681f3Smrg            .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE},
10007ec681f3Smrg      .pMultisampleState =
10017ec681f3Smrg         &(VkPipelineMultisampleStateCreateInfo){
10027ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
10037ec681f3Smrg            .rasterizationSamples = 1 << log2_samples,
10047ec681f3Smrg            .sampleShadingEnable = false,
10057ec681f3Smrg            .pSampleMask = (VkSampleMask[]){UINT32_MAX},
10067ec681f3Smrg         },
10077ec681f3Smrg      .pColorBlendState =
10087ec681f3Smrg         &(VkPipelineColorBlendStateCreateInfo){
10097ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
10107ec681f3Smrg            .attachmentCount = 0,
10117ec681f3Smrg            .pAttachments = NULL,
10127ec681f3Smrg         },
10137ec681f3Smrg      .pDepthStencilState =
10147ec681f3Smrg         &(VkPipelineDepthStencilStateCreateInfo){
10157ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
10167ec681f3Smrg            .depthTestEnable = true,
10177ec681f3Smrg            .depthWriteEnable = true,
10187ec681f3Smrg            .depthCompareOp = VK_COMPARE_OP_ALWAYS,
10197ec681f3Smrg         },
10207ec681f3Smrg      .pDynamicState =
10217ec681f3Smrg         &(VkPipelineDynamicStateCreateInfo){
10227ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
10237ec681f3Smrg            .dynamicStateCount = 9,
10247ec681f3Smrg            .pDynamicStates =
10257ec681f3Smrg               (VkDynamicState[]){
10267ec681f3Smrg                  VK_DYNAMIC_STATE_VIEWPORT,
10277ec681f3Smrg                  VK_DYNAMIC_STATE_SCISSOR,
10287ec681f3Smrg                  VK_DYNAMIC_STATE_LINE_WIDTH,
10297ec681f3Smrg                  VK_DYNAMIC_STATE_DEPTH_BIAS,
10307ec681f3Smrg                  VK_DYNAMIC_STATE_BLEND_CONSTANTS,
10317ec681f3Smrg                  VK_DYNAMIC_STATE_DEPTH_BOUNDS,
10327ec681f3Smrg                  VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
10337ec681f3Smrg                  VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
10347ec681f3Smrg                  VK_DYNAMIC_STATE_STENCIL_REFERENCE,
10357ec681f3Smrg               },
10367ec681f3Smrg         },
10377ec681f3Smrg      .flags = 0,
10387ec681f3Smrg      .layout = device->meta_state.blit2d[log2_samples].p_layouts[src_type],
10397ec681f3Smrg      .renderPass = device->meta_state.blit2d_depth_only_rp[0],
10407ec681f3Smrg      .subpass = 0,
10417ec681f3Smrg   };
10427ec681f3Smrg
10437ec681f3Smrg   const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};
10447ec681f3Smrg
10457ec681f3Smrg   result = radv_graphics_pipeline_create(
10467ec681f3Smrg      radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache),
10477ec681f3Smrg      &vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc,
10487ec681f3Smrg      &device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type]);
10497ec681f3Smrg
10507ec681f3Smrg   ralloc_free(vs);
10517ec681f3Smrg   ralloc_free(fs);
10527ec681f3Smrg
10537ec681f3Smrg   mtx_unlock(&device->meta_state.mtx);
10547ec681f3Smrg   return result;
105501e04c3fSmrg}
105601e04c3fSmrg
105701e04c3fSmrgstatic VkResult
10587ec681f3Smrgblit2d_init_stencil_only_pipeline(struct radv_device *device, enum blit2d_src_type src_type,
10597ec681f3Smrg                                  uint32_t log2_samples)
106001e04c3fSmrg{
10617ec681f3Smrg   VkResult result;
10627ec681f3Smrg   const char *name;
10637ec681f3Smrg
10647ec681f3Smrg   mtx_lock(&device->meta_state.mtx);
10657ec681f3Smrg   if (device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type]) {
10667ec681f3Smrg      mtx_unlock(&device->meta_state.mtx);
10677ec681f3Smrg      return VK_SUCCESS;
10687ec681f3Smrg   }
10697ec681f3Smrg
10707ec681f3Smrg   texel_fetch_build_func src_func;
10717ec681f3Smrg   switch (src_type) {
10727ec681f3Smrg   case BLIT2D_SRC_TYPE_IMAGE:
10737ec681f3Smrg      src_func = build_nir_texel_fetch;
10747ec681f3Smrg      name = "meta_blit2d_stencil_image_fs";
10757ec681f3Smrg      break;
10767ec681f3Smrg   case BLIT2D_SRC_TYPE_IMAGE_3D:
10777ec681f3Smrg      src_func = build_nir_texel_fetch;
10787ec681f3Smrg      name = "meta_blit3d_stencil_image_fs";
10797ec681f3Smrg      break;
10807ec681f3Smrg   case BLIT2D_SRC_TYPE_BUFFER:
10817ec681f3Smrg      src_func = build_nir_buffer_fetch;
10827ec681f3Smrg      name = "meta_blit2d_stencil_buffer_fs";
10837ec681f3Smrg      break;
10847ec681f3Smrg   default:
10857ec681f3Smrg      unreachable("unknown blit src type\n");
10867ec681f3Smrg      break;
10877ec681f3Smrg   }
10887ec681f3Smrg
10897ec681f3Smrg   const VkPipelineVertexInputStateCreateInfo *vi_create_info;
10907ec681f3Smrg   nir_shader *fs = build_nir_copy_fragment_shader_stencil(
10917ec681f3Smrg      device, src_func, name, src_type == BLIT2D_SRC_TYPE_IMAGE_3D, log2_samples > 0);
10927ec681f3Smrg   nir_shader *vs = build_nir_vertex_shader();
10937ec681f3Smrg
10947ec681f3Smrg   vi_create_info = &normal_vi_create_info;
10957ec681f3Smrg
10967ec681f3Smrg   VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
10977ec681f3Smrg      {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
10987ec681f3Smrg       .stage = VK_SHADER_STAGE_VERTEX_BIT,
10997ec681f3Smrg       .module = vk_shader_module_handle_from_nir(vs),
11007ec681f3Smrg       .pName = "main",
11017ec681f3Smrg       .pSpecializationInfo = NULL},
11027ec681f3Smrg      {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
11037ec681f3Smrg       .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
11047ec681f3Smrg       .module = vk_shader_module_handle_from_nir(fs),
11057ec681f3Smrg       .pName = "main",
11067ec681f3Smrg       .pSpecializationInfo = NULL},
11077ec681f3Smrg   };
11087ec681f3Smrg
11097ec681f3Smrg   for (enum radv_blit_ds_layout ds_layout = RADV_BLIT_DS_LAYOUT_TILE_ENABLE;
11107ec681f3Smrg        ds_layout < RADV_BLIT_DS_LAYOUT_COUNT; ds_layout++) {
11117ec681f3Smrg      if (!device->meta_state.blit2d_stencil_only_rp[ds_layout]) {
11127ec681f3Smrg         VkImageLayout layout = radv_meta_blit_ds_to_layout(ds_layout);
11137ec681f3Smrg         result = radv_CreateRenderPass2(
11147ec681f3Smrg            radv_device_to_handle(device),
11157ec681f3Smrg            &(VkRenderPassCreateInfo2){
11167ec681f3Smrg               .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
11177ec681f3Smrg               .attachmentCount = 1,
11187ec681f3Smrg               .pAttachments =
11197ec681f3Smrg                  &(VkAttachmentDescription2){
11207ec681f3Smrg                     .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
11217ec681f3Smrg                     .format = VK_FORMAT_S8_UINT,
11227ec681f3Smrg                     .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
11237ec681f3Smrg                     .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
11247ec681f3Smrg                     .initialLayout = layout,
11257ec681f3Smrg                     .finalLayout = layout,
11267ec681f3Smrg                  },
11277ec681f3Smrg               .subpassCount = 1,
11287ec681f3Smrg               .pSubpasses =
11297ec681f3Smrg                  &(VkSubpassDescription2){
11307ec681f3Smrg                     .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
11317ec681f3Smrg                     .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
11327ec681f3Smrg                     .inputAttachmentCount = 0,
11337ec681f3Smrg                     .colorAttachmentCount = 0,
11347ec681f3Smrg                     .pColorAttachments = NULL,
11357ec681f3Smrg                     .pResolveAttachments = NULL,
11367ec681f3Smrg                     .pDepthStencilAttachment =
11377ec681f3Smrg                        &(VkAttachmentReference2){
11387ec681f3Smrg                           .sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
11397ec681f3Smrg                           .attachment = 0,
11407ec681f3Smrg                           .layout = layout,
11417ec681f3Smrg                        },
11427ec681f3Smrg                     .preserveAttachmentCount = 0,
11437ec681f3Smrg                     .pPreserveAttachments = NULL,
11447ec681f3Smrg                  },
11457ec681f3Smrg               .dependencyCount = 2,
11467ec681f3Smrg               .pDependencies =
11477ec681f3Smrg                  (VkSubpassDependency2[]){{.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
11487ec681f3Smrg                                            .srcSubpass = VK_SUBPASS_EXTERNAL,
11497ec681f3Smrg                                            .dstSubpass = 0,
11507ec681f3Smrg                                            .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
11517ec681f3Smrg                                            .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
11527ec681f3Smrg                                            .srcAccessMask = 0,
11537ec681f3Smrg                                            .dstAccessMask = 0,
11547ec681f3Smrg                                            .dependencyFlags = 0},
11557ec681f3Smrg                                           {.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
11567ec681f3Smrg                                            .srcSubpass = 0,
11577ec681f3Smrg                                            .dstSubpass = VK_SUBPASS_EXTERNAL,
11587ec681f3Smrg                                            .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
11597ec681f3Smrg                                            .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
11607ec681f3Smrg                                            .srcAccessMask = 0,
11617ec681f3Smrg                                            .dstAccessMask = 0,
11627ec681f3Smrg                                            .dependencyFlags = 0}},
11637ec681f3Smrg            },
11647ec681f3Smrg            &device->meta_state.alloc, &device->meta_state.blit2d_stencil_only_rp[ds_layout]);
11657ec681f3Smrg      }
11667ec681f3Smrg   }
11677ec681f3Smrg
11687ec681f3Smrg   const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
11697ec681f3Smrg      .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
11707ec681f3Smrg      .stageCount = ARRAY_SIZE(pipeline_shader_stages),
11717ec681f3Smrg      .pStages = pipeline_shader_stages,
11727ec681f3Smrg      .pVertexInputState = vi_create_info,
11737ec681f3Smrg      .pInputAssemblyState =
11747ec681f3Smrg         &(VkPipelineInputAssemblyStateCreateInfo){
11757ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
11767ec681f3Smrg            .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
11777ec681f3Smrg            .primitiveRestartEnable = false,
11787ec681f3Smrg         },
11797ec681f3Smrg      .pViewportState =
11807ec681f3Smrg         &(VkPipelineViewportStateCreateInfo){
11817ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
11827ec681f3Smrg            .viewportCount = 1,
11837ec681f3Smrg            .scissorCount = 1,
11847ec681f3Smrg         },
11857ec681f3Smrg      .pRasterizationState =
11867ec681f3Smrg         &(VkPipelineRasterizationStateCreateInfo){
11877ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
11887ec681f3Smrg            .rasterizerDiscardEnable = false,
11897ec681f3Smrg            .polygonMode = VK_POLYGON_MODE_FILL,
11907ec681f3Smrg            .cullMode = VK_CULL_MODE_NONE,
11917ec681f3Smrg            .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE},
11927ec681f3Smrg      .pMultisampleState =
11937ec681f3Smrg         &(VkPipelineMultisampleStateCreateInfo){
11947ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
11957ec681f3Smrg            .rasterizationSamples = 1 << log2_samples,
11967ec681f3Smrg            .sampleShadingEnable = false,
11977ec681f3Smrg            .pSampleMask = (VkSampleMask[]){UINT32_MAX},
11987ec681f3Smrg         },
11997ec681f3Smrg      .pColorBlendState =
12007ec681f3Smrg         &(VkPipelineColorBlendStateCreateInfo){
12017ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
12027ec681f3Smrg            .attachmentCount = 0,
12037ec681f3Smrg            .pAttachments = NULL,
12047ec681f3Smrg         },
12057ec681f3Smrg      .pDepthStencilState =
12067ec681f3Smrg         &(VkPipelineDepthStencilStateCreateInfo){
12077ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
12087ec681f3Smrg            .depthTestEnable = false,
12097ec681f3Smrg            .depthWriteEnable = false,
12107ec681f3Smrg            .stencilTestEnable = true,
12117ec681f3Smrg            .front = {.failOp = VK_STENCIL_OP_REPLACE,
12127ec681f3Smrg                      .passOp = VK_STENCIL_OP_REPLACE,
12137ec681f3Smrg                      .depthFailOp = VK_STENCIL_OP_REPLACE,
12147ec681f3Smrg                      .compareOp = VK_COMPARE_OP_ALWAYS,
12157ec681f3Smrg                      .compareMask = 0xff,
12167ec681f3Smrg                      .writeMask = 0xff,
12177ec681f3Smrg                      .reference = 0},
12187ec681f3Smrg            .back = {.failOp = VK_STENCIL_OP_REPLACE,
12197ec681f3Smrg                     .passOp = VK_STENCIL_OP_REPLACE,
12207ec681f3Smrg                     .depthFailOp = VK_STENCIL_OP_REPLACE,
12217ec681f3Smrg                     .compareOp = VK_COMPARE_OP_ALWAYS,
12227ec681f3Smrg                     .compareMask = 0xff,
12237ec681f3Smrg                     .writeMask = 0xff,
12247ec681f3Smrg                     .reference = 0},
12257ec681f3Smrg            .depthCompareOp = VK_COMPARE_OP_ALWAYS,
12267ec681f3Smrg         },
12277ec681f3Smrg      .pDynamicState =
12287ec681f3Smrg         &(VkPipelineDynamicStateCreateInfo){
12297ec681f3Smrg            .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
12307ec681f3Smrg            .dynamicStateCount = 6,
12317ec681f3Smrg            .pDynamicStates =
12327ec681f3Smrg               (VkDynamicState[]){
12337ec681f3Smrg                  VK_DYNAMIC_STATE_VIEWPORT,
12347ec681f3Smrg                  VK_DYNAMIC_STATE_SCISSOR,
12357ec681f3Smrg                  VK_DYNAMIC_STATE_LINE_WIDTH,
12367ec681f3Smrg                  VK_DYNAMIC_STATE_DEPTH_BIAS,
12377ec681f3Smrg                  VK_DYNAMIC_STATE_BLEND_CONSTANTS,
12387ec681f3Smrg                  VK_DYNAMIC_STATE_DEPTH_BOUNDS,
12397ec681f3Smrg               },
12407ec681f3Smrg         },
12417ec681f3Smrg      .flags = 0,
12427ec681f3Smrg      .layout = device->meta_state.blit2d[log2_samples].p_layouts[src_type],
12437ec681f3Smrg      .renderPass = device->meta_state.blit2d_stencil_only_rp[0],
12447ec681f3Smrg      .subpass = 0,
12457ec681f3Smrg   };
12467ec681f3Smrg
12477ec681f3Smrg   const struct radv_graphics_pipeline_create_info radv_pipeline_info = {.use_rectlist = true};
12487ec681f3Smrg
12497ec681f3Smrg   result = radv_graphics_pipeline_create(
12507ec681f3Smrg      radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache),
12517ec681f3Smrg      &vk_pipeline_info, &radv_pipeline_info, &device->meta_state.alloc,
12527ec681f3Smrg      &device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type]);
12537ec681f3Smrg
12547ec681f3Smrg   ralloc_free(vs);
12557ec681f3Smrg   ralloc_free(fs);
12567ec681f3Smrg
12577ec681f3Smrg   mtx_unlock(&device->meta_state.mtx);
12587ec681f3Smrg   return result;
125901e04c3fSmrg}
126001e04c3fSmrg
126101e04c3fSmrgstatic VkResult
12627ec681f3Smrgmeta_blit2d_create_pipe_layout(struct radv_device *device, int idx, uint32_t log2_samples)
126301e04c3fSmrg{
12647ec681f3Smrg   VkResult result;
12657ec681f3Smrg   VkDescriptorType desc_type = (idx == BLIT2D_SRC_TYPE_BUFFER)
12667ec681f3Smrg                                   ? VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
12677ec681f3Smrg                                   : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
12687ec681f3Smrg   const VkPushConstantRange push_constant_ranges[] = {
12697ec681f3Smrg      {VK_SHADER_STAGE_VERTEX_BIT, 0, 16},
12707ec681f3Smrg      {VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4},
12717ec681f3Smrg   };
12727ec681f3Smrg   int num_push_constant_range = (idx != BLIT2D_SRC_TYPE_IMAGE || log2_samples > 0) ? 2 : 1;
12737ec681f3Smrg
12747ec681f3Smrg   result = radv_CreateDescriptorSetLayout(
12757ec681f3Smrg      radv_device_to_handle(device),
12767ec681f3Smrg      &(VkDescriptorSetLayoutCreateInfo){
12777ec681f3Smrg         .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
12787ec681f3Smrg         .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
12797ec681f3Smrg         .bindingCount = 1,
12807ec681f3Smrg         .pBindings =
12817ec681f3Smrg            (VkDescriptorSetLayoutBinding[]){
12827ec681f3Smrg               {.binding = 0,
12837ec681f3Smrg                .descriptorType = desc_type,
12847ec681f3Smrg                .descriptorCount = 1,
12857ec681f3Smrg                .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
12867ec681f3Smrg                .pImmutableSamplers = NULL},
12877ec681f3Smrg            }},
12887ec681f3Smrg      &device->meta_state.alloc, &device->meta_state.blit2d[log2_samples].ds_layouts[idx]);
12897ec681f3Smrg   if (result != VK_SUCCESS)
12907ec681f3Smrg      goto fail;
12917ec681f3Smrg
12927ec681f3Smrg   result = radv_CreatePipelineLayout(
12937ec681f3Smrg      radv_device_to_handle(device),
12947ec681f3Smrg      &(VkPipelineLayoutCreateInfo){
12957ec681f3Smrg         .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
12967ec681f3Smrg         .setLayoutCount = 1,
12977ec681f3Smrg         .pSetLayouts = &device->meta_state.blit2d[log2_samples].ds_layouts[idx],
12987ec681f3Smrg         .pushConstantRangeCount = num_push_constant_range,
12997ec681f3Smrg         .pPushConstantRanges = push_constant_ranges,
13007ec681f3Smrg      },
13017ec681f3Smrg      &device->meta_state.alloc, &device->meta_state.blit2d[log2_samples].p_layouts[idx]);
13027ec681f3Smrg   if (result != VK_SUCCESS)
13037ec681f3Smrg      goto fail;
13047ec681f3Smrg   return VK_SUCCESS;
130501e04c3fSmrgfail:
13067ec681f3Smrg   return result;
130701e04c3fSmrg}
130801e04c3fSmrg
130901e04c3fSmrgVkResult
131001e04c3fSmrgradv_device_init_meta_blit2d_state(struct radv_device *device, bool on_demand)
131101e04c3fSmrg{
13127ec681f3Smrg   VkResult result;
13137ec681f3Smrg   bool create_3d = device->physical_device->rad_info.chip_class >= GFX9;
13147ec681f3Smrg
13157ec681f3Smrg   for (unsigned log2_samples = 0; log2_samples < MAX_SAMPLES_LOG2; log2_samples++) {
13167ec681f3Smrg      for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES; src++) {
13177ec681f3Smrg         if (src == BLIT2D_SRC_TYPE_IMAGE_3D && !create_3d)
13187ec681f3Smrg            continue;
131901e04c3fSmrg
13207ec681f3Smrg         /* Don't need to handle copies between buffers and multisample images. */
13217ec681f3Smrg         if (src == BLIT2D_SRC_TYPE_BUFFER && log2_samples > 0)
13227ec681f3Smrg            continue;
132301e04c3fSmrg
13247ec681f3Smrg         /* There are no multisampled 3D images. */
13257ec681f3Smrg         if (src == BLIT2D_SRC_TYPE_IMAGE_3D && log2_samples > 0)
13267ec681f3Smrg            continue;
132701e04c3fSmrg
13287ec681f3Smrg         result = meta_blit2d_create_pipe_layout(device, src, log2_samples);
13297ec681f3Smrg         if (result != VK_SUCCESS)
13307ec681f3Smrg            goto fail;
133101e04c3fSmrg
13327ec681f3Smrg         if (on_demand)
13337ec681f3Smrg            continue;
133401e04c3fSmrg
13357ec681f3Smrg         for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) {
13367ec681f3Smrg            result = blit2d_init_color_pipeline(device, src, radv_fs_key_format_exemplars[j],
13377ec681f3Smrg                                                log2_samples);
13387ec681f3Smrg            if (result != VK_SUCCESS)
13397ec681f3Smrg               goto fail;
13407ec681f3Smrg         }
134101e04c3fSmrg
13427ec681f3Smrg         result = blit2d_init_depth_only_pipeline(device, src, log2_samples);
13437ec681f3Smrg         if (result != VK_SUCCESS)
13447ec681f3Smrg            goto fail;
134501e04c3fSmrg
13467ec681f3Smrg         result = blit2d_init_stencil_only_pipeline(device, src, log2_samples);
13477ec681f3Smrg         if (result != VK_SUCCESS)
13487ec681f3Smrg            goto fail;
13497ec681f3Smrg      }
13507ec681f3Smrg   }
135101e04c3fSmrg
13527ec681f3Smrg   return VK_SUCCESS;
135301e04c3fSmrg
135401e04c3fSmrgfail:
13557ec681f3Smrg   radv_device_finish_meta_blit2d_state(device);
13567ec681f3Smrg   return result;
135701e04c3fSmrg}
1358