anv/meta: Implement the blitter API functions
authorNanley Chery <nanley.g.chery@intel.com>
Sat, 27 Feb 2016 20:26:21 +0000 (12:26 -0800)
committerNanley Chery <nanley.g.chery@intel.com>
Thu, 3 Mar 2016 19:25:04 +0000 (11:25 -0800)
Most of the code in anv_meta_blit2d() is borrowed from do_buffer_copy().

Create an image and image view for each rectangle.
Note: For tiled RGB images, ISL will align the image's row_pitch up to
the nearest tile width.

v2 (Jason):
    Keep pitch in units of bytes
    Make src_format and dst_format variables
    s/dest/dst/ in every usage
v3: Fix dst_image width

Signed-off-by: Nanley Chery <nanley.g.chery@intel.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
src/intel/vulkan/anv_meta.h
src/intel/vulkan/anv_meta_blit.c

index 952176453e35593f4fce7367132f181f7bb1d911..587c044fa5f0ec9448d5d29b8746fece1cf669f0 100644 (file)
@@ -90,18 +90,18 @@ struct anv_meta_blit2d_rect {
    uint32_t width, height;
 };
 
-static void
+void
 anv_meta_begin_blit2d(struct anv_cmd_buffer *cmd_buffer,
                       struct anv_meta_saved_state *save);
 
-static void
+void
 anv_meta_blit2d(struct anv_cmd_buffer *cmd_buffer,
                 struct anv_meta_blit2d_surf *src,
                 struct anv_meta_blit2d_surf *dst,
                 unsigned num_rects,
                 struct anv_meta_blit2d_rect *rects);
 
-static void
+void
 anv_meta_end_blit2d(struct anv_cmd_buffer *cmd_buffer,
                     struct anv_meta_saved_state *save);
 
index 478b1997172947ceea8bda8ab7d3975e92d1503c..bef66751a7f122dfb15c0026e6910f89a0e15042 100644 (file)
@@ -119,6 +119,14 @@ meta_prepare_blit(struct anv_cmd_buffer *cmd_buffer,
                  (1 << VK_DYNAMIC_STATE_VIEWPORT));
 }
 
