Типы ресурсов (Direct3D 10)

Все ресурсы, используемые конвейером Direct3D, основаны на двух базовых типах: буферах и текстурах. Буфер — это коллекция необработанных данных (элементов); текстуры — это коллекция текселей (элементов текстуры).

Указать макет ресурса (тип размещения в памяти) можно двумя способами.

Элемент Описание
Типизированных
Полное указание типа при создании ресурса.
Нетипизированный
Тип указывается полностью, когда ресурс привязывается к конвейеру.

 

Ресурсы буфера

Буферный ресурс — это коллекция полностью типизированных данных. Сам буфер содержит элементы. Элемент состоит из 1–4 компонентов. Примеры типов элементов данных: упакованное значение данных (например, R8G8B8A8), 8-разрядное целое число, четыре 32-разрядных числа с плавающей точкой. Эти типы используются для хранения таких данных, как позиционный вектор, вектор нормали, координата текстуры в буфере вершин, индекс в буфере индексов или состояние устройства.

Буфер создается как неструктурированный ресурс. Поскольку он неструктурированный, буфер не может содержать какие-либо уровни MIP, не может использовать фильтрацию при чтении и не может подвергаться множественной дискретизации.

Типы буферов

Буфер вершин

Буфер — это коллекция элементов, а буфер вершин содержит данные вершин. Самый простой пример — это буфер вершин, который содержит один тип данных, например данные о положении. Его можно изобразить, как на следующем рисунке.

иллюстрация буфера вершин, который содержит данные положения

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

иллюстрация буфера вершин, который содержит данные положения, нормали и текстуры

Этот буфер вершин содержит данные для восьми вершин. Каждая вершина хранит три элемента (положение, нормаль и координаты текстуры). Положение и норма обычно задаются с помощью трех 32-разрядных с плавающей точкой (DXGI_FORMAT_R32G32B32_FLOAT), а координаты текстуры — двумя 32-разрядными с плавающей точкой (DXGI_FORMAT_R32G32_FLOAT).

Для доступа к данным из буфера вершин необходимо знать, к какой вершине требуется доступ, и следующие параметры буфера:

  • Смещение — число байтов от начала буфера до данных для первой вершины. Смещение предоставляется в IASetVertexBuffers.
  • BaseVertexLocation — количество байтов от смещения до первой вершины, используемой соответствующим вызовом draw (см. раздел Методы рисования).

Перед созданием буфера вершин необходимо определить его макет, создав объект input-layout; Для этого вызывается метод CreateInputLayout. После создания объекта input-layout привяжите его к этапу входного ассемблер, вызвав IASetInputLayout.

Чтобы создать буфер вершин, вызовите CreateBuffer.

Буфер индексов

Буфер индексов содержит последовательный набор 16-разрядных или 32-разрядных индексов; каждый индекс используется для идентификации вершины в буфере вершин. Использование буфера индексов с одним или несколькими буферами вершин для передачи данных этапу IA называется индексированием. Буфер индексов можно изобразить, как на следующем рисунке.

иллюстрация буфера индексов

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

  • Offset — количество байтов от начала буфера до первого индекса; Смещение предоставляется в IASetIndexBuffer.
  • StartIndexLocation — количество байтов от смещения до первой вершины, используемой соответствующим вызовом draw (см. раздел Методы рисования).
  • IndexCount — число индексов для отрисовки.

Чтобы создать буфер индекса, вызовите CreateBuffer.

Буфер индекса может сшить несколько полос линий или треугольников , разделяя каждую из них индексом, вырезанным на полосе. Индекс вырезания полосы позволяет нарисовать несколько линий или полос треугольников в одном вызове. Индекс с чередованием — это просто максимально возможное значение для индекса (0xffff для 16-разрядного индекса, 0xffffffff для 32-разрядного индекса). Индекс вырезания полос сбрасывает порядок поворота в индексированных примитивах и позволяет отказаться от вырожденных треугольников, которые в противном случае могут потребоваться для обеспечения правильной порядка поворота в полосе треугольников. Ниже представлен пример полоса индекса вырезания полосы.

иллюстрация индекса вырезания полосы

Буфер констант

В Direct3D 10 появился новый буфер для предоставления констант шейдера, который называется буфером констант шейдера или просто буфером констант. Концептуально он выглядит так же, как одноэлементный буфер вершин, как показано на следующем рисунке.

иллюстрация буфера констант шейдера

Каждый элемент хранит определяемую форматом данных константу с числом компонентов от 1 до 4.

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

Чтобы создать буфер констант шейдера, вызовите CreateBuffer и укажите флаг привязки констант и буфера D3D10_BIND_CONSTANT_BUFFER (см . D3D10_BIND_FLAG).

Чтобы привязать буфер констант шейдера к конвейеру, вызовите один из следующих методов: GSSetConstantBuffers, PSSetConstantBuffers или VSSetConstantBuffers.

