Hi guys,
I have a small issue with the interoperability between D3D11 and D2D. I mean not exactly between those two more with those and other programs like Afterburner, Fraps, OBS etc. But I will start at the very beginning.
When I ported my DX9 engine to DX11 (SharpDX) I got rid of all the Spritebatch stuff and implemented a D2D UI. I used Shared Surfaces for that and it is working. I have no issues with it. The only thing that was really strange about the engine was that Multi-GPU (Crossfire in my case) seemed not work although this is more of a driver "thing" and I can't really do anything about it.
So yesterday I had some time to dig into it. In one of my test projects crossfire was working fine so I added code from my engine to see where it would change. It was pretty easy to find. I was creating the texture with SharedKeyMutex flag. Like this:
this.d3d11Texture = new Texture2D(device, new Texture2DDescription()
{
Height = form.Height,
Width = form.Width,
MipLevels = 1,
ArraySize = 1,
Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm,
SampleDescription = new SampleDescription(1, 0),
Usage = ResourceUsage.Default,
BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
CpuAccessFlags = CpuAccessFlags.None,
OptionFlags = ResourceOptionFlags.SharedKeyedmutex
});
SharpDX.Direct3D10.Device1 d3d10_device = new SharpDX.Direct3D10.Device1(factory.GetAdapter(0), SharpDX.Direct3D10.DeviceCreationFlags.BgraSupport, SharpDX.Direct3D10.FeatureLevel.Level_10_0);
SharpDX.DXGI.Resource sharedResource = d3d11Texture.QueryInterface<SharpDX.DXGI.Resource>();
SharpDX.Direct3D10.Texture2D d3d10Texture = d3d10_device.OpenSharedResource<SharpDX.Direct3D10.Texture2D>(sharedResource.SharedHandle);
this.mutexd3d10 = d3d10Texture.QueryInterface<KeyedMutex>();
this.mutexd3d11 = d3d11Texture.QueryInterface<KeyedMutex>();
Surface surface = d3d10Texture.AsSurface();
d2dFactory = new SharpDX.Direct2D1.Factory1();
d2dRenderTarget = new RenderTarget(d2dFactory, surface,
new RenderTargetProperties(RenderTargetType.Hardware, new PixelFormat(Format.Unknown, SharpDX.Direct2D1.AlphaMode.Premultiplied),
0, 0, RenderTargetUsage.None, SharpDX.Direct2D1.FeatureLevel.Level_10));
With this code and Crossfire enabled I have 100% load on the first GPU and 4% on the second while rendering the UI. When I disable the UI the second GPU goes to 0% load. So I had to get rid of the flag. This is what I came up with:
this.d3d11Texture = new Texture2D(device, new Texture2DDescription()
{
Height = form.Height,
Width = form.Width,
MipLevels = 1,
ArraySize = 1,
Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm,
SampleDescription = new SampleDescription(1, 0),
Usage = ResourceUsage.Default,
BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
CpuAccessFlags = CpuAccessFlags.None,
OptionFlags = ResourceOptionFlags.None
});
d2dFactory = new SharpDX.Direct2D1.Factory1();
Surface1 surface1 = d3d11Texture.QueryInterface<Surface1>();
d2dRenderTarget = new RenderTarget(d2dFactory, surface1,
new RenderTargetProperties(RenderTargetType.Hardware, new PixelFormat(Format.Unknown, SharpDX.Direct2D1.AlphaMode.Premultiplied),
0, 0, RenderTargetUsage.None, SharpDX.Direct2D1.FeatureLevel.Level_10));
It works just fine and even Crossfire is working as expected....BUT now there are no overlays or video recordings possible. Afterburner or Fraps just show nothing and recording results in a black video.
The problem does not only happen when I actually use the RenderTarget. It is sufficient that it is created. So if I comment out the line where it is created I have the overlays back, Crossfire works and I can record videos but of course I cannot use the UI.
So what am I missing here?
And here are some infos you might wanna know:
SharpDX 2.5 and SharpDX 2.6.3 (tried both, same results)
Windows 7 x64 Prof
2x Radeon R290X / 2x Radeon 7870