Convert all files to CRLF line endings. authored by Alexandre Julliard's avatar Alexandre Julliard
Vkd3d is considered as work-in-progress, there are known issues that Vkd3d is considered as work-in-progress, there are known issues that
have to be resolved. Moreover, there are some incompatibilities between have to be resolved. Moreover, there are some incompatibilities between
Vulkan and Direct3D 12. Vulkan and Direct3D 12.
<table> <table>
<thead> <thead>
<tr class="header"> <tr class="header">
<th><p>Issue</p></th> <th><p>Issue</p></th>
<th><p>Description</p></th> <th><p>Description</p></th>
<th><p>Current implementation</p></th> <th><p>Current implementation</p></th>
<th><p>Possible solutions</p></th> <th><p>Possible solutions</p></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr class="odd"> <tr class="even">
<td></td> <td><p>NULL descriptors</p></td>
<td></td> <td><p>Vulkan doesn't support NULL descriptors.</p></td>
<td></td> <td><p>NULL descriptors are currently emulated using dummy resources.
<td></td> Sparse resources are used when
</tr> `residencyNonResidentStrict` is supported. The current
<tr class="even"> solution doesn't handle `resinfo` and
<td><p>NULL descriptors</p></td> `bufinfo` instructions correctly.</p></td>
<td><p>Vulkan doesn't support NULL descriptors.</p></td> <td></td>
<td><p>NULL descriptors are currently emulated using dummy resources. </tr>
Sparse resources are used when <tr class="odd">
`residencyNonResidentStrict` is supported. The current <td><p>Indirect draws</p></td>
solution doesn't handle `resinfo` and <td><p>In Direct3D 12 indirect draws can update vertex buffer views,
`bufinfo` instructions correctly.</p></td> index buffer views, root constants and root descriptors.</p></td>
<td></td> <td><p>Not supported in Vulkan.</p></td>
</tr> <td><ul>
<tr class="odd"> <li>A Vulkan extension.</li>
<td><p>Indirect draws</p></td> <li>It could be emulated in an inefficient way.</li>
<td><p>In Direct3D 12 indirect draws can update vertex buffer views, </ul></td>
index buffer views, root constants and root descriptors.</p></td> </tr>
<td><p>Not supported in Vulkan.</p></td> <tr class="even">
<td><ul> <td><p>Memory object residency</p></td>
<li>A Vulkan extension.</li> <td><p>Memory object residency management doesn't exist in Vulkan. In
<li>It could be emulated in an inefficient way.</li> Direct3D 12 resources and heaps can be evicted. Resource descriptors are
</ul></td> still valid after a resource is made resident again.</p></td>
</tr> <td></td>
<tr class="even"> <td><p>We can try to evict memory manually (e.g. using sparse
<td><p>Memory object residency</p></td> bindings).</p></td>
<td><p>Memory object residency management doesn't exist in Vulkan. In </tr>
Direct3D 12 resources and heaps can be evicted. Resource descriptors are <tr class="odd">
still valid after a resource is made resident again.</p></td> <td><p>Queries initial state</p></td>
<td></td> <td><p>Queries are initially in the available state in Direct3D 12.
<td><p>We can try to evict memory manually (e.g. using sparse Results are all equal to zero.</p></td>
bindings).</p></td> <td><p>We track the query state, and fill buffer with zeroes when a
</tr> query wasn't issued. The current implementation doesn't handle command
<tr class="odd"> lists executed out-of-order.</p></td>
<td><p>Queries initial state</p></td> <td></td>
<td><p>Queries are initially in the available state in Direct3D 12. </tr>
Results are all equal to zero.</p></td> <tr class="even">
<td><p>We track the query state, and fill buffer with zeroes when a <td><p>Texture array views</p></td>
query wasn't issued. The current implementation doesn't handle command <td><p>Texture array views and textures views are incompatible in
lists executed out-of-order.</p></td> Vulkan.</p></td>
<td></td> <td></td>
</tr> <td></td>
<tr class="even"> </tr>
<td><p>Texture array views</p></td> <tr class="odd">
<td><p>Texture array views and textures views are incompatible in <td><p>Descriptor heaps</p></td>
Vulkan.</p></td> <td><p>Direct3D 12 and Vulkan binding models are largely different. It
<td></td> seems to be implied that Direct3D 12 CBV/SRV/UAV descriptor heaps exist
<td></td> in GPU memory, but there's no real equivalent for that in Vulkan. Vulkan
</tr> descriptor sets are probably the closest match, but among others have
<tr class="odd"> the issue that the descriptor type (CBV, SRV or UAV) would need to be
<td><p>Descriptor heaps</p></td> declared in advance, while in Direct3D 12 these can be mixed freely
<td><p>Direct3D 12 and Vulkan binding models are largely different. It within the descriptor heap. Run-time translation from Direct3D 12
seems to be implied that Direct3D 12 CBV/SRV/UAV descriptor heaps exist binding model to Vulkan binding model is expected to introduce a
in GPU memory, but there's no real equivalent for that in Vulkan. Vulkan noticeable overhead.</p></td>
descriptor sets are probably the closest match, but among others have <td></td>
the issue that the descriptor type (CBV, SRV or UAV) would need to be <td></td>
declared in advance, while in Direct3D 12 these can be mixed freely </tr>
within the descriptor heap. Run-time translation from Direct3D 12 <tr class="even">
binding model to Vulkan binding model is expected to introduce a <td><p>CPU descriptor heaps</p></td>
noticeable overhead.</p></td> <td><p>Direct3D 12 allows to create and prepare descriptors in CPU
<td></td> heaps. Descriptors from CPU descriptor heaps can be copied to
<td></td> shader-visible descriptor heaps. In Vulkan, there are only
</tr> shared-visibile descriptor sets, and
<tr class="even"> `VkCopyDescriptorSet` is implemented very inefficiently
<td><p>CPU descriptor heaps</p></td> on some drivers.</p></td>
<td><p>Direct3D 12 allows to create and prepare descriptors in CPU <td></td>
heaps. Descriptors from CPU descriptor heaps can be copied to <td></td>
shader-visible descriptor heaps. In Vulkan, there are only </tr>
shared-visibile descriptor sets, and <tr class="odd">
`VkCopyDescriptorSet` is implemented very inefficiently <td><p>Descriptor heaps concurrency</p></td>
on some drivers.</p></td> <td><p>Some apps appear to concurrently overwrite descriptors in
<td></td> descriptor heaps. We need to confirm that this works reliably on
<td></td> Windows. It might not be a problem on Windows because implementations
</tr> might simply write or copy descriptors data in memory. However, in our
<tr class="odd"> translation layer we have to manage VkImageView objects and potentially
<td><p>Descriptor heaps concurrency</p></td> reference count them.</p></td>
<td><p>Some apps appear to concurrently overwrite descriptors in <td></td>
descriptor heaps. We need to confirm that this works reliably on <td></td>
Windows. It might not be a problem on Windows because implementations </tr>
might simply write or copy descriptors data in memory. However, in our <tr class="even">
translation layer we have to manage VkImageView objects and potentially <td><p>Descriptors for destroyed resources</p></td>
reference count them.</p></td> <td><p>Apps keep descriptors for destroyed resources in descriptor
<td></td> heaps. This is problematic and may lead to invalid usage in
<td></td> Vulkan.</p></td>
</tr> <td></td>
<tr class="even"> <td></td>
<td><p>Descriptors for destroyed resources</p></td> </tr>
<td><p>Apps keep descriptors for destroyed resources in descriptor <tr class="odd">
heaps. This is problematic and may lead to invalid usage in <td><p>ID3D12Fence</p></td>
Vulkan.</p></td> <td><p>ID3D12Fence have an associated UINT64 value (see also timeline
<td></td> semaphores). In addition, ID3D12Fence can be signaled by GPU or CPU, and
<td></td> can also be waited for on CPU or ID3D12CommandQueue. Moreover, it's
</tr> possible to signal native Win32 events when a fence reaches a certain
<tr class="odd"> value. In Vulkan, there is no way to signal native synchronization
<td><p>ID3D12Fence</p></td> objects (e.g. HANDLEs to Win32 events or file descriptors) when, e.g.
<td><p>ID3D12Fence have an associated UINT64 value (see also timeline VkFence is signaled.</p></td>
semaphores). In addition, ID3D12Fence can be signaled by GPU or CPU, and <td></td>
can also be waited for on CPU or ID3D12CommandQueue. Moreover, it's <td><p>Timeline semaphores.</p></td>
possible to signal native Win32 events when a fence reaches a certain </tr>
value. In Vulkan, there is no way to signal native synchronization <tr class="even">
objects (e.g. HANDLEs to Win32 events or file descriptors) when, e.g. <td><p>Sampler border color</p></td>
VkFence is signaled.</p></td> <td><p>In Direct3D 12 the sampler border color is defined as a float4
<td></td> vector. In Vulkan the border color is constrained by the values of the
<td><p>Timeline semaphores.</p></td> VkBorderColor enum. (It might not be that important because we haven't
</tr> encountered application which needs this yet).</p></td>
<tr class="even"> <td></td>
<td><p>Sampler border color</p></td> <td></td>
<td><p>In Direct3D 12 the sampler border color is defined as a float4 </tr>
vector. In Vulkan the border color is constrained by the values of the <tr class="odd">
VkBorderColor enum. (It might not be that important because we haven't <td><p>Separate resource state for depth-stencil</p></td>
encountered application which needs this yet).</p></td> <td><p>In Direct3D, the depth aspect and the stencil aspect of an image
<td></td> can be in different image layouts.</p></td>
<td></td> <td></td>
</tr> <td><p>Vulkan extension.</p></td>
<tr class="odd"> </tr>
<td><p>Separate resource state for depth-stencil</p></td> <tr class="even">
<td><p>In Direct3D, the depth aspect and the stencil aspect of an image <td><p>Out-of-bounds resource access</p></td>
can be in different image layouts.</p></td> <td><p>Vulkan doesn't give the same guarantees as Direct3D 12 when it
<td></td> comes to out-of-bounds resource access.</p></td>
<td><p>Vulkan extension.</p></td> <td></td>
</tr> <td></td>
<tr class="even"> </tr>
<td><p>Out-of-bounds resource access</p></td> <tr class="odd">
<td><p>Vulkan doesn't give the same guarantees as Direct3D 12 when it <td><p>D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT</p></td>
comes to out-of-bounds resource access.</p></td> <td><p>On radv with AMD Polaris GPUs, the required alignment for
<td></td> textures may be higher than 0x10000
<td></td> (D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT), e.g. 0x20000 or 0x40000.
</tr> World of Warcraft aligns only to
<tr class="odd"> D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT and ignores the alignment
<td><p>D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT</p></td> returned from `GetResourceAllocationInfo()`.</p></td>
<td><p>On radv with AMD Polaris GPUs, the required alignment for <td><p>We currently allocate additional device memory when the heap
textures may be higher than 0x10000 offset is misaligned.</p></td>
(D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT), e.g. 0x20000 or 0x40000. <td></td>
World of Warcraft aligns only to </tr>
D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT and ignores the alignment <tr class="even">
returned from `GetResourceAllocationInfo()`.</p></td> <td><p>Swapchain</p></td>
<td><p>We currently allocate additional device memory when the heap <td><ul>
offset is misaligned.</p></td> <li>sRGB views.</li>
<td></td> <li>Scaling.</li>
</tr> <li>Present mode without recreating.</li>
<tr class="even"> </ul></td>
<td><p>Swapchain</p></td> <td><p>We currently use additional set of images and blit from them to
<td><ul> the real swapchain.</p></td>
<li>sRGB views.</li> <td></td>
<li>Scaling.</li> </tr>
<li>Present mode without recreating.</li> <tr class="odd">
</ul></td> <td><p>Conditional rendering</p></td>
<td><p>We currently use additional set of images and blit from them to <td><p>In D3D12, 64-bit values are used.
the real swapchain.</p></td> `VK_EXT_conditional_rendering` uses 32-bit values. In
<td></td> D3D12, conditional rendering affects copy commands.</p></td>
</tr> <td><p>We do what the `VK_EXT_conditional_rendering`
<tr class="odd"> extension does.</p></td>
<td><p>Conditional rendering</p></td> <td></td>
<td><p>In D3D12, 64-bit values are used. </tr>
`VK_EXT_conditional_rendering` uses 32-bit values. In <tr class="even">
D3D12, conditional rendering affects copy commands.</p></td> <td><p>Binary occlusion queries</p></td>
<td><p>We do what the `VK_EXT_conditional_rendering` <td><p>D3D12 guarantees binary occlusion queries result in only 0 and
extension does.</p></td> 1.</p></td>
<td></td> <td></td>
</tr> <td></td>
<tr class="even"> </tr>
<td><p>Binary occlusion queries</p></td> <tr class="odd">
<td><p>D3D12 guarantees binary occlusion queries result in only 0 and <td><p>Strip cut value</p></td>
1.</p></td> <td><p>In Vulkan the strip cut value is derived from the index format.
<td></td> In Direct3D 12 0xffff or 0xffffffff can be used as the strip cut value
<td></td> with 16-bit and 32-bit index buffer formats.</p></td>
</tr> <td><p>Not supported in Vulkan.</p></td>
<tr class="odd"> <td></td>
<td><p>Strip cut value</p></td> </tr>
<td><p>In Vulkan the strip cut value is derived from the index format. <tr class="even">
In Direct3D 12 0xffff or 0xffffffff can be used as the strip cut value <td><p>GPU virtual addresses</p></td>
with 16-bit and 32-bit index buffer formats.</p></td> <td><p>In Direct3D 12, vertex buffers, index buffers, stream output
<td><p>Not supported in Vulkan.</p></td> buffers and root descriptors are bound using GPU virtual addresses. In
<td></td> Vulkan, VkBuffer objects with an offset are used instead.</p></td>
</tr> <td><p>Fake virtual addresses are allocated for buffers. Virtual
<tr class="even"> addresses have to be resolved to VkBuffer and an offset. The resolving
<td><p>GPU virtual addresses</p></td> of GPU virtual address introduces unnecessary overhead.</p></td>
<td><p>In Direct3D 12, vertex buffers, index buffers, stream output <td><ul>
buffers and root descriptors are bound using GPU virtual addresses. In <li>`VK_EXT_device_buffer_address` can be used for root
Vulkan, VkBuffer objects with an offset are used instead.</p></td> descriptors. Unfortunately, the extension doesn't help with vertex,
<td><p>Fake virtual addresses are allocated for buffers. Virtual index and stream output buffers. The extension also introduces some
addresses have to be resolved to VkBuffer and an offset. The resolving complications, e.g. multiple buffers can be bound to the same virtual
of GPU virtual address introduces unnecessary overhead.</p></td> memory address.</li>
<td><ul> <li>Ideally, we could bind vertex, index and stream output buffers using
<li>`VK_EXT_device_buffer_address` can be used for root `VkDeviceAddress` in Vulkan.</li>
descriptors. Unfortunately, the extension doesn't help with vertex, </ul></td>
index and stream output buffers. The extension also introduces some </tr>
complications, e.g. multiple buffers can be bound to the same virtual <tr class="odd">
memory address.</li> <td><p>`GetResourceAllocationInfo()`</p></td>
<li>Ideally, we could bind vertex, index and stream output buffers using <td><p>In Vulkan, a resource needs to be created to get allocation
`VkDeviceAddress` in Vulkan.</li> info.</p></td>
</ul></td> <td><p>We create temporary resources to get allocation info.</p></td>
</tr> <td></td>
<tr class="odd"> </tr>
<td><p>`GetResourceAllocationInfo()`</p></td> <tr class="even">
<td><p>In Vulkan, a resource needs to be created to get allocation <td><p>`SetEventOnCompletion()` /
info.</p></td> `SetEventOnMultipleFenceCompletion()`</p></td>
<td><p>We create temporary resources to get allocation info.</p></td> <td></td>
<td></td> <td><p>We have a separate thread that signals Win32 events.</p></td>
</tr> <td><p>Timeline semaphores.</p></td>
<tr class="even"> </tr>
<td><p>`SetEventOnCompletion()` / <tr class="odd">
`SetEventOnMultipleFenceCompletion()`</p></td> <td><p>Copy between depth-stencil and color formats</p></td>
<td></td> <td><p>In Direct3D 12 it is possible to copy data between compatible
<td><p>We have a separate thread that signals Win32 events.</p></td> color and depth-stencil resources.</p></td>
<td><p>Timeline semaphores.</p></td> <td><p>We currently use a temporary buffer to perform the copy
</tr> operation.</p></td>
<tr class="odd"> <td><p>We should implement the copy operation in shaders for graphics
<td><p>Copy between depth-stencil and color formats</p></td> and compute queues.</p></td>
<td><p>In Direct3D 12 it is possible to copy data between compatible </tr>
color and depth-stencil resources.</p></td> <tr class="even">
<td><p>We currently use a temporary buffer to perform the copy <td><p>Dynamic states</p></td>
operation.</p></td> <td><p>In Direct3D 12 the following states are dynamic: vertex buffer
<td><p>We should implement the copy operation in shaders for graphics strides, the primitive topology and viewport/scissor counts. In Vulkan,
and compute queues.</p></td> those states require compiling a new pipeline. The primitive topology
</tr> type is still specified when Direct3D 12 pipeline states are created
<tr class="even"> (one of points, lines, triangles, or patches).</p></td>
<td><p>Dynamic states</p></td> <td><p>Vulkan pipelines are created on draw call time when we know all
<td><p>In Direct3D 12 the following states are dynamic: vertex buffer parameters to compile the pipeline.</p></td>
strides, the primitive topology and viewport/scissor counts. In Vulkan, <td><ul>
those states require compiling a new pipeline. The primitive topology <li>Add pipeline cache.</li>
type is still specified when Direct3D 12 pipeline states are created <li>Compile pipelines speculatively.</li>
(one of points, lines, triangles, or patches).</p></td> </ul></td>
<td><p>Vulkan pipelines are created on draw call time when we know all </tr>
parameters to compile the pipeline.</p></td> </tbody>
<td><ul> </table>
<li>Add pipeline cache.</li>
<li>Compile pipelines speculatively.</li>
</ul></td>
</tr>
</tbody>
</table>