Ответ 1
Правильный ответ зависит от того, для чего вы собираетесь использовать текстуру. Эти три варианта - это разные способы получения данных из ЦП в текстуру. Если это rendertarget, вы обычно не предоставляете исходные данные из CPU, поэтому можете игнорировать их: создать текстуру и когда вы будете готовы в нее (возможно, сначала Clear()).
Предположим, что у вас есть данные в памяти приложения, которые вы хотите получить в текстуре:
Если это всего лишь статическая текстура (я имею в виду, что текстура считывается из гораздо большего, чем она записана), тогда вам нужна текстура USAGE_DEFAULT или USAGE_IMMUTABLE. Они, как правило, оптимизированы для производительности чтения графического процессора по сравнению с USAGE_DYNAMIC. Если у вас есть данные, которые удобны при создании текстуры, то опция (1) проще всего использовать наименее промежуточную память, а в DX11 передача данных на графический процессор может выполняться в отдельном потоке из потока рендеринга. Если у вас нет данных во время создания текстуры, используйте UpdateSubresource() или параметр (3), чтобы предоставить данные, когда у вас есть.
Если это динамическая текстура, что означает, что вы часто добавляете новое содержимое из CPU (воспроизведение на основе процессора - это канонический случай: данные предоставляются процессором один раз на кадр, а затем считываются на GPU один раз за кадр), тогда вы вероятно, захотите использовать USAGE_DYNAMIC и опцию (2). Тексты USAGE_DYNAMIC оптимизированы для потоковой передачи данных с CPU на GPU, а не просто для чтения графических процессоров. Подробности (и последствия для производительности) различаются между поставщиками оборудования, но обычно вы хотите использовать USAGE_DYNAMIC, если вы действительно загружаете данные с CPU на GPU, а не просто потому, что это удобный способ загрузки статических данных вверх.
Опция (3) более специализирована и может использоваться для начальной загрузки данных в статическую текстуру (повторное использование промежуточной поверхности (ов) для загрузки данных для многих текстур) или для потоковой передачи данных для относительно динамичного использования. Это дает вам точный контроль за синхронизацией GPU/CPU и над промежуточной памятью, используемой для передачи. Обычно вы используете кольцо промежуточных буферов и D3D11_MAP_FLAG_DO_NOT_WAIT, чтобы проверить, используется ли каждый буфер предыдущим экземпляром CopyResource. Я считаю этот вариант экспертом - если вы не будете осторожны, вы можете сильно повредить перфоманс, не позволяя процессору и графическому процессору работать асинхронно.
Полное раскрытие: я работаю над драйвером D3D в Nvidia, но это мои личные мнения.