[Mesa-dev] [PATCH 05/17] gallium: introduce semaphore object

Marek Olšák maraeo at gmail.com
Fri Nov 3 18:20:45 UTC 2017


On Fri, Nov 3, 2017 at 7:18 PM, Andres Rodriguez <andresx7 at gmail.com> wrote:
>
>
> On 2017-11-03 01:56 PM, Marek Olšák wrote:
>>
>> On Thu, Nov 2, 2017 at 4:57 AM, Andres Rodriguez <andresx7 at gmail.com>
>> wrote:
>>>
>>> Signed-off-by: Andres Rodriguez <andresx7 at gmail.com>
>>> ---
>>>   src/gallium/drivers/ddebug/dd_context.c | 23 +++++++++++++++++++
>>>   src/gallium/drivers/ddebug/dd_screen.c  | 25 +++++++++++++++++++++
>>>   src/gallium/drivers/trace/tr_context.c  | 36
>>> ++++++++++++++++++++++++++++++
>>>   src/gallium/drivers/trace/tr_screen.c   | 39
>>> +++++++++++++++++++++++++++++++++
>>>   src/gallium/include/pipe/p_context.h    | 26 ++++++++++++++++++++++
>>>   src/gallium/include/pipe/p_screen.h     | 22 +++++++++++++++++++
>>>   src/gallium/include/pipe/p_state.h      |  8 +++++++
>>>   7 files changed, 179 insertions(+)
>>>
>>> diff --git a/src/gallium/drivers/ddebug/dd_context.c
>>> b/src/gallium/drivers/ddebug/dd_context.c
>>> index 2abbff9..653e368 100644
>>> --- a/src/gallium/drivers/ddebug/dd_context.c
>>> +++ b/src/gallium/drivers/ddebug/dd_context.c
>>> @@ -663,6 +663,27 @@ dd_context_texture_subdata(struct pipe_context
>>> *_pipe,
>>>                            stride, layer_stride);
>>>   }
>>>
>>> +/********************************************************************
>>> + * Semaphores
>>> + */
>>> +
>>> +static void
>>> +dd_context_semobj_wait(struct pipe_context *_pipe,
>>> +                       struct pipe_semaphore_object *semobj)
>>> +{
>>> +   struct pipe_context *pipe = dd_context(_pipe)->pipe;
>>> +
>>> +   pipe->semobj_wait(pipe, semobj);
>>> +}
>>> +
>>> +static void
>>> +dd_context_semobj_signal(struct pipe_context *_pipe,
>>> +                         struct pipe_semaphore_object *semobj)
>>> +{
>>> +   struct pipe_context *pipe = dd_context(_pipe)->pipe;
>>> +
>>> +   pipe->semobj_signal(pipe, semobj);
>>> +}
>>>
>>>   /********************************************************************
>>>    * miscellaneous
>>> @@ -912,6 +933,8 @@ dd_context_create(struct dd_screen *dscreen, struct
>>> pipe_context *pipe)
>>>      CTX_INIT(create_image_handle);
>>>      CTX_INIT(delete_image_handle);
>>>      CTX_INIT(make_image_handle_resident);
>>> +   CTX_INIT(semobj_wait);
>>> +   CTX_INIT(semobj_signal);
>>>
>>>      dd_init_draw_functions(dctx);
>>>
>>> diff --git a/src/gallium/drivers/ddebug/dd_screen.c
>>> b/src/gallium/drivers/ddebug/dd_screen.c
>>> index caf31f6..6c854cd 100644
>>> --- a/src/gallium/drivers/ddebug/dd_screen.c
>>> +++ b/src/gallium/drivers/ddebug/dd_screen.c
>>> @@ -367,6 +367,29 @@ dd_screen_memobj_destroy(struct pipe_screen
>>> *_screen,
>>>
>>>      screen->memobj_destroy(screen, memobj);
>>>   }
>>> +
>>> +/********************************************************************
>>> + * memobj
>>> + */
>>> +
>>> +static struct pipe_semaphore_object *
>>> +dd_screen_semobj_create_from_fd(struct pipe_screen *_screen,
>>> +                                int fd)
>>> +{
>>> +   struct pipe_screen *screen = dd_screen(_screen)->screen;
>>> +
>>> +   return screen->semobj_create_from_fd(screen, fd);
>>> +}
>>> +
>>> +static void
>>> +dd_screen_semobj_destroy(struct pipe_screen *_screen,
>>> +                         struct pipe_semaphore_object *semobj)
>>> +{
>>> +   struct pipe_screen *screen = dd_screen(_screen)->screen;
>>> +
>>> +   screen->semobj_destroy(screen, semobj);
>>> +}
>>> +
>>>   /********************************************************************
>>>    * screen
>>>    */
>>> @@ -486,6 +509,8 @@ ddebug_screen_create(struct pipe_screen *screen)
>>>      SCR_INIT(fence_finish);
>>>      SCR_INIT(memobj_create_from_handle);
>>>      SCR_INIT(memobj_destroy);
>>> +   SCR_INIT(semobj_create_from_fd);
>>> +   SCR_INIT(semobj_destroy);
>>>      SCR_INIT(get_driver_query_info);
>>>      SCR_INIT(get_driver_query_group_info);
>>>      SCR_INIT(get_compiler_options);
>>> diff --git a/src/gallium/drivers/trace/tr_context.c
>>> b/src/gallium/drivers/trace/tr_context.c
>>> index 6d918d4..3e423c5 100644
>>> --- a/src/gallium/drivers/trace/tr_context.c
>>> +++ b/src/gallium/drivers/trace/tr_context.c
>>> @@ -1810,6 +1810,40 @@ static void
>>> trace_context_make_image_handle_resident(struct pipe_context *_pipe,
>>>      pipe->make_image_handle_resident(pipe, handle, access, resident);
>>>   }
>>>
>>> +/********************************************************************
>>> + * Semaphores
>>> + */
>>> +
>>> +static void
>>> +trace_context_semobj_wait(struct pipe_context *_pipe,
>>> +                          struct pipe_semaphore_object *semobj)
>>> +{
>>> +   struct trace_context *tr_ctx = trace_context(_pipe);
>>> +   struct pipe_context *pipe = tr_ctx->pipe;
>>> +
>>> +   trace_dump_call_begin("pipe_context", "semobj_wait");
>>> +   trace_dump_arg(ptr, _pipe);
>>> +   trace_dump_arg(ptr, semobj);
>>> +   trace_dump_call_end();
>>> +
>>> +   pipe->semobj_wait(pipe, semobj);
>>> +}
>>> +
>>> +static void
>>> +trace_context_semobj_signal(struct pipe_context *_pipe,
>>> +                            struct pipe_semaphore_object *semobj)
>>> +{
>>> +   struct trace_context *tr_ctx = trace_context(_pipe);
>>> +   struct pipe_context *pipe = tr_ctx->pipe;
>>> +
>>> +   trace_dump_call_begin("pipe_context", "semobj_signal");
>>> +   trace_dump_arg(ptr, _pipe);
>>> +   trace_dump_arg(ptr, semobj);
>>> +   trace_dump_call_end();
>>> +
>>> +   pipe->semobj_signal(pipe, semobj);
>>> +}
>>> +
>>>   struct pipe_context *
>>>   trace_context_create(struct trace_screen *tr_scr,
>>>                        struct pipe_context *pipe)
>>> @@ -1917,6 +1951,8 @@ trace_context_create(struct trace_screen *tr_scr,
>>>      TR_CTX_INIT(create_image_handle);
>>>      TR_CTX_INIT(delete_image_handle);
>>>      TR_CTX_INIT(make_image_handle_resident);
>>> +   TR_CTX_INIT(semobj_wait);
>>> +   TR_CTX_INIT(semobj_signal);
>>>
>>>      TR_CTX_INIT(transfer_map);
>>>      TR_CTX_INIT(transfer_unmap);
>>> diff --git a/src/gallium/drivers/trace/tr_screen.c
>>> b/src/gallium/drivers/trace/tr_screen.c
>>> index d5a8124..4c8182c 100644
>>> --- a/src/gallium/drivers/trace/tr_screen.c
>>> +++ b/src/gallium/drivers/trace/tr_screen.c
>>> @@ -560,6 +560,43 @@ trace_screen_memobj_destroy(struct pipe_screen
>>> *_screen,
>>>      screen->memobj_destroy(screen, memobj);
>>>   }
>>>
>>> +/********************************************************************
>>> + * semobj
>>> + */
>>> +
>>> +static struct pipe_semaphore_object *
>>> +trace_screen_semobj_create_from_fd(struct pipe_screen *_screen,
>>> +                                   int fd)
>>> +{
>>> +   struct pipe_screen *screen = trace_screen(_screen)->screen;
>>> +
>>> +   trace_dump_call_begin("pipe_screen", "semobj_create_from_fd");
>>> +   trace_dump_arg(ptr, screen);
>>> +   trace_dump_arg(int, fd);
>>> +
>>> +   struct pipe_semaphore_object *res =
>>> +      screen->semobj_create_from_fd(screen, fd);
>>> +
>>> +   trace_dump_ret(ptr, res);
>>> +   trace_dump_call_end();
>>> +
>>> +   return res;
>>> +}
>>> +
>>> +static void
>>> +trace_screen_semobj_destroy(struct pipe_screen *_screen,
>>> +                            struct pipe_semaphore_object *semobj)
>>> +{
>>> +   struct pipe_screen *screen = trace_screen(_screen)->screen;
>>> +
>>> +   trace_dump_call_begin("pipe_screen", "semobj_destroy");
>>> +   trace_dump_arg(ptr, screen);
>>> +   trace_dump_arg(ptr, semobj);
>>> +
>>> +   screen->semobj_destroy(screen, semobj);
>>> +
>>> +   trace_dump_call_end();
>>> +}
>>>
>>>   /********************************************************************
>>>    * screen
>>> @@ -655,6 +692,8 @@ trace_screen_create(struct pipe_screen *screen)
>>>      tr_scr->base.fence_finish = trace_screen_fence_finish;
>>>      SCR_INIT(memobj_create_from_handle);
>>>      SCR_INIT(memobj_destroy);
>>> +   SCR_INIT(semobj_create_from_fd);
>>> +   SCR_INIT(semobj_destroy);
>>>      tr_scr->base.flush_frontbuffer = trace_screen_flush_frontbuffer;
>>>      tr_scr->base.get_timestamp = trace_screen_get_timestamp;
>>>      SCR_INIT(get_driver_uuid);
>>> diff --git a/src/gallium/include/pipe/p_context.h
>>> b/src/gallium/include/pipe/p_context.h
>>> index 4609d4d..0e3e930 100644
>>> --- a/src/gallium/include/pipe/p_context.h
>>> +++ b/src/gallium/include/pipe/p_context.h
>>> @@ -61,6 +61,7 @@ struct pipe_resource;
>>>   struct pipe_sampler_state;
>>>   struct pipe_sampler_view;
>>>   struct pipe_scissor_state;
>>> +struct pipe_semaphore_object;
>>>   struct pipe_shader_buffer;
>>>   struct pipe_shader_state;
>>>   struct pipe_stencil_ref;
>>> @@ -839,6 +840,31 @@ struct pipe_context {
>>>       */
>>>      void (*make_image_handle_resident)(struct pipe_context *ctx,
>>> uint64_t handle,
>>>                                         unsigned access, bool resident);
>>> +
>>> +   /**
>>> +    * Wait for a semaphore object
>>> +    *
>>> +    * Emit a wait operation for the specified semaphore. After the wait
>>> +    * completes, the semaphore will return to the unsignaled state.
>>> +    *
>>> +    * Waiting on a semaphore that has no current signal operation
>>> associated
>>> +    * with it (from the GL client or an external semaphore signaler)
>>> results
>>> +    * in undefined behaviour.
>>> +    *
>>> +    * \param semobj  The semaphore object to wait upon
>>> +    */
>>> +   void (*semobj_wait)(struct pipe_context *ctx,
>>> +                       struct pipe_semaphore_object *semobj);
>>> +
>>> +   /**
>>> +    * Signal a semaphore object
>>> +    *
>>> +    * Emit a signal operation for the specified semaphore.
>>> +    *
>>> +    * \param semobj  The semaphore object to signal
>>> +    */
>>> +   void (*semobj_signal)(struct pipe_context *ctx,
>>> +                         struct pipe_semaphore_object *semobj);
>>>   };
>>>
>>>
>>> diff --git a/src/gallium/include/pipe/p_screen.h
>>> b/src/gallium/include/pipe/p_screen.h
>>> index c249c7d..d999d14 100644
>>> --- a/src/gallium/include/pipe/p_screen.h
>>> +++ b/src/gallium/include/pipe/p_screen.h
>>> @@ -412,6 +412,28 @@ struct pipe_screen {
>>>                                                     uint64_t offset);
>>>
>>>      /**
>>> +    * Create a semaphore object from a file descriptor
>>> +    *
>>> +    * The underlying primitive is often allocated by a foreign API, then
>>> +    * exported through interfaces compatible with EXT_semaphore.
>>> +    *
>>> +    * Note: the caller retains ownership of fd.
>>> +    *
>>> +    * \param fd  A file descriptor representing the semaphore object to
>>> import
>>> +    */
>>> +   struct pipe_semaphore_object *(*semobj_create_from_fd)(struct
>>> pipe_screen *screen,
>>> +                                                          int fd);
>>> +
>>> +
>>> +   /**
>>> +    * Destroy a semaphore object
>>> +    *
>>> +    * \param semobj  The semaphore object to destroy
>>> +    */
>>> +   void (*semobj_destroy)(struct pipe_screen *screen,
>>> +                          struct pipe_semaphore_object *semobj);
>>> +
>>> +   /**
>>>       * Fill @uuid with a unique driver identifier
>>>       *
>>>       * \param uuid    pointer to a memory region of PIPE_UUID_SIZE bytes
>>> diff --git a/src/gallium/include/pipe/p_state.h
>>> b/src/gallium/include/pipe/p_state.h
>>> index 90dc561..9edd5ef 100644
>>> --- a/src/gallium/include/pipe/p_state.h
>>> +++ b/src/gallium/include/pipe/p_state.h
>>> @@ -910,6 +910,14 @@ struct pipe_memory_object
>>>      bool dedicated;
>>>   };
>>>
>>> +/**
>>> + * Structure that contains information about semaphores
>>> + */
>>> +struct pipe_semaphore_object
>>> +{
>>> +   bool imported;
>>
>>
>> "imported" is unused.
>>
>> Also, why don't we use pipe_fence_handle and existing fence API? It's
>> a syncobj anyway. There is create_fence_fd (import), fence_get_fd
>> (export), fence_finish (CPU wait and/or return status),
>> fence_server_sync (GPU or scheduler wait).
>>
>
> Semaphores have some semantics that differ from fences, mainly around their
> re-usability. That was my initial reasoning for keeping them separate.
> However, nha just pointed out to me that those semantics are already
> supported by fences so I'm gonna look at merging things together.
>
> One small comment from when I initially was taking this approach. The
> create_fence_fd() implementation would need some changes as the incoming
> semaphore don't use sync_file fds, they use syncobj fds which are slightly.
> Are you okay with attempting to import as a sync_file fd first, and then on
> failure attempt to import as a syncobj fd?

Adding a type parameter to create_fence_fd should be sufficient. Note
that any existing pipe callback can be modified if it's necessary.

Marek


More information about the mesa-dev mailing list