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

Andres Rodriguez andresx7 at gmail.com
Fri Nov 3 18:18:56 UTC 2017



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?

Regards,
Andres

> Marek
> 


More information about the mesa-dev mailing list