vk/meta: Use the biggest format possible for buffer copies

This should substantially improve throughput of buffer copies.
This commit is contained in:
Jason Ekstrand
2015-05-20 15:38:11 -07:00
parent 13719e9225
commit 9557b85e3d
+50 -8
View File
@@ -627,6 +627,23 @@ meta_finish_blit(struct anv_cmd_buffer *cmd_buffer,
anv_cmd_buffer_restore(cmd_buffer, saved_state);
}
static VkFormat
vk_format_for_cpp(int cpp)
{
switch (cpp) {
case 1: return VK_FORMAT_R8_UINT;
case 2: return VK_FORMAT_R8G8_UINT;
case 3: return VK_FORMAT_R8G8B8_UINT;
case 4: return VK_FORMAT_R8G8B8A8_UINT;
case 6: return VK_FORMAT_R16G16B16_UINT;
case 8: return VK_FORMAT_R16G16B16A16_UINT;
case 12: return VK_FORMAT_R32G32B32_UINT;
case 16: return VK_FORMAT_R32G32B32A32_UINT;
default:
unreachable("Invalid format cpp");
}
}
void anv_CmdCopyBuffer(
VkCmdBuffer cmdBuffer,
VkBuffer srcBuffer,
@@ -643,12 +660,37 @@ void anv_CmdCopyBuffer(
meta_prepare_blit(cmd_buffer, &saved_state);
for (unsigned r = 0; r < regionCount; r++) {
size_t src_offset = src_buffer->offset + pRegions[r].srcOffset;
size_t dest_offset = dest_buffer->offset + pRegions[r].destOffset;
/* First, we compute the biggest format that can be used with the
* given offsets and size.
*/
int cpp = 16;
int fs = ffs(src_offset) - 1;
if (fs != -1)
cpp = MIN2(cpp, 1 << fs);
assert(src_offset % cpp == 0);
fs = ffs(dest_offset) - 1;
if (fs != -1)
cpp = MIN2(cpp, 1 << fs);
assert(dest_offset % cpp == 0);
fs = ffs(pRegions[r].copySize) - 1;
if (fs != -1)
cpp = MIN2(cpp, 1 << fs);
assert(pRegions[r].copySize % cpp == 0);
VkFormat copy_format = vk_format_for_cpp(cpp);
VkImageCreateInfo image_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.imageType = VK_IMAGE_TYPE_2D,
.format = VK_FORMAT_R8_UNORM,
.format = copy_format,
.extent = {
.width = pRegions[r].copySize,
.width = pRegions[r].copySize / cpp,
.height = 1,
.depth = 1,
},
@@ -668,9 +710,9 @@ void anv_CmdCopyBuffer(
* creating a dummy memory object etc. so there's really no point.
*/
src_image->bo = src_buffer->bo;
src_image->offset = src_buffer->offset + pRegions[r].srcOffset;
src_image->offset = src_offset;
dest_image->bo = dest_buffer->bo;
dest_image->offset = dest_buffer->offset + pRegions[r].destOffset;
dest_image->offset = dest_offset;
struct anv_surface_view src_view;
anv_image_view_init(&src_view, cmd_buffer->device,
@@ -678,7 +720,7 @@ void anv_CmdCopyBuffer(
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = (VkImage)src_image,
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = VK_FORMAT_R8_UNORM,
.format = copy_format,
.channels = {
VK_CHANNEL_SWIZZLE_R,
VK_CHANNEL_SWIZZLE_G,
@@ -701,7 +743,7 @@ void anv_CmdCopyBuffer(
&(VkColorAttachmentViewCreateInfo) {
.sType = VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO,
.image = (VkImage)dest_image,
.format = VK_FORMAT_R8_UNORM,
.format = copy_format,
.mipLevel = 0,
.baseArraySlice = 0,
.arraySize = 1,
@@ -711,10 +753,10 @@ void anv_CmdCopyBuffer(
meta_emit_blit(cmd_buffer,
&src_view,
(VkOffset3D) { 0, 0, 0 },
(VkExtent3D) { pRegions[r].copySize, 1, 1 },
(VkExtent3D) { pRegions[r].copySize / cpp, 1, 1 },
&dest_view,
(VkOffset3D) { 0, 0, 0 },
(VkExtent3D) { pRegions[r].copySize, 1, 1 });
(VkExtent3D) { pRegions[r].copySize / cpp, 1, 1 });
}
meta_finish_blit(cmd_buffer, &saved_state);