So I've decided to drop the SlimDX dependency from the WPF MediaKit. There's a couple reasons for this. SlimDX is written in CLI/C++, so it has a hard dependency to 32bit or 64bit code. This means that you cannot build your application as "ANY CPU" and have the JITter run automatically as 32 or 64bit code. With SlimDX, you either have to install both 64bit and 32bit assemblies in the GAC, or swap out the 32bit assembly with the 64bit one (or vice-versa). There's also a issue I was having with SlimDX requiring the latest [August] DX runtimes, which was about 30 megs. This was just way too much inconvenience.
My solution is to write my own managed Direct3D, which is not really an wrapper, but more of an interop. This will allow for compiling as "ANY CPU" and have it automatically run as 32/64bit, no CLI/C++ and no extra dependencies.
I am not going to convert all of Direct3D, but only the structures and interfaces I need specifically, which really isn't that much. It's a pretty tedious task, but I'm about 70% done! I'm not sure why SlimDX didn't go this route over the CLI/C++ (probably so they could give it a .NET feel), but I wish there was a library already like this so I wouldn't have had to go through the trouble.
If you are curious what the interop looks like, here's a taste:
public class DirectX
{
[DllImport("d3d9.dll", EntryPoint = "Direct3DCreate9", CallingConvention = CallingConvention.StdCall),
SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Interface)]
public static extern IDirect3D9 Direct3DCreate9(ushort SDKVersion);
[DllImport("d3d9.dll", EntryPoint = "Direct3DCreate9Ex", CallingConvention = CallingConvention.StdCall),
SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Interface)]
public static extern IDirect3D9Ex Direct3DCreate9Ex(ushort SDKVersion);
}
/// <summary>
/// CLSID_IDirect3D9
/// </summary>
[ComImport, Guid("81BDCBCA-64D4-426d-AE8D-AD0147F4275C"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDirect3D9
{
[PreserveSig]
int RegisterSoftwareDevice([In, Out]IntPtr pInitializeFunction);
[PreserveSig]
int GetAdapterCount();
[PreserveSig]
int GetAdapterIdentifier(uint Adapter, uint Flags, uint pIdentifier);
[PreserveSig]
uint GetAdapterModeCount(uint Adapter, D3DFORMAT Format);
[PreserveSig]
int EnumAdapterModes(uint Adapter, D3DFORMAT Format, uint Mode, [Out] out D3DDISPLAYMODE pMode);
[PreserveSig]
int GetAdapterDisplayMode(ushort Adapter, [Out]out D3DFORMAT Format);
#region Method Placeholders
[PreserveSig]
int CheckDeviceType();
[PreserveSig]
int CheckDeviceFormat();
[PreserveSig]
int CheckDeviceMultiSampleType();
[PreserveSig]
int CheckDepthStencilMatch();
[PreserveSig]
int CheckDeviceFormatConversion();
[PreserveSig]
int GetDeviceCaps();
#endregion
[PreserveSig]
IntPtr GetAdapterMonitor(uint Adapter);
[PreserveSig]
int CreateDevice(int Adapter,
D3DDEVTYPE DeviceType,
IntPtr hFocusWindow,
CreateFlags BehaviorFlags,
[In, Out]
ref D3DPRESENT_PARAMETERS pPresentationParameters,
[Out]out IntPtr ppReturnedDeviceInterface);
}