From: Marek Olšák Date: Wed, 24 Aug 2022 06:21:00 +0000 (-0400) Subject: frontend/dri: sync glthread when calling from the app side X-Git-Tag: upstream/22.3.5~2683 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=eafe72a6ccccc5528dd64dabd26557114f054fa8;p=platform%2Fupstream%2Fmesa.git frontend/dri: sync glthread when calling from the app side The comments explain the reasons. This is a prerequisite for glthread to be used by native drivers, swrast, and zink. Reviewed-by: Adam Jackson Part-of: --- diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c index 400b94e..240c5ca 100644 --- a/src/gallium/frontends/dri/dri2.c +++ b/src/gallium/frontends/dri/dri2.c @@ -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); diff --git a/src/gallium/frontends/dri/dri_context.c b/src/gallium/frontends/dri/dri_context.c index 1d48665..c304c80 100644 --- a/src/gallium/frontends/dri/dri_context.c +++ b/src/gallium/frontends/dri/dri_context.c @@ -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) diff --git a/src/gallium/frontends/dri/dri_drawable.c b/src/gallium/frontends/dri/dri_drawable.c index 2cf977e..f9df73e 100644 --- a/src/gallium/frontends/dri/dri_drawable.c +++ b/src/gallium/frontends/dri/dri_drawable.c @@ -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)) { diff --git a/src/gallium/frontends/dri/dri_helpers.c b/src/gallium/frontends/dri/dri_helpers.c index 7b3d869..a656176 100644 --- a/src/gallium/frontends/dri/dri_helpers.c +++ b/src/gallium/frontends/dri/dri_helpers.c @@ -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; diff --git a/src/gallium/frontends/dri/drisw.c b/src/gallium/frontends/dri/drisw.c index 1a31664..b5c0b7a 100644 --- a/src/gallium/frontends/dri/drisw.c +++ b/src/gallium/frontends/dri/drisw.c @@ -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, diff --git a/src/gallium/frontends/dri/kopper.c b/src/gallium/frontends/dri/kopper.c index 0d8d66d..0102e2c 100644 --- a/src/gallium/frontends/dri/kopper.c +++ b/src/gallium/frontends/dri/kopper.c @@ -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); }