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>
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,
(!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],
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));
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;
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);
}
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);
{
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);
}
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)
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)) {
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) {
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);
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
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);
}
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:
*
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;
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) {
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]);
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,
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;
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,
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,
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)
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,
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);
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);
}