Aber ja, für mich wäre einfacher, einfach einfacher.
Wer englisch lesen kann, kann sich hier eine grobe Zusammenfassung durchlesen:
DirectX 12 - Looking back at GDC 2015 and a year of amazing progress - DirectX Developer Blog - Site Home - MSDN Blogs
Folgende "Features" gibt es für eine bessere GPU-Performance:
Explicit resource transitions:
Das war die Sache mit den UAV-Barriers.
UAV = Unordered Access Views.
Grob gesagt, unter DX11 mussten Pausen eingefügt werden, damit State-Wechsel/Zugriffe auf die Ressourcen immer in einer festen Reihenfolge ausgeführt werden.
Das DX12 Modell sieht vor, dass der Entwickler es hier selber definiert.
Dadurch muss der Treiber nicht zwangsweise Dinge garantieren, sondern die App selber.
Richtig ausgeführt führt es dazu, dass man sich viele eingefügten Zwangspausen sparen kann, wenn man dem Treiber einfach garantiert das während der Zeit nicht auf die Ressourcen zugegriffen wird.
Die Sache hat bei dem Fable-Legends Beispiel 20% gebracht.
Multi-Engine:
Die ALUs von GPUs führen Arbeiten durch, die in eine Arbeitsschlange gepackt werden, in Queues.
Der Command-Processor ist dafür zuständig, dass die Arbeiten an die ALUs verteilt werden.
Damals gab es praktisch nur 3D-Queues, mit modernen APIs gibt es auch Compute-Queues.
Das Problem an dieser Stelle ist, dass man nicht parallel mehrere Queues verschicken konnte, eben bis jetzt mit DX12. (Und andere moderne APIs)
Bei alten APIs müssen Compute und 3D Aufgaben in eine Queue gepackt werden, da gibt es Abhängigkeiten, es geschieht alles in einer gewissen Reihenfolge.
Viel cooler wäre es natürlich wenn man Compute und 3D unabhängig an die ALUs verschicken könnte und das ganze asynchron berechnet wird.
Um so etwas zu ermöglichen hat AMD z.B. ACEs (asynchronous compute engines) in ihre Hardware verbaut.
Dadurch kann AMD neben 3D Queues, parallel auch Compute-Queues verschicken.
Neben 3D und Compute kann die GPU natürlich auch andere Aufgaben erledigen, z.B. Speicherzugriffe.
Mit DMA-Engines (Direct Memory Access) kannst auch noch das ganze parallel gestalten.
An dieser Stelle habe ich das Beispiel mit dem PS4 exklusivem Spiel gebracht, welches ihr Lightning durch Compute berechnet und dank async compute rund 20% Performance gewonnen hat.
Das ganze muss aber natürlich designen.
AMD steht da gut da, Intel hat keine Hardware die mehrere Queues gleichzeitig abschicken kann.
Intels bisheriger Hardware bringt es also gar nichts, ob man mehrere Queues hat oder alle Aufgaben in eine Queue packt, muss so oder nacheinander verteilt werden.
Intel hat aber eine DMA-Engine, sie geben allerdings einschränkend zu, dass diese langsam ist.
Nvidia hat Hyper-Q, grob das gleiche wie AMDs ACEs, bloß gab es dieses Feature nur beim GK110 und man gibt zwar an, dass jede Maxwell GPU es auch hat, aber da fehlen Infos, welche Beschränkungen es gibt.
Wie viele Queues können verteilt werden etc.
ExecuteIndirect:
Soweit ich es verstanden habe, kann man mit einem API-Befehl dadurch mehrere Draw-Calls auf einmal ausführen lassen.
Normalerweise muss die CPU jedes mal der GPU sagen, was sie als nächstes tun soll.
Mit ExecuteIndirect bekommt man die Möglichkeit, welche wieder nur zur Verfügung steht wenn man gewisse Dinge passend anordnet, durch einen Befehl der GPU praktisch eine Liste zu ergeben.
Die GPU kann dann für eine gewisse Sachen unabhängig von der CPU weiter Sachen ausführen.
Das entlastet stark die CPU, hilft aber auch der GPU ~10% beim Asteroiden Beispiel. (Intel Hardware)
Dann gab es noch die Sache mit
Bindless.
Bei alter Hardware wurden Ressourcen immer fest angebunden, wolltest du mehr Ressourcen nutzen musstest du alte erst entbinden etc.
GCN arbeitet intern z.B. immer bindless, es gibt keine binding-slots, allerdings arbeitet DX11 immer noch so, als müssten Ressourcen gebunden werden.
Intels Hardware konnte dadurch rund 10% gewinnen.
Das war ungefähr grob das, was ich verstanden habe.