Программно создавая текстуры directx 11, плюсы и минусы трех разных методов

на документация msdn объясняет, что в directx 11 Существует несколько способов программного заполнения текстуры directx 11:

(1) Создайте текстуру с текстурой использования по умолчанию и инициализируйте ее данными из памяти

(2) Создайте текстуру с динамическим использованием, используйте карту DeviceContext, чтобы получить указатель на память текстуры, напишите на нее, затем используйте Unmap, чтобы указать, что вы сделали (в этот момент я думаю, что он скопирован на gpu)

(3) Создайте текстуру с промежуточным использованием и выполните те же действия, что и для динамической текстуры, но выполните это с вызовом ID3D11DeviceContext.CopyResource, чтобы использовать эту промежуточную текстуру для заполнения (не неизменяемой) по умолчанию или динамической текстуры.

однако документация не объясняет плюсы и минусы каждого метода вообще, и я все еще довольно новичок в directx, поэтому мне это совсем не ясно.

каковы плюсы и минусы каждого из этих способов создание текстуры программно в directx 11?

Примечание: я прочитал это в контексте промежуточных текстур,чтение назад от gpu не буферизован, поэтому вам нужно сделать свою собственную двойную буферизацию. Но я не знаю, было ли это точно и относится ли это к написанию с использованием промежуточных текстур (или даже к тому, что это значит).

вторая сторона Примечание: методика карте документации сказано, что она возвращает указатель на данные в дочерних ресурсов и запрещает доступ к GPU для этого ресурсов. Когда GPU хочет получить доступ к текстуре, базовые данные которой были вызваны Map, что он делает? Столл? (Я спрашиваю, потому что это звучит как часть плюсов и минусов, о которых я спрашивал)

1 ответов


правильный ответ зависит от того, для чего вы собираетесь использовать текстуру. Эти три варианта являются различными способами получения данных из ЦП в текстуру. Если это rendertarget, вы обычно не предоставляете исходные данные из CPU, поэтому вы можете игнорировать их: создайте текстуру, и когда вы будете готовы к рендерингу в нее (возможно, сначала очистите ()).

Итак, предполагая, что у вас есть данные в памяти приложения, которые вы хотите получить в текстуру:

Если это просто статическая текстура (под этим я подразумеваю, что текстура читается намного больше, чем записывается), тогда вам нужна текстура USAGE_DEFAULT или USAGE_IMMUTABLE. Они, как правило, оптимизированы для производительности чтения GPU по сравнению с USAGE_DYNAMIC. Если у вас есть данные, удобные при создании текстуры, то опция (1) проще всего, использует наименьшую промежуточную память, а в DX11 передача данных на GPU может быть выполнена в отдельном потоке от вашего потока рендеринга. Если у вас нет данных в то время вы создаете текстуру, используете UpdateSubresource () или option (3), чтобы предоставить данные, когда они у вас есть.

Если это динамическая текстура, то есть вы часто предоставляете новое содержимое из ЦП (воспроизведение видео на основе ЦП является каноническим случаем: данные предоставляются ЦП один раз за кадр, а затем читаются GPU один раз за кадр), то вы, вероятно, хотите использовать USAGE_DYNAMIC и опцию (2). Usage_dynamic текстуры оптимизированы для потоковой передачи данных с процессора на GPU, а не просто для GPU читает. Детали (и последствия для производительности) различаются между поставщиками оборудования, но обычно вы хотите использовать USAGE_DYNAMIC только в том случае, если вы действительно передаете данные из CPU в GPU, а не просто потому, что это удобный способ загрузки статических данных спереди.

опция (3) является более специализированной и может использоваться для загрузки исходных данных в статическую текстуру (повторно использовать промежуточную поверхность(ы) для загрузки данных для многих текстур) или для потоковой передачи данных для относительно динамического использования. Это дает вы точно контролируете синхронизацию GPU / CPU и промежуточную память, используемую для передачи. Обычно вы используете кольцо промежуточных буферов и D3D11_MAP_FLAG_DO_NOT_WAIT, чтобы проверить, используется ли каждый буфер предыдущим CopyResource. Я считаю это экспертным вариантом - если вы не будете осторожны, вы можете сильно повредить perf, предотвратив асинхронный запуск CPU и GPU.

полное раскрытие: я работаю над драйвером D3D в Nvidia, но это мои личные чужие мнения.