From a9c8424e0837f7c6d1532ce66663937db771ebc8 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Sat, 19 Oct 2019 17:05:22 +0200 Subject: [PATCH] radv: Do sparse binding in queue submission. So we have one place to do queue things if we end up deferring submissions. Reviewed-by: Samuel Pitoiset --- src/amd/vulkan/radv_device.c | 141 +++++++++++++++++++++++++------------------ 1 file changed, 81 insertions(+), 60 deletions(-) diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index 239409adada..3c1f159de89 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -3516,6 +3516,46 @@ radv_alloc_sem_info(struct radv_instance *instance, return ret; } +static void +radv_sparse_buffer_bind_memory(struct radv_device *device, + const VkSparseBufferMemoryBindInfo *bind) +{ + RADV_FROM_HANDLE(radv_buffer, buffer, bind->buffer); + + for (uint32_t i = 0; i < bind->bindCount; ++i) { + struct radv_device_memory *mem = NULL; + + if (bind->pBinds[i].memory != VK_NULL_HANDLE) + mem = radv_device_memory_from_handle(bind->pBinds[i].memory); + + device->ws->buffer_virtual_bind(buffer->bo, + bind->pBinds[i].resourceOffset, + bind->pBinds[i].size, + mem ? mem->bo : NULL, + bind->pBinds[i].memoryOffset); + } +} + +static void +radv_sparse_image_opaque_bind_memory(struct radv_device *device, + const VkSparseImageOpaqueMemoryBindInfo *bind) +{ + RADV_FROM_HANDLE(radv_image, image, bind->image); + + for (uint32_t i = 0; i < bind->bindCount; ++i) { + struct radv_device_memory *mem = NULL; + + if (bind->pBinds[i].memory != VK_NULL_HANDLE) + mem = radv_device_memory_from_handle(bind->pBinds[i].memory); + + device->ws->buffer_virtual_bind(image->bo, + bind->pBinds[i].resourceOffset, + bind->pBinds[i].size, + mem ? mem->bo : NULL, + bind->pBinds[i].memoryOffset); + } +} + static VkResult radv_get_preambles(struct radv_queue *queue, const VkCommandBuffer *cmd_buffers, @@ -3556,6 +3596,13 @@ radv_get_preambles(struct radv_queue *queue, struct radv_queue_submission { const VkCommandBuffer *cmd_buffers; uint32_t cmd_buffer_count; + + /* Sparse bindings that happen on a queue. */ + const VkSparseBufferMemoryBindInfo *buffer_binds; + uint32_t buffer_bind_count; + const VkSparseImageOpaqueMemoryBindInfo *image_opaque_binds; + uint32_t image_opaque_bind_count; + bool flush_caches; VkPipelineStageFlags wait_dst_stage_mask; const VkSemaphore *wait_semaphores; @@ -3602,6 +3649,16 @@ radv_queue_submit(struct radv_queue *queue, if (result != VK_SUCCESS) return result; + for (uint32_t i = 0; i < submission->buffer_bind_count; ++i) { + radv_sparse_buffer_bind_memory(queue->device, + submission->buffer_binds + i); + } + + for (uint32_t i = 0; i < submission->image_opaque_bind_count; ++i) { + radv_sparse_image_opaque_bind_memory(queue->device, + submission->image_opaque_binds + i); + } + if (!submission->cmd_buffer_count) { ret = queue->device->ws->cs_submit(ctx, queue->queue_idx, &queue->device->empty_cs[queue->queue_family_index], @@ -4302,45 +4359,13 @@ VkResult radv_BindImageMemory( return radv_BindImageMemory2(device, 1, &info); } - -static void -radv_sparse_buffer_bind_memory(struct radv_device *device, - const VkSparseBufferMemoryBindInfo *bind) +static bool radv_sparse_bind_has_effects(const VkBindSparseInfo *info) { - RADV_FROM_HANDLE(radv_buffer, buffer, bind->buffer); - - for (uint32_t i = 0; i < bind->bindCount; ++i) { - struct radv_device_memory *mem = NULL; - - if (bind->pBinds[i].memory != VK_NULL_HANDLE) - mem = radv_device_memory_from_handle(bind->pBinds[i].memory); - - device->ws->buffer_virtual_bind(buffer->bo, - bind->pBinds[i].resourceOffset, - bind->pBinds[i].size, - mem ? mem->bo : NULL, - bind->pBinds[i].memoryOffset); - } -} - -static void -radv_sparse_image_opaque_bind_memory(struct radv_device *device, - const VkSparseImageOpaqueMemoryBindInfo *bind) -{ - RADV_FROM_HANDLE(radv_image, image, bind->image); - - for (uint32_t i = 0; i < bind->bindCount; ++i) { - struct radv_device_memory *mem = NULL; - - if (bind->pBinds[i].memory != VK_NULL_HANDLE) - mem = radv_device_memory_from_handle(bind->pBinds[i].memory); - - device->ws->buffer_virtual_bind(image->bo, - bind->pBinds[i].resourceOffset, - bind->pBinds[i].size, - mem ? mem->bo : NULL, - bind->pBinds[i].memoryOffset); - } + return info->bufferBindCount || + info->imageOpaqueBindCount || + info->imageBindCount || + info->waitSemaphoreCount || + info->signalSemaphoreCount; } VkResult radv_QueueBindSparse( @@ -4350,44 +4375,40 @@ radv_sparse_image_opaque_bind_memory(struct radv_device *device, VkFence fence) { RADV_FROM_HANDLE(radv_queue, queue, _queue); - bool fence_emitted = false; VkResult result; + uint32_t fence_idx = 0; - for (uint32_t i = 0; i < bindInfoCount; ++i) { - for (uint32_t j = 0; j < pBindInfo[i].bufferBindCount; ++j) { - radv_sparse_buffer_bind_memory(queue->device, - pBindInfo[i].pBufferBinds + j); - } - - for (uint32_t j = 0; j < pBindInfo[i].imageOpaqueBindCount; ++j) { - radv_sparse_image_opaque_bind_memory(queue->device, - pBindInfo[i].pImageOpaqueBinds + j); - } + if (fence != VK_NULL_HANDLE) { + for (uint32_t i = 0; i < bindInfoCount; ++i) + if (radv_sparse_bind_has_effects(pBindInfo + i)) + fence_idx = i; + } else + fence_idx = UINT32_MAX; - if (!pBindInfo[i].waitSemaphoreCount && - !pBindInfo[i].signalSemaphoreCount) + for (uint32_t i = 0; i < bindInfoCount; ++i) { + if (i != fence_idx && !radv_sparse_bind_has_effects(pBindInfo + i)) continue; VkResult result = radv_queue_submit(queue, &(struct radv_queue_submission) { + .buffer_binds = pBindInfo[i].pBufferBinds, + .buffer_bind_count = pBindInfo[i].bufferBindCount, + .image_opaque_binds = pBindInfo[i].pImageOpaqueBinds, + .image_opaque_bind_count = pBindInfo[i].imageOpaqueBindCount, .wait_semaphores = pBindInfo[i].pWaitSemaphores, .wait_semaphore_count = pBindInfo[i].waitSemaphoreCount, .signal_semaphores = pBindInfo[i].pSignalSemaphores, .signal_semaphore_count = pBindInfo[i].signalSemaphoreCount, - .fence = fence + .fence = i == fence_idx ? fence : VK_NULL_HANDLE, }); if (result != VK_SUCCESS) return result; - - fence_emitted = true; } - if (fence != VK_NULL_HANDLE) { - if (!fence_emitted) { - result = radv_signal_fence(queue, fence); - if (result != VK_SUCCESS) - return result; - } + if (fence != VK_NULL_HANDLE && !bindInfoCount) { + result = radv_signal_fence(queue, fence); + if (result != VK_SUCCESS) + return result; } return VK_SUCCESS; -- 2.11.0