Skip to content

Add MIR_PIN_COMPOSITING_TO to allow pinning a certain provider for display#4958

Open
tarek-y-ismail wants to merge 1 commit into
mainfrom
composite-on-one-gpu
Open

Add MIR_PIN_COMPOSITING_TO to allow pinning a certain provider for display#4958
tarek-y-ismail wants to merge 1 commit into
mainfrom
composite-on-one-gpu

Conversation

@tarek-y-ismail
Copy link
Copy Markdown
Contributor

@tarek-y-ismail tarek-y-ismail commented May 22, 2026

Supersedes #4640

What's new?

Works around display warping on systems with Intel + Nvidia GPUs.

In a multi-GPU setup, Mir normally picks the best rendering provider per display — Intel for Intel-connected
displays, Nvidia for Nvidia-connected displays. When buffers cross GPU boundaries via DMA-BUF for compositing,
Nvidia assumes a 32-byte stride/alignment, ignoring the actual stride. This causes output windows to appear warped.

Setting MIR_PIN_COMPOSITING_TO=<devnode> (e.g. /dev/dri/renderD128) forces all displays to be composited by one GLprovider. For displays not physically on that GPU, Mir falls back to a CPU copy path (glReadPixels into a
CPU-addressable framebuffer), bypassing the DMA-BUF import entirely.

The device node is used as the identifier because it is unique per physical GPU, handling systems with multiple GPUs of the same driver type (e.g. two AMD cards). Available nodes can be discovered with ls /dev/dri/renderD*

How to test

On a system with Intel + Nvidia GPUs and a display on each:

 MIR_PIN_COMPOSITING_TO=/dev/dri/<intel render node> <mir-shell>

Verify that previously warped windows on the Nvidia-connected display are now rendered correctly.

You can find reproduction steps in #4640

@tarek-y-ismail tarek-y-ismail self-assigned this May 22, 2026
Copilot AI review requested due to automatic review settings May 22, 2026 12:31
@tarek-y-ismail tarek-y-ismail force-pushed the composite-on-one-gpu branch from 8dbdd9a to 88debcf Compare May 22, 2026 12:34
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an opt-in workaround for multi-GPU systems (notably Intel+iGPU + NVIDIA dGPU) by allowing Mir to pin compositor/provider selection to a single rendering provider across all displays via MIR_PIN_DISPLAY_TO, avoiding problematic cross-GPU DMA-BUF paths.

Changes:

  • Introduces GLRenderingProvider::driver() as a provider identifier and implements it across in-tree providers and test doubles.
  • Updates DefaultDisplayBufferCompositorFactory to honor MIR_PIN_DISPLAY_TO when choosing a rendering provider.
  • Adds driver identification logic for GBM-KMS (DRM driver name) and EGL-based providers (EGL vendor string).

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
include/platform/mir/graphics/platform.h Adds GLRenderingProvider::driver() API for provider identification (platform interface change).
src/server/compositor/default_display_buffer_compositor_factory.cpp Implements MIR_PIN_DISPLAY_TO handling when selecting a rendering provider per display.
src/platforms/renderer-generic-egl/buffer_allocator.h Declares driver() override for the generic EGL provider.
src/platforms/renderer-generic-egl/buffer_allocator.cpp Implements driver() (currently via EGL_VENDOR).
src/platforms/gbm-kms/server/buffer_allocator.h Declares driver() override for the GBM-KMS provider.
src/platforms/gbm-kms/server/buffer_allocator.cpp Implements driver() using drmGetVersion() to return the DRM driver name.
src/platforms/eglstream-kms/server/buffer_allocator.h Declares driver() override for the EGLStream-KMS provider.
src/platforms/eglstream-kms/server/buffer_allocator.cpp Implements driver() (currently via EGL_VENDOR).
tests/include/mir/test/doubles/stub_gl_rendering_provider.h Updates stub GL rendering provider to implement driver().
tests/include/mir/test/doubles/mock_gl_rendering_provider.h Updates mock GL rendering provider to mock driver().

Comment thread include/platform/mir/graphics/platform.h Outdated
Comment thread include/platform/mir/graphics/platform.h Outdated
Comment thread src/server/compositor/default_display_buffer_compositor_factory.cpp Outdated
Comment thread src/platforms/renderer-generic-egl/buffer_allocator.cpp Outdated
Comment thread src/platforms/eglstream-kms/server/buffer_allocator.cpp Outdated
Comment thread src/server/compositor/default_display_buffer_compositor_factory.cpp Outdated
@AlanGriffiths AlanGriffiths changed the title Add MIR_PIN_DISPLAY_TO to allow pinning a certain provider for display Add MIR_PIN_COMPOSITING_TO to allow pinning a certain provider for display May 22, 2026
@tarek-y-ismail tarek-y-ismail requested a review from Copilot May 22, 2026 13:46
@tarek-y-ismail tarek-y-ismail force-pushed the composite-on-one-gpu branch from 88debcf to 803a83e Compare May 22, 2026 13:47
@tarek-y-ismail
Copy link
Copy Markdown
Contributor Author

tarek-y-ismail commented May 22, 2026

Tried another approach that doesn't require ABI breaks. It also allows us to choose a specific GPU instead of relying on drm/EGL names that might be shared for multiple cards.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread src/server/compositor/default_configuration.cpp
…compositing

Works around warping on systems with intel + nvidia GPUs.

When buffers are transferred over DMA, when rendering on an intel GPU
and displaying on an nvidia GPU for example, nvidia GPUs assume the
buffers to have a stride/alignment of 32 bytes, ignoring the given
stride. This causes the output windows to appear warped.

This sidesteps the problem by forcing a single GL provider to composite
all displays. For compositors not on the pinned GPU, Mir falls back to
the CPU copy path: the pinned GPU renders into an FBO, glReadPixels
copies the result into a CPU-addressable buffer, and the display GPU
scans that out directly. This avoids any cross-GPU DMA-BUF import, so
the Nvidia driver never has a chance to misread the stride.

The value of MIR_PIN_COMPOSITING_TO should be the DRM device node
(e.g. /dev/dri/renderD128) of the GPU to pin to. Available nodes can
be discovered with `ls /dev/dri/renderD*`. For deviceless platforms
(e.g. mir:virtual), the module name is used as the identifier.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread src/server/graphics/default_configuration.cpp
Comment thread src/include/server/mir/default_server_configuration.h
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants