Skip to content

【Beta】Enable Vulkan Renderer - #1032

Closed
LFRon wants to merge 7541 commits into
linuxdeepin:master-backup-20260717from
LFRon:feat-and-refactor/enable-vulkan-renderer
Closed

【Beta】Enable Vulkan Renderer#1032
LFRon wants to merge 7541 commits into
linuxdeepin:master-backup-20260717from
LFRon:feat-and-refactor/enable-vulkan-renderer

Conversation

@LFRon

@LFRon LFRon commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

这个PR让treeland内调用的Qt RHI Backend切换到Vulkan, 然后通过wlroots Vulkan后端进行上屏
注意: 该PR现在需要patched wlroots, 需要合并的补丁在 Better-Deepin-Repo/wlroots-0.19-deepin@c9240cd

kennylevinsen and others added 30 commits November 7, 2024 10:22
This constant can be useful whenever one has to deal with timespecs, so
let's move it to the header.
Perform a primitive garbage collection of buffers that have not been
used in the past 10 seconds, an arbitrarily selected number.

As garbage collection also makes span buffer allocation happen much more
often, logging on allocation activity leads to a lot of log noise so get
rid of that while at it.
This is the preferred name since Meson 1.1.
Signed-off-by: xurui <xurui@kylinos.cn>
Signed-off-by: xurui <xurui@kylinos.cn>
Signed-off-by: xurui <xurui@kylinos.cn>
Signed-off-by: xurui <xurui@kylinos.cn>
If we are trying directly scan-out a shm buffer, we create a temporary
buffer pool to instantiate a wl_buffer from, created in accordance to
our buffers size. If the buffer has an offset, it will end up out of
bounds of the created pool.

Extend the temporary pool by the buffer offset to compensate. Matching
the original pool size does matter unless we want to optimize away the
temporary pool to reduce mappings in the parent compositor.
Passing the wlr_client_buffer directly has a downsides because a
fresh wlr_buffer pointer is passed each output commit instead of
cycling through existing wlr_buffer objects:

- The FDs are re-imported each time in the backend.
- Any import failure is logged every output commit [1].
- The Wayland backend cannot handle import failures without
  roundtripping each output commit [2].

Instead, extract the source buffer from the wlr_client_buffer and
pass that to the backend.

