D3DX11SaveTextureToFile с общими ресурсами - PullRequest
3 голосов
/ 07 апреля 2011

Я использую общие ресурсы для отправки текстур с одного устройства D3D11 на другое, чтобы я мог скопировать задний буфер на второе устройство и использовать контекст второго устройства для сохранения этой текстуры в файл. Кажется, это работает, но когда я сохраняю текстуру, она сохраняет пустой PNG. Я попытался сохранить текстуру с основным контекстом устройства, и она работает, за исключением случаев, когда я использую MiscFlag D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX, который мне нужен для совместного использования ресурсов. Есть ли какая-либо причина, по которой D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX препятствует сохранению текстуры? Или я что-то упускаю, чтобы это сработало?

Вот код, который я использую:

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

И этот код используется для сохранения общего текста во втором устройстве

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

Кроме того, код, который должен сохранять общую текстуру в файловую систему, выполняется в своем собственном потоке.

Ответы [ 2 ]

4 голосов
/ 09 апреля 2011

Вот как я решил проблему. Оказывается, использование флага misc D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX не позволяет сохранить текстуру в файл. Поэтому я использовал вместо этого флаг 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();
    }
}

По сути, это позволяет мне сохранять снимки экрана HD без потери частоты кадров, поскольку контекст моего устройства не застрял в функции D3DX11SaveTextureToFile, он обрабатывается вторичным контекстом. Кстати, я не очень много тестировал, я просто взломал это сегодня утром, в некоторых случаях это может не сработать, но это решает проблему с другим флагом, которая приводила к сохранению пустых изображений в файл.

0 голосов
/ 08 апреля 2011

Не было бы логичнее создать CreateTexture2D и CopyResource из _device, которому принадлежит backBuffer?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...