Как / Когда освободить ресурсы и представления ресурсов в DirectX - PullRequest
0 голосов
/ 02 января 2019

Я работаю над демонстрационным приложением DirectX 11 и наткнулся на следующую проблему:
Когда я создаю представление ресурса шейдера (скажем, для текстуры) из файла, я должен выпустить его после использования, как и любой другой объект D3D11. Но как насчет базового ресурса, который создается неявно?

Я могу представить себе три сценария:
+ Я должен оставить ресурс в покое. Выдается по звонку на someShaderResourceView->Release()
+ Я должен выпустить его вручную вместе с объектом представления ресурса шейдера.
+ Я должен выпустить это немедленно. Кажется, это работает, хотя это не кажется мне разумным.

Как правильно справиться с этим?

Редактировать: я использую библиотеку загрузки текстур DirectXTex, но я бы хотел оставить вопрос в общих чертах.

ID3D11Resource *resource;
ID3D11ShaderResourceView *resourceView;
HRESULT result = CreateWICTextureFromFile(device, path.c_str(), &resource, &texture, 0);
//resource->Release(); ???

Вместо CreateWICTextureFromFile(...) можно также использовать старую функцию D3DX11 D3DX11CreateShaderResourceViewFromFile(...).

1 Ответ

0 голосов
/ 02 января 2019

Direct3D использует методы подсчета ссылок (с помощью AddRef и Release) для управления временем жизни объекта, с некоторыми специфическими особенностями, поскольку он не соответствует всем правилам общей модели объектных компонентов ( COM * 1004).*).

В частности, если ссылка only на объект есть, если вы используете установить его в контексте устройства (он же привязывает его к конвейеру рендеринга), этого недостаточно, чтобы сохранить егоживой, потому что эти методы не увеличивают / уменьшают счетчик ссылок.См. Документы Microsoft .Поэтому вашей программе необходимо сохранять некоторые другие ссылки на объекты Direct3D, которые она использует в данный момент.

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

Вы также должны помнить, что объекты Direct3D фактически не уничтожаются до некоторой будущей точки (иначе говоря, она использует lazy-destroying)так что даже если счетчик ссылок равен нулю, может потребоваться несколько кадров, прежде чем он будет полностью очищен.Это в основном имеет значение, если вы имеете дело с большим количеством активных ресурсов и вам нужно беспокоиться о чрезмерной фиксации - кроме того, вы можете принудительно завершить ожидающие разрушения, используя ID3D11DeviceContext::Flush, но это не очень хорошая практика для повышения производительности.это часто.

TL; DR: Объект ID3D11ShaderResourceView добавил счетчик ссылок к объекту ID3D11Resource, на который есть ссылка, поэтому, пока SRV активен, ресурс сохраняется какЧто ж.Вам нужно только взять один из возвращаемых объектов CreateWICTextureFromFile, но вы можете взять оба, если хотите.См. Страницу wiki для модуля WICTextureLoader для получения дополнительной информации.

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

...