In my d3d9 engine i want to take benifit of compute shader of d3d11. So firstly I created a vertex buffer in d3d11 with D3D11_BIND_UNORDERED_ACCESS and then tried to create the d3d9 vertex buffer with the Handle. like

ZeroMemory(&bd, sizeof(bd));
bd.ByteWidth = sizeof(stVertex) * 100;    
hr = dev->CreateBuffer(&bd, NULL, &pVBuffer);       // create the buffer
hr = CreateBufferUAV( dev, pVBuffer, &m_pBufOutUAV );

HANDLE sharedHandle = NULL;
IDXGIResource* pDXGIResource = NULL;
pVBuffer->QueryInterface(__uuidof(IDXGIResource), (LPVOID*) &pDXGIResource);

hr = g_pd3dDevice9->CreateVertexBuffer( 100*sizeof(stVertex), NULL , 
                                  VERTEX::FVF_Flags, D3DPOOL_DEFAULT, 
                                  &g_pVertexBuffer9, &sharedHandle ); //ERROR : 

which gives error :

Direct3D9: (ERROR) :Opened and created resources don't match, unable to open the shared resource. Direct3D9: (ERROR) :Cannot create Vidmem or Driver managed vertex buffer. Will NOT failover to Sysmem. Direct3D9: (ERROR) :Failure trying to create Vertex Buffer

After that i tried to create vertex buffer in directx9 first and tries to share that in direct11 but still it gave error.

HANDLE sharedHandle9 = NULL;
    hr = g_pd3dDevice9->CreateVertexBuffer( 100*sizeof(VERTEX), NULL , 
                                      VERTEX::FVF_Flags, D3DPOOL_DEFAULT, 
                                      &g_pVertexBuffer9, &sharedHandle9 );
ID3D11Resource*  pTempResource11 = NULL;
    hr = dev->OpenSharedResource( sharedHandle9 , __uuidof(ID3D11Buffer) ,(LPVOID*) &pTempResource11 ); //Error

D3D11: ERROR: ID3D11Device::OpenSharedResource: Returning E_INVALIDARG, meaning invalid parameters were passed. [ STATE_CREATION ERROR #381: DEVICE_OPEN_SHARED_RESOURCE_INVALIDARG_RETURN ]

I am able to share textures but not buffers.please help me here.

  • 1
    \$\begingroup\$ Ugh, I'm surprised you could share textures. Based on your error message, I'd say that you can't do that. Excuse my irreverence, but why are you making the engine in D3D9 if you're using D3D11 features? If you're already creating a D3D11 context, it means your hardware and software supports it, so why not make the engine in D3D11? I mean, It's much easier to do things in D3D11 than D3D9, why go through the trouble of making it in D3D9? \$\endgroup\$ Aug 8 '13 at 6:55
  • \$\begingroup\$ actually my code is written in d3d9 and i dont want to change it.yes i am able to share texture from d3d9 to d3d11 and from d3d11 to d3d9(if not specify D3D11_BIND_UNORDERED_ACCESS). \$\endgroup\$
    Aug 8 '13 at 7:28
  • \$\begingroup\$ What happens if you use an FVF of 0 for the D3D9 buffer? I'm also not seeing where you set the usage for your D3D11 buffer - 0 means default usage but worth double-checking other usages too. \$\endgroup\$ Aug 8 '13 at 9:00

Well, I'm surprised about the stuff you can learn when researching stuff for answering a question.

Short answer: you can't.

This stuff you probably already know, but I'll cover it in case other people find it useful.

At first I thought you can't share handles among Direct3D devices, let alone versions, but it turns out that you can actually do that! In fact, there are three things you can do:

Share data, including vertex buffers across Direct3D 9 instances

You can even do this across processes! According to this article:

Direct3D resources can now be shared between devices or processes. This applies to any Direct3D resource including textures, vertex buffers, index buffers, or surfaces (such as render targets, depth stencil buffers or off-screen plain surfaces). To be shared, you need to designate a resource for sharing at the time of creation, and locate the resource in the default pool (D3DPOOL_DEFAULT). Once a resource is created for sharing, it can be shared across devices within a process, or shared across processes.

The key to do this, as you already know, is the last parameter of CreateVertexBuffer. Remember that this is part of DirectX9Ex, which is only available on Vista and up.

Share a surface across different versions of Direct3D

You create a surface on one API, and render from another one.

This is not trivial, especially when one of the APIs is Direct3D 9, as it uses a completely different subsystem than DirectX 11 (DXGI 1.1). You also have to synchronize access to the surface, but in general, is very doable, according to this article.

Share textures across Direct3D 11 instances, or even across Direct3D versions

So you create a buffer with CreateBuffer and then retrieve it with OpenSharedResource. However, unlike Direct3D 9, in Direct3D 11, you can only create a sharable buffer for 2D non-mipmapped textures, according to this article (emphasis mine):


Enables resource data sharing between two or more Direct3D devices. The only resources that can be shared are 2D non-mipmapped textures.

Also, in here:

The only resources that can be shared are 2D non-mipmapped textures.

In fact, you can share a texture across Direct3D versions, with some restrictions. According to the same article:

Textures being shared from D3D9 to D3D11 have the following restrictions.

  • Textures must be 2D
  • Only 1 mip level is allowed
  • Texture must have default usage
  • Texture must be write only
  • MSAA textures are not allowed
  • Bind flags must have SHADER_RESOURCE and RENDER_TARGET set
  • Only R10G10B10A2_UNORM, R16G16B16A16_FLOAT and R8G8B8A8_UNORM formats are allowed

So, unfortunately you're out of luck. You can't share a vertex buffer across Direct3D versions. In fact, you can't share anything different from 2D non-mipmapped textures when you're using Direct3D 11.

  • \$\begingroup\$ that was i thinking but thought that may be any way to do this.thanks. \$\endgroup\$
    Aug 8 '13 at 13:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .