[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