<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Sep 12, 2016 at 12:30 PM, Nanley Chery <span dir="ltr"><<a href="mailto:nanleychery@gmail.com" target="_blank">nanleychery@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Wed, Aug 31, 2016 at 02:22:46PM -0700, Jason Ekstrand wrote:<br>
> ---<br>
> src/intel/vulkan/anv_blorp.c | 134 ++++++++++++++++++++++++++++++<wbr>+++++++++<br>
> src/intel/vulkan/anv_meta_<wbr>copy.c | 16 -----<br>
> 2 files changed, 134 insertions(+), 16 deletions(-)<br>
><br>
> diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c<br>
> index 5d715fc..a838b55 100644<br>
> --- a/src/intel/vulkan/anv_blorp.c<br>
> +++ b/src/intel/vulkan/anv_blorp.c<br>
> @@ -120,6 +120,38 @@ anv_device_finish_blorp(struct anv_device *device)<br>
> }<br>
><br>
> static void<br>
> +get_blorp_surf_for_anv_<wbr>buffer(struct anv_device *device,<br>
> + struct anv_buffer *buffer, uint64_t offset,<br>
> + uint32_t width, uint32_t height,<br>
> + uint32_t row_pitch, enum isl_format format,<br>
> + struct blorp_surf *blorp_surf,<br>
> + struct isl_surf *isl_surf)<br>
> +{<br>
> + *blorp_surf = (struct blorp_surf) {<br>
> + .surf = isl_surf,<br>
> + .addr = {<br>
> + .buffer = buffer->bo,<br>
> + .offset = buffer->offset + offset,<br>
> + },<br>
> + };<br>
> +<br>
> + isl_surf_init(&device->isl_<wbr>dev, isl_surf,<br>
> + .dim = ISL_SURF_DIM_2D,<br>
> + .format = format,<br>
> + .width = width,<br>
> + .height = height,<br>
> + .depth = 1,<br>
> + .levels = 1,<br>
> + .array_len = 1,<br>
> + .samples = 1,<br>
> + .min_pitch = row_pitch,<br>
<br>
</div></div>I don't think we want to set the min_pitch field. If ISL creates a<br>
surface with a pitch smaller than the required pitch, I think we'd<br>
want to know about it rather than silently aligning up. If it does<br>
get aligned up I wouldn't be confident that the HW will render or<br>
texture from the image correctly. Just having the assertion would<br>
provide such confidence whoever.<br><div><div class="h5"></div></div></blockquote><div><br></div><div>This is one of the places where the blorp code and the old meta code differ. The blorp code just creates an image with the actual width and height of the copy and pulls the row_pitch from bufferRowLength.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
> + .usage = ISL_SURF_USAGE_TEXTURE_BIT |<br>
> + ISL_SURF_USAGE_RENDER_TARGET_<wbr>BIT,<br>
> + .tiling_flags = ISL_TILING_LINEAR_BIT);<br>
> + assert(isl_surf->row_pitch == row_pitch);<br>
> +}<br>
> +<br>
> +static void<br>
> get_blorp_surf_for_anv_image(<wbr>const struct anv_image *image,<br>
> VkImageAspectFlags aspect,<br>
> struct blorp_surf *blorp_surf)<br>
> @@ -136,6 +168,108 @@ get_blorp_surf_for_anv_image(<wbr>const struct anv_image *image,<br>
> };<br>
> }<br>
><br>
> +static void<br>
> +copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,<br>
> + struct anv_buffer *anv_buffer,<br>
> + struct anv_image *anv_image,<br>
> + uint32_t regionCount,<br>
> + const VkBufferImageCopy* pRegions,<br>
> + bool buffer_to_image)<br>
> +{<br>
> + struct blorp_batch batch;<br>
> + blorp_batch_init(&cmd_buffer-><wbr>device->blorp, &batch, cmd_buffer);<br>
> +<br>
> + struct {<br>
> + struct blorp_surf surf;<br>
> + uint32_t level;<br>
> + VkOffset3D offset;<br>
> + } image, buffer, *src, *dst;<br>
> +<br>
> + buffer.level = 0;<br>
> + buffer.offset = (VkOffset3D) { 0, 0, 0 };<br>
> +<br>
> + if (buffer_to_image) {<br>
> + src = &buffer;<br>
> + dst = ℑ<br>
> + } else {<br>
> + src = ℑ<br>
> + dst = &buffer;<br>
> + }<br>
> +<br>
> + for (unsigned r = 0; r < regionCount; r++) {<br>
> + const VkImageAspectFlags aspect = pRegions[r].imageSubresource.<wbr>aspectMask;<br>
> +<br>
> + get_blorp_surf_for_anv_image(<wbr>anv_image, aspect, &image.surf);<br>
> + image.offset =<br>
> + anv_sanitize_image_offset(anv_<wbr>image->type, pRegions[r].imageOffset);<br>
> + image.level = pRegions[r].imageSubresource.<wbr>mipLevel;<br>
> +<br>
> + VkExtent3D extent =<br>
> + anv_sanitize_image_extent(anv_<wbr>image->type, pRegions[r].imageExtent);<br>
> + if (anv_image->type != VK_IMAGE_TYPE_3D) {<br>
> + image.offset.z = pRegions[r].imageSubresource.<wbr>baseArrayLayer;<br>
> + extent.depth = pRegions[r].imageSubresource.<wbr>layerCount;<br>
> + }<br>
<br>
</div></div>Always making the image 3D is a great idea.<br>
<div><div class="h5"><br>
> +<br>
> + const enum isl_format buffer_format =<br>
> + anv_get_isl_format(&cmd_<wbr>buffer->device->info, anv_image->vk_format,<br>
> + aspect, VK_IMAGE_TILING_LINEAR);<br>
> +<br>
> + const VkExtent3D bufferImageExtent = {<br>
> + .width = pRegions[r].bufferRowLength ?<br>
> + pRegions[r].bufferRowLength : extent.width,<br>
> + .height = pRegions[r].bufferImageHeight ?<br>
> + pRegions[r].bufferImageHeight : extent.height,<br>
> + };<br>
> +<br>
> + const struct isl_format_layout *buffer_fmtl =<br>
> + isl_format_get_layout(buffer_<wbr>format);<br>
> +<br>
> + const uint32_t buffer_row_pitch =<br>
> + DIV_ROUND_UP(<wbr>bufferImageExtent.width, buffer_fmtl->bw) *<br>
> + (buffer_fmtl->bpb / 8);<br>
> +<br>
> + const uint32_t buffer_layer_stride =<br>
> + DIV_ROUND_UP(<wbr>bufferImageExtent.height, buffer_fmtl->bh) *<br>
> + buffer_row_pitch;<br>
> +<br>
> + struct isl_surf buffer_isl_surf;<br>
> + get_blorp_surf_for_anv_buffer(<wbr>cmd_buffer->device,<br>
> + anv_buffer, pRegions[r].bufferOffset,<br>
> + extent.width, extent.height,<br>
> + buffer_row_pitch, buffer_format,<br>
> + &buffer.surf, &buffer_isl_surf);<br>
<br>
</div></div>I think this would be clearer if buffer_isl_surf was a struct local to<br>
get_blorp_surf_for_anv_buffer(<wbr>). It's not used anywhere outside of that<br>
function and it gets initialized from inside it.<br></blockquote><div><br></div><div>That's not possible because blorp_surf has an isl_surf * not an isl_surf. If we created the surface in get_blorp_surf_for_anv_buffer, it would go out-of-scope. Yes, it's kind-of annoying. I fought with myself back-and-forth for a long time as to whether blorp_surf should embed the isl_surf or just have a pointer to one. I settled on pointer. We could change it in the future, but until then, get_blorp_surf_for_* functions will always have to take that annoying isl_surf parameter.<br><br></div><div>--Jason<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
- Nanley<br>
<div><div class="h5"><br>
> +<br>
> + for (unsigned z = 0; z < extent.depth; z++) {<br>
> + blorp_copy(&batch, &src->surf, src->level, src->offset.z,<br>
> + &dst->surf, dst->level, dst->offset.z,<br>
> + src->offset.x, src->offset.y, dst->offset.x, dst->offset.y,<br>
> + extent.width, extent.height);<br>
> +<br>
> + image.offset.z++;<br>
> + buffer.surf.addr.offset += buffer_layer_stride;<br>
> + }<br>
> + }<br>
> +<br>
> + blorp_batch_finish(&batch);<br>
> +}<br>
> +<br>
> +void anv_CmdCopyImageToBuffer(<br>
> + VkCommandBuffer commandBuffer,<br>
> + VkImage srcImage,<br>
> + VkImageLayout srcImageLayout,<br>
> + VkBuffer dstBuffer,<br>
> + uint32_t regionCount,<br>
> + const VkBufferImageCopy* pRegions)<br>
> +{<br>
> + ANV_FROM_HANDLE(anv_cmd_<wbr>buffer, cmd_buffer, commandBuffer);<br>
> + ANV_FROM_HANDLE(anv_image, src_image, srcImage);<br>
> + ANV_FROM_HANDLE(anv_buffer, dst_buffer, dstBuffer);<br>
> +<br>
> + copy_buffer_to_image(cmd_<wbr>buffer, dst_buffer, src_image,<br>
> + regionCount, pRegions, false);<br>
> +}<br>
> +<br>
> static bool<br>
> flip_coords(unsigned *src0, unsigned *src1, unsigned *dst0, unsigned *dst1)<br>
> {<br>
> diff --git a/src/intel/vulkan/anv_meta_<wbr>copy.c b/src/intel/vulkan/anv_meta_<wbr>copy.c<br>
> index 3f548e6..a17dd63 100644<br>
> --- a/src/intel/vulkan/anv_meta_<wbr>copy.c<br>
> +++ b/src/intel/vulkan/anv_meta_<wbr>copy.c<br>
> @@ -232,22 +232,6 @@ void anv_CmdCopyBufferToImage(<br>
> regionCount, pRegions, true);<br>
> }<br>
><br>
> -void anv_CmdCopyImageToBuffer(<br>
> - VkCommandBuffer commandBuffer,<br>
> - VkImage srcImage,<br>
> - VkImageLayout srcImageLayout,<br>
> - VkBuffer destBuffer,<br>
> - uint32_t regionCount,<br>
> - const VkBufferImageCopy* pRegions)<br>
> -{<br>
> - ANV_FROM_HANDLE(anv_cmd_<wbr>buffer, cmd_buffer, commandBuffer);<br>
> - ANV_FROM_HANDLE(anv_image, src_image, srcImage);<br>
> - ANV_FROM_HANDLE(anv_buffer, dst_buffer, destBuffer);<br>
> -<br>
> - meta_copy_buffer_to_image(cmd_<wbr>buffer, dst_buffer, src_image,<br>
> - regionCount, pRegions, false);<br>
> -}<br>
> -<br>
> void anv_CmdCopyImage(<br>
> VkCommandBuffer commandBuffer,<br>
> VkImage srcImage,<br>
> --<br>
> 2.5.0.400.gff86faf<br>
><br>
</div></div>> ______________________________<wbr>_________________<br>
> mesa-dev mailing list<br>
> <a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> <a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</blockquote></div><br></div></div>