feature levels

Started by
3 comments, last by 16bit_port 12 years, 9 months ago
My understanding of feature levels is that with it you can use the D3D11 API on older video cards that don't support D3D11 but with two caveats : one being that the client OS must be Vista or higher and the second is that D3D11-exclusive features are not available to those non-D3D11 cards.

Question 1 :
If the device is created with feature level 9.0 (card only supports 9.0), what happens under the hood when a D3D11 function is called? Like for example somewhere in my code I have a call to D3D11CreateDevice(), but since it's running on the 9.0 feature level, is the D3D9-equivalent of the function called instead (in this case IDirect3D9::CreateDevice)?

Question 2 :
Same situation as the previous (using feature level 9.0) but this time a hull and a domain shader is created in the code. What happens? Does it crash at that point or are those calls just simply ignored?

Question 3 :
I came across a year-old thread and in it :

N3Xus : I have another question: I have a DX10 compatible graphics card, if I use the feature level for DX10-SM4.0, does the new multithreading DX11 thing work?
MJP : Yes you can


Correct me if I'm wrong but isn't the multi-threading exclusive to DX11 only? If what I said before is true (D3D11-exclusive features are not available to those non-D3D11 cards), how can the multi-threading work on a DX10 card? Is MJP implying that that will only work with a reference rasterizer?

Question 4 :
In this MSDN article, it says "In prior versions of Direct3D, you could find out the version of Direct3D the video card implemented, and then program your application accordingly." and then it goes on to talk about feature levels. Maybe I'm reading too much into that sentence but is it implying that with the introduction of feature levels, you no longer have to do something like this (?) :

if( D3D11 is supported in the hardware )
// render with D3D11 code
else if( D3D10 is supported in hardware )
// render with D3D10 code
else if( D3D9 is supported in hardware )
// render with D3D9 code

and that with feature levels you just have to write one "version" of code (D3D11) and it will implicitly handle all different versions (D3D 9/10) and you don't have to do those nasty if-cases?

If you can directly answer each of these questions and not jumble it into one generic answer, that would help me a lot. Thanks! =)
Advertisement
[font="Calibri"]1.[/font] [font="Calibri"]The Direct3D 11 runtime will call the Direct3D 9 (ex) driver. The Direct3D 9 runtime is not used.[/font]

[font="Calibri"]2.[/font] [font="Calibri"]It should never crash. Calls that are not supported should return an error code. Not tested by my own as I try to not make calls that are not supported.[/font]

[font="Calibri"]3.[/font] [font="Calibri"]There is a runtime level emulation for this feature if the driver doesn’t support it. You can still benefit from it but you need to be carefully as it may have a different performances behavior as real driver support.[/font]

[font="Calibri"]4.[/font] [font="Calibri"]You still might need to write feature level specific code if you need fallbacks for techniques that are not supported by lower feature levels. One case is using a compute shader vs. pixel shader for post processing. But in general you need to write much less specific code.[/font]

2. If you try to do something not supported by the feature level of the device, the call will fail and (if you have it enabled) the debug output will tell you what you did wrong. Here's a real-life example that I just got this morning:
[size=1]D3D11: ERROR: ID3D11Device::CreateDepthStencilView: A non-zero Flags field (0x3) is not valid, unless the GetFeatureLevel returns D3D_FEATURE_LEVEL_11_0 or greater. [ STATE_CREATION ERROR #2097153: CREATEDEPTHSTENCILVIEW_INVALIDFLAGS ]

[size=1]First-chance exception at 0x779676fd in imrender.exe: Microsoft C++ exception: _com_error at memory location 0x0012e7e8..

[size=1]D3D11: ERROR: ID3D11Device::CreateDepthStencilView: Returning E_INVALIDARG, meaning invalid parameters were passed. [ STATE_CREATION ERROR #148: CREATEDEPTHSTENCILVIEW_INVALIDARG_RETURN ]

3. Yeah like Demirug says, the runtime always supports it even if the driver doesn't. Obviously you get the most benefit out of a driver that actually supports multithreaded command buffer generation and resource creation, but even if it doesn't you can still get some benefit from the runtime-emulated command generation. In my experience it's been around 20-25% max. There are caps you can check at runtime if you want to know what the driver supports.

4. You still need to have different code paths for different hardware capabilities if you don't want to just go with the lowest common denominator. The big difference is that you no longer have to abstract out different versions of the API. So if you want to set a pixel shader on a 9-level device, it's the same function call and same interfaces that you use for an 11-level device.
3. In addition to the above, new DX10+ drivers released with/after Win7 may have updates to support downlevel features such as multithreading and compute shader. That means older hardware can support some of the newer features if the driver was updated. Cap flags were added to the D3D11 API to check if there is support for these optional downlevel features.
When you guys say Direct3D 11 runtime, do you mean the d3d11 dll?

#3
With regards to the runtime level emulation, is it only for that feature (multi-threading), or does it apply for other features not supported by the hardware? And what exactly do you mean by runtime emulation? Do you mean WARP?

#4
So if I want to support different video cards with various directx versions, I should go this route (code with D3D11 and let feature levels do its thing, while making sure to handle features that might be absent on older hardware) rather than creating abstracted version-specific rendering engines.

This topic is closed to new replies.

Advertisement