summaryrefslogtreecommitdiffstats
path: root/src/intel/vulkan/anv_queue.c
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2017-02-15 17:25:46 -0800
committerJason Ekstrand <[email protected]>2017-05-03 15:09:46 -0700
commit4201cc2dd3aaa4b6c15c52037b3a6413274082ec (patch)
tree0038fcf65886bcb383c3e96d25fd42e59f32e3e2 /src/intel/vulkan/anv_queue.c
parentef2e427d783b5c192e9ec5c25613c8a992bfc79b (diff)
anv: Implement VK_KHX_external_semaphore_fd
This implementation allocates a 4k BO for each semaphore that can be exported using OPAQUE_FD and uses the kernel's already-existing synchronization mechanism on BOs. Reviewed-by: Chad Versace <[email protected]>
Diffstat (limited to 'src/intel/vulkan/anv_queue.c')
-rw-r--r--src/intel/vulkan/anv_queue.c141
1 files changed, 133 insertions, 8 deletions
diff --git a/src/intel/vulkan/anv_queue.c b/src/intel/vulkan/anv_queue.c
index 64c59006ca8..fac979a52c0 100644
--- a/src/intel/vulkan/anv_queue.c
+++ b/src/intel/vulkan/anv_queue.c
@@ -25,6 +25,10 @@
* This file implements VkQueue, VkFence, and VkSemaphore
*/
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/eventfd.h>
+
#include "anv_private.h"
#include "util/vk_util.h"
@@ -161,7 +165,23 @@ VkResult anv_QueueSubmit(
assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY);
assert(!anv_batch_has_error(&cmd_buffer->batch));
- result = anv_cmd_buffer_execbuf(device, cmd_buffer);
+ const VkSemaphore *in_semaphores = NULL, *out_semaphores = NULL;
+ uint32_t num_in_semaphores = 0, num_out_semaphores = 0;
+ if (j == 0) {
+ /* Only the first batch gets the in semaphores */
+ in_semaphores = pSubmits[i].pWaitSemaphores;
+ num_in_semaphores = pSubmits[i].waitSemaphoreCount;
+ }
+
+ if (j == pSubmits[i].commandBufferCount - 1) {
+ /* Only the last batch gets the out semaphores */
+ out_semaphores = pSubmits[i].pSignalSemaphores;
+ num_out_semaphores = pSubmits[i].signalSemaphoreCount;
+ }
+
+ result = anv_cmd_buffer_execbuf(device, cmd_buffer,
+ in_semaphores, num_in_semaphores,
+ out_semaphores, num_out_semaphores);
if (result != VK_SUCCESS)
goto out;
}
@@ -513,14 +533,33 @@ VkResult anv_CreateSemaphore(
VkExternalSemaphoreHandleTypeFlagsKHX handleTypes =
export ? export->handleTypes : 0;
- /* External semaphores are not yet supported */
- assert(handleTypes == 0);
+ if (handleTypes == 0) {
+ /* The DRM execbuffer ioctl always execute in-oder so long as you stay
+ * on the same ring. Since we don't expose the blit engine as a DMA
+ * queue, a dummy no-op semaphore is a perfectly valid implementation.
+ */
+ semaphore->permanent.type = ANV_SEMAPHORE_TYPE_DUMMY;
+ } else if (handleTypes & VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHX) {
+ assert(handleTypes == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHX);
+
+ semaphore->permanent.type = ANV_SEMAPHORE_TYPE_BO;
+ VkResult result = anv_bo_cache_alloc(device, &device->bo_cache,
+ 4096, &semaphore->permanent.bo);
+ if (result != VK_SUCCESS) {
+ vk_free2(&device->alloc, pAllocator, semaphore);
+ return result;
+ }
+
+ /* If we're going to use this as a fence, we need to *not* have the
+ * EXEC_OBJECT_ASYNC bit set.
+ */
+ semaphore->permanent.bo->flags &= ~EXEC_OBJECT_ASYNC;
+ } else {
+ assert(!"Unknown handle type");
+ vk_free2(&device->alloc, pAllocator, semaphore);
+ return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX);
+ }
- /* The DRM execbuffer ioctl always execute in-oder, even between
- * different rings. As such, a dummy no-op semaphore is a perfectly
- * valid implementation.
- */
- semaphore->permanent.type = ANV_SEMAPHORE_TYPE_DUMMY;
semaphore->temporary.type = ANV_SEMAPHORE_TYPE_NONE;
*pSemaphore = anv_semaphore_to_handle(semaphore);
@@ -528,6 +567,24 @@ VkResult anv_CreateSemaphore(
return VK_SUCCESS;
}
+static void
+anv_semaphore_impl_cleanup(struct anv_device *device,
+ struct anv_semaphore_impl *impl)
+{
+ switch (impl->type) {
+ case ANV_SEMAPHORE_TYPE_NONE:
+ case ANV_SEMAPHORE_TYPE_DUMMY:
+ /* Dummy. Nothing to do */
+ return;
+
+ case ANV_SEMAPHORE_TYPE_BO:
+ anv_bo_cache_release(device, &device->bo_cache, impl->bo);
+ return;
+ }
+
+ unreachable("Invalid semaphore type");
+}
+
void anv_DestroySemaphore(
VkDevice _device,
VkSemaphore _semaphore,
@@ -539,6 +596,9 @@ void anv_DestroySemaphore(
if (semaphore == NULL)
return;
+ anv_semaphore_impl_cleanup(device, &semaphore->temporary);
+ anv_semaphore_impl_cleanup(device, &semaphore->permanent);
+
vk_free2(&device->alloc, pAllocator, semaphore);
}
@@ -548,9 +608,74 @@ void anv_GetPhysicalDeviceExternalSemaphorePropertiesKHX(
VkExternalSemaphorePropertiesKHX* pExternalSemaphoreProperties)
{
switch (pExternalSemaphoreInfo->handleType) {
+ case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHX:
+ pExternalSemaphoreProperties->exportFromImportedHandleTypes =
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHX;
+ pExternalSemaphoreProperties->compatibleHandleTypes =
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHX;
+ pExternalSemaphoreProperties->externalSemaphoreFeatures =
+ VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHX |
+ VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHX;
+ break;
+
default:
pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
pExternalSemaphoreProperties->compatibleHandleTypes = 0;
pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
}
}
+
+VkResult anv_ImportSemaphoreFdKHX(
+ VkDevice _device,
+ const VkImportSemaphoreFdInfoKHX* pImportSemaphoreFdInfo)
+{
+ ANV_FROM_HANDLE(anv_device, device, _device);
+ ANV_FROM_HANDLE(anv_semaphore, semaphore, pImportSemaphoreFdInfo->semaphore);
+
+ switch (pImportSemaphoreFdInfo->handleType) {
+ case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHX: {
+ struct anv_bo *bo;
+ VkResult result = anv_bo_cache_import(device, &device->bo_cache,
+ pImportSemaphoreFdInfo->fd, 4096,
+ &bo);
+ if (result != VK_SUCCESS)
+ return result;
+
+ /* If we're going to use this as a fence, we need to *not* have the
+ * EXEC_OBJECT_ASYNC bit set.
+ */
+ bo->flags &= ~EXEC_OBJECT_ASYNC;
+
+ anv_semaphore_impl_cleanup(device, &semaphore->permanent);
+
+ semaphore->permanent.type = ANV_SEMAPHORE_TYPE_BO;
+ semaphore->permanent.bo = bo;
+
+ return VK_SUCCESS;
+ }
+
+ default:
+ return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX);
+ }
+}
+
+VkResult anv_GetSemaphoreFdKHX(
+ VkDevice _device,
+ VkSemaphore _semaphore,
+ VkExternalSemaphoreHandleTypeFlagBitsKHX handleType,
+ int* pFd)
+{
+ ANV_FROM_HANDLE(anv_device, device, _device);
+ ANV_FROM_HANDLE(anv_semaphore, semaphore, _semaphore);
+
+ switch (semaphore->permanent.type) {
+ case ANV_SEMAPHORE_TYPE_BO:
+ return anv_bo_cache_export(device, &device->bo_cache,
+ semaphore->permanent.bo, pFd);
+
+ default:
+ return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX);
+ }
+
+ return VK_SUCCESS;
+}