summaryrefslogtreecommitdiffstats
path: root/src/vulkan/meta.c
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2015-05-20 15:38:11 -0700
committerJason Ekstrand <[email protected]>2015-05-20 16:20:04 -0700
commit9557b85e3dc6b14a44ee724c3c618fbec8779ccd (patch)
treee05519fca0ab699c0dbf8c1e53d6ac8745b8f4a8 /src/vulkan/meta.c
parent13719e92254d055b560bdb1ec8c5e36ae856db99 (diff)
vk/meta: Use the biggest format possible for buffer copies
This should substantially improve throughput of buffer copies.
Diffstat (limited to 'src/vulkan/meta.c')
-rw-r--r--src/vulkan/meta.c58
1 files changed, 50 insertions, 8 deletions
diff --git a/src/vulkan/meta.c b/src/vulkan/meta.c
index f1524f9db28..b1612c2dc2d 100644
--- a/src/vulkan/meta.c
+++ b/src/vulkan/meta.c
@@ -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);