Skip to content

Fall back to the system D3D12 runtime when the Agility SDK device factory cannot create a device - #2280

Merged
kunal-vaishnavi merged 3 commits into
microsoft:mainfrom
gianlucamazza:fix/dml-device-factory-fallback
Jul 13, 2026
Merged

Fall back to the system D3D12 runtime when the Agility SDK device factory cannot create a device#2280
kunal-vaishnavi merged 3 commits into
microsoft:mainfrom
gianlucamazza:fix/dml-device-factory-fallback

Conversation

@gianlucamazza

Copy link
Copy Markdown
Contributor

Problem

CreateDmlObjects (src/dml/dml_helpers.cpp) tries the Agility SDK device factory first and throws on any CreateDevice failure instead of reaching the existing system-runtime fallback branch:

if (SUCCEEDED(D3D12GetInterface(...)) && SUCCEEDED(sdk_config->CreateDeviceFactory(614, module_path, ...))) {
  THROW_IF_FAILED(d3d12_factory->CreateDevice(...));   // throws — fallback below is unreachable
} else {
  ...
  THROW_IF_FAILED(D3D12CreateDevice(...));
}

A known failure is DXGI_ERROR_ALREADY_EXISTS (0x887A0036): the process already holds a D3D12 device created with the system runtime — e.g. the XAML/WinUI compositor in a packaged app creates one at Window.Activate() — and devices from different D3D12 runtimes cannot coexist in one process. The plain D3D12CreateDevice branch handles exactly this situation, but is unreachable.

Whether this bites is OS-dependent: if the in-box D3D12 is older than the requested SDK version (614), CreateDeviceFactory itself fails and the fallback runs — an OS update silently flips the branch and breaks OgaCreateModel in XAML hosts.

Fix

Treat a factory CreateDevice failure like a factory creation failure: log a warning with the HRESULT and fall back to D3D12CreateDevice.

No regression for #612 (which introduced the Agility path): the new fallback only runs when the in-box runtime is >= the requested SDK version — i.e. the system runtime already contains the fixes the Agility dependency was added for. Related: #1054 (the pre-existing fallback branch for factory-creation failure).

Validation (real hardware)

Xbox Series S, Dev Mode UWP (OS 26100), ORT GenAI 0.13.2 DirectML + ORT 1.24.4, SmolLM2-360M INT4 (DML model built with the model builder):

Scenario vanilla DLL patched DLL
XAML app + DML EP 887A0036 at OgaCreateModel (reproduced 3x) loads in 886 ms, weights resident on GPU (315 MB), full decode (739 tokens)
XAML app + CPU EP works works (67.2 tok/s, unchanged)
Headless (no compositor) + DML EP works via Agility path works via Agility path

…tory cannot create a device

The Agility SDK device factory path in CreateDmlObjects throws on any
CreateDevice failure instead of reaching the existing system-runtime
fallback branch. A known failure is DXGI_ERROR_ALREADY_EXISTS
(0x887A0036): the process already holds a D3D12 device created with the
system runtime (e.g. the XAML/WinUI compositor in a packaged app), and
devices from different D3D12 runtimes cannot coexist in one process.
Whether this path fails is OS-dependent: on systems whose in-box D3D12
is older than the requested SDK version, CreateDeviceFactory fails and
the fallback already runs; an OS update silently flips the branch and
breaks model load.

Treat a factory CreateDevice failure like a factory creation failure:
log a warning with the HRESULT and fall back to D3D12CreateDevice.

Validated on Xbox Series S (Dev Mode UWP, OS 26100): a XAML app calling
OgaCreateModel with the DML EP failed with 887A0036 before this change
and loads and runs correctly through the fallback with it.
Copilot AI review requested due to automatic review settings July 7, 2026 20:51
@gianlucamazza
Gianluca Mazza (gianlucamazza) requested a review from a team as a code owner July 7, 2026 20:51
Gianluca Mazza (gianlucamazza) added a commit to gianlucamazza/xllama that referenced this pull request Jul 7, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR improves DirectML initialization robustness on Windows by allowing CreateDmlObjects to fall back to the in-box (system) D3D12 runtime when the D3D12 Agility SDK device factory is present but fails to create a device (e.g., DXGI_ERROR_ALREADY_EXISTS in XAML/WinUI hosts that already created a system-runtime D3D12 device).

Changes:

  • Treat Agility ID3D12DeviceFactory::CreateDevice failures as non-fatal and fall back to D3D12CreateDevice.
  • Add diagnostics that include the failing HRESULT when the Agility factory device creation fails.

Comment thread src/dml/dml_helpers.cpp Outdated
Comment thread src/dml/dml_helpers.cpp Outdated
@gianlucamazza

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree

Comment thread src/dml/dml_helpers.cpp Outdated
Address review feedback on microsoft#2280: the diagnostic strings hardcoded
1.614.0 while the factory used the agility_sdk_version constant, so
the two could drift apart when the SDK is updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0152PPkDwULuMR9hshirPXQx
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.

4 participants