From 438eaa3ae7f7c79c4362c8900195a1ddeceb1ab0 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Fri, 20 Nov 2015 17:39:06 -0800 Subject: [PATCH] anv/meta: Add initial support for multi-slice array and 3-D copies We still need to fix up a few bits once we have real CPP values, but this should get us a long ways. --- src/vulkan/anv_meta.c | 348 ++++++++++++++++++++++++------------------ 1 file changed, 200 insertions(+), 148 deletions(-) diff --git a/src/vulkan/anv_meta.c b/src/vulkan/anv_meta.c index 5df33c0a8d1..c9e46a9286e 100644 --- a/src/vulkan/anv_meta.c +++ b/src/vulkan/anv_meta.c @@ -869,7 +869,7 @@ void anv_CmdCopyImage( .baseMipLevel = pRegions[r].srcSubresource.mipLevel, .mipLevels = 1, .baseArrayLayer = pRegions[r].srcSubresource.arrayLayer, - .arraySize = 1 + .arraySize = pRegions[r].destSubresource.arraySize, }, }, cmd_buffer); @@ -880,48 +880,59 @@ void anv_CmdCopyImage( .z = 0, }; - const uint32_t dest_array_slice = + unsigned num_slices; + if (src_image->type == VK_IMAGE_TYPE_3D) { + assert(pRegions[r].srcSubresource.arraySize == 1 && + pRegions[r].destSubresource.arraySize == 1); + num_slices = pRegions[r].extent.depth; + } else { + assert(pRegions[r].srcSubresource.arraySize == + pRegions[r].destSubresource.arraySize); + assert(pRegions[r].extent.depth == 1); + num_slices = pRegions[r].destSubresource.arraySize; + } + + const uint32_t dest_base_array_slice = meta_blit_get_dest_view_base_array_slice(dest_image, &pRegions[r].destSubresource, &pRegions[r].destOffset); - if (pRegions[r].srcSubresource.arraySize > 1) - anv_finishme("FINISHME: copy multiple array layers"); - - if (pRegions[r].extent.depth > 1) - anv_finishme("FINISHME: copy multiple depth layers"); - - struct anv_image_view dest_iview; - anv_image_view_init(&dest_iview, cmd_buffer->device, - &(VkImageViewCreateInfo) { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .image = destImage, - .viewType = VK_IMAGE_VIEW_TYPE_2D, - .format = dest_image->format->vk_format, - .channels = { - VK_CHANNEL_SWIZZLE_R, - VK_CHANNEL_SWIZZLE_G, - VK_CHANNEL_SWIZZLE_B, - VK_CHANNEL_SWIZZLE_A - }, - .subresourceRange = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseMipLevel = pRegions[r].destSubresource.mipLevel, - .mipLevels = 1, - .baseArrayLayer = dest_array_slice, - .arraySize = 1 + for (unsigned slice = 0; slice < num_slices; slice++) { + VkOffset3D src_offset = pRegions[r].srcOffset; + src_offset.z += slice; + + struct anv_image_view dest_iview; + anv_image_view_init(&dest_iview, cmd_buffer->device, + &(VkImageViewCreateInfo) { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = destImage, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = dest_image->format->vk_format, + .channels = { + VK_CHANNEL_SWIZZLE_R, + VK_CHANNEL_SWIZZLE_G, + VK_CHANNEL_SWIZZLE_B, + VK_CHANNEL_SWIZZLE_A + }, + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = pRegions[r].destSubresource.mipLevel, + .mipLevels = 1, + .baseArrayLayer = dest_base_array_slice + slice, + .arraySize = 1 + }, }, - }, - cmd_buffer); - - meta_emit_blit(cmd_buffer, - src_image, &src_iview, - pRegions[r].srcOffset, - pRegions[r].extent, - dest_image, &dest_iview, - dest_offset, - pRegions[r].extent, - VK_TEX_FILTER_NEAREST); + cmd_buffer); + + meta_emit_blit(cmd_buffer, + src_image, &src_iview, + src_offset, + pRegions[r].extent, + dest_image, &dest_iview, + dest_offset, + pRegions[r].extent, + VK_TEX_FILTER_NEAREST); + } } meta_finish_blit(cmd_buffer, &saved_state); @@ -1028,9 +1039,10 @@ void anv_CmdBlitImage( meta_finish_blit(cmd_buffer, &saved_state); } -static VkImage +static struct anv_image * make_image_for_buffer(VkDevice vk_device, VkBuffer vk_buffer, VkFormat format, VkImageUsageFlags usage, + VkImageType image_type, const VkBufferImageCopy *copy) { ANV_FROM_HANDLE(anv_buffer, buffer, vk_buffer); @@ -1066,7 +1078,7 @@ make_image_for_buffer(VkDevice vk_device, VkBuffer vk_buffer, VkFormat format, image->bo = buffer->bo; image->offset = buffer->offset + copy->bufferOffset; - return anv_image_to_handle(image); + return image; } void anv_CmdCopyBufferToImage( @@ -1094,81 +1106,102 @@ void anv_CmdCopyBufferToImage( proxy_aspect = VK_IMAGE_ASPECT_COLOR; } - VkImage srcImage = make_image_for_buffer(vk_device, srcBuffer, - proxy_format, VK_IMAGE_USAGE_SAMPLED_BIT, &pRegions[r]); - - struct anv_image_view src_iview; - anv_image_view_init(&src_iview, cmd_buffer->device, - &(VkImageViewCreateInfo) { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .image = srcImage, - .viewType = VK_IMAGE_VIEW_TYPE_2D, - .format = proxy_format, - .channels = { - VK_CHANNEL_SWIZZLE_R, - VK_CHANNEL_SWIZZLE_G, - VK_CHANNEL_SWIZZLE_B, - VK_CHANNEL_SWIZZLE_A - }, - .subresourceRange = { - .aspectMask = 1 << proxy_aspect, - .baseMipLevel = 0, - .mipLevels = 1, - .baseArrayLayer = 0, - .arraySize = 1 - }, - }, - cmd_buffer); + struct anv_image *src_image = + make_image_for_buffer(vk_device, srcBuffer, proxy_format, + VK_IMAGE_USAGE_SAMPLED_BIT, + dest_image->type, &pRegions[r]); - const VkOffset3D dest_offset = { - .x = pRegions[r].imageOffset.x, - .y = pRegions[r].imageOffset.y, - .z = 0, - }; - - const uint32_t dest_array_slice = + const uint32_t dest_base_array_slice = meta_blit_get_dest_view_base_array_slice(dest_image, &pRegions[r].imageSubresource, &pRegions[r].imageOffset); - if (pRegions[r].imageExtent.depth > 1) - anv_finishme("FINISHME: copy multiple depth layers"); + unsigned num_slices; + if (dest_image->type == VK_IMAGE_TYPE_3D) { + assert(pRegions[r].imageSubresource.arraySize == 1); + num_slices = pRegions[r].imageExtent.depth; + } else { + assert(pRegions[r].imageExtent.depth == 1); + num_slices = pRegions[r].imageSubresource.arraySize; + } - struct anv_image_view dest_iview; - anv_image_view_init(&dest_iview, cmd_buffer->device, - &(VkImageViewCreateInfo) { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .image = anv_image_to_handle(dest_image), - .viewType = VK_IMAGE_VIEW_TYPE_2D, - .format = proxy_format, - .channels = { - VK_CHANNEL_SWIZZLE_R, - VK_CHANNEL_SWIZZLE_G, - VK_CHANNEL_SWIZZLE_B, - VK_CHANNEL_SWIZZLE_A + for (unsigned slice = 0; slice < num_slices; slice++) { + struct anv_image_view src_iview; + anv_image_view_init(&src_iview, cmd_buffer->device, + &(VkImageViewCreateInfo) { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = anv_image_to_handle(src_image), + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = proxy_format, + .channels = { + VK_CHANNEL_SWIZZLE_R, + VK_CHANNEL_SWIZZLE_G, + VK_CHANNEL_SWIZZLE_B, + VK_CHANNEL_SWIZZLE_A + }, + .subresourceRange = { + .aspectMask = 1 << proxy_aspect, + .baseMipLevel = 0, + .mipLevels = 1, + .baseArrayLayer = 0, + .arraySize = 1, + }, }, - .subresourceRange = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseMipLevel = pRegions[r].imageSubresource.mipLevel, - .mipLevels = 1, - .baseArrayLayer = dest_array_slice, - .arraySize = 1 + cmd_buffer); + + struct anv_image_view dest_iview; + anv_image_view_init(&dest_iview, cmd_buffer->device, + &(VkImageViewCreateInfo) { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = anv_image_to_handle(dest_image), + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = proxy_format, + .channels = { + VK_CHANNEL_SWIZZLE_R, + VK_CHANNEL_SWIZZLE_G, + VK_CHANNEL_SWIZZLE_B, + VK_CHANNEL_SWIZZLE_A + }, + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = pRegions[r].imageSubresource.mipLevel, + .mipLevels = 1, + .baseArrayLayer = dest_base_array_slice + slice, + .arraySize = 1 + }, }, - }, - cmd_buffer); - - meta_emit_blit(cmd_buffer, - anv_image_from_handle(srcImage), - &src_iview, - (VkOffset3D) { 0, 0, 0 }, - pRegions[r].imageExtent, - dest_image, - &dest_iview, - dest_offset, - pRegions[r].imageExtent, - VK_TEX_FILTER_NEAREST); + cmd_buffer); + + VkOffset3D src_offset = { 0, 0, slice }; + + const VkOffset3D dest_offset = { + .x = pRegions[r].imageOffset.x, + .y = pRegions[r].imageOffset.y, + .z = 0, + }; + + meta_emit_blit(cmd_buffer, + src_image, + &src_iview, + src_offset, + pRegions[r].imageExtent, + dest_image, + &dest_iview, + dest_offset, + pRegions[r].imageExtent, + VK_TEX_FILTER_NEAREST); + + /* Once we've done the blit, all of the actual information about + * the image is embedded in the command buffer so we can just + * increment the offset directly in the image effectively + * re-binding it to different backing memory. + */ + /* XXX: Insert a real CPP */ + src_image->offset += src_image->extent.width * + src_image->extent.height * 4; + } - anv_DestroyImage(vk_device, srcImage); + anv_DestroyImage(vk_device, anv_image_to_handle(src_image)); } meta_finish_blit(cmd_buffer, &saved_state); @@ -1193,12 +1226,6 @@ void anv_CmdCopyImageToBuffer( meta_prepare_blit(cmd_buffer, &saved_state); for (unsigned r = 0; r < regionCount; r++) { - if (pRegions[r].imageSubresource.arraySize > 1) - anv_finishme("FINISHME: copy multiple array layers"); - - if (pRegions[r].imageExtent.depth > 1) - anv_finishme("FINISHME: copy multiple depth layers"); - struct anv_image_view src_iview; anv_image_view_init(&src_iview, cmd_buffer->device, &(VkImageViewCreateInfo) { @@ -1217,7 +1244,7 @@ void anv_CmdCopyImageToBuffer( .baseMipLevel = pRegions[r].imageSubresource.mipLevel, .mipLevels = 1, .baseArrayLayer = pRegions[r].imageSubresource.arrayLayer, - .arraySize = 1 + .arraySize = pRegions[r].imageSubresource.arraySize, }, }, cmd_buffer); @@ -1227,44 +1254,69 @@ void anv_CmdCopyImageToBuffer( dest_format = VK_FORMAT_R8_UINT; } - VkImage destImage = make_image_for_buffer(vk_device, destBuffer, - dest_format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, &pRegions[r]); + struct anv_image *dest_image = + make_image_for_buffer(vk_device, destBuffer, dest_format, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + src_image->type, &pRegions[r]); + + unsigned num_slices; + if (src_image->type == VK_IMAGE_TYPE_3D) { + assert(pRegions[r].imageSubresource.arraySize == 1); + num_slices = pRegions[r].imageExtent.depth; + } else { + assert(pRegions[r].imageExtent.depth == 1); + num_slices = pRegions[r].imageSubresource.arraySize; + } - struct anv_image_view dest_iview; - anv_image_view_init(&dest_iview, cmd_buffer->device, - &(VkImageViewCreateInfo) { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .image = destImage, - .viewType = VK_IMAGE_VIEW_TYPE_2D, - .format = dest_format, - .channels = { - VK_CHANNEL_SWIZZLE_R, - VK_CHANNEL_SWIZZLE_G, - VK_CHANNEL_SWIZZLE_B, - VK_CHANNEL_SWIZZLE_A - }, - .subresourceRange = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseMipLevel = 0, - .mipLevels = 1, - .baseArrayLayer = 0, - .arraySize = 1 + for (unsigned slice = 0; slice < num_slices; slice++) { + VkOffset3D src_offset = pRegions[r].imageOffset; + src_offset.z += slice; + + struct anv_image_view dest_iview; + anv_image_view_init(&dest_iview, cmd_buffer->device, + &(VkImageViewCreateInfo) { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = anv_image_to_handle(dest_image), + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = dest_format, + .channels = { + VK_CHANNEL_SWIZZLE_R, + VK_CHANNEL_SWIZZLE_G, + VK_CHANNEL_SWIZZLE_B, + VK_CHANNEL_SWIZZLE_A + }, + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .mipLevels = 1, + .baseArrayLayer = 0, + .arraySize = 1 + }, }, - }, - cmd_buffer); + cmd_buffer); + + meta_emit_blit(cmd_buffer, + anv_image_from_handle(srcImage), + &src_iview, + src_offset, + pRegions[r].imageExtent, + dest_image, + &dest_iview, + (VkOffset3D) { 0, 0, 0 }, + pRegions[r].imageExtent, + VK_TEX_FILTER_NEAREST); + + /* Once we've done the blit, all of the actual information about + * the image is embedded in the command buffer so we can just + * increment the offset directly in the image effectively + * re-binding it to different backing memory. + */ + /* XXX: Insert a real CPP */ + dest_image->offset += dest_image->extent.width * + dest_image->extent.height * 4; + } - meta_emit_blit(cmd_buffer, - anv_image_from_handle(srcImage), - &src_iview, - pRegions[r].imageOffset, - pRegions[r].imageExtent, - anv_image_from_handle(destImage), - &dest_iview, - (VkOffset3D) { 0, 0, 0 }, - pRegions[r].imageExtent, - VK_TEX_FILTER_NEAREST); - - anv_DestroyImage(vk_device, destImage); + anv_DestroyImage(vk_device, anv_image_to_handle(dest_image)); } meta_finish_blit(cmd_buffer, &saved_state); -- 2.30.2