summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNanley Chery <[email protected]>2016-02-27 12:26:21 -0800
committerNanley Chery <[email protected]>2016-03-03 11:25:04 -0800
commit2e9b08b9b89c0cf10cc7ca73fd39380766943283 (patch)
tree769fb10741bd55b1fce2baed66e17fccd62364ea
parent032bf172b48211af8fc892747dc4600fb6595f99 (diff)
anv/meta: Implement the blitter API functions
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 <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]>
-rw-r--r--src/intel/vulkan/anv_meta.h6
-rw-r--r--src/intel/vulkan/anv_meta_blit.c142
2 files changed, 145 insertions, 3 deletions
diff --git a/src/intel/vulkan/anv_meta.h b/src/intel/vulkan/anv_meta.h
index 952176453e3..587c044fa5f 100644
--- a/src/intel/vulkan/anv_meta.h
+++ b/src/intel/vulkan/anv_meta.h
@@ -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);
diff --git a/src/intel/vulkan/anv_meta_blit.c b/src/intel/vulkan/anv_meta_blit.c
index 478b1997172..bef66751a7f 100644
--- a/src/intel/vulkan/anv_meta_blit.c
+++ b/src/intel/vulkan/anv_meta_blit.c
@@ -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,