I haven't been able to find such a chart on the web, so I made one here. (Everyone, feel free to add, elaborate, or correct any mistakes. Some of these are just best guesses based on a partial understanding of the API and hardware internals.)
D3D11 OpenGL 4.x ----- ---------- device context immediate context (implicit; no specific name) deferred context (no cross-vendor equivalent, but see GL_NV_command_list) swap chain (implicit; no specific name) (no cross-vendor equivalent) extensions debug layer; info queue GL_KHR_debug extension
D3D11 OpenGL 4.x ----- ---------- pixel shader fragment shader hull shader tessellation control shader domain shader tessellation evaluation shader (vertex shader, geometry shader, and compute shader are called the same in both) registers binding points semantics interface layouts SV_Foo semantics gl_Foo builtin variables class linkage subroutines (no equivalent) program objects; program linking (D3D11's normal behavior; no separate shader objects specific name)
D3D11 OpenGL 4.x ----- ---------- vertex buffer vertex attribute array buffer; vertex buffer object index buffer element array buffer input layout vertex array object (sort of) Draw glDrawArrays DrawIndexed glDrawElements (instancing and indirect draw are called similarly in both) (no equivalent) multi-draw, e.g. glMultiDrawElements stream-out transform feedback DrawAuto glDrawTransformFeedback predication conditional rendering (no equivalent) sync objects
D3D11 OpenGL 4.x ----- ---------- constant buffer uniform buffer object typed buffer texture buffer structured buffer (no specific name; subset of SSBO features) UAV buffer; RWBuffer SSBO (shader storage buffer object) UAV texture; RWTexture image load/store shader resource view texture view sampler state sampler object interlocked operations atomic operations append/consume buffer SSBO + atomic counter discard buffer/texture invalidate buffer/texture (no equivalent) persistent mapping (D3D11's normal behavior; no immutable storage specific name) (implicitly inserted glMemoryBarrier; glTextureBarrier by the API)
D3D11 OpenGL 4.x ----- ---------- (no equivalent) framebuffer object render target view framebuffer color attachment depth-stencil view framebuffer depth-stencil attachment multisample resolve blit multisampled buffer to non-multisampled one multiple render targets multiple color attachments render target array layered image (no equivalent) renderbuffer
D3D11 OpenGL 4.x ----- ---------- timestamp query timer query timestamp-disjoint query (no equivalent) (no equivalent) time-elapsed query occlusion query samples-passed query occlusion predicate query any-samples-passed query pipeline statistics query (no equivalent in core, but see GL_ARB_pipeline_statistics_query) SO statistics query primitives-generated/-written queries (no equivalent) query buffer object
D3D11 OpenGL 4.x ----- ---------- thread invocation thread group work group thread group size local size threadgroup variable shared variable group sync "plain" barrier group memory barrier shared memory barrier device memory barrier atomic+buffer+image memory barriers all memory barrier group memory barrier
Here's a non-exhaustive list of Vulkan and DirectX 12. This is cobbled together using criteria similar to that of Nathan's.
Overall both APIs are surprisingly similar. Things like shader stages remain unchanged from DX11 and OpenGL. And obviously, DirectX uses views to make things visible to shaders. Vulkan also uses views, but they are less frequent.
Shader visibility behavior differs a bit between the two. Vulkan uses a mask to determine if a descriptor is visible to the various shader stages. DX12 handles this a little differently, resource visibility is either done on single stage or all stages.
I broke the descriptor set / root parameter stuff down best I could. Descriptor handling is one of the areas that vary greatly between the two APIs. However, the end result is fairly similar.
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
Vulkan's WSI layer supplies images for the swapchain. DX12 requires creation resources to represent the image.
General queue behavior is pretty similar between both. There's a bit of idiosyncrasy when submitting from multiple threads.
Will try to update as I remember more stuff...
Vulkan DirectX 12 --------------- --------------- VkCommandPool ID3D12CommandAllocator VkCommandBuffer ID3D12CommandList/ID3D12GraphicsCommandList
Verbiage about command pool/allocator from Vulkan/DX12 docs state the behavior in very different words - but the actual behavior is pretty similar. Users are free to allocate many command buffers/lists from the pool. However, only one command buffer/list from the pool can be recording. Pools cannot be shared between threads. So multiple threads require multiple pools. You can also begin recording immediately after submitting the command buffer/list on both.
DX12 command list are created in an open state. I find this a bit annoying since I'm used to Vulkan. DX12 also requires and explicit reset of the command allocator and command list. This is an optional behavior in Vulkan.
Vulkan DirectX 12 --------------- --------------- VkDescriptorPool n/a VkDescriptorSet n/a VkDescriptorSetLayout n/a VkDescriptorSetLayoutBinding RootParameter** n/a ID3D12DescriptorHeap
** RootParameter - not an exact equivalent to VkDescriptorSetLayoutBinding but similar thinking in the bigger picture.
VkDescriptorPool and ID3D12DescriptorHeaps are sort of similar (thanks Nicolas) in that they both manage allocation of the descriptors themselves.
It should be noted that DX12 only supports at most two descriptor heaps bound to a command list at any given time. One CBVSRVUAV and one sampler. You can have as many descriptor tables as you want referencing these heaps.
On the Vulkan side, there is a hard limit to the max number of descriptor sets that you tell the descriptor pool. On both you have to do a bit of manual accounting on the number of descriptors per type the pool/heap can have. Vulkan is also more explicit with the type of descriptors. Whereas on DX12 descriptors are either CBVSRVUAV or sampler.
DX12 also has a feature where you can sort of bind a CBV on the fly using SetGraphicsRootConstantBufferView. However, the SRV version of this, SetGraphicsRootShaderResourceView, does not work on textures. It's in the docs - but may also take you a couple of hours to figure this out if you're not a careful reader.
Vulkan DirectX 12 --------------- --------------- VkPipelineLayout RootSignature*** VkPipeline ID3D12PipelineState VkVertexInputAttributeDescription D3D12_INPUT_ELEMENT_DESC VkVertexInputBindingDescription "
* **RootSignature - not an exact equivalent to VkPipelineLayout.
DX12 combines the vertex attribute and binding into a single description.
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
Barriers on both APIs break down a bit different, but have similar net result.
Vulkan DirectX 12 --------------- --------------- VkRenderPass render pass VkFramebuffer collection of ID3D12Resource subpass n/a n/a render target
Vulkan render passes have a nice auto-resolve feature. DX12 doesn't have this AFIAK. Both APIs provide functions for manual resolve.
There's not a direct equivalence between VkFramebuffer and any objects in DX12. A collection of ID3D12Resource that map to RTVs is a loose similarity.
VkFramebuffer acts more or less like an attachment pool that VkRenderPass references using an index. Subpasses within a VkRenderPass can reference any of the attachments in a VkFramebuffer assuming the same attachment isn't referenced more than once per subpass. Max number of color attachments used at once is limited to VkPhysicalDeviceLimits.maxColorAttachments.
DX12's render targets are just RTVs that are backed by an ID3D12Resource objects. Max number of color attachments used at once is limited to D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT (8).
Both APIs require you to specify the render targets/passes at the creation of the pipeline objects. However, Vulkan allows you to use compatible render passes, so you're not locked into the ones you specify during the pipline creation. I haven't tested it on DX12, but I would guess since it's just an RTV, this is also true on DX12.