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