From: Jason Ekstrand Date: Wed, 24 Aug 2016 03:19:57 +0000 (-0700) Subject: anv: Use blorp for CopyImageToBuffer X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f07f44a5bc092f4a8fbef772de2c4af224094b01;p=mesa.git anv: Use blorp for CopyImageToBuffer 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 5d715fca26d..a838b55bfe0 100644 --- a/src/intel/vulkan/anv_blorp.c +++ b/src/intel/vulkan/anv_blorp.c @@ -119,6 +119,38 @@ anv_device_finish_blorp(struct anv_device *device) anv_pipeline_cache_finish(&device->blorp_shader_cache); } +static void +get_blorp_surf_for_anv_buffer(struct anv_device *device, + struct anv_buffer *buffer, uint64_t offset, + uint32_t width, uint32_t height, + uint32_t row_pitch, enum isl_format format, + struct blorp_surf *blorp_surf, + struct isl_surf *isl_surf) +{ + *blorp_surf = (struct blorp_surf) { + .surf = isl_surf, + .addr = { + .buffer = buffer->bo, + .offset = buffer->offset + offset, + }, + }; + + isl_surf_init(&device->isl_dev, isl_surf, + .dim = ISL_SURF_DIM_2D, + .format = format, + .width = width, + .height = height, + .depth = 1, + .levels = 1, + .array_len = 1, + .samples = 1, + .min_pitch = row_pitch, + .usage = ISL_SURF_USAGE_TEXTURE_BIT | + ISL_SURF_USAGE_RENDER_TARGET_BIT, + .tiling_flags = ISL_TILING_LINEAR_BIT); + assert(isl_surf->row_pitch == row_pitch); +} + static void get_blorp_surf_for_anv_image(const struct anv_image *image, VkImageAspectFlags aspect, @@ -136,6 +168,108 @@ get_blorp_surf_for_anv_image(const struct anv_image *image, }; } +static void +copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer, + struct anv_buffer *anv_buffer, + struct anv_image *anv_image, + uint32_t regionCount, + const VkBufferImageCopy* pRegions, + bool buffer_to_image) +{ + struct blorp_batch batch; + blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer); + + struct { + struct blorp_surf surf; + uint32_t level; + VkOffset3D offset; + } image, buffer, *src, *dst; + + buffer.level = 0; + buffer.offset = (VkOffset3D) { 0, 0, 0 }; + + if (buffer_to_image) { + src = &buffer; + dst = ℑ + } else { + src = ℑ + dst = &buffer; + } + + for (unsigned r = 0; r < regionCount; r++) { + const VkImageAspectFlags aspect = pRegions[r].imageSubresource.aspectMask; + + get_blorp_surf_for_anv_image(anv_image, aspect, &image.surf); + image.offset = + anv_sanitize_image_offset(anv_image->type, pRegions[r].imageOffset); + image.level = pRegions[r].imageSubresource.mipLevel; + + VkExtent3D extent = + anv_sanitize_image_extent(anv_image->type, pRegions[r].imageExtent); + if (anv_image->type != VK_IMAGE_TYPE_3D) { + image.offset.z = pRegions[r].imageSubresource.baseArrayLayer; + extent.depth = pRegions[r].imageSubresource.layerCount; + } + + const enum isl_format buffer_format = + anv_get_isl_format(&cmd_buffer->device->info, anv_image->vk_format, + aspect, VK_IMAGE_TILING_LINEAR); + + const VkExtent3D bufferImageExtent = { + .width = pRegions[r].bufferRowLength ? + pRegions[r].bufferRowLength : extent.width, + .height = pRegions[r].bufferImageHeight ? + pRegions[r].bufferImageHeight : extent.height, + }; + + const struct isl_format_layout *buffer_fmtl = + isl_format_get_layout(buffer_format); + + const uint32_t buffer_row_pitch = + DIV_ROUND_UP(bufferImageExtent.width, buffer_fmtl->bw) * + (buffer_fmtl->bpb / 8); + + const uint32_t buffer_layer_stride = + DIV_ROUND_UP(bufferImageExtent.height, buffer_fmtl->bh) * + buffer_row_pitch; + + struct isl_surf buffer_isl_surf; + get_blorp_surf_for_anv_buffer(cmd_buffer->device, + anv_buffer, pRegions[r].bufferOffset, + extent.width, extent.height, + buffer_row_pitch, buffer_format, + &buffer.surf, &buffer_isl_surf); + + for (unsigned z = 0; z < extent.depth; z++) { + blorp_copy(&batch, &src->surf, src->level, src->offset.z, + &dst->surf, dst->level, dst->offset.z, + src->offset.x, src->offset.y, dst->offset.x, dst->offset.y, + extent.width, extent.height); + + image.offset.z++; + buffer.surf.addr.offset += buffer_layer_stride; + } + } + + blorp_batch_finish(&batch); +} + +void anv_CmdCopyImageToBuffer( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferImageCopy* pRegions) +{ + ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); + ANV_FROM_HANDLE(anv_image, src_image, srcImage); + ANV_FROM_HANDLE(anv_buffer, dst_buffer, dstBuffer); + + copy_buffer_to_image(cmd_buffer, dst_buffer, src_image, + regionCount, pRegions, false); +} + static bool flip_coords(unsigned *src0, unsigned *src1, unsigned *dst0, unsigned *dst1) { diff --git a/src/intel/vulkan/anv_meta_copy.c b/src/intel/vulkan/anv_meta_copy.c index 3f548e69867..a17dd639502 100644 --- a/src/intel/vulkan/anv_meta_copy.c +++ b/src/intel/vulkan/anv_meta_copy.c @@ -232,22 +232,6 @@ void anv_CmdCopyBufferToImage( regionCount, pRegions, true); } -void anv_CmdCopyImageToBuffer( - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkBuffer destBuffer, - uint32_t regionCount, - const VkBufferImageCopy* pRegions) -{ - ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); - ANV_FROM_HANDLE(anv_image, src_image, srcImage); - ANV_FROM_HANDLE(anv_buffer, dst_buffer, destBuffer); - - meta_copy_buffer_to_image(cmd_buffer, dst_buffer, src_image, - regionCount, pRegions, false); -} - void anv_CmdCopyImage( VkCommandBuffer commandBuffer, VkImage srcImage,