Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/graphics-sdk/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ runs:
name: Resolve graphics SDK cache identity
shell: bash
env:
SDK_INPUTS: ${{ hashFiles('eng/graphics/dependencies.lock.json', 'eng/graphics/windows-runtime.json', 'eng/graphics/build.py', 'eng/graphics/DawnSymbolBoundary.cmake', 'eng/graphics/dawn_exports.py', 'eng/graphics/dawn_native_device.cpp', 'eng/graphics/dawn_native_device_internal.h', 'experiments/WebScene.NativeEngine.Probe/native/graphics/webscene/dawn_native_device.h', 'eng/graphics/install-windows-sdk.ps1', '.github/actions/graphics-sdk/action.yml') }}
SDK_INPUTS: ${{ hashFiles('eng/graphics/dependencies.lock.json', 'eng/graphics/windows-runtime.json', 'eng/graphics/build.py', 'eng/graphics/DawnSymbolBoundary.cmake', 'eng/graphics/dawn_exports.py', 'eng/graphics/dawn_native_device.cpp', 'eng/graphics/dawn_native_device_internal.h', 'experiments/WebScene.NativeEngine.Probe/native/graphics/webscene/dawn_native_device.h', 'experiments/WebScene.NativeEngine.Probe/native/graphics/dawn_linux_external_provider.h', 'eng/graphics/install-windows-sdk.ps1', '.github/actions/graphics-sdk/action.yml') }}
run: |
set -euo pipefail
{
Expand Down
12 changes: 7 additions & 5 deletions docs/validation/linux-exact-vulkan-instance-query-649.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ lifetime. The host supplies the X11 `Display` and visual ID and must call
`vkGetPhysicalDeviceXlibPresentationSupportKHR` through the returned resolver
before it creates an Xlib surface.

`bind_dawn_linux_external_device` consumes v2 and copies the public
`wgpu::Device` into the existing native owner. That reference retains the Dawn
backend and every borrowed Vulkan identity. Allocator identity checks now
include the instance, resolver and presentation capability mask. No Vulkan
object returned by this API may be destroyed by the consumer, and no second
Issue #651 subsequently advances `bind_dawn_linux_external_device` to v3 so it
can require balanced access to Dawn's exact queue; direct v2 consumers remain
ABI compatible. The binding copies the public `wgpu::Device` into the existing
native owner. That reference retains the Dawn backend and every borrowed Vulkan
identity. Allocator identity checks include the instance, resolver,
presentation capability mask and v3 queue-access capability. No Vulkan object
returned by this API may be destroyed by the consumer, and no second
instance/device or CPU transfer path is permitted.

## SDK and build contracts
Expand Down
6 changes: 6 additions & 0 deletions docs/validation/linux-external-image-interop-28.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ The X11 host must still call
unsupported displays fail before surface creation and cannot select a second
Vulkan instance or a CPU presentation route.

Issue #651 adds v3 without changing v1 or v2. V3 preserves the exact native
tuple and adds a balanced queue-access capability. Its acquire/release pair
holds Dawn's own device synchronization guard around external Graphite submit
and native present work, so those calls cannot race Dawn's submissions to the
same `VkQueue`.

The SDK now exposes `dawn_linux_external_device_factory`. An AppScene host with
an exact-device Dawn integration creates the WebGPU instance/adapter/device and
native allocator atomically, and returns one
Expand Down
61 changes: 61 additions & 0 deletions docs/validation/linux-vulkan-queue-access-651-28.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Exact Dawn Vulkan queue access

Issue #651 is a prerequisite of AppScene #265/#264 under WebScene #28. It
extends the Linux-only native-device bridge at Dawn revision
`2ca8cbfe0f8275aa0f739e7b6b4345a16e2f0378` without changing the v1 or v2 ABI.

## Dawn synchronization seam

The pinned Dawn source enables `Feature::ImplicitDeviceSynchronization` in
`PhysicalDevice.cpp`. Device initialization consequently creates the
ref-counted recursive `DeviceMutex`. Generated native API entry points acquire
`DeviceBase::GetGuard()` before queue operations. Vulkan
`Queue::SubmitPendingCommandsImpl` reaches `vkQueueSubmit` inside that guard,
and `Surface::APIPresent` explicitly holds the same guard through
`SwapChain::Present` and `vkQueuePresentKHR`.

The bridge therefore needs no private queue replacement and no patch to
`QueueVk`. `websceneDawnAcquireVulkanQueueV3` retains both an external
`WGPUDevice` reference and an internal `DeviceBase` reference, then holds the
exact `DeviceGuard`. `websceneDawnReleaseVulkanQueueV3` drops the guard before
either reference. External work in that interval is serialized with all Dawn
submit and present work on the returned exact queue.

## ABI and lifecycle

`websceneDawnQueryVulkanDeviceV3` preserves the v2 instance, physical device,
device, queue, resolver, Xlib capability, queue family and UUID identity. It
also requires Dawn's device-guard capability. Query and acquire validate the
public size/version and authoritative live registry before private device
memory is dereferenced. Foreign and stale tokens fail at lookup; non-Vulkan,
lost, disconnecting, disconnected and destroyed devices fail before access is
published.

Access scopes do not nest and acquire/release must run on the same thread. A
live-token registry rejects random, stale and double-release tokens without
dereferencing caller memory. Release removes the token from that registry
before unlocking, and unlocking occurs without the registry mutex held so Dawn
deferred work cannot invert the lock order. The C++ wrapper is non-copyable and
non-movable and keeps the complete public Linux device lifetime until its
same-thread destructor releases the token. Native operations inside the scope
must not call WebGPU or invoke user callbacks.

An active token prevents last-reference teardown. Explicit destroy or device
loss on another thread waits for the bounded external operation, then observes
the released guard; an access request already waiting on the guard rechecks the
device state and fails if teardown won. The release path remains available
after loss so the mutex and retained device references cannot be stranded.

## SDK boundary and remaining acceptance

The Linux symbol allowlist requires v1, v2, v3, acquire and release together.
The installed public header, provenance bridge sources, export inventory and
SDK manifest remain content-hashed, and their inputs participate in the exact
graphics SDK cache key. No private Dawn header enters the SDK.

Only `git diff --check` was run. Builds and authored tests remain unexecuted
under the directed fast policy. Physical Linux acceptance still requires the
AppScene external-memory and semaphore path to hold one access scope across
Graphite insertion/submission and native present, retire frames from private
completion primitives, and prove loss/teardown bounds and race-free
interleaving with Dawn submissions under validation layers.
2 changes: 1 addition & 1 deletion eng/graphics/DawnSymbolBoundary.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function(webscene_isolate_dawn)
target_link_options(webgpu_dawn PRIVATE "LINKER:-exported_symbols_list,${CMAKE_BINARY_DIR}/webscene-dawn.exports")
elseif(UNIX)
file(WRITE "${CMAKE_BINARY_DIR}/webscene-dawn.exports"
"{ global: wgpu*; websceneDawnQueryVulkanDeviceV1; websceneDawnQueryVulkanDeviceV2; local: *; };\n")
"{ global: wgpu*; websceneDawnQueryVulkanDeviceV1; websceneDawnQueryVulkanDeviceV2; websceneDawnQueryVulkanDeviceV3; websceneDawnAcquireVulkanQueueV3; websceneDawnReleaseVulkanQueueV3; local: *; };\n")
target_link_options(webgpu_dawn PRIVATE "LINKER:--version-script=${CMAKE_BINARY_DIR}/webscene-dawn.exports")
endif()
# Windows exports only functions decorated by WGPU_SHARED_LIBRARY;
Expand Down
7 changes: 7 additions & 0 deletions eng/graphics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ configuration controls its runtime. Windows build/link and runtime dependency
validation (including D3D shader compiler packaging) remain hardware-runner
gates. Never exchange CRT-owned allocations between these libraries.

