diff options
author | Bas Nieuwenhuizen <[email protected]> | 2017-02-04 15:58:39 +0100 |
---|---|---|
committer | Bas Nieuwenhuizen <[email protected]> | 2017-03-29 08:50:41 +0200 |
commit | e527e62e759547577d3afcb1ea5fafcb8530db4c (patch) | |
tree | 7cdf1ba1fd46f36aead116fe0d2aae5cdf7c6665 | |
parent | 6154efc1931a8ac581991e9b1103201590b590ca (diff) |
radv: Implement sparse memory binding.
v2: Only submit when semaphores are specified.
Signed-off-by: Bas Nieuwenhuizen <[email protected]>
Reviewed-by: Dave Airlie <[email protected]>
-rw-r--r-- | src/amd/vulkan/radv_device.c | 84 |
1 files changed, 80 insertions, 4 deletions
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index adcc63a8172..d10d420c3cf 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -1959,13 +1959,89 @@ VkResult radv_BindImageMemory( return VK_SUCCESS; } -VkResult radv_QueueBindSparse( - VkQueue queue, + +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); + } +} + + VkResult radv_QueueBindSparse( + VkQueue _queue, uint32_t bindInfoCount, const VkBindSparseInfo* pBindInfo, - VkFence fence) + VkFence _fence) { - stub_return(VK_ERROR_INCOMPATIBLE_DRIVER); + RADV_FROM_HANDLE(radv_fence, fence, _fence); + RADV_FROM_HANDLE(radv_queue, queue, _queue); + struct radeon_winsys_fence *base_fence = fence ? fence->fence : NULL; + bool fence_emitted = false; + + 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 (pBindInfo[i].waitSemaphoreCount || pBindInfo[i].signalSemaphoreCount) { + queue->device->ws->cs_submit(queue->hw_ctx, queue->queue_idx, + &queue->device->empty_cs[queue->queue_family_index], + 1, NULL, NULL, + (struct radeon_winsys_sem **)pBindInfo[i].pWaitSemaphores, + pBindInfo[i].waitSemaphoreCount, + (struct radeon_winsys_sem **)pBindInfo[i].pSignalSemaphores, + pBindInfo[i].signalSemaphoreCount, + false, base_fence); + fence_emitted = true; + if (fence) + fence->submitted = true; + } + } + + if (fence && !fence_emitted) { + fence->signalled = true; + } + + return VK_SUCCESS; } VkResult radv_CreateFence( |