anv: Use blorp for CopyImageToBuffer

Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com>
Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
This commit is contained in:
Jason Ekstrand 2016-08-23 20:19:57 -07:00
parent 9f44745eca
commit f07f44a5bc
2 changed files with 134 additions and 16 deletions

View file

@ -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 = &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)
{

View file

@ -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,