Linux also exports the additive v3 query and balanced
`websceneDawnAcquireVulkanQueueV3`/`websceneDawnReleaseVulkanQueueV3` pair. An
active access retains the exact public device and Dawn object and holds the
same `DeviceGuard` used by generated Dawn API entry points and Vulkan surface
presentation. It serializes external submit/present work with Dawn without
publishing a second queue or any private Dawn type.

`GraphicsDependencies.cmake` verifies the SDK before importing it, including revision, RID, lock, settings, complete installed file inventory and content hashes. CMake cannot silently choose another `Dawn_DIR`. A dependency roll requires rebuilding headers and libraries together. Package manifests prove integrity and provenance, not API conformance or hardware execution.

Dependency checkouts explicitly set both `core.autocrlf=false` and `core.eol=lf`: upstream `text=auto` attributes otherwise permit Windows-native CRLF license bytes. The optional Dawn C++ module wrapper is disabled; WebScene uses generated C/C++ headers and does not require compiler module scanning. This avoids a hosted GCC configuration that passed the language feature test but lacked CMake import-graph discovery support.
Expand Down
5 changes: 4 additions & 1 deletion eng/graphics/dawn_exports.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ def inspect_exports(library, rid):
symbol = match.group(1)
symbols.append(symbol[1:] if rid.startswith("osx-") and symbol.startswith("_") else symbol)
allowed_bridge = ({"websceneDawnQueryVulkanDeviceV1",
"websceneDawnQueryVulkanDeviceV2"}
"websceneDawnQueryVulkanDeviceV2",
"websceneDawnQueryVulkanDeviceV3",
"websceneDawnAcquireVulkanQueueV3",
"websceneDawnReleaseVulkanQueueV3"}
if rid.startswith("linux-") else set())
unexpected = [name for name in symbols
if not re.fullmatch(r"wgpu[A-Z][A-Za-z0-9]*", name)
Expand Down
Loading
Loading