Commit Graph

494 Commits

Author SHA1 Message Date
Henri Verbeet
cb4b5641ea vkd3d: Handle multiple fence NULL event waits in d3d12_device_SetEventOnMultipleFenceCompletion(). 2025-05-06 18:29:06 +02:00
Henri Verbeet
9222f5e5b1 vkd3d: Handle multiple fence ALL waits in d3d12_device_SetEventOnMultipleFenceCompletion(). 2025-05-06 18:29:06 +02:00
Henri Verbeet
e54070c2d7 vkd3d: Introduce d3d12_fence_add_waiting_event(). 2025-05-06 18:29:06 +02:00
Henri Verbeet
615dce0eaa vkd3d: Introduce struct vkd3d_null_event.
This effectively moves "null_event_cond" from struct d3d12_fence and
"latch" from struct vkd3d_waiting_event together into a separate
structure, as well as storing the signalling function in struct
vkd3d_waiting_event instead of getting it from struct d3d12_device. I
think that largely makes sense on its own, but storing the signalling
function in struct vkd3d_waiting_event also allows us to more easily
implement d3d12_device_SetEventOnMultipleFenceCompletion() in a
subsequent commit.
2025-05-06 18:29:06 +02:00
Giovanni Mascellani
07b7975d09 vkd3d: Put all root descriptors in a single Vulkan descriptor set when using Vulkan heaps.
Since 4a94bfc2f6 we segregate
different D3D12 descriptor types in different Vulkan descriptor sets.
This change was introduced to reduce descriptor wasting when
allocating a new descriptor pool; that can be very useful when
using virtual heaps, which have to often cycle through many
descriptors, but it is expected to have limited impact for Vulkan
heaps, given that in that case most descriptors are allocated through
the descriptor heap rather than through the command allocator.

Instead, it has a rather detrimental effect with Vulkan heaps,
because it tends to use many more Vulkan descriptor sets than
necessary, often with just a handful of descriptors each. This
causes a regression on some Vulkan implementations that support
too few descriptor sets.

With this change we revert to a situation similar to before,
stuffing all the descriptors that do not live in a root
descriptor table in as few descriptor sets as possible (at most
one or two, depending on whether push descriptors are used).
2025-02-19 17:58:23 +01:00
Giovanni Mascellani
a7337bc999 vkd3d: Require extension VK_KHR_maintenance2.
We're already implicitly using it for image layouts in which
either depth or stencil is writeable and the other is not.
Correspondingly, add the _KHR suffix in those cases, so the
extension usage is more evident.

According to the Vulkan Hardware Database, only four reports
without this extension were filed since 2023, and all of them
for configurations we likely don't target.
2025-02-19 17:41:30 +01:00
Giovanni Mascellani
5b2d62e59a vkd3d: Explicitly call the appropriate waiting function in the fence worker.
Avoid using an indirect call that makes the code less clear for no
real advantage.
2025-01-21 14:09:29 +01:00
Giovanni Mascellani
22d0841412 vkd3d: Support signalling a fence once all outstanding work is submitted to Vulkan.
When the client acquires the Vulkan queue it has to ensure that
it is not submitting work before other work it depends on already
submitted through the Direct3D 12 API but currently in the internal
vkd3d queue. Currently we suggest to enqueue signalling a fence and
than wait for it before acquiring the Vulkan queue, which is
correct but excessive: it will wait not just for the work currently
in the queue to be submitted, but for it to be executed too,
introducing useless dependencies.

