Hier ist eine nicht vollständige Liste von Vulkan und DirectX 12. Diese sind nach ähnlichen Kriterien wie Nathans zusammengestellt.
Insgesamt sind beide APIs überraschend ähnlich. Dinge wie Shader-Stufen bleiben gegenüber DX11 und OpenGL unverändert. Und natürlich verwendet DirectX Ansichten, um Dinge für Shader sichtbar zu machen. Vulkan verwendet auch Ansichten, aber sie sind weniger häufig.
Das Verhalten der Shader-Sichtbarkeit unterscheidet sich etwas zwischen den beiden. Vulkan verwendet eine Maske, um festzustellen, ob ein Deskriptor für die verschiedenen Shader-Stufen sichtbar ist. DX12 geht damit etwas anders um, die Sichtbarkeit der Ressourcen erfolgt entweder einstufig oder über alle Stufen.
Ich habe das Deskriptor-Set / Root-Parameter-Zeug nach besten Kräften heruntergebrochen. Die Behandlung von Deskriptoren ist einer der Bereiche, die zwischen den beiden APIs sehr unterschiedlich sind. Das Endergebnis ist jedoch ziemlich ähnlich.
API-Grundlagen
Vulkan DirectX 12
--------------- ---------------
n/a IDXGIFactory4
VkInstance n/a
VkPhysicalDevice IDXGIAdapter1
VkDevice ID3D12Device
VkQueue ID3D12CommandQueue
VkSwapchain IDXGISwapChain3
VkFormat DXGI_FORMAT
SPIR-V D3D12_SHADER_BYTECODE
VkFence fences
VkSemaphore n/a
VkEvent n/a
Vulkans WSI-Schicht liefert Bilder für die Swap-Kette. Für DX12 sind Erstellungsressourcen erforderlich, um das Image darzustellen.
Das allgemeine Warteschlangenverhalten ist zwischen beiden ziemlich ähnlich. Es ist etwas eigenwillig, wenn Sie von mehreren Threads aus übermitteln.
Ich werde versuchen zu aktualisieren, wenn ich mich an mehr Dinge erinnere ...
Befehlspuffer und Pool
Vulkan DirectX 12
--------------- ---------------
VkCommandPool ID3D12CommandAllocator
VkCommandBuffer ID3D12CommandList/ID3D12GraphicsCommandList
Die in Vulkan / DX12-Dokumenten enthaltenen Informationen zu Befehlspool / Allokator beschreiben das Verhalten in sehr unterschiedlichen Worten - das tatsächliche Verhalten ist jedoch ziemlich ähnlich. Den Benutzern steht es frei, viele Befehlspuffer / -listen aus dem Pool zuzuweisen. Es kann jedoch nur ein Befehlspuffer / eine Befehlsliste aus dem Pool aufgezeichnet werden. Pools können nicht zwischen Threads geteilt werden. Daher erfordern mehrere Threads mehrere Pools. Sie können die Aufzeichnung auch sofort nach dem Senden des Befehlspuffers / der Befehlsliste auf beiden starten.
DX12-Befehlslisten werden in geöffnetem Zustand erstellt. Ich finde das etwas nervig, da ich an Vulkan gewöhnt bin. DX12 erfordert auch ein explizites Zurücksetzen des Befehlszuordners und der Befehlsliste. Dies ist ein optionales Verhalten in Vulkan.
Deskriptoren
Vulkan DirectX 12
--------------- ---------------
VkDescriptorPool n/a
VkDescriptorSet n/a
VkDescriptorSetLayout n/a
VkDescriptorSetLayoutBinding RootParameter**
n/a ID3D12DescriptorHeap
** RootParameter - kein genaues Äquivalent zu VkDescriptorSetLayoutBinding, aber im Großen und Ganzen ähnliches Denken.
VkDescriptorPool und ID3D12DescriptorHeaps sind ähnlich (danke Nicolas), da sie beide die Zuordnung der Deskriptoren selbst verwalten.
Es ist zu beachten, dass DX12 maximal zwei Deskriptor-Heaps unterstützt, die zu einem bestimmten Zeitpunkt an eine Befehlsliste gebunden sind. Ein CBVSRVUAV und ein Sampler. Sie können so viele Deskriptortabellen haben, wie Sie möchten, um auf diese Heaps zu verweisen.
Auf der vulkanischen Seite gibt es eine feste Grenze für die maximale Anzahl von Deskriptorsätzen, die Sie dem Deskriptorpool mitteilen. In beiden Fällen müssen Sie die Anzahl der Deskriptoren pro Typ, die der Pool / Heap haben kann, manuell abrechnen. Vulkan ist auch expliziter mit der Art der Deskriptoren. Während auf DX12 Deskriptoren entweder CBVSRVUAV oder Sampler sind.
DX12 verfügt auch über eine Funktion, mit der Sie eine CBV mithilfe von SetGraphicsRootConstantBufferView direkt binden können. Die SRV-Version von SetGraphicsRootShaderResourceView funktioniert jedoch nicht für Texturen. Es steht in der Dokumentation - aber es kann auch ein paar Stunden dauern, bis Sie dies herausgefunden haben, wenn Sie kein sorgfältiger Leser sind.
Pipeline
Vulkan DirectX 12
--------------- ---------------
VkPipelineLayout RootSignature***
VkPipeline ID3D12PipelineState
VkVertexInputAttributeDescription D3D12_INPUT_ELEMENT_DESC
VkVertexInputBindingDescription "
* ** RootSignature - entspricht nicht exakt VkPipelineLayout .
DX12 kombiniert das Vertex-Attribut und die Bindung in einer einzigen Beschreibung.
Bilder und Puffer
Vulkan DirectX 12
--------------- ---------------
VkImage ID3D12Resource
VkBuffer ID3D12Resource
uniform buffer constant buffer
index buffer index buffer
vertex buffer vertex buffer
VkSampler sampler
barriers/transitions barriers/transitions
Die Barrieren auf beiden APIs sind etwas unterschiedlich, haben jedoch ein ähnliches Nettoergebnis.
RenderPasses / RenderTargets
Vulkan DirectX 12
--------------- ---------------
VkRenderPass render pass
VkFramebuffer collection of ID3D12Resource
subpass n/a
n/a render target
Vulkan-Renderpässe haben eine nette Funktion zur automatischen Auflösung. DX12 hat diesen AFIAK nicht. Beide APIs bieten Funktionen für die manuelle Lösung.
Es gibt keine direkte Entsprechung zwischen VkFramebuffer und Objekten in DX12. Eine Sammlung von ID3D12Resource, die RTVs zugeordnet sind, weist eine lose Ähnlichkeit auf.
VkFramebuffer verhält sich mehr oder weniger wie ein Anhangspool, auf den VkRenderPass mithilfe eines Index verweist. Subpässe in einem VkRenderPass können auf alle Anhänge in einem VkFramebuffer verweisen, vorausgesetzt, auf denselben Anhang wird nicht mehr als einmal pro Subpass verwiesen. Die maximale Anzahl der gleichzeitig verwendeten Farbanhänge ist auf VkPhysicalDeviceLimits.maxColorAttachments beschränkt.
Die Renderziele von DX12 sind nur RTVs, die von einem ID3D12Resource-Objekt unterstützt werden. Die maximale Anzahl der gleichzeitig verwendeten Farbanhänge ist auf D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT (8) begrenzt.
Bei beiden APIs müssen Sie die Renderziele / -durchläufe bei der Erstellung der Pipelineobjekte angeben. In Vulkan können Sie jedoch kompatible Renderpässe verwenden, sodass Sie nicht an die gebunden sind, die Sie bei der Erstellung der Pipeline angegeben haben. Ich habe es nicht auf DX12 getestet, aber ich würde raten, da es nur ein RTV ist, gilt dies auch für DX12.