[Mesa-dev] [RFC 21/21] anv: Use DRM sync objects for external semaphores when available
Pohjolainen, Topi
topi.pohjolainen at gmail.com
Tue Apr 18 12:32:04 UTC 2017
On Fri, Apr 14, 2017 at 10:38:08AM -0700, Jason Ekstrand wrote:
> ---
> src/intel/vulkan/anv_batch_chain.c | 69 ++++++++++++++++++++++++++++
> src/intel/vulkan/anv_device.c | 2 +
> src/intel/vulkan/anv_private.h | 8 ++++
> src/intel/vulkan/anv_queue.c | 93 ++++++++++++++++++++++++++++----------
> 4 files changed, 148 insertions(+), 24 deletions(-)
>
> diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c
> index ec37c81..0f118c8 100644
> --- a/src/intel/vulkan/anv_batch_chain.c
> +++ b/src/intel/vulkan/anv_batch_chain.c
> @@ -953,6 +953,19 @@ anv_cmd_buffer_add_secondary(struct anv_cmd_buffer *primary,
> &secondary->surface_relocs, 0);
> }
>
> +struct drm_i915_gem_exec_fence {
> + /**
> + * User's handle for a dma-fence to wait on or signal.
> + */
> + __u32 handle;
> +
> +#define I915_EXEC_FENCE_WAIT (1<<0)
> +#define I915_EXEC_FENCE_SIGNAL (1<<1)
> + __u32 flags;
> +};
> +
> +#define I915_EXEC_FENCE_ARRAY (1<<19)
> +
> struct anv_execbuf {
> struct drm_i915_gem_execbuffer2 execbuf;
>
> @@ -962,6 +975,10 @@ struct anv_execbuf {
>
> /* Allocated length of the 'objects' and 'bos' arrays */
> uint32_t array_length;
> +
> + uint32_t fence_count;
> + uint32_t fence_array_length;
> + struct drm_i915_gem_exec_fence * fences;
> };
>
> static void
> @@ -976,6 +993,7 @@ anv_execbuf_finish(struct anv_execbuf *exec,
> {
> vk_free(alloc, exec->objects);
> vk_free(alloc, exec->bos);
> + vk_free(alloc, exec->fences);
> }
>
> static VkResult
> @@ -1061,6 +1079,35 @@ anv_execbuf_add_bo(struct anv_execbuf *exec,
> return VK_SUCCESS;
> }
>
> +static VkResult
> +anv_execbuf_add_syncobj(struct anv_execbuf *exec,
> + uint32_t handle,
> + uint32_t flags,
> + const VkAllocationCallbacks *alloc)
> +{
> + if (exec->fence_count >= exec->fence_array_length) {
> + uint32_t new_len = MAX2(exec->fence_array_length * 2, 64);
> +
> + struct drm_i915_gem_exec_fence *new_fences =
> + vk_realloc(alloc, exec->fences, new_len * sizeof(*new_fences),
> + 8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
> + if (new_fences == NULL)
> + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
> +
> + exec->fences = new_fences;
> + exec->fence_array_length = new_len;
> + }
> +
> + exec->fences[exec->fence_count] = (struct drm_i915_gem_exec_fence) {
> + .handle = handle,
> + .flags = flags,
> + };
> +
> + exec->fence_count++;
> +
> + return VK_SUCCESS;
> +}
> +
> static void
> anv_cmd_buffer_process_relocs(struct anv_cmd_buffer *cmd_buffer,
> struct anv_reloc_list *list)
> @@ -1447,6 +1494,14 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
> impl->fd = -1;
> break;
>
> + case ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ:
> + result = anv_execbuf_add_syncobj(&execbuf, impl->syncobj,
> + I915_EXEC_FENCE_WAIT,
> + &device->alloc);
> + if (result != VK_SUCCESS)
> + return result;
> + break;
> +
> default:
> break;
> }
> @@ -1481,6 +1536,14 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
> need_out_fence = true;
> break;
>
> + case ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ:
> + result = anv_execbuf_add_syncobj(&execbuf, impl->syncobj,
> + I915_EXEC_FENCE_SIGNAL,
> + &device->alloc);
> + if (result != VK_SUCCESS)
> + return result;
> + break;
> +
> default:
> break;
> }
> @@ -1494,6 +1557,12 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
> setup_empty_execbuf(&execbuf, device);
> }
>
> + if (execbuf.fence_count > 0) {
> + execbuf.execbuf.flags |= I915_EXEC_FENCE_ARRAY;
> + execbuf.execbuf.num_cliprects = execbuf.fence_count;
> + execbuf.execbuf.cliprects_ptr = (uintptr_t) execbuf.fences;
> + }
> +
> if (in_fence != -1) {
> execbuf.execbuf.flags |= I915_EXEC_FENCE_IN;
> execbuf.execbuf.rsvd2 |= (uint32_t)in_fence;
> diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
> index f853905..13d01d1 100644
> --- a/src/intel/vulkan/anv_device.c
> +++ b/src/intel/vulkan/anv_device.c
> @@ -233,6 +233,8 @@ anv_physical_device_init(struct anv_physical_device *device,
>
> 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);
> + device->has_syncobj =
> + anv_gem_get_param(fd, 47 /* I915_PARAM_HAS_EXEC_FENCE_ARRAY */);
>
> bool swizzled = anv_gem_get_bit6_swizzle(fd, I915_TILING_X);
>
> diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
> index d1406ab..0731e89 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -648,6 +648,7 @@ struct anv_physical_device {
> int cmd_parser_version;
> bool has_exec_async;
> bool has_exec_fence;
> + bool has_syncobj;
>
> uint32_t eu_total;
> uint32_t subslice_total;
> @@ -1724,6 +1725,7 @@ enum anv_semaphore_type {
> ANV_SEMAPHORE_TYPE_DUMMY,
> ANV_SEMAPHORE_TYPE_BO,
> ANV_SEMAPHORE_TYPE_SYNC_FILE,
> + ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ,
> };
>
> struct anv_semaphore_impl {
> @@ -1742,6 +1744,12 @@ struct anv_semaphore_impl {
> * created or because it has been used for a wait, fd will be -1.
> */
> int fd;
> +
> + /* Sync object handle when type == AKV_SEMAPHORE_TYPE_DRM_SYNCOBJ.
ANV
More information about the mesa-dev
mailing list