By adding a way to enqueue signalling a fence on the CPU side we
allow the client to wait for the currently outstanding work to
be submitted to Vulkan, but nothing more.
2025-01-21 14:02:22 +01:00
Giovanni Mascellani
bdb8291f6c vkd3d: Release queued fences when stopping the fence worker. 2025-01-21 13:45:33 +01:00
Giovanni Mascellani
ed7a846e2e vkd3d: Only call d3d12_fence_garbage_collect_vk_semaphores_locked() when using binary semaphores.
The function is specific to binary semaphores, and will unconditionally
access the "u.binary" field of struct vkd3d_signaled_semaphore.
2025-01-21 13:45:27 +01:00
Henri Verbeet
bbeecfc835 vkd3d: Drop smaller pools in d3d12_command_allocator_reset_descriptor_pool_array().
Effectively consolidating them.
2024-12-09 16:10:22 +01:00
Conor McCarthy
a43f6a6600 vkd3d: Create descriptor pools of geometrically increasing size.
Creating a pool of 16k descriptors is wasteful if an allocator only uses
a fraction of them, so start at 1k and double for each subsequent
allocation until 16k is reached.
2024-12-05 20:54:45 +01:00
Conor McCarthy
e729ceeb1a vkd3d: Create separate descriptor pools for each vkd3d descriptor type.
Now that our Vulkan descriptor sets contain only a single vkd3d
descriptor type, we're able to create descriptor pools containing only a
single vkd3d descriptor type as well. This avoids wasting unallocated
descriptors of one type when we run out of descriptors of another type.
2024-12-05 20:54:45 +01:00
Conor McCarthy
19c6df1adb vkd3d: Introduce vkd3d_vk_descriptor_pool_array_destroy_pools(). 2024-12-05 20:54:45 +01:00
Conor McCarthy
8dc9fe725a vkd3d: Introduce vkd3d_vk_descriptor_pool_array_pop(). 2024-12-05 20:54:45 +01:00
Conor McCarthy
9d46a1863b vkd3d: Introduce vkd3d_vk_descriptor_pool_array_push(). 2024-12-05 20:54:45 +01:00
Conor McCarthy
7c0ce25bb7 vkd3d: Introduce vkd3d_vk_descriptor_pool_array_push_array(). 2024-12-05 20:54:45 +01:00
Conor McCarthy
3c620e88a0 vkd3d: Introduce struct vkd3d_vk_descriptor_pool_array. 2024-12-05 20:54:45 +01:00
Conor McCarthy
4a94bfc2f6 vkd3d: Store only a single vkd3d descriptor type in each Vulkan descriptor set.
We currently create statically sized descriptor pools, shared among
different descriptor types. Once we're unable to allocate a descriptor
set from a pool, we create a new pool. The unfortunate but predictable
consequence is that when we run out of descriptors of one type, we waste
any unallocated descriptors of the other types.

Dynamically adjusting the pool sizes could mitigate the issue, but it
seems non-trivial to handle all the edge cases, particularly in
situations where the descriptor count ratios change significantly
between frames. Instead, by storing only a single vkd3d descriptor type
in each Vulkan descriptor set we're able to create separate descriptor
pools for each vkd3d descriptor type, which also avoids the issue.

The main drawback of using separate descriptor sets for each descriptor
type is that we can no longer pack all bounded descriptor ranges into a
single descriptor set, potentially leaving fewer descriptor sets
available for unbounded ranges. That seems worth it, but we may end up
having to switch to a more complicated strategy if this ends up being a
problem on Vulkan implementations with a very limited number of
available descriptor sets.
2024-12-05 20:54:45 +01:00
Conor McCarthy
76fd1388d8 vkd3d: Check the IASetVertexBuffers() view count against the device limits.
For example, current MoltenVK only supports 31 vertex buffers.
2024-11-06 21:43:32 +01:00
Conor McCarthy
4889c71857 vkd3d: Zero the pipeline state UAV counter view array when the state is invalidated. (Valgrind)
Otherwise a comparison with uninitialised data occurs in
d3d12_command_list_update_descriptor_table() if virtual heaps are used.
2024-10-22 20:42:06 +02:00
Henri Verbeet
8943999bd2 vkd3d: Slightly simplify the SRV/UAV logic in vk_write_descriptor_set_from_d3d12_desc(). 2024-10-17 17:28:52 +02:00
Conor McCarthy
bfaab9700d vkd3d: Lay out virtual descriptor heap buffer and image bindings consecutively instead of interleaving them.
Slightly simplifies descriptor write addressing, and makes layouts
essentially the same as array layouts, differing only in the binding
details, and therefore easier to understand. This also simplifies the
addition of storage buffer bindings, which can all be added onto the end.
2024-10-17 17:28:46 +02:00
Anna (navi) Figueiredo Gomes
127ae6cf12 vkd3d: Implement d3d12_command_list_OMSetDepthBounds().
Based on the design document, "The runtime will not clamp or validate
the input, but implementations may clamp to the range [0,1] if necessary.",
so we test for the EXT_depth_range_unrestricted extension, and only clamp if
it's not available (thus, necessary to do so).

NaNs are converted to zero as per "NaNs must be treated as 0, but the runtime
will convert NaNs to 0 on behalf of the implementation.", and a default bounds
are set to 0.0 and 1.0.
2024-09-11 14:53:33 +02:00
Giovanni Mascellani
d71966c77e vkd3d: Do not keep track of descriptor heaps when using virtual heaps.
Descriptors only need flushing when using Vulkan heaps, so let's avoid
uselessly scanning an array and taking and releasing a mutex if we're not.
2024-09-10 21:47:38 +02:00