From: Jason Ekstrand Date: Sun, 28 Aug 2016 04:05:13 +0000 (-0700) Subject: anv: Use blorp for CopyImage X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0f1ca5407abcbfb40627068a8efdae54f2ada5ad;p=mesa.git anv: Use blorp for CopyImage Signed-off-by: Jason Ekstrand Reviewed-by: Anuj Phogat Reviewed-by: Nanley Chery --- diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c index 5fa6699e9fe..23ebc429bf3 100644 --- a/src/intel/vulkan/anv_blorp.c +++ b/src/intel/vulkan/anv_blorp.c @@ -168,6 +168,73 @@ get_blorp_surf_for_anv_image(const struct anv_image *image, }; } +void anv_CmdCopyImage( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageCopy* pRegions) +{ + ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); + ANV_FROM_HANDLE(anv_image, src_image, srcImage); + ANV_FROM_HANDLE(anv_image, dst_image, dstImage); + + struct blorp_batch batch; + blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer); + + for (unsigned r = 0; r < regionCount; r++) { + VkOffset3D srcOffset = + anv_sanitize_image_offset(src_image->type, pRegions[r].srcOffset); + VkOffset3D dstOffset = + anv_sanitize_image_offset(dst_image->type, pRegions[r].dstOffset); + VkExtent3D extent = + anv_sanitize_image_extent(src_image->type, pRegions[r].extent); + + unsigned dst_base_layer, layer_count; + if (dst_image->type == VK_IMAGE_TYPE_3D) { + dst_base_layer = pRegions[r].dstOffset.z; + layer_count = pRegions[r].extent.depth; + } else { + dst_base_layer = pRegions[r].dstSubresource.baseArrayLayer; + layer_count = pRegions[r].dstSubresource.layerCount; + } + + unsigned src_base_layer; + if (src_image->type == VK_IMAGE_TYPE_3D) { + src_base_layer = pRegions[r].srcOffset.z; + } else { + src_base_layer = pRegions[r].srcSubresource.baseArrayLayer; + assert(pRegions[r].srcSubresource.layerCount == layer_count); + } + + assert(pRegions[r].srcSubresource.aspectMask == + pRegions[r].dstSubresource.aspectMask); + + uint32_t a; + for_each_bit(a, pRegions[r].dstSubresource.aspectMask) { + VkImageAspectFlagBits aspect = (1 << a); + + struct blorp_surf src_surf, dst_surf; + get_blorp_surf_for_anv_image(src_image, aspect, &src_surf); + get_blorp_surf_for_anv_image(dst_image, aspect, &dst_surf); + + for (unsigned i = 0; i < layer_count; i++) { + blorp_copy(&batch, &src_surf, pRegions[r].srcSubresource.mipLevel, + src_base_layer + i, + &dst_surf, pRegions[r].dstSubresource.mipLevel, + dst_base_layer + i, + srcOffset.x, srcOffset.y, + dstOffset.x, dstOffset.y, + extent.width, extent.height); + } + } + } + + blorp_batch_finish(&batch); +} + static void copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer, struct anv_buffer *anv_buffer, diff --git a/src/intel/vulkan/anv_meta_copy.c b/src/intel/vulkan/anv_meta_copy.c index 5df04e6cea9..b33273e1e38 100644 --- a/src/intel/vulkan/anv_meta_copy.c +++ b/src/intel/vulkan/anv_meta_copy.c @@ -23,63 +23,6 @@ #include "anv_meta.h" -static VkExtent3D -meta_image_block_size(const struct anv_image *image) -{ - if (image->aspects == VK_IMAGE_ASPECT_COLOR_BIT) { - const struct isl_format_layout *isl_layout = - isl_format_get_layout(image->color_surface.isl.format); - return (VkExtent3D) { isl_layout->bw, isl_layout->bh, isl_layout->bd }; - } else { - return (VkExtent3D) { 1, 1, 1 }; - } -} - -/* Returns the user-provided VkBufferImageCopy::imageExtent in units of - * elements rather than texels. One element equals one texel or one block - * if Image is uncompressed or compressed, respectively. - */ -static struct VkExtent3D -meta_region_extent_el(const struct anv_image *image, - const struct VkExtent3D *extent) -{ - const VkExtent3D block = meta_image_block_size(image); - return anv_sanitize_image_extent(image->type, (VkExtent3D) { - .width = DIV_ROUND_UP(extent->width , block.width), - .height = DIV_ROUND_UP(extent->height, block.height), - .depth = DIV_ROUND_UP(extent->depth , block.depth), - }); -} - -/* Returns the user-provided VkBufferImageCopy::imageOffset in units of - * elements rather than texels. One element equals one texel or one block - * if Image is uncompressed or compressed, respectively. - */ -static struct VkOffset3D -meta_region_offset_el(const struct anv_image *image, - const struct VkOffset3D *offset) -{ - const VkExtent3D block = meta_image_block_size(image); - return anv_sanitize_image_offset(image->type, (VkOffset3D) { - .x = offset->x / block.width, - .y = offset->y / block.height, - .z = offset->z / block.depth, - }); -} - -static struct anv_meta_blit2d_surf -blit_surf_for_image(const struct anv_image* image, - const struct anv_surface *surf) -{ - return (struct anv_meta_blit2d_surf) { - .bo = image->bo, - .tiling = surf->isl.tiling, - .base_offset = image->offset + surf->offset, - .bs = isl_format_get_layout(surf->isl.format)->bpb / 8, - .pitch = isl_surf_get_row_pitch(&surf->isl), - }; -} - static void do_buffer_copy(struct anv_cmd_buffer *cmd_buffer, struct anv_bo *src, uint64_t src_offset, @@ -107,107 +50,6 @@ do_buffer_copy(struct anv_cmd_buffer *cmd_buffer, anv_meta_blit2d(cmd_buffer, &b_src, &b_dst, 1, &rect); } -void anv_CmdCopyImage( - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage destImage, - VkImageLayout destImageLayout, - uint32_t regionCount, - const VkImageCopy* pRegions) -{ - ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); - ANV_FROM_HANDLE(anv_image, src_image, srcImage); - ANV_FROM_HANDLE(anv_image, dest_image, destImage); - struct anv_meta_saved_state saved_state; - - /* From the Vulkan 1.0 spec: - * - * 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); - - anv_meta_begin_blit2d(cmd_buffer, &saved_state); - - for (unsigned r = 0; r < regionCount; r++) { - assert(pRegions[r].srcSubresource.aspectMask == - pRegions[r].dstSubresource.aspectMask); - - VkImageAspectFlags aspect = pRegions[r].srcSubresource.aspectMask; - - /* Create blit surfaces */ - const struct anv_surface *src_surf = - anv_image_get_surface_for_aspect_mask(src_image, aspect); - const struct anv_surface *dst_surf = - anv_image_get_surface_for_aspect_mask(dest_image, aspect); - struct anv_meta_blit2d_surf b_src = - blit_surf_for_image(src_image, src_surf); - struct anv_meta_blit2d_surf b_dst = - blit_surf_for_image(dest_image, dst_surf); - - /** - * From the Vulkan 1.0.6 spec: 18.4 Copying Data Between Buffers and Images - * imageExtent is the size in texels of the image to copy in width, height - * and depth. 1D images use only x and width. 2D images use x, y, width - * and height. 3D images use x, y, z, width, height and depth. - * - * Also, convert the offsets and extent from units of texels to units of - * blocks - which is the highest resolution accessible in this command. - */ - const VkOffset3D dst_offset_el = - meta_region_offset_el(dest_image, &pRegions[r].dstOffset); - 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); - - /* Start creating blit rect */ - struct anv_meta_blit2d_rect rect = { - .width = img_extent_el.width, - .height = img_extent_el.height, - }; - - /* Loop through each 3D or array slice */ - unsigned num_slices_3d = img_extent_el.depth; - unsigned num_slices_array = pRegions[r].dstSubresource.layerCount; - unsigned slice_3d = 0; - unsigned slice_array = 0; - while (slice_3d < num_slices_3d && slice_array < num_slices_array) { - - /* Finish creating blit rect */ - isl_surf_get_image_offset_el(&dst_surf->isl, - pRegions[r].dstSubresource.mipLevel, - pRegions[r].dstSubresource.baseArrayLayer - + slice_array, - dst_offset_el.z + slice_3d, - &rect.dst_x, - &rect.dst_y); - isl_surf_get_image_offset_el(&src_surf->isl, - pRegions[r].srcSubresource.mipLevel, - pRegions[r].srcSubresource.baseArrayLayer - + slice_array, - src_offset_el.z + slice_3d, - &rect.src_x, - &rect.src_y); - rect.dst_x += dst_offset_el.x; - rect.dst_y += dst_offset_el.y; - rect.src_x += src_offset_el.x; - rect.src_y += src_offset_el.y; - - /* Perform Blit */ - anv_meta_blit2d(cmd_buffer, &b_src, &b_dst, 1, &rect); - - if (dest_image->type == VK_IMAGE_TYPE_3D) - slice_3d++; - else - slice_array++; - } - } - - anv_meta_end_blit2d(cmd_buffer, &saved_state); -} - void anv_CmdCopyBuffer( VkCommandBuffer commandBuffer, VkBuffer srcBuffer,