Обратите внимание, что при использовании интерфейса ID3D10Effect процесс создания, привязки и создания буфера констант обрабатывается экземпляром интерфейса ID3D10Effect . В этом случае можно только получить переменную из эффекта с помощью одного из методов GetVariable, таких как GetVariableByName , и обновить переменную с помощью одного из методов SetVariable, таких как SetMatrix. Пример использования интерфейса ID3D10Effect для управления буфером констант см. в руководстве 07.

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

На каждом этапе шейдера можно определить до 15 буферов констант шейдера, причем каждый буфер может содержать до 4096 констант.

Буфер констант можно использовать для хранения результатов этапа вывода потока.

Пример объявления буфера констант в шейдере см. в разделе Константы шейдера (DirectX HLSL).

Ресурсы текстуры

Текстурный ресурс — это структурированный набор данных, предназначенный для хранения текселей. В отличие от буферов текстуры можно фильтровать по дискретизаторам текстур во время их считывания блоками шейдера. Тип текстуры влияет на способ ее фильтрации. Тексель представляет собой наименьший элемент текстуры, который может использоваться конвейером для чтения или записи. Каждый тексель содержит от 1 до 4 компонентов, расположенных в одном из форматов DXGI (см . DXGI_FORMAT).

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

Типы текстур

Существует несколько типов текстур: одно-, двух-, и трехмерный; каждый из них может быть создан с использованием MIP-карт и без них. Direct3D 10 также поддерживает массивы текстур и многомерные текстуры.

Одномерная текстура

Одномерная текстура в самом простом своем виде содержит данные текстуры, к которым можно обращаться по одной координате текстуры; ее можно отобразить как массив текселей, как показано на следующем рисунке.

иллюстрация одномерной текстуры

Каждый тексель содержит несколько цветовых компонентов в зависимости от формата хранимых данных. Повышая сложность, можно создать одномерную текстуру с уровнями MIP-карт, как показано на следующем рисунке.

иллюстрация одномерной текстуры с уровнями MIP-карт

Уровень MIP-карты — это текстура, которая меньше вышестоящего уровня на число, соответствующее степени двух. Самый верхний уровень содержит наиболее больше всего деталей, а для каждого последующего уровня детализация уменьшается. Для одномерной MIP-1карты наименьший уровень содержит один тексель. Различные уровни определяются с помощью индекса LOD (уровень детализации). Вы можете можно использовать LOD для доступа к более мелким текстурам при отрисовке геометрических фигур, которые далеко от камеры.

Массив текстур 1D

В Direct3D 10 также есть новая структура данных для массива текстур. Массив одномерных текстур концептуально выглядит как на следующем рисунке.

иллюстрация массива одномерных текстур

Этот массив текстур содержит три текстуры. Ширина всех трех текстур равна 5 (это число элементов на первом уровне). Каждая текстура также содержит трехслойную MIP-карту.

Все массивы текстур в Direct3D однородные, это означает, что у каждой текстуры в массиве должна быть одинаковый формат данных и размер (в том числе ширина текстуры и количество уровней MIP). Вы можете создавать массивы текстур различных размеров при условии, что все текстуры в отдельном массиве соответствуют друг другу по размеру.

Двухмерная текстура и массив двухмерных текстур

Ресурс Texture2D содержит двухмерную сетку текселей. На каждый тексель указывает вектор u, v. Поскольку это текстурный ресурс, он может содержать уровни MIP и подресурсы. Полностью заполненный ресурс двухмерных текстур соответствует изображению на следующем рисунке.

иллюстрация ресурса двухмерной текстуры

Этот текстурный ресурс содержит одну текстуру 3 x 5 с тремя уровнями MIP.

Ресурс Texture2DArray — это однородный массив двухмерных текстур (формат данных и размер всех текстур, включая уровни MIP, совпадают). Макет этого ресурса похож на макет одномерной текстуры за исключением того, что текстуры теперь содержат двухмерные данные, поэтому ресурс выглядит, как на следующем рисунке.

иллюстрация массива ресурсов двухмерных текстур

Этот массив текстур содержит три текстуры; каждая текстура имеет размер 3 x 5 и два уровня MIP.

Использование Texture2DArray как куба текстур

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

иллюстрация массива ресурсов двухмерных текстур, представляющих куб текстур

Чтение массива двухмерных текстур, содержащего 6 текстур, может производиться из шейдеров со встроенными функциями карт куба, после их привязки к конвейеру с представлением кубической текстуры. Обращение к кубам текстур производится из шейдера с трехмерным вектором, направленным от центра куба текстур.

Трехмерная текстура

Ресурс Texture3D (или объемная текстура) содержит трехмерный объем текселей. Поскольку это ресурс текстуры, он может содержать уровни MIP. Полностью заполненная трехмерная текстура выглядит так, как показано на следующем рисунке.

иллюстрация ресурса трехмерной текстуры

