2011-04-07 38 views
3

私は第二の装置の上にバックバッファをコピーして、ファイルにそのテクスチャを保存するために、第2のデバイスコンテキストを使用できるように、別のD3D11デバイスからテクスチャを送信するために、共有リソースを使用しています。これは機能しているようですが、テクスチャを保存すると空のPNGが保存されます。 私は、プライマリデバイスコンテキストと質感を節約しようと、それは私がリソースを共有するために必要なD3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX MiscFlagを、使用している場合を除き、動作します。 D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEXがテクスチャの保存を妨げる理由はありますか?それとも、私はそれが機能するために何かを逃している可能性がありますか?ここで 共有リソースとD3DX11SaveTextureToFile

は、私が使用しているコードです:

D3D11_TEXTURE2D_DESC td; 
backBuffer->GetDesc(&td); 
td.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; 
this->_device->CreateTexture2D(&td, 0, &g_tex); 
this->_context->CopyResource(g_tex, backBuffer); 

// saves a blank image if using D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX 
D3DX11SaveTextureToFile(this->_context, g_tex, D3DX11_IFF_JPG, "test.jpg"); 

g_tex->QueryInterface(__uuidof(IDXGIResource), reinterpret_cast<void **>(&g_dxgiResource)); 
g_dxgiResource->GetSharedHandle(&g_shaderHandle); 
g_dxgiResource->Release(); 
g_tex->QueryInterface(__uuidof(IDXGIKeyedMutex), reinterpret_cast<void **>(&g_dxgiMutex)); 

そして、これは、第2のデバイスも

ID3D11Texture2D *texture = 0; 
IDXGIKeyedMutex *keyedMutex = 0; 
device2->OpenSharedResource(g_shaderHandle, __uuidof(ID3D11Texture2D), reinterpret_cast<void **>(&texture)); 
texture->QueryInterface(__uuidof(IDXGIKeyedMutex), reinterpret_cast<void **>(&keyedMutex)); 
UINT acqKey = 0; 
UINT relKey = 1; 
DWORD timeout = 16; 
DWORD res = keyedMutex->AcquireSync(acqKey, timeout); 
if (res == WAIT_OBJECT_0 && texture) 
{ 
    // saves a blank image too 
    D3DX10SaveTextureToFile(texture, D3DX10_IFF_JPG, "test2.jpg"); 
} 
keyedMutex->ReleaseSync(relKey); 

で共有textueを保存するために使用されるコードになっているコードですそれ自身のスレッドで実行されているファイルシステムに共有テクスチャを保存します。

答えて

4

ここで問題を解決しました。 D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEXのmiscフラグを使用してテクスチャをファイルに保存することはできません。だから、私はDXGIKeyedMutexのものを使わずに、通常のmutexでD3D11_RESOURCE_MISC_SHAREDフラグを使用しました。

コピー共有テクスチャにバックバッファと共有ハンドルを作成:今、私たちはバックバッファの共有コピーを持っており、それに対処することを

D3D11_TEXTURE2D_DESC td; 
backBuffer->GetDesc(&td); 
td.MiscFlags = D3D11_RESOURCE_MISC_SHARED; 

this->_device->CreateTexture2D(&td, 0, &g_tex); 
this->_context->CopyResource(g_tex, backBuffer); 
IDXGIResource *dxgiResource = 0; 
g_tex->QueryInterface(__uuidof(IDXGIResource), reinterpret_cast<void **>(&dxgiResource)); 
dxgiResource->GetSharedHandle(&g_shaderHandle); 
dxgiResource->Release(); 
backBuffer->Release(); 

を、我々は別のスレッドからファイルに保存することができますデバイスコンテキスト占有せず:

// device_2 and context_2 are the "secondary" device and context 
bool imgSaved = true; 
ID3D11Texture2D *texture = 0; 
HRESULT h = WaitForSingleObject(g_mutex, INFINITE); 
if (h == WAIT_OBJECT_0) 
{ 
    // check to see if there is an image to save 
    if (wdata->hasFrame) 
    { 
     wdata->hasFrame = false; 
     imgSaved = false 
    } 
} 
ReleaseMutex(g_mutex); 
if (!imgSaved) 
{ 
    device_2->OpenSharedResource(g_shaderHandle, __uuidof(ID3D11Texture2D), (LPVOID*)&texture); 
    if (texture) 
    { 
     h = D3DX11SaveTextureToFile(context_2, texture, D3DX11_IFF_PNG, "image.png"); 
     texture->Release(); 
    } 
} 

を基本的にこれは私がHD画面を保存することができます私のデバイスコンテキストがD3DX11SaveTextureToFile機能で立ち往生されていないので、それは二次的文脈で扱うのフレームレートを殺さずにキャプチャします。 サイドノートでは、私はたくさんのことをテストしていません、今朝一緒にこれをハックするだけで動作しないかもしれませんが、空のイメージを引き起こす原因となった別のフラグファイルに保存されます。

0

は、それがバックバッファを所有している_deviceからCreateTexture2DとCOPYRESOURCEに複数の論理ではないでしょうか?

+0

これは私がやっていることです。 – dotminic