Voici une liste non exhaustive de Vulkan et DirectX 12. Ceci est bricolé en utilisant des critères similaires à ceux de Nathan.
Dans l'ensemble, les deux API sont étonnamment similaires. Des choses comme les étapes de shader restent inchangées par rapport à DX11 et OpenGL. Et évidemment, DirectX utilise des vues pour rendre les choses visibles aux shaders. Vulkan utilise également des vues, mais elles sont moins fréquentes.
Le comportement de visibilité du shader diffère un peu entre les deux. Vulkan utilise un masque pour déterminer si un descripteur est visible aux différentes étapes du shader. DX12 gère cela un peu différemment, la visibilité des ressources se fait sur une seule étape ou sur toutes les étapes.
J'ai cassé le jeu de descripteurs / paramètres de racine du mieux que je pouvais. La gestion des descripteurs est l'un des domaines qui varient considérablement entre les deux API. Cependant, le résultat final est assez similaire.
Bases de l'API
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
La couche WSI de Vulkan fournit des images pour le swapchain. DX12 nécessite des ressources de création pour représenter l'image.
Le comportement général de la file d'attente est assez similaire entre les deux. Il y a un peu d'idiosyncrasie lors de la soumission à partir de plusieurs threads.
J'essaierai de mettre à jour car je me souviens de plus de choses ...
Tampon de commande et pool
Vulkan DirectX 12
--------------- ---------------
VkCommandPool ID3D12CommandAllocator
VkCommandBuffer ID3D12CommandList/ID3D12GraphicsCommandList
Le verbiage sur le pool de commandes / l'allocateur des documents Vulkan / DX12 énonce le comportement en termes très différents - mais le comportement réel est assez similaire. Les utilisateurs sont libres d'allouer de nombreux tampons / listes de commandes à partir du pool. Cependant, un seul tampon / liste de commandes du pool peut être enregistré. Les pools ne peuvent pas être partagés entre les threads. Ainsi, plusieurs threads nécessitent plusieurs pools. Vous pouvez également commencer l'enregistrement immédiatement après avoir soumis la mémoire tampon / liste de commandes sur les deux.
La liste de commandes DX12 est créée dans un état ouvert. Je trouve cela un peu ennuyeux depuis que je suis habitué à Vulkan. DX12 nécessite également une réinitialisation explicite de l'allocateur de commandes et de la liste de commandes. Il s'agit d'un comportement facultatif dans Vulkan.
Descripteurs
Vulkan DirectX 12
--------------- ---------------
VkDescriptorPool n/a
VkDescriptorSet n/a
VkDescriptorSetLayout n/a
VkDescriptorSetLayoutBinding RootParameter**
n/a ID3D12DescriptorHeap
** RootParameter - pas un équivalent exact de VkDescriptorSetLayoutBinding mais une pensée similaire dans une plus grande image.
VkDescriptorPool et ID3D12DescriptorHeaps sont en quelque sorte similaires (merci Nicolas) en ce qu'ils gèrent tous deux l'allocation des descripteurs eux-mêmes.
Il convient de noter que DX12 ne prend en charge à tout moment que deux tas de descripteurs liés à une liste de commandes. Un CBVSRVUAV et un échantillonneur. Vous pouvez avoir autant de tables de descripteurs que vous voulez référencer ces tas.
Du côté de Vulkan, il y a une limite stricte au nombre maximum d'ensembles de descripteurs que vous indiquez au pool de descripteurs. Sur les deux, vous devez faire un peu de comptabilité manuelle sur le nombre de descripteurs par type que le pool / tas peut avoir. Vulkan est également plus explicite avec le type de descripteurs. Alors que sur DX12, les descripteurs sont CBVSRVUAV ou échantillonneur.
DX12 a également une fonctionnalité où vous pouvez trier un CBV à la volée à l'aide de SetGraphicsRootConstantBufferView. Cependant, la version SRV de cela, SetGraphicsRootShaderResourceView, ne fonctionne pas sur les textures. C'est dans les documents - mais cela peut également vous prendre quelques heures pour comprendre si vous n'êtes pas un lecteur attentif.
Pipeline
Vulkan DirectX 12
--------------- ---------------
VkPipelineLayout RootSignature***
VkPipeline ID3D12PipelineState
VkVertexInputAttributeDescription D3D12_INPUT_ELEMENT_DESC
VkVertexInputBindingDescription "
* ** RootSignature - pas un équivalent exact de VkPipelineLayout .
DX12 combine l'attribut vertex et la liaison en une seule description.
Images et tampons
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
Les barrières sur les deux API tombent un peu différentes, mais ont un résultat net similaire.
RenderPasses / RenderTargets
Vulkan DirectX 12
--------------- ---------------
VkRenderPass render pass
VkFramebuffer collection of ID3D12Resource
subpass n/a
n/a render target
Les passes de rendu Vulkan ont une belle fonction de résolution automatique. DX12 n'a pas cet AFIAK. Les deux API fournissent des fonctions de résolution manuelle.
Il n'y a pas d'équivalence directe entre VkFramebuffer et les objets dans DX12. Une collection de ID3D12Resource qui mappent aux RTV est une similitude lâche.
VkFramebuffer agit plus ou moins comme un pool de pièces jointes que VkRenderPass référence à l'aide d'un index. Les sous-passages d'un VkRenderPass peuvent référencer n'importe quelle pièce jointe dans un VkFramebuffer en supposant que la même pièce jointe n'est pas référencée plus d'une fois par sous-passage. Le nombre maximal de pièces jointes de couleur utilisées simultanément est limité à VkPhysicalDeviceLimits.maxColorAttachments.
Les cibles de rendu de DX12 ne sont que des RTV qui sont soutenus par des objets ID3D12Resource. Le nombre maximal de pièces jointes couleur utilisées simultanément est limité à D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT (8).
Les deux API nécessitent que vous spécifiez les cibles / passes de rendu lors de la création des objets de pipeline. Cependant, Vulkan vous permet d'utiliser des passes de rendu compatibles, vous n'êtes donc pas verrouillé dans celles que vous spécifiez lors de la création de la ligne de repère. Je ne l'ai pas testé sur DX12, mais je suppose que puisque c'est juste un RTV, c'est également vrai sur DX12.