frontend/dri: sync glthread when calling from the app side
authorMarek Olšák <marek.olsak@amd.com>
Wed, 24 Aug 2022 06:21:00 +0000 (02:21 -0400)
committerMarge Bot <emma+marge@anholt.net>
Wed, 21 Sep 2022 14:54:50 +0000 (14:54 +0000)
The comments explain the reasons.

This is a prerequisite for glthread to be used by native drivers, swrast,
and zink.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18223>

src/gallium/frontends/dri/dri2.c
src/gallium/frontends/dri/dri_context.c
src/gallium/frontends/dri/dri_drawable.c
src/gallium/frontends/dri/dri_helpers.c
src/gallium/frontends/dri/drisw.c
src/gallium/frontends/dri/kopper.c

index 400b94e..240c5ca 100644 (file)
@@ -453,6 +453,12 @@ dri2_allocate_textures(struct dri_context *ctx,
 
    assert(num_buffers <= __DRI_BUFFER_COUNT);
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (ctx->st->thread_finish)
+      ctx->st->thread_finish(ctx->st);
+
    /* First get the buffers from the loader */
    if (image) {
       if (!dri_image_drawable_get_buffers(drawable, &images,
@@ -752,6 +758,12 @@ dri2_flush_frontbuffer(struct dri_context *ctx,
        (!ctx->is_shared_buffer_bound || statt != ST_ATTACHMENT_BACK_LEFT))
          return false;
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (ctx->st->thread_finish)
+      ctx->st->thread_finish(ctx->st);
+
    if (drawable->stvis.samples > 1) {
       /* Resolve the buffer used for front rendering. */
       dri_pipe_blit(ctx->st->pipe, drawable->textures[statt],
@@ -1755,6 +1767,12 @@ dri2_blit_image(__DRIcontext *context, __DRIimage *dst, __DRIimage *src,
    if (!dst || !src)
       return;
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (ctx->st->thread_finish)
+      ctx->st->thread_finish(ctx->st);
+
    handle_in_fence(context, dst);
 
    memset(&blit, 0, sizeof(blit));
@@ -1807,6 +1825,12 @@ dri2_map_image(__DRIcontext *context, __DRIimage *image,
    if (plane >= dri2_get_mapping_by_format(image->dri_format)->nplanes)
       return NULL;
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (ctx->st->thread_finish)
+      ctx->st->thread_finish(ctx->st);
+
    handle_in_fence(context, image);
 
    struct pipe_resource *resource = image->texture;
@@ -1834,6 +1858,12 @@ dri2_unmap_image(__DRIcontext *context, __DRIimage *image, void *data)
    struct dri_context *ctx = dri_context(context);
    struct pipe_context *pipe = ctx->st->pipe;
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (ctx->st->thread_finish)
+      ctx->st->thread_finish(ctx->st);
+
    pipe_texture_unmap(pipe, (struct pipe_transfer *)data);
 }
 
@@ -2008,6 +2038,10 @@ dri2_interop_export_object(__DRIcontext *_ctx,
        in->miplevel != 0)
       return MESA_GLINTEROP_INVALID_MIP_LEVEL;
 
+   /* Wait for glthread to finish to get up-to-date GL object lookups. */
+   if (st->thread_finish)
+      st->thread_finish(st);
+
    /* Validate the OpenGL object and get pipe_resource. */
    simple_mtx_lock(&ctx->Shared->Mutex);
 
index 1d48665..c304c80 100644 (file)
@@ -236,6 +236,12 @@ dri_destroy_context(__DRIcontext * cPriv)
 {
    struct dri_context *ctx = dri_context(cPriv);
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (ctx->st->thread_finish)
+      ctx->st->thread_finish(ctx->st);
+
    if (ctx->hud) {
       hud_destroy(ctx->hud, ctx->st->cso_context);
    }
@@ -289,6 +295,12 @@ dri_make_current(__DRIcontext * cPriv,
    struct dri_drawable *draw = dri_drawable(driDrawPriv);
    struct dri_drawable *read = dri_drawable(driReadPriv);
 
+   /* Wait for glthread to finish because we can't use st_context from
+    * multiple threads.
+    */
+   if (ctx->st->thread_finish)
+      ctx->st->thread_finish(ctx->st);
+
    if (!draw && !read)
       return ctx->stapi->make_current(ctx->stapi, ctx->st, NULL, NULL);
    else if (!draw || !read)
index 2cf977e..f9df73e 100644 (file)
@@ -415,6 +415,12 @@ notify_before_flush_cb(void* _args)
    struct st_context_iface *st = args->ctx->st;
    struct pipe_context *pipe = st->pipe;
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (st->thread_finish)
+      st->thread_finish(st);
+
    if (args->drawable->stvis.samples > 1 &&
        (args->reason == __DRI2_THROTTLE_SWAPBUFFER ||
         args->reason == __DRI2_THROTTLE_COPYSUBBUFFER)) {
index 7b3d869..a656176 100644 (file)
@@ -96,6 +96,12 @@ dri2_create_fence(__DRIcontext *_ctx)
    if (!fence)
       return NULL;
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (stapi->thread_finish)
+      stapi->thread_finish(stapi);
+
    stapi->flush(stapi, 0, &fence->pipe_fence, NULL, NULL);
 
    if (!fence->pipe_fence) {
@@ -114,6 +120,12 @@ dri2_create_fence_fd(__DRIcontext *_ctx, int fd)
    struct pipe_context *ctx = stapi->pipe;
    struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (stapi->thread_finish)
+      stapi->thread_finish(stapi);
+
    if (fd == -1) {
       /* exporting driver created fence, flush: */
       stapi->flush(stapi, ST_FLUSH_FENCE_FD, &fence->pipe_fence, NULL, NULL);
@@ -211,7 +223,8 @@ dri2_client_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags,
 static void
 dri2_server_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags)
 {
-   struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
+   struct st_context_iface *st = dri_context(_ctx)->st;
+   struct pipe_context *ctx = st->pipe;
    struct dri2_fence *fence = (struct dri2_fence*)_fence;
 
    /* We might be called here with a NULL fence as a result of WaitSyncKHR
@@ -220,6 +233,12 @@ dri2_server_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags)
    if (!fence)
       return;
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (st->thread_finish)
+      st->thread_finish(st);
+
    if (ctx->fence_server_sync)
       ctx->fence_server_sync(ctx, fence->pipe_fence);
 }
@@ -273,13 +292,18 @@ dri2_create_image_from_renderbuffer2(__DRIcontext *context,
                                     int renderbuffer, void *loaderPrivate,
                                      unsigned *error)
 {
-   struct st_context *st_ctx = (struct st_context *)dri_context(context)->st;
+   struct st_context_iface *st = dri_context(context)->st;
+   struct st_context *st_ctx = (struct st_context *)st;
    struct gl_context *ctx = st_ctx->ctx;
    struct pipe_context *p_ctx = st_ctx->pipe;
    struct gl_renderbuffer *rb;
    struct pipe_resource *tex;
    __DRIimage *img;
 
+   /* Wait for glthread to finish to get up-to-date GL object lookups. */
+   if (st->thread_finish)
+      st->thread_finish(st);
+
    /* Section 3.9 (EGLImage Specification and Management) of the EGL 1.5
     * specification says:
     *
@@ -369,13 +393,18 @@ dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture,
                          void *loaderPrivate)
 {
    __DRIimage *img;
-   struct st_context *st_ctx = (struct st_context *)dri_context(context)->st;
+   struct st_context_iface *st = dri_context(context)->st;
+   struct st_context *st_ctx = (struct st_context *)st;
    struct gl_context *ctx = st_ctx->ctx;
    struct pipe_context *p_ctx = st_ctx->pipe;
    struct gl_texture_object *obj;
    struct pipe_resource *tex;
    GLuint face = 0;
 
+   /* Wait for glthread to finish to get up-to-date GL object lookups. */
+   if (st->thread_finish)
+      st->thread_finish(st);
+
    obj = _mesa_lookup_texture(ctx, texture);
    if (!obj || obj->Target != target) {
       *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
index 1a31664..b5c0b7a 100644 (file)
@@ -245,6 +245,12 @@ drisw_swap_buffers(__DRIdrawable *dPriv)
    if (!ctx)
       return;
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (ctx->st->thread_finish)
+      ctx->st->thread_finish(ctx->st);
+
    ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
 
    if (ptex) {
@@ -286,6 +292,12 @@ drisw_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y,
    ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
 
    if (ptex) {
+      /* Wait for glthread to finish because we can't use pipe_context from
+       * multiple threads.
+       */
+      if (ctx->st->thread_finish)
+         ctx->st->thread_finish(ctx->st);
+
       struct pipe_fence_handle *fence = NULL;
       if (ctx->pp && drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL])
          pp_run(ctx->pp, ptex, ptex, drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]);
@@ -318,6 +330,12 @@ drisw_flush_frontbuffer(struct dri_context *ctx,
    if (!ctx || statt != ST_ATTACHMENT_FRONT_LEFT)
       return false;
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (ctx->st->thread_finish)
+      ctx->st->thread_finish(ctx->st);
+
    if (drawable->stvis.samples > 1) {
       /* Resolve the front buffer. */
       dri_pipe_blit(ctx->st->pipe,
@@ -353,6 +371,12 @@ drisw_allocate_textures(struct dri_context *stctx,
    boolean resized;
    unsigned i;
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (stctx->st->thread_finish)
+      stctx->st->thread_finish(stctx->st);
+
    width  = drawable->dPriv->w;
    height = drawable->dPriv->h;
 
@@ -439,6 +463,12 @@ drisw_update_tex_buffer(struct dri_drawable *drawable,
    int ximage_stride, line;
    int cpp = util_format_get_blocksize(res->format);
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (ctx->st->thread_finish)
+      ctx->st->thread_finish(ctx->st);
+
    get_drawable_info(dPriv, &x, &y, &w, &h);
 
    map = pipe_texture_map(pipe, res,
index 0d8d66d..0102e2c 100644 (file)
@@ -507,6 +507,12 @@ kopper_allocate_textures(struct dri_context *ctx,
    resized = (drawable->old_w != width ||
               drawable->old_h != height);
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (ctx->st->thread_finish)
+      ctx->st->thread_finish(ctx->st);
+
    /* First get the buffers from the loader */
    if (image) {
       if (!dri_image_drawable_get_buffers(drawable, &images,
@@ -717,6 +723,12 @@ kopper_flush_frontbuffer(struct dri_context *ctx,
    if (!ctx || statt != ST_ATTACHMENT_FRONT_LEFT)
       return false;
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (ctx->st->thread_finish)
+      ctx->st->thread_finish(ctx->st);
+
    if (drawable) {
       /* prevent recursion */
       if (drawable->flushing)
@@ -811,6 +823,12 @@ kopper_update_tex_buffer(struct dri_drawable *drawable,
       return;
    int cpp = util_format_get_blocksize(res->format);
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (ctx->st->thread_finish)
+      ctx->st->thread_finish(ctx->st);
+
    get_drawable_info(dPriv, &x, &y, &w, &h);
 
    map = pipe_texture_map(pipe, res,
@@ -912,6 +930,12 @@ kopperSwapBuffers(__DRIdrawable *dPriv)
    if (!ptex)
       return 0;
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (ctx->st->thread_finish)
+      ctx->st->thread_finish(ctx->st);
+
    drawable->texture_stamp = dPriv->lastStamp - 1;
    dri_flush(ctx->cPriv, dPriv, __DRI2_FLUSH_DRAWABLE | __DRI2_FLUSH_CONTEXT, __DRI2_THROTTLE_SWAPBUFFER);
    kopper_copy_to_front(ctx->st->pipe, dPriv, ptex);
@@ -1001,6 +1025,12 @@ kopperQueryBufferAge(__DRIdrawable *dPriv)
                                 drawable->textures[ST_ATTACHMENT_BACK_LEFT] :
                                 drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
 
+   /* Wait for glthread to finish because we can't use pipe_context from
+    * multiple threads.
+    */
+   if (ctx->st->thread_finish)
+      ctx->st->thread_finish(ctx->st);
+
    return zink_kopper_query_buffer_age(ctx->st->pipe, ptex);
 }