Jump to content
  • Advertisement
Sign in to follow this  

[SlimDX] how to create software rendering device

This topic is 2389 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

We like developing with SlimDX a lot. Using software renderer is an issue that we don't find documentation or working solution.

My software works nicely when D3D9 Device is created with DeviceType.Hardware.

I want to add a fall-back mechanism to use DeviceType.Software, when Direct3D9 hardware is not accessible, even if the performance would be poor.

There are two common cases, when this happens:
1. Computer does not have DirectX9 compatible hardware

2. Computer is using a virtual operating system, such as Virtual PC, Parallels, VMWare etc.

SlimDX version is March 2011.



By using a software rendering device, it should work on virtual operating systems too, right? Or have I understood this horribly wrong?


I try to create a software rendering device as follows:


[font="Times New Roman"]

[color="#2b91af"][color="#2b91af"]Direct3D d3d = [color="#0000ff"][color="#0000ff"]new [color="#2b91af"][color="#2b91af"]Direct3D();



[color="#0000ff"][color="#0000ff"]bool bSWRendererRegistered = RegisterSoftwareRenderer(d3d);



[color="#0000ff"][color="#0000ff"]if (bSWRendererRegistered == [color="#0000ff"][color="#0000ff"]false)



{





[color="#0000ff"][color="#0000ff"]throw [color="#0000ff"][color="#0000ff"]new [color="#2b91af"][color="#2b91af"]ChartException([color="#2b91af"][color="#2b91af"]ErrorType.RenderDeviceCreateFailed,



[color="#a31515"][color="#a31515"]"Failed to register software renderer.", [color="#2b91af"][color="#2b91af"]DateTime.Now);



}





[color="#2b91af"][color="#2b91af"]Capabilities capsSW = d3d.GetDeviceCaps(0, [color="#2b91af"][color="#2b91af"]DeviceType.Software); [color="#008000"][color="#008000"]//This works only after the Software device has been registered!



[color="#008000"] [color="#2b91af"][color="#2b91af"]CreateFlags createFlags = 0;



createFlags |=

[color="#2b91af"][color="#2b91af"]CreateFlags.FpuPreserve;



createFlags |=

[color="#2b91af"][color="#2b91af"]CreateFlags.SoftwareVertexProcessing;

[color="#2b91af"][color="#2b91af"]PresentParameters pp = [color="#0000ff"][color="#0000ff"]new [color="#2b91af"][color="#2b91af"]PresentParameters();



pp.Windowed =

[color="#0000ff"][color="#0000ff"]true;



pp.DeviceWindowHandle = parentControl.Handle;



pp.PresentFlags =

[color="#2b91af"][color="#2b91af"]PresentFlags.None;



pp.BackBufferHeight = 0;

[color="#008000"][color="#008000"]//auto



[color="#008000"] pp.BackBufferWidth = 0;

[color="#008000"][color="#008000"]//auto



[color="#008000"] pp.BackBufferFormat = d3d.Adapters[0].CurrentDisplayMode.Format;



pp.Multisample =

[color="#2b91af"][color="#2b91af"]MultisampleType.None;



pp.MultisampleQuality = 0;



pp.PresentationInterval =

[color="#2b91af"][color="#2b91af"]PresentInterval.Default;



pp.PresentFlags =

[color="#2b91af"][color="#2b91af"]PresentFlags.None;



pp.SwapEffect =

[color="#2b91af"][color="#2b91af"]SwapEffect.Discard;



[color="#2b91af"][color="#2b91af"]Device newDevice = [color="#0000ff"][color="#0000ff"]null;



[color="#0000ff"][color="#0000ff"]try



[color="#0000ff"] {



newDevice =

[color="#0000ff"][color="#0000ff"]new [color="#2b91af"][color="#2b91af"]Device(d3d, 0,



[color="#2b91af"][color="#2b91af"]DeviceType.Software,



parentControl.Handle,



createFlags,



pp);



}





[color="#0000ff"][color="#0000ff"]catch ([color="#2b91af"][color="#2b91af"]Exception ex)



{





[color="#0000ff"][color="#0000ff"]throw [color="#0000ff"][color="#0000ff"]new [color="#2b91af"][color="#2b91af"]Exception([color="#a31515"][color="#a31515"]"Failed to create DirectX software render device.");



}



[/font]And the RegisterSoftwareRenderer method (and imports) which loads the dll and function correctly, and seems to be OK:

[

[color="#2b91af"][color="#2b91af"]DllImport([color="#a31515"][color="#a31515"]"kernel32.dll")]



