<p dir="ltr"></p>
<p dir="ltr">On Sep 12, 2016 1:31 PM, "Nanley Chery" <<a href="mailto:nanleychery@gmail.com">nanleychery@gmail.com</a>> wrote:<br>
><br>
> On Mon, Sep 12, 2016 at 12:45:51PM -0700, Jason Ekstrand wrote:<br>
> > On Mon, Sep 12, 2016 at 12:30 PM, Nanley Chery <<a href="mailto:nanleychery@gmail.com">nanleychery@gmail.com</a>><br>
> > wrote:<br>
> ><br>
> > > On Wed, Aug 31, 2016 at 02:22:46PM -0700, Jason Ekstrand wrote:<br>
> > > > ---<br>
> > > >  src/intel/vulkan/anv_blorp.c     | 134 ++++++++++++++++++++++++++++++<br>
> > > +++++++++<br>
> > > >  src/intel/vulkan/anv_meta_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_buffer(struct anv_device *device,<br>
> > > > +                              struct anv_buffer *buffer, uint64_t<br>
> > > offset,<br>
> > > > +                              uint32_t width, uint32_t height,<br>
> > > > +                              uint32_t row_pitch, enum isl_format<br>
> > > 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_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>
> > > 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>
> > ><br>
> ><br>
> > This is one of the places where the blorp code and the old meta code<br>
> > differ.  The blorp code just creates an image with the actual width and<br>
> > height of the copy and pulls the row_pitch from bufferRowLength.<br>
> ><br>
> ><br>
><br>
> I forgot that bufferRowLength could be greater than the image's<br>
> width * block_size. Using min_pitch is in fact necessary.<br>
><br>
> > > > +                 .usage = ISL_SURF_USAGE_TEXTURE_BIT |<br>
> > > > +                          ISL_SURF_USAGE_RENDER_TARGET_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(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(const struct<br>
> > > 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->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 = &image;<br>
> > > > +   } else {<br>
> > > > +      src = &image;<br>
> > > > +      dst = &buffer;<br>
> > > > +   }<br>
> > > > +<br>
> > > > +   for (unsigned r = 0; r < regionCount; r++) {<br>
> > > > +      const VkImageAspectFlags aspect = pRegions[r].imageSubresource.<br>
> > > aspectMask;<br>
> > > > +<br>
> > > > +      get_blorp_surf_for_anv_image(anv_image, aspect, &image.surf);<br>
> > > > +      image.offset =<br>
> > > > +         anv_sanitize_image_offset(anv_image->type,<br>
> > > pRegions[r].imageOffset);<br>
> > > > +      image.level = pRegions[r].imageSubresource.mipLevel;<br>
> > > > +<br>
> > > > +      VkExtent3D extent =<br>
> > > > +         anv_sanitize_image_extent(anv_image->type,<br>
> > > pRegions[r].imageExtent);<br>
> > > > +      if (anv_image->type != VK_IMAGE_TYPE_3D) {<br>
> > > > +         image.offset.z = pRegions[r].imageSubresource.baseArrayLayer;<br>
> > > > +         extent.depth = pRegions[r].imageSubresource.layerCount;<br>
> > > > +      }<br>
> > ><br>
> > > Always making the image 3D is a great idea.<br>
> > ><br>
> > > > +<br>
> > > > +      const enum isl_format buffer_format =<br>
> > > > +         anv_get_isl_format(&cmd_buffer->device->info,<br>
> > > 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_format);<br>
> > > > +<br>
> > > > +      const uint32_t buffer_row_pitch =<br>
> > > > +         DIV_ROUND_UP(bufferImageExtent.width, buffer_fmtl->bw) *<br>
> > > > +         (buffer_fmtl->bpb / 8);<br>
> > > > +<br>
> > > > +      const uint32_t buffer_layer_stride =<br>
> > > > +         DIV_ROUND_UP(bufferImageExtent.height, buffer_fmtl->bh) *<br>
> > > > +         buffer_row_pitch;<br>
> > > > +<br>
> > > > +      struct isl_surf buffer_isl_surf;<br>
> > > > +      get_blorp_surf_for_anv_buffer(cmd_buffer->device,<br>
> > > > +                                    anv_buffer,<br>
> > > pRegions[r].bufferOffset,<br>
> > > > +                                    extent.width, extent.height,<br>
> > > > +                                    buffer_row_pitch, buffer_format,<br>
> > > > +                                    &buffer.surf, &buffer_isl_surf);<br>
> > ><br>
> > > I think this would be clearer if buffer_isl_surf was a struct local to<br>
> > > get_blorp_surf_for_anv_buffer(). It's not used anywhere outside of that<br>
> > > function and it gets initialized from inside it.<br>
> > ><br>
> ><br>
> > That's not possible because blorp_surf has an isl_surf * not an isl_surf.<br>
> > If we created the surface in get_blorp_surf_for_anv_buffer, it would go<br>
> > out-of-scope.  Yes, it's kind-of annoying.  I fought with myself<br>
> > back-and-forth for a long time as to whether blorp_surf should embed the<br>
> > isl_surf or just have a pointer to one.  I settled on pointer.  We could<br>
> > change it in the future, but until then, get_blorp_surf_for_* functions<br>
> > will always have to take that annoying isl_surf parameter.<br>
> ><br>
><br>
> Ah, got it.<br>
><br>
> Patches 27 and 28 are,<br>
><br>
> Reviewed-by: Nanley Chery <<a href="mailto:nanley.g.chery@intel.com">nanley.g.chery@intel.com</a>></p>
<p dir="ltr">Thanks!</p>
<p dir="ltr">> > --Jason<br>
> ><br>
> ><br>
> > > - Nanley<br>
> > ><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,<br>
> > > 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_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_buffer, dst_buffer, src_image,<br>
> > > > +                        regionCount, pRegions, false);<br>
> > > > +}<br>
> > > > +<br>
> > > >  static bool<br>
> > > >  flip_coords(unsigned *src0, unsigned *src1, unsigned *dst0, unsigned<br>
> > > *dst1)<br>
> > > >  {<br>
> > > > diff --git a/src/intel/vulkan/anv_meta_copy.c<br>
> > > b/src/intel/vulkan/anv_meta_copy.c<br>
> > > > index 3f548e6..a17dd63 100644<br>
> > > > --- a/src/intel/vulkan/anv_meta_copy.c<br>
> > > > +++ b/src/intel/vulkan/anv_meta_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_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_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>
> > > > _______________________________________________<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">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
> > ><br></p>