stride3d / stride3d/stride

GraphicsProfile.Level_11_2 is unusable on Direct3D (invalid feature-level mapping)

Open
#3,301 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C#
Stars
7.8k
Forks
1.2k
Avg merge
2d 17h
Merged PRs (30d)
49

Description

Release Type: GitHub (built from source)

Version: master (reproduced on 03edac194); the mapping has been wrong since the initial
open-source commit (2018), so this affects all versions.

Platform(s): Windows — Direct3D11 and Direct3D12 (Vulkan is unaffected).

Describe the bug

Setting Game Settings → Rendering → Default Graphics Profile = Level 11.2 crashes the game at
startup on the Direct3D backends. It is not hardware-dependent: it reproduces on any GPU, and even on
the WARP software rasterizer.

GraphicsProfile.Level_11_2 = 0xB200 has no corresponding native Direct3D feature level — real D3D
feature levels jump from 11_1 (0xB100) straight to 12_0 (0xC000) (Direct3D 11.2 was an API
revision that runs on FL 11_1 hardware, not a new feature level). GraphicsProfileHelper.ToFeatureLevel
raw-casts the profile to (D3DFeatureLevel) 0xB200, a value the API never returns, so device creation
can never satisfy it.

To Reproduce

  1. Create a game project on the Direct3D11 backend.
  2. Open the GameSettings asset → Rendering → set Default Graphics Profile = Level 11.2.
  3. Run the game → it crashes at startup with the exception below.
  4. (Optional) Switch the backend to Direct3D12 → also crashes (at device creation). Vulkan
    runs.

Minimal repro repository (code-only game + WARP software-renderer proof):
https://github.com/sasvdw/stride-graphicsprofile-level112-repro

Expected behavior

Level_11_2 should behave like every other profile — the game should launch (running at its real
capability tier, FL 11_1, the same as Level_11_1 and what its own tooltip claims: "~ Direct3D 11.2
/ Vulkan 1.1"), consistent with Vulkan. Only profiles a device genuinely cannot provide (e.g.
Level_11_x on FL10-only hardware) should be rejected.

Screenshots

N/A — the crash occurs during device creation, before anything renders.

Log and callstacks

System.InvalidOperationException: None of the graphics profiles [Level_11_2] are supported by the Graphics Device. The highest available profile is [Level_11_1].
   at Stride.Games.GraphicsDeviceManager.FindBestDevice(Boolean anySuitableDevice)
   at Stride.Games.GraphicsDeviceManager.<ChangeOrCreateDevice>g__ChangeOrCreateDevice|128_0(<>c__DisplayClass128_0&)
   at Stride.Games.GraphicsDeviceManager.ChangeOrCreateDevice(Boolean forceCreate)
   at Stride.Games.GraphicsDeviceManager.Stride.Games.IGraphicsDeviceManager.CreateDevice()
   at Stride.Games.GameBase.InitializeBeforeRun()
   at Stride.Games.GamePlatform.OnInitCallback()
   at Stride.Games.GameWindowWinforms.Run()
   at Stride.Games.GamePlatform.Run(GameContext gameContext)
   at Stride.Games.GameBase.Run(GameContext gameContext)
   at Program.<Main>$(String[] args)

(That is the Direct3D11 message. On Direct3D12 the availability check passes and it instead fails
later inside CreateDevice.)

Additional context

Per-backend behaviour with Level 11.2:

Backend Behaviour
Direct3D11 GraphicsAdapter.IsProfileSupported requests CreateDevice at 0xB200 and requires an exact match; it never matches, so the profile is reported unsupported and GraphicsDeviceManager throws (above).
Direct3D12 IsProfileSupported returns true unconditionally, so the availability check passes — then CreateDevice(0xB200) fails (the existing guard only clamps the lower bound < 11_0).
Vulkan Ignores the profile entirely and runs.

That Vulkan runs while both Direct3D backends fail is the tell: the fault is the Direct3D
profile→feature-level mapping, not the enum value.

Proof it is not a hardware/driver capability query. A standalone program mirroring Stride's exact
D3D11CreateDevice call against the WARP software rasterizer (source in the repro) produces:

WARP max feature level : 0xC100   [0x00000000]                    <- WARP supports FL 12_1
Request 0xB200 (11_2)  : FAILED   [0x80070057]  matched=0x0000    <- E_INVALIDARG
Request 0xB100 (11_1)  : SUCCEEDED   [0x00000000]  matched=0xB100

WARP — a software rasterizer reporting FL 12_1 — rejects 0xB200 with E_INVALIDARG while
accepting 0xB100, confirming the failure is the invalid requested value.

History. Present since the initial open-source commit (2018). The June-2025 "Documentation pass for
GraphicsDevice" (beb66ce9b) added the [Display("Level 11.2 ~ like Direct3D 11.2 / Vulkan 1.1")]
label, which makes an unusable option look legitimate in the settings dropdown.

Suggested fix. Map Level_11_2 to its real capability tier (FL 11_1) in the Direct3D
profile→feature-level mapping, so all backends accept it and run at 11_1 while genuine capability gaps
still fail. A fix PR follows.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at GraphicsProfileHelper.ToFeatureLevel and inspect the Direct3D11 and Direct3D12 profile-support and device-creation paths, focusing on GraphicsProfile.Level_11_2. Run the linked minimal repro on Direct3D11, Direct3D12, and Vulkan; done means Level_11_2 launches on both Direct3D backends at the FL 11_1 capability tier while genuine unsupported profiles remain rejected.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
computer-graphics, game-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.