From b1d1318e1754dd0549edebc4516d3b70993c316f Mon Sep 17 00:00:00 2001 From: KiralyCraft Date: Wed, 28 Oct 2026 21:26:40 +0200 Subject: [PATCH] dri: make KGSL presentation waits opt-in on native Wayland The DRI3 opt-out disabled the X11 bridge but left KGSL's shared CPU-completion fallback active. Native Wayland does not use that bridge, so it continued waiting on every presented buffer. Carry the presentation policy on each context. Native Wayland EGL contexts default to the earlier nonblocking behavior; X11 contexts, including XWayland, keep their existing fenced default. Honor the same environment override in the shared wait: 1 disables it and 0 keeps the conservative native Wayland wait enabled. Keeping the policy on the context also covers later attachment flushes. Resource submission and explicit OpenGL/EGL synchronization remain intact. This is a compatibility rollback for native Wayland, not a new implicit synchronization implementation. Generated-by: LLM --- docs/envvars.rst | 15 +++++++++++++++ src/egl/drivers/dri2/egl_dri2.c | 9 +++++++++ src/gallium/drivers/freedreno/freedreno_context.c | 3 +++ src/gallium/drivers/freedreno/freedreno_context.h | 1 + .../drivers/freedreno/freedreno_resource.c | 6 ++++-- src/gallium/frontends/dri/dri_context.c | 14 ++++++++++++++ src/gallium/frontends/dri/dri_util.h | 3 +++ src/gallium/include/pipe/p_defines.h | 5 +++++ src/gallium/targets/dri/dri.sym.in | 1 + 9 files changed, 55 insertions(+), 2 deletions(-) diff --git a/docs/envvars.rst b/docs/envvars.rst index 13dd548538b2..e311fc0c71e9 100644 --- a/docs/envvars.rst +++ b/docs/envvars.rst @@ -1081,6 +1081,21 @@ Hasvk driver environment variables DRI environment variables ------------------------- +.. envvar:: MESA_DRI3_DISABLE_PRESENT_WAIT_FENCE + + Controls the X11 Present wait-fence bridge and the shared KGSL + presentation-completion wait. For native Wayland EGL contexts the + default is ``true``, restoring the earlier nonblocking presentation + behavior. For X11 contexts, including XWayland and Termux:X11, the + default is ``false``, preserving the Present wait-fence bridge. + + Set ``1`` to disable both presentation mechanisms, or ``0`` to keep + them enabled, including the conservative KGSL completion wait on + native Wayland. This does not disable resource submission, OpenGL + synchronization objects, or EGL native fences. Disabling the wait + does not add an asynchronous fence handoff to the compositor; visual + correctness still depends on the existing buffer synchronization. + .. envvar:: DRI_NO_MSAA disable MSAA for GLX/EGL MSAA visuals diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index c57debe67dcb..09f089e3865b 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -1330,6 +1330,15 @@ dri2_create_context(_EGLDisplay *disp, _EGLConfig *conf, if (!dri2_ctx->dri_context) goto cleanup; + if (disp->Platform == _EGL_PLATFORM_WAYLAND) { + /* Native Wayland has no X11 Present wait-fence bridge. Keep its + * pre-bridge default, with the same environment override as DRI3. + * This is a context policy, so later attachment flushes agree too. + */ + dri_disable_present_wait_fence(dri2_ctx->dri_context, + debug_get_bool_option("MESA_DRI3_DISABLE_PRESENT_WAIT_FENCE", true)); + } + mtx_unlock(&dri2_dpy->lock); return &dri2_ctx->base; diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c index 24be91b1e2b4..e2291d24d4c5 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.c +++ b/src/gallium/drivers/freedreno/freedreno_context.c @@ -147,6 +147,9 @@ fd_set_context_param(struct pipe_context *pctx, enum pipe_context_param param, case PIPE_CONTEXT_PARAM_EXPLICIT_PRESENT_FENCE: ctx->explicit_present_fence = value; break; + case PIPE_CONTEXT_PARAM_DISABLE_PRESENT_WAIT_FENCE: + ctx->disable_present_wait_fence = value; + break; default: break; } diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index 6b31855a79f5..92bf6b9ebcb4 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -362,6 +362,7 @@ struct fd_context { * the window-system presentation path. */ bool explicit_present_fence; + bool disable_present_wait_fence; /* * Counter to keep track of batch's most recent update. Ie. the batch with diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index 5b09206d768c..6abf4270bbe2 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -770,9 +770,11 @@ fd_flush_resource(struct pipe_context *pctx, struct pipe_resource *prsc) * If the window-system path is not carrying the next submission's native * fence explicitly, wait here before handing the resource to an * implicit-sync consumer. The explicit Present-fence path avoids this - * per-frame CPU stall. + * per-frame CPU stall. The compatibility opt-out restores the previous + * window-system behavior without changing resource submission or API fences. */ - if (ctx->screen->is_kgsl && !ctx->explicit_present_fence) + if (ctx->screen->is_kgsl && !ctx->explicit_present_fence && + !ctx->disable_present_wait_fence) fd_resource_wait(ctx, rsc, FD_BO_PREP_READ); } diff --git a/src/gallium/frontends/dri/dri_context.c b/src/gallium/frontends/dri/dri_context.c index 21251fdf839e..6f9c57899129 100644 --- a/src/gallium/frontends/dri/dri_context.c +++ b/src/gallium/frontends/dri/dri_context.c @@ -32,6 +32,7 @@ #include "dri_screen.h" #include "dri_drawable.h" #include "dri_context.h" +#include "dri_util.h" #include "frontend/drm_driver.h" #include "pipe/p_context.h" @@ -42,6 +43,16 @@ #include "util/u_memory.h" #include "util/u_debug.h" +void +dri_disable_present_wait_fence(struct dri_context *ctx, bool disable) +{ + struct pipe_context *pipe = ctx->st->pipe; + if (pipe->set_context_param) + pipe->set_context_param(pipe, + PIPE_CONTEXT_PARAM_DISABLE_PRESENT_WAIT_FENCE, + disable); +} + struct dri_context * dri_create_context(struct dri_screen *screen, struct st_context_attribs *attribs, @@ -136,6 +147,9 @@ dri_create_context(struct dri_screen *screen, if (!thread_safe) enable_glthread = false; + dri_disable_present_wait_fence(ctx, debug_get_bool_option( + "MESA_DRI3_DISABLE_PRESENT_WAIT_FENCE", false)); + /* Do this last. */ if (enable_glthread) _mesa_glthread_init(ctx->st->ctx); diff --git a/src/gallium/frontends/dri/dri_util.h b/src/gallium/frontends/dri/dri_util.h index a7eeb913bb58..39a4163f3924 100644 --- a/src/gallium/frontends/dri/dri_util.h +++ b/src/gallium/frontends/dri/dri_util.h @@ -139,6 +139,9 @@ dri_query_renderer_integer(struct dri_screen *_screen, int param, PUBLIC void dri_flush_drawable(struct dri_drawable *dPriv); +/* Set the window-system policy before the context is made current. */ +PUBLIC void +dri_disable_present_wait_fence(struct dri_context *ctx, bool disable); PUBLIC void dri_flush(struct dri_context *cPriv, struct dri_drawable *dPriv, diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 25d249ecb7f1..574e5644ea93 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -1269,6 +1269,11 @@ enum pipe_context_param */ PIPE_CONTEXT_PARAM_EXPLICIT_PRESENT_FENCE, + /* Compatibility policy for window-system presentation. Disable only the + * driver's additional CPU completion wait, not submission or API fences. + */ + PIPE_CONTEXT_PARAM_DISABLE_PRESENT_WAIT_FENCE, + /* The minification/magnification switch-over point, the constant c of the * GL and ES specs. Value 1 selects c = 0.5, value 0 selects c = 0. * diff --git a/src/gallium/targets/dri/dri.sym.in b/src/gallium/targets/dri/dri.sym.in index f2ea9f564ff6..25f4f22e89d9 100644 --- a/src/gallium/targets/dri/dri.sym.in +++ b/src/gallium/targets/dri/dri.sym.in @@ -27,6 +27,7 @@ dri_query_renderer_string; dri_query_renderer_integer; dri_flush_drawable; + dri_disable_present_wait_fence; dri_flush; dri_invalidate_drawable; dri2GalliumConfigQuery*;