Monogame: [DirectX] Reach profile can crash on DX10+ GPUs that don't support intermediate feature levels

Created on 22 Jun 2017  ·  11Comments  ·  Source: MonoGame/MonoGame

Some GPUs support DirectX 10_0 feature level, but don't support all 9_x feature levels.

In my case, a laptop GPU supports only 10_0 & 9_1 (no 9_2 & 9_3).
Shaders that use ps_4_0_level_9_3 will crash on that laptop when using _Reach_ GraphicsProfile.
They work with other GPUs under Reach and they work on this laptop when using HiDef profile.

Problem is that MG tries to make a device with feature level 9_3 first when GraphicsProfile is set to Reach. When that fails 9_1 device is created, although 10_0 is supported. This results in crash when trying to use 9_3 shaders.

Proposed solution by @Jjagg is that MonoGame should always try to create a device with the highest possible feature level to prevent this issue. Even under Reach.

DirectX

All 11 comments

We need to take care of checking graphics capabilites (what is currently the GraphicsProfile, but will likely be more granular when we resolve #1941) everywhere before we can implement the fix I proposed. If we'd implement the fix right now, devs won't be able to catch errors due to the GraphicsProfile being too low when their GPU supports a higher feature level so players might get unexpected crashes.

Some GPUs support DirectX 10_0 feature level, but don't support all 9_x feature levels.

That is really odd... but laptops are weird things.

Proposed solution by @Jjagg is that MonoGame should always try to create a device with the highest possible feature level to prevent this issue.

My concern is the same as @Jjagg on this...

devs won't be able to catch errors

We would have to prevent people from accidentally using HiDef features when they intended to be limited by Reach.

An alternate proposal is to detect this weird case specifically. Check to see if a higher feature level is supported when 9.3 or 9.2 is not. If we detect this case... we use the higher feature level, but also spew a message to the output window for a developer to see.

Make sense?

We would have to prevent people from accidentally using HiDef features when they intended to be limited by Reach.

I have a PR (#5451) to check for Reach features but it's far from complete, one example are shaders, we don't have the information of shader version.
IMO, the best way to do that is to create a 9.1 device for Reach profile which will throw errors if you try to use features above this level (essentially emulating a 9.1 card). In that case #5451 will catch some cases early and throw a more helpful message.

I think key point here is, if some GPU supports some feature level, it is not guaranteed that it also supports all lower feature levels.

It doesn't make sense to crash the game on users machine if his GPU supports higher feature level that we wanted to set, but doesn't support that particular feature level (that we wanted to set).

In my case I just changed to HiDef. Reach profile hasn't aged well anyway. Still I wouldn't want a crash if similar thing happened with HiDef (does MG ties HiDef to specific feature level?). So in case a desired feature level isn't supported, MG should definitely first check if any higher level is supported (and spew a message to the output window for a developer to see, like @tomspilman suggested)

Considering how rare this issue is, I think it's fine to fix checking the profile caps first, when that's done we can just create a device with the highest supported profile.

@tomspilman if you're fine with what I proposed in #1941 I'll take a look at taking care of that in the coming weeks (I just finished exams, so heaps of free time atm). We will probably want to add at least an unrestricted graphics profile. Other profiles are still up for discussion and can be added later.

Is this old XNA sample of any use - it shows source of exactly which caps are needed for the 2 profiles

http://xbox.create.msdn.com/en-US/education/catalog/utility/graphics_profile_checker

Nice, that will definitely be useful :)

This might be handy - I came across an interesting blog article which mentions this specific quirk (as well as a heap of other useful info regarding feature levels):

https://blogs.msdn.microsoft.com/chuckw/2012/06/20/direct3d-feature-levels/

Most hardware that supports a given feature level supports all the feature levels below it, but that is not actually required behavior. There are a few older integrated graphics parts that only support Feature Level 9.1 and Feature Level 10.0, but not 9.2 or 9.3. This also means that while most 10.x or 11.x class cards will also have support for Feature Level 9.1, 9.2, and 9.3 through the Direct3D 9 “10level9” layer, they aren’t required to.

@MichaelDePiazzi

a few older integrated graphics parts that only support Feature Level 9.1 and Feature Level 10.0, but not 9.2 or 9.3.

If that's the only known case then I don't see a problem with the current implementation in monogame, since all cards support at least 9.1. This issue is something to consider only if it's decided to lower HiDef to use strictly 9.3.

Going back to the original issue...

@zigzag312

Shaders that use ps_4_0_level_9_3 will crash on that laptop when using Reach GraphicsProfile.

Reach format doesn't support SM3.0. So this is to be expected.

They work with other GPUs under Reach [...]

The real issue here is that MG didn't throw an error during Development to let you know that you are using features above the Reach (9.1) limitations.

If we make sure we do the proper checks we can just create the highest possible level device and all this won't matter. In tests we can create devices for a specific feature level if deemed necessary.

Fixed in #6394.

Was this page helpful?
0 / 5 - 0 ratings