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 <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18223>
This commit is contained in:
Marek Olšák 2022-08-24 02:21:00 -04:00 committed by Marge Bot
parent c0a05b604a
commit eafe72a6cc
6 changed files with 144 additions and 3 deletions

View 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);

View 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)

View 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)) {

View 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;

View 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,

View 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);
}