summaryrefslogtreecommitdiffstats
path: root/src/intel
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2016-08-23 20:19:57 -0700
committerJason Ekstrand <[email protected]>2016-09-13 12:40:12 -0700
commitf07f44a5bc092f4a8fbef772de2c4af224094b01 (patch)
tree7b9dfe8ab30da57bdb8f985bd996b744fd178125 /src/intel
parent9f44745eca0e41de9dc62a6e1ea0b4bf5b0db240 (diff)
anv: Use blorp for CopyImageToBuffer
Signed-off-by: Jason Ekstrand <[email protected]> Reviewed-by: Anuj Phogat <[email protected]> Reviewed-by: Nanley Chery <[email protected]>
Diffstat (limited to 'src/intel')
-rw-r--r--src/intel/vulkan/anv_blorp.c134
-rw-r--r--src/intel/vulkan/anv_meta_copy.c16
2 files changed, 134 insertions, 16 deletions
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
@@ -120,6 +120,38 @@ anv_device_finish_blorp(struct anv_device *device)
}
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,
struct blorp_surf *blorp_surf)
@@ -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 = &image;
+ } else {
+ src = &image;
+ 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,