+void
+anv_meta_begin_blit2d(struct anv_cmd_buffer *cmd_buffer,
+                      struct anv_meta_saved_state *save)
+{
+   meta_prepare_blit(cmd_buffer, save);
+}
+
+
 /* Returns the user-provided VkBufferImageCopy::imageOffset in units of
  * elements rather than texels. One element equals one texel or one block
  * if Image is uncompressed or compressed, respectively.
@@ -372,6 +380,13 @@ meta_finish_blit(struct anv_cmd_buffer *cmd_buffer,
    anv_meta_restore(saved_state, cmd_buffer);
 }
 
+void
+anv_meta_end_blit2d(struct anv_cmd_buffer *cmd_buffer,
+                    struct anv_meta_saved_state *save)
+{
+   meta_finish_blit(cmd_buffer, save);
+}
+
 static VkFormat
 vk_format_for_size(int bs)
 {
@@ -402,6 +417,133 @@ vk_format_for_size(int bs)
    }
 }
 
+void
+anv_meta_blit2d(struct anv_cmd_buffer *cmd_buffer,
+                struct anv_meta_blit2d_surf *src,
+                struct anv_meta_blit2d_surf *dst,
+                unsigned num_rects,
+                struct anv_meta_blit2d_rect *rects)
+{
+   VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
+   VkFormat src_format = vk_format_for_size(src->bs);
+   VkFormat dst_format = vk_format_for_size(dst->bs);
+
+   for (unsigned r = 0; r < num_rects; ++r) {
+
+      /* Create VkImages */
+      VkImageCreateInfo image_info = {
+         .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+         .imageType = VK_IMAGE_TYPE_2D,
+         .format = 0, /* TEMPLATE */
+         .extent = {
+            .width = 0, /* TEMPLATE */
+            /* Pad to highest tile height to compensate for a vertical intratile offset */
+            .height = MIN(rects[r].height + 64, 1 << 14),
+            .depth = 1,
+         },
+         .mipLevels = 1,
+         .arrayLayers = 1,
+         .samples = 1,
+         .tiling = 0, /* TEMPLATE */
+         .usage = 0, /* TEMPLATE */
+      };
+      struct anv_image_create_info anv_image_info = {
+         .vk_info = &image_info,
+         .isl_tiling_flags = 0, /* TEMPLATE */
+      };
+
+      anv_image_info.isl_tiling_flags = 1 << src->tiling;
+      image_info.tiling = anv_image_info.isl_tiling_flags == ISL_TILING_LINEAR_BIT ?
+                        VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
+      image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
+      image_info.format = src_format,
+      image_info.extent.width = src->pitch / src->bs;
+      VkImage src_image;
+      anv_image_create(vk_device, &anv_image_info,
+                     &cmd_buffer->pool->alloc, &src_image);
+
+      anv_image_info.isl_tiling_flags = 1 << dst->tiling;
+      image_info.tiling = anv_image_info.isl_tiling_flags == ISL_TILING_LINEAR_BIT ?
+                        VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
+      image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+      image_info.format = dst_format,
+      image_info.extent.width = dst->pitch / dst->bs;
+      VkImage dst_image;
+      anv_image_create(vk_device, &anv_image_info,
+                     &cmd_buffer->pool->alloc, &dst_image);
+
+      /* We could use a vk call to bind memory, but that would require
+      * creating a dummy memory object etc. so there's really no point.
+      */
+      anv_image_from_handle(src_image)->bo = src->bo;
+      anv_image_from_handle(src_image)->offset = src->base_offset;
+      anv_image_from_handle(dst_image)->bo = dst->bo;
+      anv_image_from_handle(dst_image)->offset = dst->base_offset;
+
+      /* Create VkImageViews */
+      VkImageViewCreateInfo iview_info = {
+         .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+         .image = 0, /* TEMPLATE */
+         .viewType = VK_IMAGE_VIEW_TYPE_2D,
+         .format = 0, /* TEMPLATE */
+         .subresourceRange = {
+            .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+            .baseMipLevel = 0,
+            .levelCount = 1,
+            .baseArrayLayer = 0,
+            .layerCount = 1
+         },
+      };
+      uint32_t img_o = 0;
+
+      iview_info.image = src_image;
+      iview_info.format = src_format;
+      VkOffset3D src_offset_el = {0};
+      isl_surf_get_image_intratile_offset_el_xy(&cmd_buffer->device->isl_dev,
+                                                &anv_image_from_handle(src_image)->
+                                                   color_surface.isl,
+                                                rects[r].src_x,
+                                                rects[r].src_y,
+                                                &img_o,
+                                                (uint32_t*)&src_offset_el.x,
+                                                (uint32_t*)&src_offset_el.y);
+
+      struct anv_image_view src_iview;
+      anv_image_view_init(&src_iview, cmd_buffer->device,
+         &iview_info, cmd_buffer, img_o, VK_IMAGE_USAGE_SAMPLED_BIT);
+
+      iview_info.image = dst_image;
+      iview_info.format = dst_format;
+      VkOffset3D dst_offset_el = {0};
+      isl_surf_get_image_intratile_offset_el_xy(&cmd_buffer->device->isl_dev,
+                                                &anv_image_from_handle(dst_image)->
+                                                   color_surface.isl,
+                                                rects[r].dst_x,
+                                                rects[r].dst_y,
+                                                &img_o,
+                                                (uint32_t*)&dst_offset_el.x,
+                                                (uint32_t*)&dst_offset_el.y);
+      struct anv_image_view dst_iview;
+      anv_image_view_init(&dst_iview, cmd_buffer->device,
+         &iview_info, cmd_buffer, img_o, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
+
+      /* Perform blit */
+      meta_emit_blit(cmd_buffer,
+                     anv_image_from_handle(src_image),
+                     &src_iview,
+                     src_offset_el,
+                     (VkExtent3D){rects[r].width, rects[r].height, 1},
+                     anv_image_from_handle(dst_image),
+                     &dst_iview,
+                     dst_offset_el,
+                     (VkExtent3D){rects[r].width, rects[r].height, 1},
+                     VK_FILTER_NEAREST);
+
+      anv_DestroyImage(vk_device, src_image, &cmd_buffer->pool->alloc);
+      anv_DestroyImage(vk_device, dst_image, &cmd_buffer->pool->alloc);
+   }
+}
+
 static void
 do_buffer_copy(struct anv_cmd_buffer *cmd_buffer,
                struct anv_bo *src, uint64_t src_offset,