Обзор дескрипторов
Дескрипторы создаются вызовами API и определяют ресурсы.
- Дескриптор данных
- Дескриптор обрабатывает
- Нулевые дескрипторы
- Дескрипторы по умолчанию
- связанные темы
Дескрипторные данные
Дескриптор представляет собой относительно небольшой блок данных, который полностью описывает объект для GPU в специфичном для GPU непрозрачном формате. Существует несколько различных типов дескрипторов: представления целевых объектов отрисовки (RTV), представления элементов глубины (DSV), представления ресурсов шейдера (SRV), неупорядоченные представления доступа (UAV), представления буферов констант (CBV) и сэмплеры.
Дескрипторы различаются по размеру в зависимости от аппаратного обеспечения GPU. Вы можете запросить размер SRV, UAV или CBV, вызвав ID3D12Device::GetDescriptorHandleIncrementSize. Дескрипторы отображаются в этой документации как невидимые единицы; Вот пример.
Дескрипторы создаются вызовами API и включают такие сведения, как ресурс и карты MIP, которые требуется содержать дескриптор.
Драйвер не отслеживает и не хранит ссылки на дескрипторы. Ответственность за это лежит на приложении, которое должно убедиться, что используется правильный тип дескриптора и что информация актуальна. Существует одно небольшое исключение из этого правила: драйвер проверяет привязки целевых объектов отрисовки, чтобы обеспечить правильную работу цепочек буферов.
Дескрипторы объектов не должны быть освобождены или выпущены. Драйверы не присоединяют выделенные ресурсы к процессу создания дескриптора. Дескриптор может, однако, кодировать ссылки на другие выделения, сроком жизни которых управляет приложение. Например, дескриптор для SRV должен содержать виртуальный адрес ресурса D3D (например, текстуры), на который ссылается SRV. Приложение должно убедиться, что оно не использует дескриптор SRV, когда базовый ресурс D3D, от которого оно зависит, уничтожен или изменяется (например, объявлен нерезидентным).
Основным способом использования дескрипторов является размещение их в кучах дескриптора, которые создают резервную память для дескрипторов.
Обработчики дескрипторов
Дескрипторный дескриптор — это уникальный адрес дескриптора. Он похож на указатель, но скрытый, поскольку его реализация зависит от конкретного оборудования. Идентификатор является уникальным в кучах идентификаторов, поэтому, например, массив таких идентификаторов может ссылаться на идентификаторы в нескольких кучах.
Дескрипторы процессора предназначены для немедленного использования, например, в случаях копирования, где необходимо определить как источник, так и назначение. Сразу после использования (например, вызов ID3D12GraphicsCommandList::OMSetRenderTargets), их можно повторно использовать или их базовую кучу можно удалить.
Идентификаторы GPU не предназначены для немедленного использования — они определяют местоположения из списка команд для использования во время выполнения задач GPU. Они должны сохраняться до тех пор, пока все списки команд, ссылающиеся на них, полностью не будут выполнены.
Чтобы создать дескриптор для начала кучи, после создания самой кучи дескриптора вызовите один из следующих методов:
- ID3D12DescriptorHeap::GetCPUDescriptorHandleForHeapStart
- ID3D12DescriptorHeap::GetGPUDescriptorHandleForHeapStart
Эти методы возвращают следующие структуры:
Так как размер дескрипторов зависит от оборудования, чтобы получить разницу между каждым дескриптором в куче, используйте:
Можно безопасно смещать начальное расположение на несколько инкрементов, копировать дескрипторы и передавать дескрипторы в вызовы API. Небезопасно разыменовывать дескриптор, как если бы он был допустимым указателем ЦП, а также анализировать биты в дескрипторе.
Добавлены некоторые вспомогательные структуры с элементами инициализации, чтобы упростить управление дескрипторами.
Дескрипторы «null»
При создании дескрипторов с помощью вызовов API приложения передают значение NULL для указателя ресурса в определении дескриптора, чтобы добиться эффекта отсутствия привязки при доступе к шейдеру.
Остальная часть дескриптора должна быть заполнена насколько это возможно. Например, в случае представлений ресурсов шейдера (SRV) дескриптор можно использовать для различения типа представления (Texture1D, Texture2D и т. д.). Числовые параметры в дескрипторе представления, такие как число mipmaps, должны иметь значения, допустимые для ресурса.
Во многих случаях существует определенное поведение для доступа к несвязанным ресурсам, таким как SRVs, возвращающие значения по умолчанию. Они будут учитываться при доступе к дескриптору NULL, если тип доступа шейдера совместим с типом дескриптора. Например, если шейдер ожидает SRV типа Texture2D и обращается к NULL SRV, заданному как Texture1D, то поведение неопределено и может привести к сбросу устройства.
В целом, чтобы создать дескриптор NULL, передайте null
для параметра pResource при создании представления с такими методами, как CreateShaderResourceView. Для параметра описания представления pDescзадайте конфигурацию, которая будет работать, если ресурс не имеет значения NULL (в противном случае может произойти сбой на некотором оборудовании).
Однако корневые дескрипторы не должны иметь значение NULL.
На оборудовании уровня 1 (см. уровни оборудования), все привязанные дескрипторы (через таблицы дескрипторов) должны быть инициализированы как реальные дескрипторы или нулевые дескрипторы, даже если к ним не обращается оборудование, в противном случае поведение не определено.
На оборудовании уровня 2 это относится к привязанным дескрипторам CBV и UAV, но не к дескрипторам SRV.
На оборудовании Tier3 нет ограничений на это, если не происходит обращения к неинициализированным дескрипторам.
Дескрипторы по умолчанию
Чтобы создать дескриптор по умолчанию для определенного представления, передайте допустимый параметр pResource в метод создания представления (например, CreateShaderResourceView), но передайте NULL для параметра pDesc. Например, если ресурс содержал 14 мипс, то представление также будет содержать 14 мипс. Сценарий по умолчанию предусматривает наиболее очевидное сопоставление ресурса с представлением. Для этого требуется, чтобы ресурс был выделен с полностью квалифицированным именем формата (например, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, а не DXGI_FORMAT_R8G8B8A8_TYPELESS).
Дескрипторы по умолчанию нельзя использовать с представлением структуры ускорения луча, так как указанный параметр pResource должен быть null, а расположение должно передаваться через D3D12_RAYTRACING_ACCELERATION_STRUCTURE_SRV.