I am working on Direct2D and Direct3D 11 interop and have managed to create the shared DXGI resources necessary to do this, but now I have an issue with the DXGI.KeyedMutex.
The loop will execute once before throwing an exception on the D3D11KeyedMutex.Acquire() on the second pass. I have tested it using multiple Acquire() and Release() method calls inside the loop, and everything works fine until the SwapChain.Present() call is made. Also, only the D3D11KeyedMutex is affected, as the D2DKeyedMutex.Acquire() always succeeds. The exception is as follows:
First-chance exception at 0x772cb727 in Direct2DTest.exe: Microsoft C++ exception: _com_error at memory location 0x0033e6d8..
A first chance exception of type 'SlimDX.DXGI.DXGIException' occurred in SlimDX.dll
An unhandled exception of type 'SlimDX.DXGI.DXGIException' occurred in SlimDX.dll
Additional information: E_INVALIDARG: An invalid parameter was passed to the returning function (-2147024809)
The resources are initialized here:
GraphicsDevice10_1 = new D3D10_1.Device1(Factory.GetAdapter(0), D3D10.DriverType.Hardware, D3D10.DeviceCreationFlags.BgraSupport | D3D10.DeviceCreationFlags.Debug, D3D10_1.FeatureLevel.Level_10_0);
SharedTextureD3D11 = new D3D11.Texture2D(GraphicsDevice11, SharedTextureDesc);
D3D11KeyedMutex = new DXGI.KeyedMutex(SharedTextureD3D11);
SharedResource = new DXGI.Resource(SharedTextureD3D11);
SharedTextureD3D10 = GraphicsDevice10_1.OpenSharedResource<D3D10.Texture2D>(SharedResource.SharedHandle);
SharedSurface = SharedTextureD3D10.AsSurface();
D2DKeyedMutex = new DXGI.KeyedMutex(SharedTextureD3D10);
D2DFactory = new D2D.Factory(SlimDX.Direct2D.FactoryType.Multithreaded, SlimDX.Direct2D.DebugLevel.Information);
PixelFormat = new SlimDX.Direct2D.PixelFormat
{
AlphaMode = SlimDX.Direct2D.AlphaMode.Ignore,
Format = DXGI.Format.B8G8R8A8_UNorm
};
After considering the information found here, I decided to try something new. I changed my back buffer and depth stencil descriptions in my SwapChain to not use any multisampling. Now my mutex locks do not fail. I know that a multisampled surface cannot be shared, however, I am sharing a non-multisampled texture (and not doing anything with it yet).
Can anyone explain this behavior? Is there any way I can work around it? I cannot sacrifice MSAA in my rendered scene just to allow me to share a non-MSAA texture so I can overlay some text.
In case anyone is interested in trying this out, I have created a minimal working sample that reproduces the error.
Just execute it and press A to initialize. Once D is pressed (and the screen turns green), any subsequent push of S should cause an exception (prior to that, S should not cause any errors).
If the SwapChainDescription is changed to use SampleDescription(1,0), then the error should not occur.
If I am an idiot and doing something obviously wrong in this code, I would like that feedback as well.
using System;
using System.Drawing;
using System.Windows.Forms;
using D3D11 = SlimDX.Direct3D11;
using D3D10 = SlimDX.Direct3D10;
using D3D10_1 = SlimDX.Direct3D10_1;
using DXGI = SlimDX.DXGI;
namespace SharedResourceTest
{
public class RenderForm : IDisposable
{
private Form BackingForm { get; set; }
Sorry to keep replying to this and bumping the post, but I wanted to put my latest results down in case anyone finds this thread and has the same problem.
Ultimately, it seems that there is no problem, or that it might be a driver issue or some other point of failure. I loaded up the exact same code today and it executed flawlessly. Then I added code to add a depth stencil buffer in with my back buffer, and the problem appeared again. I closed my browser window in frustration (and preparation for a reboot) and the issue disappeared. I added more code for using a Direct2D factory and the issue surfaced once again, but after a reboot, it went away. For the most part, cleaning my solution and forcing a full rebuild often makes the problem disappear. Also, closing other running applications seemed to have an impact.