При привязке фрагмента MIP-карты трехмерной текстуры в качестве целевых выходных данных отрисовки (с использованием представления целевого объекта отрисовки) трехмерная текстура ведет себя аналогично массиву двухмерных текстур с n фрагментами. Конкретный срез отрисовки выбирается на этапе геометрического шейдера путем объявления скалярного компонента выходных данных в качестве SV_RenderTargetArrayIndex системного значения.

Понятие массива трехмерных текстур не существует, соответственно, подресурс трехмерной текстуры — это один уровень MIP-карты.

Подресурсы

API Direct3D 10 ссылается на все ресурсы или подмножества ресурсов. Чтобы указать часть ресурсов, Direct3D ввел термин subresources, который означает подмножество ресурса.

Буфер определяется как один подресурс. Текстуры немного более сложны, так как существует несколько типов текстур (одномерные, двухмерные и т. д.), некоторые из которых поддерживают уровни MIP или массивы текстур. Самый простой случай — это одномерная текстура, которая определяется как один подресурс (см. следующий рисунок).

иллюстрация одномерной текстуры

Это означает, что массив текселей, из которых состоит одномерная текстура, содержится в одном подресурсе.

Если развернуть одномерную текстуру с тремя уровнями MIP, ее можно показать следующим образом.

иллюстрация одномерной текстуры с уровнями MIP-карт

Это можно представить как одну текстуру, которая состоит из трех подтекстур. Каждый подтекстура считается подресурсом, поэтому эта одномерная текстура содержит три подресурса. Подтекстура (или подресурс) может индексироваться с помощью уровня детализации (LOD) одной текстуры. При использовании массива текстур для доступа к определенной подтекстуре требуется LOD и конкретная текстура. Или же API объединяет эти два фрагмента информации в один начинающийся с нуля индекс подресурса, как показано здесь.

иллюстрация начинающегося с нуля индекса подресурса

Выбор подресурсов

Некоторые API получают доступ ко всему ресурсу (например , CopyResource), другие — к части ресурса (например , UpdateSubresource или CopySubresourceRegion). Api, который обращается к части ресурса, обычно использует описание представления (например , D3D10_TEX2D_ARRAY_DSV), чтобы указать подресурсы для доступа.

На этих рисунках показаны термины, используемые в описание представления при доступе к массиву текстур.

Срез массива

В массиве текстур, где у каждой текстуры есть MIP-карты, срез массива (представленный белым прямоугольником) содержит одну текстуру и все ее подтекстуры, как показано на следующем рисунке.

иллюстрация среза массива

Срез MIP

Срез MIP (представленный белым прямоугольником) содержит один уровень MIP-карты для каждой текстуры в массиве, как показано на следующем рисунке.

иллюстрация среза MIP

Выбор одного подресурса

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

иллюстрация выбора подресурса с помощью среза массива и среза MIP

Выбор нескольких подресурсов

Или можно использовать эти два типа срезов с количеством уровней MIP-карты или числом текстур, чтобы выбрать несколько подресурсов.

иллюстрация выбора нескольких подресурсов

Независимо от используемого типа текстуры с MIP-картами или без них, с массивом текстур или без них, для вычисления индекса определенного подресурса можно использовать вспомогательную функцию D3D10CalcSubresource.

Строгая и нестрогая типизация

При создании полностью типизированного ресурса он может использовать только тот формат, с которым был создан. Это позволяет среде выполнения оптимизировать доступ, особенно если ресурс создан с флагами, указывающими, что приложение не может сопоставить его. Ресурсы, создаваемые с помощью определенного типа, не могут интерпретироваться с помощью механизма представления.

В ресурсе меньшего типа тип данных неизвестен при первом создании ресурса. Приложение должно выбрать один из доступных типов меньше форматов (см . DXGI_FORMAT). Вам следует указать размер выделяемой области памяти и то, потребуется ли среде выполнения создать подтекстуры в MIP-карте. Однако формат данных, который определяет, будет ли память интерпретироваться как целые числа, значения с плавающей запятой, беззнаковые целые числа и т. д., не определен, пока ресурс не будет привязан к конвейеру с представлением. Так как формат текстуры остается произвольным до привязки текстуры к конвейеру, ресурс называется хранилищем с нестрогой типизацией. Преимущество такого типа хранилища заключается в том, что его можно повторно использовать или интерпретировать (в другом формате), пока компонентный бит формата соответствует разрядности старого формата.

Один ресурс можно привязать к нескольким этапам конвейера, если у каждой из них есть уникального представление, которое полностью квалифицирует форматы в каждом расположении. Например, ресурс, созданный в формате DXGI_FORMAT_R32G32B32A32_TYPELESS, можно одновременно использовать в качестве DXGI_FORMAT_R32G32B32A32_FLOAT и DXGI_FORMAT_R32G32B32A32_UINT в разных местах конвейера.

Ресурсы (Direct3D 10)