2

I created a texture with flags D3D11_RESOURCE_MISC_SHARED_NTHANDLE | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX as described in the documentation to share it among different devices (I have multiple threads concurring to read that resource once created)

D3D11_TEXTURE2D_DESC textureDesc;
textureDesc.Width = Width;
textureDesc.Height = Height;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
textureDesc.SampleDesc.Count = 1;
textureDesc.SampleDesc.Quality = 0;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_NTHANDLE | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;

ID3D11Texture2D *returnTexture;
d3d11Device->CreateTexture2D(&textureDesc, NULL, &returnTexture);

IDXGIResource1 *sharedResource;
returnTexture->QueryInterface(__uuidof(IDXGIResource1), reinterpret_cast<void**>(&sharedResource));

HANDLE shareHandle;
sharedResource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, nullptr, &shareHandle);

// acquire the mutex and copy data into the texture from another one
// release the mutex

After populating this texture (I acquire its IDXGIKeyedMutex, copy data into it and then release the mutex) I pass the shareHandle around multiple threads.

Each thread might occasionally need to transfer memory on the CPU from that texture

ID3D11Device1 *d3d11Device1;
d3d11Device->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&d3d11Device1));

HANDLE shareHandle = getSharedHandleSomewhere();
IDXGIResource1 *sharedResource;
d3d11Device1->OpenSharedResource1(shareHandle, __uuidof(IDXGIResource1), reinterpret_cast<void**>(&sharedResource));

// acquire the mutex and write the contents into another staging texture
// release the mutex

CloseHandle(shareHandle);

All HRESULT error codes (excluded from the code above for clarity reasons) return no errors, but after a few frames OpenSharedResource1 on one of the threads fails with DXGI_ERROR_DEVICE_REMOVED (and I'm quite sure no physical monitor is ever removed).

What could be the cause of this? I also tried duplicating the handle with DuplicateHandle one per each thread but that doesn't fix the problem either (the handles are all opaque 'references' to the same resource right I suppose). Could that be that I can only open the shared resource once instead of doing it multiple times?

Dean
  • 6,610
  • 6
  • 40
  • 90
  • 1
    The `DXGI_ERROR_DEVICE_REMOVED` is about the ` video card`, not the monitor ;-) – Stefan May 30 '18 at 07:55
  • HAve you used `D3D11_CREATE_DEVICE_SINGLETHREADED` in the device creation flags? – Stefan May 30 '18 at 08:03
  • 1
    You typically enable D3D11 debug layer to get related diagnostics. – Roman R. May 30 '18 at 08:10
  • @Stefan no, the flags were just 0 – Dean May 30 '18 at 09:46
  • @RomanR. I added the debug layer flag to every context creation but stderr is sadly empty – Dean May 30 '18 at 09:47
  • You need to look at debug output, either Debug Output window when running from Visual Studio, or DebugView app capturing that output when you runs your app standalone. – Roman R. May 30 '18 at 09:54
  • @RomanR. it's empty :( – Dean May 30 '18 at 10:37
  • @RomanR. it's weird, it seems like I can't `OpenSharedResource1` a resource even from a duplicated handle if that same resource was `OpenSharedResource1`-opened before from a different thread – Dean May 30 '18 at 11:08
  • The API is in general operational, if you follow the lines of https://msdn.microsoft.com/en-us/library/windows/desktop/ee913554 You might want to either get debug output working, or post a runnable code (not just snippet pieces) to exhibit the issue. – Roman R. May 30 '18 at 11:55
  • Why do you QueryInterface itself for the ID3D11Device1? – thewhiteambit Aug 07 '21 at 15:16

0 Answers0