[1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4836
[2]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4841
create_immed() is a bit dangerous because on failure, either the
connection is closed or the buffer is silently ignored.

Use create() with a roundtrip to figure out whether the import
succeeded.
We don't need to use the private header in these files.
We don't need any custom behavior since d8c0707 ("backend/drm: return
secondary backend DRM FD").
We assumed that all atomic backends supported syncobj, but gud does not.
Instead, query DRM_CAP_SYNCOBJ_TIMELINE when using the atomic backend.
wlr_drm_format_set_remove lets you remove a modifier from the specified
format, useful for filtering implicit modifiers.
If init_drm_renderer failed, it would destroy the renderer but would not
set it to NULL, leading to use-after-free.

NULL the renderer after destroying it.
We create a renderer for the sole purpose of blitting buffers from a
primary renderer that we might not be able to scan-out from. If we end
up with the pixman renderer, it either won't work becuase it cannot
import dmabufs from the primary renderer, or won't have any effect
because the primary renderer already uses dumb buffers.

We test for DMA-BUF capabilities specifically to make it clear what our
interest is, rather than focusing too much on the pixman renderer.
The presence of the renderer is what matters with respect to blitting.
Having a parent without the need to blit will be allowed later.
This helps readability a bit and will make error handling in a coming
commit easier.
If an mgpu device does not have a renderer, continue without one rather
than ignoring it entirely. It is not guaranteed that we will be able to
scan out to it in any particular configuration, but that is true for any
output regardless, and having the output visible is not harmful even if
it cannot light up.

To proceed safely, we strip implicit modifier support from all planes,
while avoiding duplication of the same logic for mdgpu_formats.

This helps GUD and DisplayLink scenarios.
wlr_renderer and wlr_allocator will print out errors as they go, and end
with a final error if they fail to create anything. The caller of this
function will also log when it fails.

Skip the redundant errors emitted here.
Client buffers backed by wl_shm is aggressively released, in which case
we are not allowed to access it. Locking an already released buffer and
later unlocking it will also re-trigger release, confusing clients.

As a quick workaround, guard the unwrap by checking if the buffer is
locked, which will be the case for non-wl_shm buffers.
wl_buffer.release event delivery becomes undefined when using the
linux-drm-syncobj-v1 protocol, so we need to wait for buffer
release via a timeline point instead.

The protocol requires both wait and signal timelines to be set, so
we need to create one when the compositor only supplies a wait
timeline.
We were always creating a custom mode object when the output didn't
have a fixed mode. This is important to handle two cases:

- Virtual outputs with no concept of fixed modes.
- DRM outputs with a list of fixed modes but with a custom mode set.

However, in the case where an output didn't have a fixed mode and
was disabled, we were also creating the custom mode object. Clients
would then see a "ghost" mode: a mode object with no properties at
all.

Fix this by only creating the custom mode object if the output is
enabled.

Fixes: 5de9e1a ("wlr-output-management: Send custom modes to clients")
Closes: swaywm/sway#8420
It got removed in 3ed1268 ("render: Nuke old read pixels API")

Signed-off-by: Guido Günther <agx@sigxcpu.org>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sorry @LFRon, your pull request is larger than the review limit of 150000 diff characters

@LFRon

LFRon commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

现在的这个实现我在Mesa RADV/ANV驱动上都检查过除了Blur效果外没有问题了

@LFRon LFRon changed the title 【Experimental】Enable Vulkan Renderer 【Beta】Enable Vulkan Renderer Jul 16, 2026
@LFRon
LFRon force-pushed the feat-and-refactor/enable-vulkan-renderer branch 5 times, most recently from 42c5204 to fca7de4 Compare July 17, 2026 04:25
@deepin-bot

deepin-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown

TAG Bot

New tag: 0.8.15
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #1163

@LFRon
LFRon force-pushed the feat-and-refactor/enable-vulkan-renderer branch from fca7de4 to 94efc4f Compare July 17, 2026 07:46
@github-actions

Copy link
Copy Markdown

CLA Assistant Lite bot:

如果你是以企业贡献者的身份进行提交,请联系我们签署企业贡献者许可协议
If you submit as corporate contributor, please contact us to sign our Corporate Contributor License Agreement

感谢您的提交,我们非常感谢。 像许多开源项目一样,在接受您的贡献之前,我们要求您签署我们的个人贡献者许可协议。 您只需发布与以下格式相同的评论即可签署个人贡献者许可协议
Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you all sign our Individual Contributor License Agreement before we can accept your contribution. You can sign the Individual Contributor License Agreement by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA.

0 out of 12 committers have signed the CLA.
@kennylevinsen
@emersion
@agx
@vyivel
@Nefsen402
@tokyo4j
@tych0
@Consolatis
@mstoeckl
@liupeng
@sunzhguy
@llyyr
Consolatis, liupeng, sunzhguy seem not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You can retrigger this bot by commenting recheck in this Pull Request

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: LFRon

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

LFRon added 10 commits July 17, 2026 17:16
… patched wlroots)

Select Qt Quick Vulkan when WLR_RENDERER=vulkan is requested while keeping the
default OpenGL/GLES path unchanged. Wire linux-dmabuf to the wlroots renderer
and use the patched wlroots Vulkan helpers to render Qt Quick directly into
compositor-owned output buffers.

Keep client buffers on the wlroots texture path: surfaces still become
wlroots-provided QSGTextures for read-only Qt sampling, with per-pass sampling
preparation and provider lifetime fixes. Do not add syncobj support or a
Treeland-owned client dmabuf cache/fence/direct-import pipeline.

Acquire and release wlroots render buffers around Qt RenderControl frames.
Disable Vulkan backdrop blits that copy from the output buffer, use a software
cursor for the first Vulkan path, and create a separate preserve render target
for overlay passes so Vulkan load/store state is fixed before QRhi creates the
render pass.

