Skip to content

Honor the surface's alphaMode in the D3D swapchain - #85

Open
d3x0r wants to merge 1 commit into
google:mainfrom
d3x0r:d3d-alphamode-composition
Open

d3x0r wants to merge 1 commit into
google:mainfrom
d3x0r:d3d-alphamode-composition

Conversation

@d3x0r

@d3x0r d3x0r commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

SwapChainD3D hardcoded DXGI_ALPHA_MODE_IGNORE even though PhysicalDeviceD3D advertises Premultiplied as a supported alpha mode, so a surface configured for per-pixel transparency was validated and then composited as opaque.

DXGI rejects a non-opaque alpha mode on CreateSwapChainForHwnd, so a premultiplied HWND surface is instead created with CreateSwapChainForComposition and bound to the window through a DirectComposition visual whose device, target and visual hang off the swapchain and are moved across when a swapchain is recycled - leaving them behind would destroy the target while Present kept succeeding, and the window would go blank. DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH is masked out for composition swapchains, which DXGI refuses outright, and MakeWindowAssociation is skipped since a composition swapchain is not associated with a window. Recycling an existing swapchain now also requires the alpha mode to be unchanged: AlphaMode is fixed at creation, so without that check a runtime configure() with a different alpha mode silently adopted the old swapchain and dropped the request. dcomp.lib is added to both the CMake and GN builds.

For the transparency to be visible the application's window must have been created with WS_EX_NOREDIRECTIONBITMAP; otherwise the window's redirection surface sits behind the DirectComposition visual and stays opaque.

Split out of #69 at review request so the Windows side can be looked at separately; the Vulkan half of that change is unaffected by this one. The branch is based on current main, and the two PRs touch disjoint files. ManualSurfaceTest.cpp is deliberately absent here: the note explaining the GLFW limitation below belongs on top of the T key added in #69, so it should follow once that lands rather than duplicate it.

Verified on Windows 11 + NVIDIA with a Node addon embedding Dawn, driving three.js WebGPURenderer over a WS_EX_NOREDIRECTIONBITMAP window on D3D12. This cannot be demonstrated through ManualSurfaceTest: GLFW implements GLFW_TRANSPARENT_FRAMEBUFFER with DwmEnableBlurBehindWindow, so the window keeps a redirection surface, and WS_EX_NOREDIRECTIONBITMAP has no effect when applied after CreateWindowEx.

Known follow-ups carried over from the Gerrit comments on the combined change, not yet addressed here: the code-history comment, break -> if {} else {}, whether UsesComposition's HWND check is redundant with PhysicalDevice::GetSurfaceCapabilities (and whether that capability computation should move here so the logic is local), and caching the DComp device on DeviceD3D through per-backend virtual overrides so the right IUnknown is passed. dcomp.lib availability for UWP has not been checked.

🤖 Generated with Claude Code

SwapChainD3D hardcoded DXGI_ALPHA_MODE_IGNORE even though PhysicalDeviceD3D
advertises Premultiplied as supported, so a surface configured for per-pixel
transparency was validated and then composited as opaque.

DXGI rejects a non-opaque alpha mode on CreateSwapChainForHwnd, so a
premultiplied HWND surface is created with CreateSwapChainForComposition and
bound to the window through a DirectComposition visual, whose lifetime follows
the swapchain across recycling. Recycling an existing swapchain now also
requires the alpha mode to be unchanged, since AlphaMode is fixed at creation
and a composition swapchain is not interchangeable with an HWND one.

Split out of the Vulkan alphaMode change so the Windows side can be reviewed
separately.
@github-actions

Copy link
Copy Markdown

👋 Thanks for your contribution! Your PR has been imported to Gerrit.
Please visit https://dawn-review.googlesource.com/c/dawn/+/341475 to see it and CC yourself on the change.
After iterating on feedback, please comment on the Gerrit review to notify reviewers.
All reviews are handled within Gerrit, any comments on the GitHub PR may be missed.
You can continue to upload commits to this PR, and they will be automatically imported
into Gerrit.

copybara-service Bot pushed a commit that referenced this pull request Sep 15, 2026
`SwapChainVk::ChooseConfig` hardcoded `VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR` outside of Android, so a surface configured with a transparent `alphaMode` was validated and then composited as opaque even though the adapter advertised the mode as supported.

The Vulkan enum is now converted directly from the WebGPU one. `Auto` and unsupported modes are already resolved and validated in `Surface.cpp` against the capabilities `PhysicalDeviceVk` reports, so the Android-only fallback loop is gone and the remaining condition is a `DAWN_CHECK`. This is not an Android regression: `PhysicalDeviceVk` lists the modes in the same order the old loop preferred them (OPAQUE, PRE, POST, INHERIT) and `Surface.cpp` resolves `Auto` to `alphaModes[0]`, so `Auto` reproduces the previous behaviour exactly.

`ManualSurfaceTest` gains a `T` key that creates a window with `GLFW_TRANSPARENT_FRAMEBUFFER`, and on such a window the clear-cycle render mode cycles a premultiplied alpha, so cycling alpha modes with `A` has a visible effect against the desktop.

The D3D side has been split into a separate PR as requested: #85

This is an imported pull request from
#69

GITHUB_PR_HEAD_SHA=07e6602ad886faf3d81eaebd918c67aaad6d550a
ORIGINAL_AUTHOR=Jim B <d3x0r@users.noreply.github.com>
GitOrigin-RevId: 7dde90e
Change-Id: Ieb349a3ba4b5f094ba10102b45d17c6fb9efbfc1
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/314855
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
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.

1 participant