[color="#0000ff"][color="#0000ff"]internal [color="#0000ff"][color="#0000ff"]extern [color="#0000ff"][color="#0000ff"]static [color="#2b91af"][color="#2b91af"]IntPtr LoadLibrary([color="#0000ff"][color="#0000ff"]string librayName);



[

[color="#2b91af"][color="#2b91af"]DllImport([color="#a31515"][color="#a31515"]"kernel32.dll", CharSet = [color="#2b91af"][color="#2b91af"]CharSet.Ansi, ExactSpelling = [color="#0000ff"][color="#0000ff"]true, SetLastError = [color="#0000ff"][color="#0000ff"]true)]



[color="#0000ff"][color="#0000ff"]internal [color="#0000ff"][color="#0000ff"]static [color="#0000ff"][color="#0000ff"]extern [color="#2b91af"][color="#2b91af"]IntPtr GetProcAddress([color="#2b91af"][color="#2b91af"]IntPtr hModule, [color="#0000ff"][color="#0000ff"]string procName);



[color="#0000ff"][color="#0000ff"]private [color="#0000ff"][color="#0000ff"]bool RegisterSoftwareRenderer([color="#2b91af"][color="#2b91af"]Direct3D d3d)



{





[color="#0000ff"][color="#0000ff"]bool result = [color="#0000ff"][color="#0000ff"]false;



[color="#0000ff"][color="#0000ff"]try



[color="#0000ff"] {





[color="#2b91af"][color="#2b91af"]IntPtr hRast = LoadLibrary([color="#a31515"][color="#a31515"]"RGB9Rast.dll");



[color="#2b91af"][color="#2b91af"]IntPtr D3D9GetSWInfo = GetProcAddress(hRast, [color="#a31515"][color="#a31515"]"D3D9GetSWInfo");



[color="#2b91af"][color="#2b91af"]Result res = d3d.RegisterSoftwareDevice(D3D9GetSWInfo);



[color="#0000ff"][color="#0000ff"]if(res == [color="#2b91af"][color="#2b91af"]ResultCode.Success)



result =

[color="#0000ff"][color="#0000ff"]true;



}





[color="#0000ff"][color="#0000ff"]catch



[color="#0000ff"] {



result =

[color="#0000ff"][color="#0000ff"]false;



}





[color="#0000ff"][color="#0000ff"]return result;



}






I'm unable to find parameters to create the device without "Invalid call" or "Not available" exceptions. Does anybody have proper PresentParameters and CreateFlags, to get the renderer working?

Thanks for any advice!






Share this post


Link to post
Share on other sites
Advertisement
To create a D3D9 software renderer you're going to need to get the Windows DDK and write your own driver, and then you need to feed this into D3D9. I've never seen any documentation or information from anyone who has ever tried this. I think you'd be hard pressed to find someone without D3D9-compatible hardware in this day and age, but if you decide to forge on anyway let us know if you ever get it working.

Share this post


Link to post
Share on other sites
It's much easier to do using D3D10 or above - it has WARP built in.

Adding D3D11 support is also probably easier than getting software rasterization working in D3D9.

Share this post


Link to post
Share on other sites
In theory you can use the reference device instead. Users will need d3dref9.dll on their machines (I'm not certain if that distributes with the regular runtime or what the legalities of distributing it yourself may be) and I feel that it will meet your requirements better - full software emulation of everything in D3D9.

In practice, replacing hardware accelerated rendering with software rendering is not a great idea. Performance isn't just slower, it's (for any non-trivial cases) utterly abysmal, running at less than 1 frame per second. (Note that this isn't specific to D3D; the same happens under OpenGL with e.g. the MS generic implementation or Mesa).

I second the comment upthread that your case 1 for this requirement can be essentially ignored; it's incredibly difficult to find a machine that doesn't have at least D3D9 class hardware these days. Even a 6-year-old Intel integrated can do it (with SM2 support and all). Do you really need to go to the effort of supporting the one person who absolutely refuses to upgrade their mouldy old Geforce 4 MX? The payback for supporting that kind of hardware is going to be miniscule compared to the expense involved in getting that support in.

Regarding your point 2, you're going to find that much virtualization software actually supports hardware acceleration quite well. VMWare player, for example, has given full D3D9 support for at least the past two years. Even where this may not be the case, there is always hardware virtualization to assist. And anyway, we're also talking about an extremely marginal target audience here too.

Setting your minimum entry level requirement to some kind of D3D9 class hardware is what I'd recommend.

Share this post


Link to post
Share on other sites
It seems WARP does not support WinXP... So we have to forget about it then... at least for now.


Aren't there really any working software rasterizer drivers?



It is funny developing pro software and to struggle with these hardware and virtual os problems :-) Maybe I should start writing games instead, this should be less headache there.


Thanks guys for your comments.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!