With the patched wlroots 0.19 helpers installed, the explicit Vulkan path now
displays DDM, dde-shell, DTK and ordinary clients correctly.
Remove the branch-local VulkanSamplingPolicy API and the Raw/ShmUpload
classification in WSGTextureProvider. All valid wlroots Vulkan textures are now
declared to Qt as shader-read sampled textures, while per-render-pass sampling
still uses wlroots' Vulkan helper to prepare and finish the active texture set.

Keep the established Vulkan correctness boundaries intact: client buffers remain
wlroots-provided QSGTextures, output rendering still uses wlroots render-buffer
acquire/release, and primary output renderers are not exposed as texture
providers on Vulkan.

Also remove high-frequency success debug logs from the Vulkan sampling/cache
paths and keep the Vulkan RenderBufferBlitter fallback as an explicit backdrop
source policy.
Add a waylib WPresentation wrapper around wlroots wp_presentation and attach it for the Vulkan backend. Track surfaces actually sampled by the Qt Quick render pass, then submit textured-on-output feedback before committing the matching wlroots output buffer.

Fix the qwlroots wlroots-0.19 presentation create signature, keep the presentation global lifetime owned by wlroots, and add the centralized waylib.protocols.presentation logging category.
Keep cursor contents on the existing QtQuick/software cursor path, but stop binding cursor item geometry to the live cursor position when it is rendered through OutputLayer. Schedule output frames on cursor motion and compute cursor layer placement from wlroots cursor/output coordinates during layer rendering.

This avoids dirtying the main QML scene on cursor movement while preserving the existing cursor content generation and fallback behavior.
Pair Vulkan texture sampling prepare with a matching per-pass finish.
Release prepared wlroots textures in LIFO order after Qt records the pass
commands, continue best-effort on failures, and fail the render pass if
any release cannot be recorded.

Defer destruction of Vulkan render resources that may still be referenced
by the current QRhi frame. Let WOutput swapchain configuration optionally
return the replaced swapchain, retire old Vulkan swapchains in
WBufferRenderer, and retire old WRenderHelper BufferData/render target
wrappers until several completed frames after rc()->endFrame().

Keep non-Vulkan paths on the existing immediate cleanup behavior. This
prevents stale foreign texture ownership and avoids destroying wlroots
VkImages while Qt/Vulkan command buffers may still reference them.
When wrapping wlroots Vulkan textures for Qt Quick sampling, create an
exact VkImageView using the original format instead of Qt's mapped
format. Qt's QSGRhiSupport maps both VK_FORMAT_A2R10G10B10_UNORM_PACK32
and VK_FORMAT_A2B10G10R10_UNORM_PACK32 to a single QRhiTexture::RGB10A2
format, but the Vulkan backend creates an A2B10G10R10 view first. This
causes channel order mismatches for A2R10 images (e.g. BGRA buffers from
Electron apps like Youdao Note) resulting in color corruption.

The fix:
- Create a candidate QRhiTexture wrapper for the external VkImage
- Replace Qt's default image view with an exact view using the wlroots
  texture's actual format
- Apply correct alpha swizzle based on wlroots texture's has_alpha flag
- Reject A2R10G10B10 format that cannot be precisely represented without
  MUTABLE_FORMAT

Also includes:
- Add qw_vulkan namespace for type-safe wlroots Vulkan API wrappers
- Add WVulkanTrace debug tracing system (enabled via WAYLIB_VULKAN_TRACE=1)
- Improve texture provider lifecycle with 4-frame delayed cleanup for
  Vulkan resources
- Add helper methods to qw_client_buffer for texture/source access

Fixes color corruption in Electron-based applications (e.g. Youdao Note)
running under the Vulkan renderer backend.
Avoid QRhi texture readback for treeland interactive capture. The Vulkan backend wraps wlroots-owned images for rendering/sampling, not for Qt-side transfer readback, which can leave portal screenshot clients waiting forever.

