Re: [Mesa-dev] [PATCH v3 4/8] anv: Implement support for exporting semaphores as FENCE_FD
On 04/08/17 18:24, Jason Ekstrand wrote: --- src/intel/vulkan/anv_batch_chain.c | 57 +-- src/intel/vulkan/anv_device.c | 1 + src/intel/vulkan/anv_gem.c | 36 src/intel/vulkan/anv_private.h | 23 + src/intel/vulkan/anv_queue.c | 69 -- 5 files changed, 175 insertions(+), 11 deletions(-) diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c index 65fe366..7a84bbd 100644 --- a/src/intel/vulkan/anv_batch_chain.c +++ b/src/intel/vulkan/anv_batch_chain.c @@ -1416,11 +1416,13 @@ anv_cmd_buffer_execbuf(struct anv_device *device, struct anv_execbuf execbuf; anv_execbuf_init(&execbuf); + int in_fence = -1; VkResult result = VK_SUCCESS; for (uint32_t i = 0; i < num_in_semaphores; i++) { ANV_FROM_HANDLE(anv_semaphore, semaphore, in_semaphores[i]); - assert(semaphore->temporary.type == ANV_SEMAPHORE_TYPE_NONE); - struct anv_semaphore_impl *impl = &semaphore->permanent; + struct anv_semaphore_impl *impl = + semaphore->temporary.type != ANV_SEMAPHORE_TYPE_NONE ? + &semaphore->temporary : &semaphore->permanent; I know you're not enabling this until patch 8, but for consistency, shouldn't this be part of patch 1? switch (impl->type) { case ANV_SEMAPHORE_TYPE_BO: @@ -1429,11 +1431,29 @@ anv_cmd_buffer_execbuf(struct anv_device *device, if (result != VK_SUCCESS) return result; break; + + case ANV_SEMAPHORE_TYPE_SYNC_FILE: + if (in_fence == -1) { +in_fence = impl->fd; + } else { +int merge = anv_gem_sync_file_merge(device, in_fence, impl->fd); +if (merge == -1) + return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR); + +close(impl->fd); +close(in_fence); +in_fence = merge; + } + + impl->fd = -1; + break; + default: break; } } + bool need_out_fence = false; for (uint32_t i = 0; i < num_out_semaphores; i++) { ANV_FROM_HANDLE(anv_semaphore, semaphore, out_semaphores[i]); @@ -1459,6 +1479,11 @@ anv_cmd_buffer_execbuf(struct anv_device *device, if (result != VK_SUCCESS) return result; break; + + case ANV_SEMAPHORE_TYPE_SYNC_FILE: + need_out_fence = true; + break; + default: break; } @@ -1472,9 +1497,19 @@ anv_cmd_buffer_execbuf(struct anv_device *device, setup_empty_execbuf(&execbuf, device); } + if (in_fence != -1) { + execbuf.execbuf.flags |= I915_EXEC_FENCE_IN; + execbuf.execbuf.rsvd2 |= (uint32_t)in_fence; + } + + if (need_out_fence) + execbuf.execbuf.flags |= I915_EXEC_FENCE_OUT; result = anv_device_execbuf(device, &execbuf.execbuf, execbuf.bos); + /* Execbuf does not consume the in_fence. It's our job to close it. */ + close(in_fence); + for (uint32_t i = 0; i < num_in_semaphores; i++) { ANV_FROM_HANDLE(anv_semaphore, semaphore, in_semaphores[i]); /* From the Vulkan 1.0.53 spec: @@ -1489,6 +1524,24 @@ anv_cmd_buffer_execbuf(struct anv_device *device, anv_semaphore_reset_temporary(device, semaphore); } + if (result == VK_SUCCESS && need_out_fence) { + int out_fence = execbuf.execbuf.rsvd2 >> 32; + for (uint32_t i = 0; i < num_out_semaphores; i++) { + ANV_FROM_HANDLE(anv_semaphore, semaphore, out_semaphores[i]); + /* Out fences can't have temporary state because that would imply + * that we imported a sync file and are trying to signal it. + */ + assert(semaphore->temporary.type == ANV_SEMAPHORE_TYPE_NONE); + struct anv_semaphore_impl *impl = &semaphore->permanent; + + if (impl->type == ANV_SEMAPHORE_TYPE_SYNC_FILE) { +assert(impl->fd == -1); +impl->fd = dup(out_fence); + } + } + close(out_fence); + } + anv_execbuf_finish(&execbuf, &device->alloc); return result; diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index e82e1e9..3c5f78c 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -337,6 +337,7 @@ anv_physical_device_init(struct anv_physical_device *device, goto fail; device->has_exec_async = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_ASYNC); + device->has_exec_fence = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE); bool swizzled = anv_gem_get_bit6_swizzle(fd, I915_TILING_X); diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c index 36692f5..5b68e9b 100644 --- a/src/intel/vulkan/anv_gem.c +++ b/src/intel/vulkan/anv_gem.c @@ -22,6 +22,7 @@ */ #include +#include #include #include #include @@ -400,3 +401,38 @@ anv_gem_fd_to_handle(struc
[Mesa-dev] [PATCH v3 4/8] anv: Implement support for exporting semaphores as FENCE_FD
--- src/intel/vulkan/anv_batch_chain.c | 57 +-- src/intel/vulkan/anv_device.c | 1 + src/intel/vulkan/anv_gem.c | 36 src/intel/vulkan/anv_private.h | 23 + src/intel/vulkan/anv_queue.c | 69 -- 5 files changed, 175 insertions(+), 11 deletions(-) diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c index 65fe366..7a84bbd 100644 --- a/src/intel/vulkan/anv_batch_chain.c +++ b/src/intel/vulkan/anv_batch_chain.c @@ -1416,11 +1416,13 @@ anv_cmd_buffer_execbuf(struct anv_device *device, struct anv_execbuf execbuf; anv_execbuf_init(&execbuf); + int in_fence = -1; VkResult result = VK_SUCCESS; for (uint32_t i = 0; i < num_in_semaphores; i++) { ANV_FROM_HANDLE(anv_semaphore, semaphore, in_semaphores[i]); - assert(semaphore->temporary.type == ANV_SEMAPHORE_TYPE_NONE); - struct anv_semaphore_impl *impl = &semaphore->permanent; + struct anv_semaphore_impl *impl = + semaphore->temporary.type != ANV_SEMAPHORE_TYPE_NONE ? + &semaphore->temporary : &semaphore->permanent; switch (impl->type) { case ANV_SEMAPHORE_TYPE_BO: @@ -1429,11 +1431,29 @@ anv_cmd_buffer_execbuf(struct anv_device *device, if (result != VK_SUCCESS) return result; break; + + case ANV_SEMAPHORE_TYPE_SYNC_FILE: + if (in_fence == -1) { +in_fence = impl->fd; + } else { +int merge = anv_gem_sync_file_merge(device, in_fence, impl->fd); +if (merge == -1) + return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR); + +close(impl->fd); +close(in_fence); +in_fence = merge; + } + + impl->fd = -1; + break; + default: break; } } + bool need_out_fence = false; for (uint32_t i = 0; i < num_out_semaphores; i++) { ANV_FROM_HANDLE(anv_semaphore, semaphore, out_semaphores[i]); @@ -1459,6 +1479,11 @@ anv_cmd_buffer_execbuf(struct anv_device *device, if (result != VK_SUCCESS) return result; break; + + case ANV_SEMAPHORE_TYPE_SYNC_FILE: + need_out_fence = true; + break; + default: break; } @@ -1472,9 +1497,19 @@ anv_cmd_buffer_execbuf(struct anv_device *device, setup_empty_execbuf(&execbuf, device); } + if (in_fence != -1) { + execbuf.execbuf.flags |= I915_EXEC_FENCE_IN; + execbuf.execbuf.rsvd2 |= (uint32_t)in_fence; + } + + if (need_out_fence) + execbuf.execbuf.flags |= I915_EXEC_FENCE_OUT; result = anv_device_execbuf(device, &execbuf.execbuf, execbuf.bos); + /* Execbuf does not consume the in_fence. It's our job to close it. */ + close(in_fence); + for (uint32_t i = 0; i < num_in_semaphores; i++) { ANV_FROM_HANDLE(anv_semaphore, semaphore, in_semaphores[i]); /* From the Vulkan 1.0.53 spec: @@ -1489,6 +1524,24 @@ anv_cmd_buffer_execbuf(struct anv_device *device, anv_semaphore_reset_temporary(device, semaphore); } + if (result == VK_SUCCESS && need_out_fence) { + int out_fence = execbuf.execbuf.rsvd2 >> 32; + for (uint32_t i = 0; i < num_out_semaphores; i++) { + ANV_FROM_HANDLE(anv_semaphore, semaphore, out_semaphores[i]); + /* Out fences can't have temporary state because that would imply + * that we imported a sync file and are trying to signal it. + */ + assert(semaphore->temporary.type == ANV_SEMAPHORE_TYPE_NONE); + struct anv_semaphore_impl *impl = &semaphore->permanent; + + if (impl->type == ANV_SEMAPHORE_TYPE_SYNC_FILE) { +assert(impl->fd == -1); +impl->fd = dup(out_fence); + } + } + close(out_fence); + } + anv_execbuf_finish(&execbuf, &device->alloc); return result; diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index e82e1e9..3c5f78c 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -337,6 +337,7 @@ anv_physical_device_init(struct anv_physical_device *device, goto fail; device->has_exec_async = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_ASYNC); + device->has_exec_fence = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE); bool swizzled = anv_gem_get_bit6_swizzle(fd, I915_TILING_X); diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c index 36692f5..5b68e9b 100644 --- a/src/intel/vulkan/anv_gem.c +++ b/src/intel/vulkan/anv_gem.c @@ -22,6 +22,7 @@ */ #include +#include #include #include #include @@ -400,3 +401,38 @@ anv_gem_fd_to_handle(struct anv_device *device, int fd) return args.handle; } + +#ifndef SYNC_IOC_MAGIC +/* duplicated from linux/sync_file.h to avoid build-time depnedency + * on new (v4.7) kernel headers. Once distro's are mostly using +