2011-04-07 290 views
3

我使用共享資源從一個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)); 

這是用來保存共享textue在第二設備

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); 

另外的代碼,是應該的代碼將共享紋理保存到文件系統正在它自己的線程中運行。

回答

4

以下是我如何解決問題。原來,使用D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX misc標誌不允許將紋理保存到文件。所以我使用了D3D11_RESOURCE_MISC_SHARED標誌,而不是使用DXGIKeyedMutex,而是使用常規互斥量。

複製後臺緩存共享的質地和創建共享手柄:

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(); 
    } 
} 

基本上,這讓我保存的高清屏幕捕捉而不殺死的幀速率,因爲我的設備上下文沒有在D3DX11SaveTextureToFile功能卡,它是由輔環境處理。 另一方面,我沒有測試過很多,今天早上我只是一起破解它,在某些情況下它可能不起作用,但它解決了我與另一個標記導致的問題,這會導致空圖像保存到文件。

0

對於擁有backBuffer的_device中的CreateTexture2D和CopyResource來說更合乎邏輯嗎?

+0

這就是我正在做的。 – dotminic 2011-04-08 06:38:28