From 2e9b08b9b89c0cf10cc7ca73fd39380766943283 Mon Sep 17 00:00:00 2001 From: Nanley Chery Date: Sat, 27 Feb 2016 12:26:21 -0800 Subject: [PATCH] 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 Reviewed-by: Jason Ekstrand --- src/intel/vulkan/anv_meta.h | 6 +- src/intel/vulkan/anv_meta_blit.c | 142 +++++++++++++++++++++++++++++++ 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, -- 2.30.2