Sign in to follow this  
Barguast

[SlimDX] Initialise Direct3D10.1 with WARP driver

Recommended Posts

Barguast    181
Quick question - In SlimDX, how I do create a Direct3D 10 device which uses the WARP device? In unmanaged Direct3D, it seems you do it by specifying the driver type as D3D10_DRIVER_TYPE_WARP, but the equivalent SlimDX enumeration (SlimDX.Direct3D10.DriverType) has only Hardware, Software, Reference, and Null values. Thanks. :)

Share this post


Link to post
Share on other sites
jpetrie    13104
D3D10_DRIVER_TYPE_WARP has the value of 5. To work around the fact that the enumeration seems to be missing in SlimDX, cast 5 to the DriverType type.

Share this post


Link to post
Share on other sites
Barguast    181
Quote:
Original post by jpetrie
D3D10_DRIVER_TYPE_WARP has the value of 5. To work around the fact that the enumeration seems to be missing in SlimDX, cast 5 to the DriverType type.


Thanks. I assumed .NET would be more strict with casting an integer to an enum, but it certainly seems to do the trick!

Share this post


Link to post
Share on other sites
Barguast    181
I spoke too soon - the following line doesn't work:

new Device1(null, (DriverType)5, DeviceCreationFlags.None, SlimDX.Direct3D10_1.FeatureLevel.Level_9_1);

I get an exception of 'E_INVALIDARG: An invalid parameter was passed to the returning function (-2147024809)'. Oddly enough nothing shows up in DebugView when the error occurs, but I do get a warning in DebugView saying the device wasn't disposed when the application is closed. So, it seems the device is created, but isn't usable. :(

The following line, on the other hand, does work (0 being 'Hardware')

new Device1(null, (DriverType)0, DeviceCreationFlags.None, SlimDX.Direct3D10_1.FeatureLevel.Level_9_1);

Share this post


Link to post
Share on other sites
Barguast    181
Quote:
Original post by Barguast
And yet, my attempt with Device.CreateWithSwapChain succeeds. :p


EDIT: To update, it only works when FeatureLevel is 10 or above. Does the WARP renderer not like targetting Direct3D 9 under Direct3D 10? It worked with Direct3D 11 when I tried it.

Share this post


Link to post
Share on other sites
Barguast    181
Quote:
Original post by DieterVW
WARP only supports the D3D10 DDI, there is no DX9 or DX11 support from WARP. I think that it also covers D3D10.1.


But in Direct3D 11, it's possible to create a WARP device, targetting Direct3D 9. Does this in fact use Direct3D 10?

... This is all very confusing. :p

Share this post


Link to post
Share on other sites
DieterVW    724
That sounds like a bug in device creation to me. It does seem safe though since the shader blobs will contain a *s_4_* target.

I'm not sure why anyone would want to target 10Level9 with WARP anyway given that WARP 10 would have more features - and you're using the dx10/dx11 api anyway.

Share this post


Link to post
Share on other sites
Promit    13246
Quote:
Original post by DieterVW
WARP only supports the D3D10 DDI, there is no DX9 or DX11 support from WARP. I think that it also covers D3D10.1.
That's in conflict with the documentation for the flag:
Quote:
A WARP driver, which is a high-performance software rasterizer. The rasterizer supports feature level 9_1 through level 10.1 with a high performance software implementation when hardware is not available.

And I've added the WARP enum to SVN for SlimDX.

Share this post


Link to post
Share on other sites
Barguast    181
Quote:
Original post by DieterVW
I'm not sure why anyone would want to target 10Level9 with WARP anyway given that WARP 10 would have more features - and you're using the dx10/dx11 api anyway.


True enough. I want to target Direct3D 9 hardware with the new API but have the option of falling back to a software renderer. Presumably (and hopefully) I won't have any trouble doing something like the following?


Device1 device;
SwapChain swapChain;
if (hardwareRenderingMode)
Device1.CreateWithSwapChain(null, DriverType.Hardware, DeviceCreationFlags.Debug, FeatureLevel.Level_9_1, scd, out device, out swapChain);
else
Device1.CreateWithSwapChain(null, (DriverType)5, DeviceCreationFlags.Debug, FeatureLevel.Level_10_0, scd, out device, out swapChain);




That is, creating a Hardware Direct3D 9-targetted device if D3D9 hardware is available, otherwise creating a WARP Direct3D10 device, and then using the device instance as an interface to whichever device was created in the rest of my code. Provided that I write all of my shaders,etc. for Direct3D 9 of course?

Thanks for your help so far.

Share this post


Link to post
Share on other sites
DieterVW    724
Well that's cool.

I imagine that would mean that you'll get 10Level9 error checking, though underneath WARP will still be routing things through the DX10 DDI path.

However, the documentation doesn't seem to be in agreement with the behavior Barguast is finding in device creation. Seems that might warrant an investigation of sorts.

Share this post


Link to post
Share on other sites
Barguast    181
One last question (hopefully). As I say, I'm trying to target any hardware from feature level 10.1 to 9.1, and falling back to a WARP/Direct3D 10 device where no hardware support could be found. With that in mind, I'm hoping to write all of my application including shaders etc. to work with feature level 9.1.

I assume subsequent versions support older shader profiles, etc. Is this a correct assumption? I ask because my test effect...

// ---------
// Variables
// ---------
float4x4 worldViewProjection;
texture tex;

// ---------------
// Texture Sampler
// ---------------
sampler textureSampler = sampler_state
{
Texture = <tex>;
Filter = MIN_MAG_POINT_MIP_LINEAR; // ANISOTROPIC

AddressU = MIRROR;
AddressV = MIRROR;
};

// ----------
// Structures
// ----------
struct VS_IN
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
};

