+ }, cmd_buffer, usage);
+}
+
+struct blit2d_src_temps {
+ VkImage image;
+ struct anv_image_view iview;
+
+ struct anv_buffer buffer;
+ struct anv_buffer_view bview;
+
+ VkDescriptorPool desc_pool;
+ VkDescriptorSet set;
+};
+
+static void
+blit2d_bind_src(struct anv_cmd_buffer *cmd_buffer,
+ struct anv_meta_blit2d_surf *src,
+ enum blit2d_src_type src_type,
+ struct anv_meta_blit2d_rect *rect,
+ struct blit2d_src_temps *tmp)
+{
+ struct anv_device *device = cmd_buffer->device;
+ VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
+
+ if (src_type == BLIT2D_SRC_TYPE_NORMAL) {
+ uint32_t offset = 0;
+ isl_tiling_get_intratile_offset_el(&cmd_buffer->device->isl_dev,
+ src->tiling, src->bs, src->pitch,
+ rect->src_x, rect->src_y,
+ &offset, &rect->src_x, &rect->src_y);
+
+ create_iview(cmd_buffer, src, offset, VK_IMAGE_USAGE_SAMPLED_BIT,
+ rect->src_x + rect->width, rect->src_y + rect->height,
+ &tmp->image, &tmp->iview);
+
+ anv_CreateDescriptorPool(vk_device,
+ &(const VkDescriptorPoolCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
+ .pNext = NULL,
+ .flags = 0,
+ .maxSets = 1,
+ .poolSizeCount = 1,
+ .pPoolSizes = (VkDescriptorPoolSize[]) {
+ {
+ .type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
+ .descriptorCount = 1
+ },
+ }
+ }, &cmd_buffer->pool->alloc, &tmp->desc_pool);
+
+ anv_AllocateDescriptorSets(vk_device,
+ &(VkDescriptorSetAllocateInfo) {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
+ .descriptorPool = tmp->desc_pool,
+ .descriptorSetCount = 1,
+ .pSetLayouts = &device->meta_state.blit2d.img_ds_layout
+ }, &tmp->set);
+
+ anv_UpdateDescriptorSets(vk_device,
+ 1, /* writeCount */
+ (VkWriteDescriptorSet[]) {
+ {
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .dstSet = tmp->set,
+ .dstBinding = 0,
+ .dstArrayElement = 0,
+ .descriptorCount = 1,
+ .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
+ .pImageInfo = (VkDescriptorImageInfo[]) {
+ {
+ .sampler = NULL,
+ .imageView = anv_image_view_to_handle(&tmp->iview),
+ .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
+ },
+ }
+ }
+ }, 0, NULL);
+
+ anv_CmdBindDescriptorSets(anv_cmd_buffer_to_handle(cmd_buffer),
+ VK_PIPELINE_BIND_POINT_GRAPHICS,
+ device->meta_state.blit2d.img_p_layout, 0, 1,
+ &tmp->set, 0, NULL);
+ } else {
+ assert(src_type == BLIT2D_SRC_TYPE_W_DETILE);
+ assert(src->tiling == ISL_TILING_W);
+ assert(src->bs == 1);
+
+ uint32_t tile_offset = 0;
+ isl_tiling_get_intratile_offset_el(&cmd_buffer->device->isl_dev,
+ ISL_TILING_W, 1, src->pitch,
+ rect->src_x, rect->src_y,
+ &tile_offset,
+ &rect->src_x, &rect->src_y);
+
+ tmp->buffer = (struct anv_buffer) {
+ .device = device,
+ .size = align_u32(rect->src_y + rect->height, 64) * src->pitch,
+ .usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
+ .bo = src->bo,
+ .offset = src->base_offset + tile_offset,
+ };
+
+ anv_buffer_view_init(&tmp->bview, device,
+ &(VkBufferViewCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
+ .buffer = anv_buffer_to_handle(&tmp->buffer),
+ .format = VK_FORMAT_R8_UINT,
+ .offset = 0,
+ .range = VK_WHOLE_SIZE,
+ }, cmd_buffer);
+
+ anv_CreateDescriptorPool(vk_device,
+ &(const VkDescriptorPoolCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
+ .pNext = NULL,
+ .flags = 0,
+ .maxSets = 1,
+ .poolSizeCount = 1,
+ .pPoolSizes = (VkDescriptorPoolSize[]) {
+ {
+ .type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
+ .descriptorCount = 1
+ },
+ }
+ }, &cmd_buffer->pool->alloc, &tmp->desc_pool);
+
+ anv_AllocateDescriptorSets(vk_device,
+ &(VkDescriptorSetAllocateInfo) {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
+ .descriptorPool = tmp->desc_pool,
+ .descriptorSetCount = 1,
+ .pSetLayouts = &device->meta_state.blit2d.buf_ds_layout
+ }, &tmp->set);
+
+ anv_UpdateDescriptorSets(vk_device,
+ 1, /* writeCount */
+ (VkWriteDescriptorSet[]) {
+ {
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .dstSet = tmp->set,
+ .dstBinding = 0,
+ .dstArrayElement = 0,
+ .descriptorCount = 1,
+ .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
+ .pTexelBufferView = (VkBufferView[]) {
+ anv_buffer_view_to_handle(&tmp->bview),
+ },
+ }
+ }, 0, NULL);
+
+ anv_CmdBindDescriptorSets(anv_cmd_buffer_to_handle(cmd_buffer),
+ VK_PIPELINE_BIND_POINT_GRAPHICS,
+ device->meta_state.blit2d.buf_p_layout, 0, 1,
+ &tmp->set, 0, NULL);
+ }
+}
+
+static void
+blit2d_unbind_src(struct anv_cmd_buffer *cmd_buffer,
+ enum blit2d_src_type src_type,
+ struct blit2d_src_temps *tmp)
+{
+ anv_DestroyDescriptorPool(anv_device_to_handle(cmd_buffer->device),
+ tmp->desc_pool, &cmd_buffer->pool->alloc);
+ if (src_type == BLIT2D_SRC_TYPE_NORMAL) {
+ anv_DestroyImage(anv_device_to_handle(cmd_buffer->device),
+ tmp->image, &cmd_buffer->pool->alloc);
+ }
+}
+
+struct blit2d_dst_temps {
+ VkImage image;
+ struct anv_image_view iview;
+ VkFramebuffer fb;
+};
+
+static void
+blit2d_bind_dst(struct anv_cmd_buffer *cmd_buffer,
+ struct anv_meta_blit2d_surf *dst,
+ uint64_t offset,
+ uint32_t width,
+ uint32_t height,
+ struct blit2d_dst_temps *tmp)
+{
+ create_iview(cmd_buffer, dst, offset, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+ width, height, &tmp->image, &tmp->iview);
+
+ anv_CreateFramebuffer(anv_device_to_handle(cmd_buffer->device),
+ &(VkFramebufferCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+ .attachmentCount = 1,
+ .pAttachments = (VkImageView[]) {
+ anv_image_view_to_handle(&tmp->iview),
+ },
+ .width = width,
+ .height = height,
+ .layers = 1
+ }, &cmd_buffer->pool->alloc, &tmp->fb);
+}
+
+static void
+blit2d_unbind_dst(struct anv_cmd_buffer *cmd_buffer,
+ struct blit2d_dst_temps *tmp)
+{
+ VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
+ anv_DestroyFramebuffer(vk_device, tmp->fb, &cmd_buffer->pool->alloc);
+ anv_DestroyImage(vk_device, tmp->image, &cmd_buffer->pool->alloc);