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.
API Basics
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...
Command Buffer and Pool
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.
Descriptors
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.
Pipeline
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.
Images and Buffers
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.
RenderPasses / RenderTargets
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.