diff --git a/docs/gallium/screen.rst b/docs/gallium/screen.rst index 279ef397f10..da8e7748692 100644 --- a/docs/gallium/screen.rst +++ b/docs/gallium/screen.rst @@ -621,6 +621,7 @@ The integer capabilities: * ``PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART``: Driver requests all draws using a non-fixed restart index to be rewritten to use a fixed restart index. * ``PIPE_CAP_SUPPORTED_PRIM_MODES``: A bitmask of the ``pipe_prim_type`` enum values that the driver can natively support. * ``PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART``: A bitmask of the ``pipe_prim_type`` enum values that the driver can natively support for primitive restart. Only useful if ``PIPE_CAP_PRIMITIVE_RESTART`` is also exported. +* ``PIPE_CAP_PREFER_BACK_BUFFER_REUSE``: Only applies to DRI_PRIME. If 1, the driver prefers that DRI3 tries to use the same back buffer each frame. If 0, this means DRI3 will at least use 2 back buffers and ping-pong between them to allow the tiled->linear copy to run in parallel. .. _pipe_capf: diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 6f436b00e90..d31a8531e3e 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -1991,6 +1991,7 @@ typedef struct __DRIDriverVtableExtensionRec { #define __DRI2_RENDERER_HAS_CONTEXT_PRIORITY_HIGH (1 << 2) #define __DRI2_RENDERER_HAS_PROTECTED_CONTENT 0x000e +#define __DRI2_RENDERER_PREFER_BACK_BUFFER_REUSE 0x000f typedef struct __DRI2rendererQueryExtensionRec __DRI2rendererQueryExtension; struct __DRI2rendererQueryExtensionRec { diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c index e117105fcb6..81fb73a8cd1 100644 --- a/src/egl/drivers/dri2/platform_x11_dri3.c +++ b/src/egl/drivers/dri2/platform_x11_dri3.c @@ -175,6 +175,7 @@ dri3_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf, dri2_dpy->dri_screen, dri2_dpy->is_different_gpu, dri2_dpy->multibuffers_available, + true, dri_config, &dri2_dpy->loader_dri3_ext, &egl_dri3_vtable, diff --git a/src/gallium/auxiliary/util/u_screen.c b/src/gallium/auxiliary/util/u_screen.c index 8c519ba4e5a..eb6be76b228 100644 --- a/src/gallium/auxiliary/util/u_screen.c +++ b/src/gallium/auxiliary/util/u_screen.c @@ -291,6 +291,7 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen, return 4; /* GLES 2.0 minimum value */ case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY: + case PIPE_CAP_PREFER_BACK_BUFFER_REUSE: return 1; case PIPE_CAP_GLSL_TESS_LEVELS_AS_INPUTS: diff --git a/src/gallium/frontends/dri/dri_query_renderer.c b/src/gallium/frontends/dri/dri_query_renderer.c index d9d2984bd64..eeebdb76572 100644 --- a/src/gallium/frontends/dri/dri_query_renderer.c +++ b/src/gallium/frontends/dri/dri_query_renderer.c @@ -74,6 +74,11 @@ dri2_query_renderer_integer(__DRIscreen *_screen, int param, if (!value[0]) return -1; return 0; + case __DRI2_RENDERER_PREFER_BACK_BUFFER_REUSE: + value[0] = + screen->base.screen->get_param(screen->base.screen, + PIPE_CAP_PREFER_BACK_BUFFER_REUSE); + return 0; default: return driQueryRendererIntegerCommon(_screen, param, value); } diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 908b74e8509..0bc713db69b 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -993,6 +993,7 @@ enum pipe_cap PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART, PIPE_CAP_SUPPORTED_PRIM_MODES, PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART, + PIPE_CAP_PREFER_BACK_BUFFER_REUSE, PIPE_CAP_LAST, /* XXX do not add caps after PIPE_CAP_LAST! */ diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c index b551a29d66a..3b3918cf6c1 100644 --- a/src/glx/dri3_glx.c +++ b/src/glx/dri3_glx.c @@ -375,6 +375,7 @@ dri3_create_drawable(struct glx_screen *base, XID xDrawable, if (loader_dri3_drawable_init(XGetXCBConnection(base->dpy), xDrawable, psc->driScreen, psc->is_different_gpu, has_multibuffer, + psc->prefer_back_buffer_reuse, config->driConfig, &psc->loader_dri3_ext, &glx_dri3_vtable, &pdraw->loader_drawable)) { @@ -1022,6 +1023,15 @@ dri3_create_screen(int screen, struct glx_display * priv) InfoMessageF("Using DRI3 for screen %d\n", screen); + psc->prefer_back_buffer_reuse = 1; + if (psc->is_different_gpu && psc->rendererQuery) { + unsigned value; + if (psc->rendererQuery->queryInteger(psc->driScreen, + __DRI2_RENDERER_PREFER_BACK_BUFFER_REUSE, + &value) == 0) + psc->prefer_back_buffer_reuse = value; + } + return &psc->base; handle_error: diff --git a/src/glx/dri3_priv.h b/src/glx/dri3_priv.h index c0e833c16ef..192238fde14 100644 --- a/src/glx/dri3_priv.h +++ b/src/glx/dri3_priv.h @@ -108,6 +108,7 @@ struct dri3_screen { void *driver; int fd; bool is_different_gpu; + bool prefer_back_buffer_reuse; /* fd for display GPU in case of prime */ int fd_display_gpu; diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c index 6e825f9a898..16cb1faf7b3 100644 --- a/src/loader/loader_dri3_helper.c +++ b/src/loader/loader_dri3_helper.c @@ -373,6 +373,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn, __DRIscreen *dri_screen, bool is_different_gpu, bool multiplanes_available, + bool prefer_back_buffer_reuse, const __DRIconfig *dri_config, struct loader_dri3_extensions *ext, const struct loader_dri3_vtable *vtable, @@ -392,6 +393,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn, draw->dri_screen = dri_screen; draw->is_different_gpu = is_different_gpu; draw->multiplanes_available = multiplanes_available; + draw->prefer_back_buffer_reuse = prefer_back_buffer_reuse; draw->have_back = 0; draw->have_fake_front = 0; diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h index 028e25dc070..615212c331a 100644 --- a/src/loader/loader_dri3_helper.h +++ b/src/loader/loader_dri3_helper.h @@ -134,6 +134,7 @@ struct loader_dri3_drawable { __DRIscreen *dri_screen; bool is_different_gpu; bool multiplanes_available; + bool prefer_back_buffer_reuse; /* DRI screen created for display GPU in case of prime */ __DRIscreen *dri_screen_display_gpu; @@ -204,6 +205,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn, __DRIscreen *dri_screen, bool is_different_gpu, bool is_multiplanes_available, + bool prefer_back_buffer_reuse, const __DRIconfig *dri_config, struct loader_dri3_extensions *ext, const struct loader_dri3_vtable *vtable,