Simon Kozlov:
Ну что, событие года, будет D3D12!
Макс живой, похудевший.
Йей, на первом слайде - "Console API effeciency and performance".
Итак, первая половина про уменьшение CPU overhead, вторая про parallelization.
В D3D10+ весь внутренний стейт GPU выставлялся драйвером on draw time, потому что замаппить из D3D11 state в hardware state можно только зная всю картину.
Печалька, оверхед.
В D3D12 весь pipeline state инкапуслирован в один объект,
который выставляет весь стейт разом -
и драйвер может эффективно кешировать готовые части железного стейта.
Второй момент - resource hazards, а именно синхронизация между чтением и записью на одном ресурсе.
Типичный пример - render target, далее используемая как текстура.
И вот теперь есть explicit resource barriers,
т.е. нужно говорить рантайму когда хочешь использовать RT как текстуру.
Кроме этого, дают руками менеджить лайфтайм всех GPU-ресурсов,
т.е. надо самому убедиться, что GPU не читает ресурсы прежде чем его убить,
пользовать самому фенсы, чтобы убедиться что GPU закончило оттуда рендерить.
Дают контроль над residency в GPU memory,
в обход WDDM.
И, наконец, больше не делают state mirroring вообще.
Больше нет Get* APIs.

Resource binding

Resource bindings вынесены отдельно от контекста.
(и даже называются descriptors!)
Simon Kozlov:
Descriptor - кусок hardware-dependent данных, описывающих условно D3D View of the resource.
Есть концепт Descriptor Heaps - кусок памяти, где живут эти дескрипторы.
Можно их просто туда-сюда копировать и как угодно изменять в памяти,
можно создать их несколько и между ними переключаться (у переключения есть overhead)
Внутри pipeline object байндинг происходит по паре (указатель + размер) внутри текущей descriptor heap.
Т.е. можно просто менять память внутри descriptor heap и pipeline object будет прозрачно видеть изменения.

Execution Model

Отдельная большая проблема - это что поток команд GPU, собираемый на каждом фрейме практически одинаковый (на 90-95% тот же самый, шок)
И для решения этого - да, теперь можно сгенерировать набор команд один раз и потом его много раз запускать! (это называется command bundles)
Создавать и констуировать в любых тредах.
Они наследуют resource binding из execution thread в момент выполнения,
т.е. их можно запускать с разными resource bindings.
Говорят, что в WDDM 2.0 command buffer submission намного дешевле,
но без деталей, понятно.
Мощный поворот - это что нужно всегда сгенерировать так называемый Command List (в котором могут быть и обычные команды на отрисовку, и Command Bundles) и отдать его в очередь (Command Queue) чтобы хоть что-то отрисовать -
т.е. больше нет "immediate context", всегда нужно сначала подготовить Command List.
Создание Command List может быть на любом треде,
как и сабмишшен в Command Queue. Это и обеспечивает скалируемость по ядрам - можно готовить последовательность команд GPU в многих тредах и быстро их сливать в Command Queue.

Resource Allocation

Фенсы можно ставить видимо между этими запусками Command lists.
Дают контроль над тем, как аллоцируется GPU-память между ресурсами, чем-то похоже на описанные выше Descriptor Heaps -
можно выделить большой хип и просто класть туда данные для VB/IB/texture в стандартном формате.
Если heap является dynamic, то он еще и persistently mapped,
т.е. можно просто туда писать с CPU,
синхронизироваться самому через фенсы.
Вот @Zeux вылезет в Кружки и расскажет, насколько оно отличается от Mantle -
найдет, так сказать, 10 отличий.
Показывают 5x уменьшение оверхеда в 3Dmark с портированием на D3D12 и command bundles.
Ничего не говорят про то, на каких OS будет работать.
В общем, не знаю, этого ли хотел добиться AMD своим Мантлом, но считаю неплохо получилось.
Лишь бы не сделали win8 only.

Итого

Я значит подведу маленький итог. Основной фокус DX12 - улучшение CPU-side управления GPU.
Во-первых, с помощью уменьшения оверхеда вызовов API, во-вторых, через улучшение мультитредности.
Основная модель - готовить куски command buffer в отдельных тредах и посылать их в queue.
Также дать полный контроль над почти голой памятью, где размещаются GPU-ресурсы, дать возможность их держать в видеопамяти.
И наконец отделить binding ресурсов к выполнению операций на GPU через indirection table в памяти, которая тоже доступна разработчику.
Т.е. основной паттерн - приготовить bundles редко, использовать их в построении command buffers в многих тредах, между ними очень быстро подменять только указатели на ресурсы.
Ivan Vashchaev:
Очень похоже на GL44, как мне кажется.
Arseny Kapoulkine:
Совсем нет.
Может я чего-то про GL44 не знаю конечно.
Почему тебе кажется что похоже?
Ivan Vashchaev:
Да скорее я чего-то не знаю. Похоже в плане фичей: persistent мапинг ресурсов, ориентация на 100500 дипов через multi draw indirect и биндлес текстуры. Из отличий это здоровый рендер стейт в DX12.
Arseny Kapoulkine:
multi draw indirect это не то.
в смысле это способ уменьшать количество дипов.
но для этого надо менять подход к рендеру.
фундаментально.
я сегодня вечером расскажу про много дипов в GL4 (был talk) и про Mantle/DX12.
постараюсь подробнее чем это сделал Семен чтобы было понятно.