DirectX11 ресурс релиз многопоточность - PullRequest
0 голосов
/ 13 ноября 2018

Я прочитал https://docs.microsoft.com/en-us/windows/desktop/direct3d11/overviews-direct3d-11-render-multi-thread-intro

И в нем говорится, что я могу совершать вызовы ID3D11Device из нескольких потоков (если не был использован D3D11_CREATE_DEVICE_SINGLETHREADED), но вызовы ID3D11DeviceContext должны быть окружены критической секцией.

Я не нашел никакой информации об освобождении ресурсов, используя их метод 'Release', для таких ресурсов, как текстуры, цели рендеринга, буферы вершин / индексов, шейдеры.

ID3D11Texture2D, ID3D11Texture3D, ID3D11ShaderResourceView, ID3D11RenderTargetView, ID3D11DepthStencilView

ID3D11Buffer.

ID3D11VertexShader, ID3D11HullShader, ID3D11DomainShader, ID3D11PixelShader.

1) Могу ли я вызвать 'Release' для этих ресурсов в любое время из любого потока без использования критических разделов, пока они НЕ используются ID3D11DeviceContext потока рендеринга?

2) Можно ли вызвать 'Release' для этих ресурсов из других потоков, даже если они используются ID3D11DeviceContext в потоке рендеринга?

Или мне нужно окружить вызовы Release тем же критическим разделом, который использовался для доступа к ID3D11DeviceContext?

1 Ответ

0 голосов
/ 14 ноября 2018

Обычно внутренняя реализация подсчета ссылок COM выполняется поточно-ориентированным способом (атомные приращения / убывания), поэтому можно безопасно вызывать AddRef и Release из нескольких потоков.

Конечно, если refcount идет в 0, то у вас есть уничтожение объекта, поэтому важно, чтобы, если у вас было несколько потоков, использующих один и тот же ресурс, у него было соответствующее количество ссылок для поддержания его работоспособности. В Direct3D уничтожение объектов, как правило, отложенное уничтожение , поэтому фактическая очистка объекта может не произойти в течение нескольких кадров, но вы все равно должны сохранять ненулевой пересчет, если кто-либо ссылается на него.

Direct3D 11 использует те же правила, что и Direct3D 10. Он использует «слабые ссылки» для методов конвейерного набора, поэтому просто установить ресурс в контексте устройства не достаточно для увеличения счетчика ссылок. IOW: если у вас есть два потока, которые рендерится с одним и тем же ресурсом, то каждый поток должен хранить счетчик ссылок на объект, чтобы он оставался «живым», независимо от того, «активен ли он» в контексте устройства в любой данный момент.

Это работает таким образом, чтобы избежать накладных расходов на постоянное увеличение / уменьшение счетчиков ссылок каждого кадра рендеринга. В Direct3D 9 это происходило тысячи раз за кадр или более.

Кроме того, если ID3D11Device достигает нулевого повторного счета, он и все его дочерние объекты освобождаются независимо от количества ссылок на отдельные дочерние устройства.

См. Документы Microsoft .

Лучший ответ - использовать умный указатель, такой как Microsoft :: WRL :: ComPtr , и каждый поток, использующий данный ресурс, имеет собственный ComPtr, указывающий на этот ресурс. Таким образом, единственный реальный особый случай, который у вас будет, это когда вы отключаете устройство (например, отвечаете на DXGI_ERROR_DEVICE_REMOVED или делаете «чистый выход»).

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