summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBas Nieuwenhuizen <[email protected]>2017-02-04 15:58:39 +0100
committerBas Nieuwenhuizen <[email protected]>2017-03-29 08:50:41 +0200
commite527e62e759547577d3afcb1ea5fafcb8530db4c (patch)
tree7cdf1ba1fd46f36aead116fe0d2aae5cdf7c6665
parent6154efc1931a8ac581991e9b1103201590b590ca (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.c84
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(