struct VS_OUT
{
float4 Position : SV_POSITION;
float2 TexCoord : TEXCOORD0;
};

struct PS_OUT
{
float4 Colour : SV_TARGET;
};

// -------------
// Vertex Shader
// -------------
VS_OUT vs_main(VS_IN input)
{
VS_OUT output;
output.Position = mul(input.Position, worldViewProjection);
output.TexCoord = input.TexCoord * 2;

return output;
}

// ------------
// Pixel Shader
// ------------
PS_OUT ps_main(VS_OUT input)
{
PS_OUT output;

output.Colour = float4(1, 1, 1, 1);
output.Colour = tex2D(textureSampler, input.TexCoord);
output.Colour.g = input.TexCoord.g / 2;
output.Colour.b = input.TexCoord.r / 2;

return output;
}


// ----------
// Techniques
// ----------
technique10 Render
{
pass Pass_0
{
VertexShader = compile vs_4_0 vs_main();
PixelShader = compile ps_4_0 ps_main();
}
}


... seems to work on feature level 9.1, but the vertex and pixel shaders seem to compile to profile 4.0, and feature level 9.1 is supposed to only support profile 2.0. So presumably this wouldn't work on Direct3D 9 hardware that only supports shader model 2.0?

I assume that effect are written to target the Direct3D version (10) in this case, and the shaders within that effect are written to target specific shader profiles - in this case, 2.0 onwards. Please correct these assumptions where necessary!

I've been unable to create a Direct3D 10-loadable effect which compile to vs_2_0 / ps_2_0. If someone happens to have an example of this, it'd be very helpful.

Thanks

Share this post


Link to post
Share on other sites
DieterVW    724
For your shaders to work with 10Level9 you will have to use different shader targets. Inside your effect, use the targets:

vs_4_0_level_9_1
vs_4_0_level_9_3

ps_4_0_level_9_1
ps_4_0_level_9_3

You will not make use of any *s_2_0 or *s_3_0 targets.

Share this post


Link to post
Share on other sites
Barguast    181
Does this compile the shaders as shader profile 4? What if my graphics card only supports vertex / pixel shader profile 2.0 (as indicated by the 10Level9 feature level)? Will this cause all of my shaders to be emulated in software?

Thanks.

Share this post


Link to post
Share on other sites
DieterVW    724
It's not really that complex. First, the device type decides how the shaders will run. If you have a hardware device, then the shaders will not run in software unless the IHV driver decides to do so. (for instance intel vertex shaders on some intel hardware run on the CPU). WARP and REF will run your shaders in software, while hardware devices are supposed to run on hardware.

But, that doesn't have an impact on the shader targets you need to use. The new shader targets instruct the compiler to generate code and do error checking for the particular scenario in your code. In this case, vs_2_0, ps_2_0 code will not execute on anything drive by the DX10, DX10.1, DX11 API since the shader blobs are completely different. The point of the new targets such as vs_4_0_level_9_1 is to tell the compiler to emit blobs for use with the DX10 runtime, but using sm 2.0 or sm 3.0 assembly. (this isn't completely accurate since the *level_9_1 and *level_9_3 don't map perfectly to sm 2.0 or sm 3.0, but those differences are documented). So yes, your shaders will run on DX9 hardware when compiled to a *level_9_* target. These are the 10Level9 shader targets, nothing else will work in this scenario.

Share this post


Link to post
Share on other sites
DieterVW    724
So it turns out that he behavior is not consistent across creates between dx versions.

D3D10CreateDevice1 cannot create a warp or ref device as 10Level9.

D3D11CreateDevice can create a warp device as 10Level9 - though internally it is running dx10 and running the dx10 shader blob.

The documentation will be updated to reflect this.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this