[05/17] gallium: introduce semaphore object

Submitted by Andres Rodriguez on Nov. 2, 2017, 3:57 a.m.

Details

Message ID 20171102035720.6839-6-andresx7@gmail.com
State New
Headers show
Series "Add support for GL_EXT_semaphore" ( rev: 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Andres Rodriguez Nov. 2, 2017, 3:57 a.m.
Signed-off-by: Andres Rodriguez <andresx7@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(+)

Patch hide | download patch | download mbox

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;
+};
+
 #ifdef __cplusplus
 }
 #endif

Comments

On Thu, Nov 2, 2017 at 4:57 AM, Andres Rodriguez <andresx7@gmail.com> wrote:
> Signed-off-by: Andres Rodriguez <andresx7@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).

Marek
On 2017-11-03 01:56 PM, Marek Olšák wrote:
> On Thu, Nov 2, 2017 at 4:57 AM, Andres Rodriguez <andresx7@gmail.com> wrote:
>> Signed-off-by: Andres Rodriguez <andresx7@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
>
On Fri, Nov 3, 2017 at 7:18 PM, Andres Rodriguez <andresx7@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@gmail.com>
>> wrote:
>>>
>>> Signed-off-by: Andres Rodriguez <andresx7@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
On 2017-11-03 02:20 PM, Marek Olšák wrote:
> On Fri, Nov 3, 2017 at 7:18 PM, Andres Rodriguez <andresx7@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@gmail.com>
>>> wrote:
>>>>
>>>> Signed-off-by: Andres Rodriguez <andresx7@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.
>


Sounds good.

> Marek
>