X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Famd%2Fvulkan%2Fradv_meta_copy.c;h=7f7ef22efc815f7b01f43d80ec657386c1b355f9;hb=2670ebb5840c2108c55607520f1cf9eb5868e27a;hp=6333e5c08306d6b42aa1043167d5b63704f45a42;hpb=6f08dcd398f8c93d050c4781a1bf119a38f86f75;p=mesa.git diff --git a/src/amd/vulkan/radv_meta_copy.c b/src/amd/vulkan/radv_meta_copy.c index 6333e5c0830..7f7ef22efc8 100644 --- a/src/amd/vulkan/radv_meta_copy.c +++ b/src/amd/vulkan/radv_meta_copy.c @@ -78,25 +78,28 @@ vk_format_for_size(int bs) } static struct radv_meta_blit2d_surf -blit_surf_for_image_level_layer(struct radv_image* image, VkImageAspectFlags aspectMask, - int level, int layer) +blit_surf_for_image_level_layer(struct radv_image *image, + VkImageLayout layout, + const VkImageSubresourceLayers *subres) { VkFormat format = image->vk_format; - if (aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) + if (subres->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) format = vk_format_depth_only(format); - else if (aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) + else if (subres->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) format = vk_format_stencil_only(format); - if (!image->surface.dcc_size) + if (!image->surface.dcc_size && + !(image->surface.htile_size && image->tc_compatible_htile)) format = vk_format_for_size(vk_format_get_blocksize(format)); return (struct radv_meta_blit2d_surf) { .format = format, .bs = vk_format_get_blocksize(format), - .level = level, - .layer = layer, + .level = subres->mipLevel, + .layer = subres->baseArrayLayer, .image = image, - .aspect_mask = aspectMask, + .aspect_mask = subres->aspectMask, + .current_layout = layout, }; } @@ -104,17 +107,23 @@ static void meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer, struct radv_buffer* buffer, struct radv_image* image, + VkImageLayout layout, uint32_t regionCount, const VkBufferImageCopy* pRegions) { + bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE; struct radv_meta_saved_state saved_state; /* The Vulkan 1.0 spec says "dstImage must have a sample count equal to * VK_SAMPLE_COUNT_1_BIT." */ - assert(image->samples == 1); + assert(image->info.samples == 1); - radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer); + radv_meta_save(&saved_state, cmd_buffer, + (cs ? RADV_META_SAVE_COMPUTE_PIPELINE : + RADV_META_SAVE_GRAPHICS_PIPELINE) | + RADV_META_SAVE_CONSTANTS | + RADV_META_SAVE_DESCRIPTORS); for (unsigned r = 0; r < regionCount; r++) { @@ -150,9 +159,8 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer, /* Create blit surfaces */ struct radv_meta_blit2d_surf img_bsurf = blit_surf_for_image_level_layer(image, - pRegions[r].imageSubresource.aspectMask, - pRegions[r].imageSubresource.mipLevel, - pRegions[r].imageSubresource.baseArrayLayer); + layout, + &pRegions[r].imageSubresource); struct radv_meta_blit2d_buffer buf_bsurf = { .bs = img_bsurf.bs, @@ -162,6 +170,8 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer, .pitch = buf_extent_el.width, }; + if (image->type == VK_IMAGE_TYPE_3D) + img_bsurf.layer = img_offset_el.z; /* Loop through each 3D or array slice */ unsigned num_slices_3d = img_extent_el.depth; unsigned num_slices_array = pRegions[r].imageSubresource.layerCount; @@ -174,7 +184,10 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer, /* Perform Blit */ - radv_meta_blit2d(cmd_buffer, NULL, &buf_bsurf, &img_bsurf, 1, &rect); + if (cs) + radv_meta_buffer_to_image_cs(cmd_buffer, &buf_bsurf, &img_bsurf, 1, &rect); + else + radv_meta_blit2d(cmd_buffer, NULL, &buf_bsurf, &img_bsurf, 1, &rect); /* Once we've done the blit, all of the actual information about * the image is embedded in the command buffer so we can just @@ -190,6 +203,7 @@ meta_copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer, slice_array++; } } + radv_meta_restore(&saved_state, cmd_buffer); } @@ -205,7 +219,7 @@ void radv_CmdCopyBufferToImage( RADV_FROM_HANDLE(radv_image, dest_image, destImage); RADV_FROM_HANDLE(radv_buffer, src_buffer, srcBuffer); - meta_copy_buffer_to_image(cmd_buffer, src_buffer, dest_image, + meta_copy_buffer_to_image(cmd_buffer, src_buffer, dest_image, destImageLayout, regionCount, pRegions); } @@ -213,12 +227,17 @@ static void meta_copy_image_to_buffer(struct radv_cmd_buffer *cmd_buffer, struct radv_buffer* buffer, struct radv_image* image, + VkImageLayout layout, uint32_t regionCount, const VkBufferImageCopy* pRegions) { - struct radv_meta_saved_compute_state saved_state; + struct radv_meta_saved_state saved_state; + + radv_meta_save(&saved_state, cmd_buffer, + RADV_META_SAVE_COMPUTE_PIPELINE | + RADV_META_SAVE_CONSTANTS | + RADV_META_SAVE_DESCRIPTORS); - radv_meta_begin_bufimage(cmd_buffer, &saved_state); for (unsigned r = 0; r < regionCount; r++) { /** @@ -253,9 +272,9 @@ meta_copy_image_to_buffer(struct radv_cmd_buffer *cmd_buffer, /* Create blit surfaces */ struct radv_meta_blit2d_surf img_info = blit_surf_for_image_level_layer(image, - pRegions[r].imageSubresource.aspectMask, - pRegions[r].imageSubresource.mipLevel, - pRegions[r].imageSubresource.baseArrayLayer); + layout, + &pRegions[r].imageSubresource); + struct radv_meta_blit2d_buffer buf_info = { .bs = img_info.bs, .format = img_info.format, @@ -264,6 +283,8 @@ meta_copy_image_to_buffer(struct radv_cmd_buffer *cmd_buffer, .pitch = buf_extent_el.width, }; + if (image->type == VK_IMAGE_TYPE_3D) + img_info.layer = img_offset_el.z; /* Loop through each 3D or array slice */ unsigned num_slices_3d = img_extent_el.depth; unsigned num_slices_array = pRegions[r].imageSubresource.layerCount; @@ -287,7 +308,8 @@ meta_copy_image_to_buffer(struct radv_cmd_buffer *cmd_buffer, slice_array++; } } - radv_meta_end_bufimage(cmd_buffer, &saved_state); + + radv_meta_restore(&saved_state, cmd_buffer); } void radv_CmdCopyImageToBuffer( @@ -303,16 +325,20 @@ void radv_CmdCopyImageToBuffer( RADV_FROM_HANDLE(radv_buffer, dst_buffer, destBuffer); meta_copy_image_to_buffer(cmd_buffer, dst_buffer, src_image, + srcImageLayout, regionCount, pRegions); } static void meta_copy_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *src_image, + VkImageLayout src_image_layout, struct radv_image *dest_image, + VkImageLayout dest_image_layout, uint32_t regionCount, const VkImageCopy *pRegions) { + bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE; struct radv_meta_saved_state saved_state; /* From the Vulkan 1.0 spec: @@ -320,9 +346,13 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer, * vkCmdCopyImage can be used to copy image data between multisample * images, but both images must have the same number of samples. */ - assert(src_image->samples == dest_image->samples); + assert(src_image->info.samples == dest_image->info.samples); - radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer); + radv_meta_save(&saved_state, cmd_buffer, + (cs ? RADV_META_SAVE_COMPUTE_PIPELINE : + RADV_META_SAVE_GRAPHICS_PIPELINE) | + RADV_META_SAVE_CONSTANTS | + RADV_META_SAVE_DESCRIPTORS); for (unsigned r = 0; r < regionCount; r++) { assert(pRegions[r].srcSubresource.aspectMask == @@ -331,17 +361,39 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer, /* Create blit surfaces */ struct radv_meta_blit2d_surf b_src = blit_surf_for_image_level_layer(src_image, - pRegions[r].srcSubresource.aspectMask, - pRegions[r].srcSubresource.mipLevel, - pRegions[r].srcSubresource.baseArrayLayer); + src_image_layout, + &pRegions[r].srcSubresource); + struct radv_meta_blit2d_surf b_dst = blit_surf_for_image_level_layer(dest_image, - pRegions[r].dstSubresource.aspectMask, - pRegions[r].dstSubresource.mipLevel, - pRegions[r].dstSubresource.baseArrayLayer); + dest_image_layout, + &pRegions[r].dstSubresource); + + uint32_t dst_queue_mask = radv_image_queue_family_mask(dest_image, + cmd_buffer->queue_family_index, + cmd_buffer->queue_family_index); + bool dst_compressed = radv_layout_dcc_compressed(dest_image, dest_image_layout, dst_queue_mask); + uint32_t src_queue_mask = radv_image_queue_family_mask(src_image, + cmd_buffer->queue_family_index, + cmd_buffer->queue_family_index); + bool src_compressed = radv_layout_dcc_compressed(src_image, src_image_layout, src_queue_mask); + + if (!src_compressed || radv_dcc_formats_compatible(b_src.format, b_dst.format)) { + b_src.format = b_dst.format; + } else if (!dst_compressed) { + b_dst.format = b_src.format; + } else { + radv_decompress_dcc(cmd_buffer, dest_image, &(VkImageSubresourceRange) { + .aspectMask = pRegions[r].dstSubresource.aspectMask, + .baseMipLevel = pRegions[r].dstSubresource.mipLevel, + .levelCount = 1, + .baseArrayLayer = pRegions[r].dstSubresource.baseArrayLayer, + .layerCount = pRegions[r].dstSubresource.layerCount, + }); + b_dst.format = b_src.format; + b_dst.current_layout = VK_IMAGE_LAYOUT_GENERAL; + } - /* for DCC */ - b_src.format = b_dst.format; /** * From the Vulkan 1.0.6 spec: 18.4 Copying Data Between Buffers and Images @@ -357,7 +409,7 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer, const VkOffset3D src_offset_el = meta_region_offset_el(src_image, &pRegions[r].srcOffset); const VkExtent3D img_extent_el = - meta_region_extent_el(src_image, &pRegions[r].extent); + meta_region_extent_el(dest_image, &pRegions[r].extent); /* Start creating blit rect */ struct radv_meta_blit2d_rect rect = { @@ -365,6 +417,9 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer, .height = img_extent_el.height, }; + if (dest_image->type == VK_IMAGE_TYPE_3D) + b_dst.layer = dst_offset_el.z; + /* Loop through each 3D or array slice */ unsigned num_slices_3d = img_extent_el.depth; unsigned num_slices_array = pRegions[r].dstSubresource.layerCount; @@ -379,7 +434,10 @@ meta_copy_image(struct radv_cmd_buffer *cmd_buffer, rect.src_y = src_offset_el.y; /* Perform Blit */ - radv_meta_blit2d(cmd_buffer, &b_src, NULL, &b_dst, 1, &rect); + if (cs) + radv_meta_image_to_image_cs(cmd_buffer, &b_src, &b_dst, 1, &rect); + else + radv_meta_blit2d(cmd_buffer, &b_src, NULL, &b_dst, 1, &rect); b_src.layer++; b_dst.layer++; @@ -406,6 +464,29 @@ void radv_CmdCopyImage( RADV_FROM_HANDLE(radv_image, src_image, srcImage); RADV_FROM_HANDLE(radv_image, dest_image, destImage); - meta_copy_image(cmd_buffer, src_image, dest_image, + meta_copy_image(cmd_buffer, + src_image, srcImageLayout, + dest_image, destImageLayout, regionCount, pRegions); } + +void radv_blit_to_prime_linear(struct radv_cmd_buffer *cmd_buffer, + struct radv_image *image, + struct radv_image *linear_image) +{ + struct VkImageCopy image_copy = { 0 }; + + image_copy.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + image_copy.srcSubresource.layerCount = 1; + + image_copy.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + image_copy.dstSubresource.layerCount = 1; + + image_copy.extent.width = image->info.width; + image_copy.extent.height = image->info.height; + image_copy.extent.depth = 1; + + meta_copy_image(cmd_buffer, image, VK_IMAGE_LAYOUT_GENERAL, linear_image, + VK_IMAGE_LAYOUT_GENERAL, + 1, &image_copy); +}