Route one-shot capture through qw_buffer/qw_renderer-based WBufferDumper, use the output viewport's last buffer for output/region sources, and report frame failures when image creation or client-buffer copy fails.
Cursor output layers cache their rendered buffer and previously only redrew when geometry or render state changed. With the Vulkan render path, cursor shape/image updates can keep the same geometry, so the compositor could keep committing a stale cursor layer until another output repaint happened.
Track WQuickCursor content revisions and mark cursor layers dirty when the cursor content changes. Schedule the owning output conservatively: reuse an already-dirty output when possible, otherwise force an output update so  software-composited Vulkan cursors repaint in the same frame. Avoid duplicate dirty notifications when WCursorImage already emitted imageChanged.

Also route Vulkan textures created during updatePaintNode() through the current render pass prepare list, so late-created cursor textures are finished together with the rest of the pass instead of being prepared out of band.
Keep QRhi's native output layout in sync with the GENERAL layout
recorded by the wlroots release barrier, so reused render buffers get
the required transition back to COLOR_ATTACHMENT_OPTIMAL.

Treat Vulkan rendering as an all-or-nothing frame transaction. Preserve
QRhi begin/end results, reject output commits after acquire, release,
submission, or device-loss failures, and terminate the compositor on
unrecoverable scene graph errors.

Stage sampled texture candidates until preparation succeeds and keep the
previous valid texture on failure. Restrict active provider scans to the
Vulkan path so GLES2 and software rendering retain their existing
behavior.

Replace the four-frame Vulkan cleanup delay with exact retirement after
successful synchronous offscreen completion and output state handling.
Destroy QRhi wrappers before owned wlroots textures and buffer locks,
and remove the forced updates previously used to advance cleanup. Also drop unsupported async-offscreen claims from Vulkan tracing.

This keeps the existing wlroots texture -> Qt Quick composition -> wlroots output buffer architecture without modifying Qt or wlroots.
Vulkan renderers may expose DMA-BUF import formats only through explicit
modifiers. Advertising the legacy wl_drm global unconditionally lets clients
select the implicit DMA-BUF path even when the renderer cannot import
DRM_FORMAT_MOD_INVALID buffers.

Add qwlroots helpers to inspect the renderer's DMA-BUF texture format set and
check for DRM_FORMAT_MOD_INVALID. Only create the legacy wl_drm global when the
renderer actually supports implicit DMA-BUF import; otherwise keep
zwp_linux_dmabuf_v1 as the DMA-BUF path exposed to clients.

This preserves the GLES2 compatibility case while avoiding a misleading legacy
global for the Vulkan renderer. wl_drm remains owned and destroyed by wlroots as
before.
@LFRon
LFRon force-pushed the feat-and-refactor/enable-vulkan-renderer branch from d815183 to 8e9532d Compare July 17, 2026 09:18
Treeland now builds against the vendored wlroots under 3rdparty/wlroots
instead of the previously patched wlroots-upstream tree. The Vulkan render
path still needs the wlroots Vulkan helper entry points used by qwlroots and
waylib to bridge Qt Quick RHI rendering with wlroots-owned buffers and
textures.

Port the existing Vulkan helper patch into the vendored wlroots tree:

- expose render-buffer VkImage attributes for compositor-owned output buffers
- record acquire/release barriers around Qt rendering into wlroots buffers
- prepare wlroots Vulkan textures before Qt samples them
- flush pending stage uploads for shm/pixel textures
- wait DMA-BUF fences and return foreign texture ownership after sampling

The change is limited to the Vulkan renderer. GLES2 behavior is unchanged,
and this does not enable the linux-drm-syncobj protocol or add a separate
Treeland-side client buffer import/cache pipeline.

Verification:
- cmake --build --preset default
- ctest --test-dir build --output-on-failure
- nm -D build/wlroots/libwaylib-wlroots.so confirms the new helpers are exported
@llyyr

llyyr commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Can you guys fix your CLA bot? It mentions every wlroots contributor every time you guys force push a PR with the wlroots tree, I have over 50 email notifications for this

@LFRon

LFRon commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

Can you guys fix your CLA bot? It mentions every wlroots contributor every time you guys force push a PR with the wlroots tree, I have over 50 email notifications for this

I will fix it tomorrow with force rebase

@LFRon LFRon closed this Jul 18, 2026
@LFRon
LFRon deleted the feat-and-refactor/enable-vulkan-renderer branch July 18, 2026 04:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.