Mesa (main): vulkan/runtime: Add sparse bind support.
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Dec 31 15:40:22 UTC 2021
Module: Mesa
Branch: main
Commit: 7a84314c12ae0d001eb7d9df7d1f3c5c1c04b819
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=7a84314c12ae0d001eb7d9df7d1f3c5c1c04b819
Author: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Date: Sun Nov 28 18:52:16 2021 +0100
vulkan/runtime: Add sparse bind support.
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13974>
---
src/vulkan/runtime/vk_queue.c | 182 +++++++++++++++++++++++++++++++++++++++++-
src/vulkan/runtime/vk_queue.h | 8 ++
2 files changed, 187 insertions(+), 3 deletions(-)
diff --git a/src/vulkan/runtime/vk_queue.c b/src/vulkan/runtime/vk_queue.c
index c76a7321b6f..cd9c7daccf9 100644
--- a/src/vulkan/runtime/vk_queue.c
+++ b/src/vulkan/runtime/vk_queue.c
@@ -131,13 +131,30 @@ static struct vk_queue_submit *
vk_queue_submit_alloc(struct vk_queue *queue,
uint32_t wait_count,
uint32_t command_buffer_count,
- uint32_t signal_count)
+ uint32_t buffer_bind_count,
+ uint32_t image_opaque_bind_count,
+ uint32_t image_bind_count,
+ uint32_t bind_entry_count,
+ uint32_t image_bind_entry_count,
+ uint32_t signal_count,
+ VkSparseMemoryBind **bind_entries,
+ VkSparseImageMemoryBind **image_bind_entries)
{
VK_MULTIALLOC(ma);
VK_MULTIALLOC_DECL(&ma, struct vk_queue_submit, submit, 1);
VK_MULTIALLOC_DECL(&ma, struct vk_sync_wait, waits, wait_count);
VK_MULTIALLOC_DECL(&ma, struct vk_command_buffer *, command_buffers,
command_buffer_count);
+ VK_MULTIALLOC_DECL(&ma, VkSparseBufferMemoryBindInfo, buffer_binds,
+ buffer_bind_count);
+ VK_MULTIALLOC_DECL(&ma, VkSparseImageOpaqueMemoryBindInfo,
+ image_opaque_binds, image_opaque_bind_count);
+ VK_MULTIALLOC_DECL(&ma, VkSparseImageMemoryBindInfo, image_binds,
+ image_bind_count);
+ VK_MULTIALLOC_DECL(&ma, VkSparseMemoryBind,
+ bind_entries_local, bind_entry_count);
+ VK_MULTIALLOC_DECL(&ma, VkSparseImageMemoryBind, image_bind_entries_local,
+ image_bind_entry_count);
VK_MULTIALLOC_DECL(&ma, struct vk_sync_signal, signals, signal_count);
VK_MULTIALLOC_DECL(&ma, struct vk_sync *, wait_temps, wait_count);
@@ -156,14 +173,26 @@ vk_queue_submit_alloc(struct vk_queue *queue,
submit->wait_count = wait_count;
submit->command_buffer_count = command_buffer_count;
submit->signal_count = signal_count;
+ submit->buffer_bind_count = buffer_bind_count;
+ submit->image_opaque_bind_count = image_opaque_bind_count;
+ submit->image_bind_count = image_bind_count;
submit->waits = waits;
submit->command_buffers = command_buffers;
submit->signals = signals;
+ submit->buffer_binds = buffer_binds;
+ submit->image_opaque_binds = image_opaque_binds;
+ submit->image_binds = image_binds;
submit->_wait_temps = wait_temps;
submit->_wait_points = wait_points;
submit->_signal_points = signal_points;
+ if (bind_entries)
+ *bind_entries = bind_entries_local;
+
+ if (image_bind_entries)
+ *image_bind_entries = image_bind_entries_local;
+
return submit;
}
@@ -518,6 +547,15 @@ struct vulkan_submit_info {
uint32_t signal_count;
const VkSemaphoreSubmitInfoKHR *signals;
+ uint32_t buffer_bind_count;
+ const VkSparseBufferMemoryBindInfo *buffer_binds;
+
+ uint32_t image_opaque_bind_count;
+ const VkSparseImageOpaqueMemoryBindInfo *image_opaque_binds;
+
+ uint32_t image_bind_count;
+ const VkSparseImageMemoryBindInfo *image_binds;
+
struct vk_fence *fence;
};
@@ -526,6 +564,19 @@ vk_queue_submit(struct vk_queue *queue,
const struct vulkan_submit_info *info)
{
VkResult result;
+ uint32_t sparse_memory_bind_entry_count = 0;
+ uint32_t sparse_memory_image_bind_entry_count = 0;
+ VkSparseMemoryBind *sparse_memory_bind_entries = NULL;
+ VkSparseImageMemoryBind *sparse_memory_image_bind_entries = NULL;
+
+ for (uint32_t i = 0; i < info->buffer_bind_count; ++i)
+ sparse_memory_bind_entry_count += info->buffer_binds[i].bindCount;
+
+ for (uint32_t i = 0; i < info->image_opaque_bind_count; ++i)
+ sparse_memory_bind_entry_count += info->image_opaque_binds[i].bindCount;
+
+ for (uint32_t i = 0; i < info->image_bind_count; ++i)
+ sparse_memory_image_bind_entry_count += info->image_binds[i].bindCount;
const struct wsi_memory_signal_submit_info *mem_signal =
vk_find_struct_const(info->pNext, WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA);
@@ -536,8 +587,15 @@ vk_queue_submit(struct vk_queue *queue,
struct vk_queue_submit *submit =
vk_queue_submit_alloc(queue, info->wait_count,
info->command_buffer_count,
+ info->buffer_bind_count,
+ info->image_opaque_bind_count,
+ info->image_bind_count,
+ sparse_memory_bind_entry_count,
+ sparse_memory_image_bind_entry_count,
info->signal_count +
- signal_mem_sync + (info->fence != NULL));
+ signal_mem_sync + (info->fence != NULL),
+ &sparse_memory_bind_entries,
+ &sparse_memory_image_bind_entries);
if (unlikely(submit == NULL))
return vk_error(queue, VK_ERROR_OUT_OF_HOST_MEMORY);
@@ -607,6 +665,43 @@ vk_queue_submit(struct vk_queue *queue,
submit->command_buffers[i] = cmd_buffer;
}
+ sparse_memory_bind_entry_count = 0;
+ sparse_memory_image_bind_entry_count = 0;
+
+ typed_memcpy(submit->buffer_binds, info->buffer_binds, info->buffer_bind_count);
+ for (uint32_t i = 0; i < info->buffer_bind_count; ++i) {
+ VkSparseMemoryBind *binds = sparse_memory_bind_entries +
+ sparse_memory_bind_entry_count;
+ submit->buffer_binds[i].pBinds = binds;
+ typed_memcpy(binds, info->buffer_binds[i].pBinds,
+ info->buffer_binds[i].bindCount);
+
+ sparse_memory_bind_entry_count += info->buffer_binds[i].bindCount;
+ }
+
+ typed_memcpy(submit->image_opaque_binds, info->image_opaque_binds,
+ info->image_opaque_bind_count);
+ for (uint32_t i = 0; i < info->image_opaque_bind_count; ++i) {
+ VkSparseMemoryBind *binds = sparse_memory_bind_entries +
+ sparse_memory_bind_entry_count;
+ submit->image_opaque_binds[i].pBinds = binds;
+ typed_memcpy(binds, info->image_opaque_binds[i].pBinds,
+ info->image_opaque_binds[i].bindCount);
+
+ sparse_memory_bind_entry_count += info->image_opaque_binds[i].bindCount;
+ }
+
+ typed_memcpy(submit->image_binds, info->image_binds, info->image_bind_count);
+ for (uint32_t i = 0; i < info->image_bind_count; ++i) {
+ VkSparseImageMemoryBind *binds = sparse_memory_image_bind_entries +
+ sparse_memory_image_bind_entry_count;
+ submit->image_binds[i].pBinds = binds;
+ typed_memcpy(binds, info->image_binds[i].pBinds,
+ info->image_binds[i].bindCount);
+
+ sparse_memory_image_bind_entry_count += info->image_binds[i].bindCount;
+ }
+
for (uint32_t i = 0; i < info->signal_count; i++) {
VK_FROM_HANDLE(vk_semaphore, semaphore,
info->signals[i].semaphore);
@@ -933,7 +1028,8 @@ vk_queue_signal_sync(struct vk_queue *queue,
struct vk_sync *sync,
uint32_t signal_value)
{
- struct vk_queue_submit *submit = vk_queue_submit_alloc(queue, 0, 0, 1);
+ struct vk_queue_submit *submit = vk_queue_submit_alloc(queue, 0, 0, 0, 0, 0,
+ 0, 0, 1, NULL, NULL);
if (unlikely(submit == NULL))
return vk_error(queue, VK_ERROR_OUT_OF_HOST_MEMORY);
@@ -1033,6 +1129,86 @@ vk_common_QueueSubmit2KHR(VkQueue _queue,
return VK_SUCCESS;
}
+VKAPI_ATTR VkResult VKAPI_CALL
+vk_common_QueueBindSparse(VkQueue _queue,
+ uint32_t bindInfoCount,
+ const VkBindSparseInfo *pBindInfo,
+ VkFence _fence)
+{
+ VK_FROM_HANDLE(vk_queue, queue, _queue);
+ VK_FROM_HANDLE(vk_fence, fence, _fence);
+
+ if (vk_device_is_lost(queue->base.device))
+ return VK_ERROR_DEVICE_LOST;
+
+ if (bindInfoCount == 0) {
+ if (fence == NULL) {
+ return VK_SUCCESS;
+ } else {
+ return vk_queue_signal_sync(queue, vk_fence_get_active_sync(fence), 0);
+ }
+ }
+
+ for (uint32_t i = 0; i < bindInfoCount; i++) {
+ const VkTimelineSemaphoreSubmitInfo *timeline_info =
+ vk_find_struct_const(pBindInfo[i].pNext, TIMELINE_SEMAPHORE_SUBMIT_INFO);
+ const uint64_t *wait_values = timeline_info &&
+ timeline_info->waitSemaphoreValueCount ? timeline_info->pWaitSemaphoreValues : NULL;
+ const uint64_t *signal_values = timeline_info &&
+ timeline_info->signalSemaphoreValueCount ? timeline_info->pSignalSemaphoreValues : NULL;
+
+ STACK_ARRAY(VkSemaphoreSubmitInfoKHR, wait_semaphore_infos,
+ pBindInfo[i].waitSemaphoreCount);
+ STACK_ARRAY(VkSemaphoreSubmitInfoKHR, signal_semaphore_infos,
+ pBindInfo[i].signalSemaphoreCount);
+
+ if (!wait_semaphore_infos || !signal_semaphore_infos) {
+ STACK_ARRAY_FINISH(wait_semaphore_infos);
+ STACK_ARRAY_FINISH(signal_semaphore_infos);
+ return vk_error(queue, VK_ERROR_OUT_OF_HOST_MEMORY);
+ }
+
+ for (uint32_t j = 0; j < pBindInfo[i].waitSemaphoreCount; j++) {
+ wait_semaphore_infos[j] = (VkSemaphoreSubmitInfoKHR) {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR,
+ .semaphore = pBindInfo[i].pWaitSemaphores[j],
+ .value = wait_values ? wait_values[j] : 0,
+ };
+ }
+
+ for (uint32_t j = 0; j < pBindInfo[i].signalSemaphoreCount; j++) {
+ signal_semaphore_infos[j] = (VkSemaphoreSubmitInfoKHR) {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR,
+ .semaphore = pBindInfo[i].pSignalSemaphores[j],
+ .value = signal_values ? signal_values[j] : 0,
+ };
+ }
+ struct vulkan_submit_info info = {
+ .pNext = pBindInfo[i].pNext,
+ .wait_count = pBindInfo[i].waitSemaphoreCount,
+ .waits = wait_semaphore_infos,
+ .signal_count = pBindInfo[i].signalSemaphoreCount,
+ .signals = signal_semaphore_infos,
+ .buffer_bind_count = pBindInfo[i].bufferBindCount,
+ .buffer_binds = pBindInfo[i].pBufferBinds,
+ .image_opaque_bind_count = pBindInfo[i].imageOpaqueBindCount,
+ .image_opaque_binds = pBindInfo[i].pImageOpaqueBinds,
+ .image_bind_count = pBindInfo[i].imageBindCount,
+ .image_binds = pBindInfo[i].pImageBinds,
+ .fence = i == bindInfoCount - 1 ? fence : NULL
+ };
+ VkResult result = vk_queue_submit(queue, &info);
+
+ STACK_ARRAY_FINISH(wait_semaphore_infos);
+ STACK_ARRAY_FINISH(signal_semaphore_infos);
+
+ if (unlikely(result != VK_SUCCESS))
+ return result;
+ }
+
+ return VK_SUCCESS;
+}
+
static const struct vk_sync_type *
get_cpu_wait_type(struct vk_physical_device *pdevice)
{
diff --git a/src/vulkan/runtime/vk_queue.h b/src/vulkan/runtime/vk_queue.h
index 1e3dc12d9f8..88f6da6c037 100644
--- a/src/vulkan/runtime/vk_queue.h
+++ b/src/vulkan/runtime/vk_queue.h
@@ -180,10 +180,18 @@ struct vk_queue_submit {
uint32_t command_buffer_count;
uint32_t signal_count;
+ uint32_t buffer_bind_count;
+ uint32_t image_opaque_bind_count;
+ uint32_t image_bind_count;
+
struct vk_sync_wait *waits;
struct vk_command_buffer **command_buffers;
struct vk_sync_signal *signals;
+ VkSparseBufferMemoryBindInfo *buffer_binds;
+ VkSparseImageOpaqueMemoryBindInfo *image_opaque_binds;
+ VkSparseImageMemoryBindInfo *image_binds;
+
uint32_t perf_pass_index;
/* Used internally; should be ignored by drivers */
More information about the mesa-commit
mailing list