DirectX - разделение дескриптора ресурса между различными потоками - PullRequest
0 голосов
/ 30 мая 2018

Я создал текстуру с флагами D3D11_RESOURCE_MISC_SHARED_NTHANDLE | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX, как описано в документации, чтобы поделиться ею с различными устройствами (у меня есть несколько потоков, совпадающих для чтения этого ресурса после создания)

D3D11_TEXTURE2D_DESC textureDesc;
textureDesc.Width = Width;
textureDesc.Height = Height;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
textureDesc.SampleDesc.Count = 1;
textureDesc.SampleDesc.Quality = 0;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_NTHANDLE | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;

ID3D11Texture2D *returnTexture;
d3d11Device->CreateTexture2D(&textureDesc, NULL, &returnTexture);

IDXGIResource1 *sharedResource;
returnTexture->QueryInterface(__uuidof(IDXGIResource1), reinterpret_cast<void**>(&sharedResource));

HANDLE shareHandle;
sharedResource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, nullptr, &shareHandle);

// acquire the mutex and copy data into the texture from another one
// release the mutex

После заполнения этой текстуры (Я получаю IDXGIKeyedMutex, копирую в него данные и затем освобождаю мьютекс) Я пропускаю shareHandle вокруг нескольких потоков.

Каждому потоку иногда может понадобиться перенести память на ЦП из этой текстуры

ID3D11Device1 *d3d11Device1;
d3d11Device->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&d3d11Device1));

HANDLE shareHandle = getSharedHandleSomewhere();
IDXGIResource1 *sharedResource;
d3d11Device1->OpenSharedResource1(shareHandle, __uuidof(IDXGIResource1), reinterpret_cast<void**>(&sharedResource));

// acquire the mutex and write the contents into another staging texture
// release the mutex

CloseHandle(shareHandle);

Все HRESULT коды ошибок (исключены из кода выше для ясности) не возвращают ошибок, но через несколько кадров OpenSharedResource1 в одном из потоков завершается с DXGI_ERROR_DEVICE_REMOVED (и я вполнеуверен, что ни один физический монитор никогда не будет удален).

Что может быть причиной этого?Я также попытался дублировать дескриптор с DuplicateHandle по одному на каждый поток, но это также не решает проблему (я полагаю, все дескрипторы являются непрозрачными «ссылками» на одно и то же право ресурса).Может ли быть так, что я могу открыть общий ресурс только один раз вместо того, чтобы делать это несколько раз?

...