I'm trying to set up a shared texture (render target) such that it is created on a D3D11 device and subsequently opened and drawn to from a D3D9Ex device. Unfortunately I've found the information on how to actually go about this to be rather scarce and the debug layers don't seem to want to be more helpful than to tell me the "opened and created resources don't match". Therefore I thought I would ask and see if anybody around here would be able and willing to shed some more light on how resource sharing is supposed to be carried out?
So what I do is to first create a Texture2D from my IDirect3D11Device like so:
tex2DDesc.Width = width; // Tested with 256
tex2DDesc.Height = height; // Tested with 256
tex2DDesc.MipLevels = 1;
tex2DDesc.ArraySize = 1;
tex2DDesc.Format = DXGI_FORMAT_A8G8B8R8_UNORM;
tex2DDesc.SampleDesc.Count = 1;
tex2DDesc.SampleDesc.Quality = 0;
tex2DDesc.Usage = D3D11_USAGE_DEFAULT;
tex2DDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
tex2DDesc.CPUAccessFlags = 0;
tex2DDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
// Create render target
if(FAILED(gGlob.pDevice->CreateTexture2D(&tex2DDesc, nullptr, &pTexture2D)))
Fail("Failed to create shared texture", "Could not create the shared texture!", 1);
// Create shader resource view
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Format = DXGI_FORMAT_A8G8B8R8_UNORM;
srvDesc.Texture2D.MipLevels = 1;
srvDesc.Texture2D.MostDetailedMip = 0;
if(FAILED(gGlob.pDevice->CreateShaderResourceView(pTexture2D, &srvDesc, &pResourceView)))
Fail("Failed to create shared texture", "Could not create SRV for shared texture!", 2);
// Obtain the keyed mutex interface
if(FAILED(pTexture2D->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)&pMutex)))
Fail("Failed to create shared texture", "Could not obtain resource locking interface!", 3);
// Obtain IDXGIResource interface for the texture; this is needed to get its shared handle
IDXGIResource *pResource = nullptr;
if(FAILED(pTexture2D->QueryInterface(__uuidof(IDXGIResource), (void**)&pResource)))
Fail("Failed to create shared texture", "Could not obtain resource interface!", 4);
if(FAILED(pResource->GetSharedHandle(&hSharedResource)))
Fail("Failed to create shared texture", "Could not obtain shared resource handle!", 5);
// Shouldn't need this open anymore; the handle should presumably be valid for as long as the
// resource (the texture2d) remains in existance
SAFE_RELEASE(pResource);
After this, an attempt is made to access it from an IDirect3DDevice9Ex:
hr = m_pD3DEx->CreateTexture(iWidth, iHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pTexture, &hSharedResource);
// The above returns E_INVALIDARG
The D3D9 debug layer reports the following when invoking CreateTexture as per above:
Direct3D9: (ERROR) :Opened and created resources don't match, unable to open the shared resource.
Direct3D9: (ERROR) :Error during initialization of texture. CreateTexture failed.
Direct3D9: (ERROR) :Failure trying to create a texture
The D3D11 debug layer remains silent and all D3D11 calls above succeed.
From what I've been able to gather while searching for info on this, this seems to be how you are supposed to set it up. Most places that mention it seem to make a point of having D3D9Ex create the resource and then open it using ID3D11Device::OpenSharedResource however. But certainly this can't be a requirement? In my project it makes a whole lot better sense to have the D3D11 device create the shared textures than the other way around.
Furthermore there is the slightly ambigious route of getting the IDXGIResource interface from the IDXGITexture2d in order to obtain the shared handle. Could it be that you are in fact supposed to get this from somewhere else? The MSDN documentation seems prone to refer to surfaces when talking about resource sharing; is it in fact supposed to be so that you are supposed to be sharing the IDXGISurface view of the resource? But while D3D9 uses surfaces, what would the corresponding thing be in D3D11 if so, since it is apparently imperative that both resources be created / opened using the same type? (Furthermore it appears that texture resources should indeed be shareable out-of-the-box going by some mentions here: https://msdn.microsoft.com/en-us/library/windows/desktop/bb219800(v=vs.85).aspx#Sharing_Resources).
Grateful for any pointers :)