Ecco un elenco non esaustivo di Vulkan e DirectX 12. Questo è messo insieme usando criteri simili a quelli di Nathan.
Nel complesso entrambe le API sono sorprendentemente simili. Cose come gli shader stage rimangono invariati da DX11 e OpenGL. E ovviamente, DirectX utilizza le viste per rendere le cose visibili agli shader. Anche Vulkan utilizza le viste, ma sono meno frequenti.
Il comportamento di visibilità dello shader differisce leggermente tra i due. Vulkan utilizza una maschera per determinare se un descrittore è visibile ai vari stadi dello shader. DX12 lo gestisce in modo leggermente diverso, la visibilità delle risorse viene eseguita su uno o più livelli.
Ho rotto il descrittore set / roba dei parametri root meglio che potevo. La gestione dei descrittori è una delle aree che variano notevolmente tra le due API. Tuttavia, il risultato finale è abbastanza simile.
Nozioni di base sulle 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
Il livello WSI di Vulkan fornisce immagini per lo swapchain. DX12 richiede risorse di creazione per rappresentare l'immagine.
Il comportamento generale della coda è abbastanza simile tra i due. C'è un po 'di idiosincrasia quando si invia da più thread.
Proverò ad aggiornare come ricordo più cose ...
Buffer di comando e pool
Vulkan DirectX 12
--------------- ---------------
VkCommandPool ID3D12CommandAllocator
VkCommandBuffer ID3D12CommandList/ID3D12GraphicsCommandList
La discordanza sul pool di comandi / allocatore dai documenti Vulkan / DX12 afferma il comportamento in parole molto diverse, ma il comportamento effettivo è piuttosto simile. Gli utenti sono liberi di allocare molti pool / buffer di comando dal pool. Tuttavia, è possibile registrare solo un buffer / elenco comandi dal pool. I pool non possono essere condivisi tra thread. Quindi più thread richiedono più pool. Puoi anche iniziare a registrare immediatamente dopo aver inviato il buffer / elenco dei comandi su entrambi.
L'elenco dei comandi DX12 viene creato in uno stato aperto. Lo trovo un po 'fastidioso poiché sono abituato a Vulkan. DX12 richiede inoltre un ripristino esplicito dell'allocatore dei comandi e dell'elenco dei comandi. Questo è un comportamento facoltativo in Vulkan.
descrittori
Vulkan DirectX 12
--------------- ---------------
VkDescriptorPool n/a
VkDescriptorSet n/a
VkDescriptorSetLayout n/a
VkDescriptorSetLayoutBinding RootParameter**
n/a ID3D12DescriptorHeap
** RootParameter - non esattamente un equivalente di VkDescriptorSetLayoutBinding ma un pensiero simile nel quadro generale.
VkDescriptorPool e ID3D12DescriptorHeaps sono in qualche modo simili (grazie Nicolas) in quanto entrambi gestiscono l'allocazione dei descrittori stessi.
Va notato che DX12 supporta al massimo due heap di descrittori associati a un elenco di comandi in qualsiasi momento. Un CBVSRVUAV e un campionatore. Puoi avere tutte le tabelle descrittive che vuoi fare riferimento a questi heap.
Sul lato Vulkan, esiste un limite rigido al numero massimo di set di descrittori che si comunica al pool di descrittori. Su entrambi devi fare un po 'di contabilità manuale sul numero di descrittori per tipo che il pool / heap può avere. Vulkan è anche più esplicito con il tipo di descrittori. Considerando che i descrittori DX12 sono CBVSRVUAV o campionatore.
DX12 ha anche una funzione in cui è possibile in qualche modo associare un CBV al volo usando SetGraphicsRootConstantBufferView. Tuttavia, la versione SRV di questo, SetGraphicsRootShaderResourceView, non funziona sulle trame. È nei documenti, ma potrebbe anche richiedere un paio d'ore per capirlo se non sei un lettore attento.
conduttura
Vulkan DirectX 12
--------------- ---------------
VkPipelineLayout RootSignature***
VkPipeline ID3D12PipelineState
VkVertexInputAttributeDescription D3D12_INPUT_ELEMENT_DESC
VkVertexInputBindingDescription "
* ** RootSignature - non esattamente equivalente a VkPipelineLayout .
DX12 combina l'attributo vertice e l'associazione in un'unica descrizione.
Immagini e buffer
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
Le barriere su entrambe le API sono leggermente diverse, ma hanno un risultato netto simile.
RenderPasses / RenderTargets
Vulkan DirectX 12
--------------- ---------------
VkRenderPass render pass
VkFramebuffer collection of ID3D12Resource
subpass n/a
n/a render target
I passaggi di rendering di Vulkan hanno una bella funzione di risoluzione automatica. DX12 non ha questo AFIAK. Entrambe le API forniscono funzioni per la risoluzione manuale.
Non esiste un'equivalenza diretta tra VkFramebuffer e qualsiasi oggetto in DX12. Una raccolta di risorse ID3D12 associate a RTV è una somiglianza libera.
VkFramebuffer agisce più o meno come un pool di allegati a cui VkRenderPass fa riferimento utilizzando un indice. I sottopassi all'interno di un VkRenderPass possono fare riferimento a qualsiasi allegato in un VkFramebuffer supponendo che lo stesso allegato non faccia riferimento più di una volta per sottopassaggio. Il numero massimo di allegati colorati utilizzati contemporaneamente è limitato a VkPhysicalDeviceLimits.maxColorAttachments.
Le destinazioni di rendering di DX12 sono solo RTV supportate da oggetti ID3D12Resource. Il numero massimo di allegati colorati utilizzati contemporaneamente è limitato a D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT (8).
Entrambe le API richiedono di specificare le destinazioni / i passaggi di rendering alla creazione degli oggetti della pipeline. Tuttavia, Vulkan ti consente di utilizzare passaggi di rendering compatibili, quindi non sei bloccato in quelli specificati durante la creazione della pipeline. Non l'ho testato su DX12, ma immagino che dal momento che è solo un RTV, questo è vero anche su DX12.