D3D12 supports out-of-order signal and wait. So does Vulkan timeline
semaphores. However, in Vulkan we don't have an infinite amount of
virtual queues. We must potentially map multiple D3D12 queues on top of
Vulkan, which might lead to a deadlock when app attempts to
wait-before-signal if the two queues are mapped to the same physical
Vulkan queue.
In order to solve this, we need to hold back submissions until we know
it is safe to do so. To make this work in practice as simply as possible, each
ID3D12CommandQueue has its own submission thread, which will block on an
ID3D12Fence's pending timeline value for a Wait command. The main reason to use a
submission thread is that resolving this directly in
ID3D12CommandQueue::Signal is extremely tricky and potentially
needs recursively locking queues and fences.
Note that we only block on the pending wait value, not the actual wait
value, so there is no real CPU <-> GPU synchronization here. In the
common case, no submission thread will block.
The added benefit is that submits are async now, so main thread CPU
overhead might slightly decrease.
To play nice with DXGI swapchain, the external entry point for acquiring
the Vulkan queue needs to drain the submission thread and lock it to ensure
submissions happen in order.
Fixes hangs in The Division 1, which makes use of this D3D12 feature.
Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
The current code uses D3D12 abstractions to create pipelines but
issues raw Vulkan API calls to actually implement the functionality,
which means the code makes assumptions about the exact descriptor
set layout and push constant layout, which is generally a bad idea
now that we have multiple code paths for root constants etc.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Prepares for a rewrite of queue submission, the legacy path is never
run in practice and will likely break in subtle ways.
Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
On NVIDIA we sometimes fail to place images on a heap because the memory
region was dedicated. Only bother trying this if heap flags only allow
buffers.
Fixes a GPU crash in The Division.
Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
We currently can't implement this in a meaningful way, but we
should return an empty blob in order to not crash applications.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
We're going to need this to implement other parts of the
API, so it should be in common code.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
And expose the following feature cap on capable GPUs:
VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
And add a function to (re-)apply dynamic state as necessary. This
will allow us to ignore dynamic state not needed by the pipeline,
and may become necessary if we implement shader-based copies etc.
Currently unused; the following commits will subsequently change
state setting methods over.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Resident Evil 2 needs this method. Since we don't really have a concept
of explicit memory residency in Vulkan, we're fine not doing anything else.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
This way we don't have to change all function parameter types
every time we upgrade the interface version.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
We need a more extensible struct to contain the pipeline
descriptions in order to be able to support new rendering
features.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
RenderDoc will sometimes report extensions as unsupported, but still
fill out and accept the respective feature structs. Since we assume
extensions to be supported if the feature is enabled, we sometimes
try to use functionality that RenderDoc disables and crash.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Besides cleaning up the code, this also allows us to
use information about the available extensions earlier.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
We'll add this to the root descriptor set since moving the binding
to one of the bindless sets would be hard to do; we'd need to track
the binding index of each "bindless" binding for set updates etc.
In order to stay within the limit of 8 sets, we also cannot introduce
a separate set for UAV counters (currently there are 6 bindless sets,
the static sampler set, and the root descriptor set).
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Greatly improves performance in various games that update or
copy a large number of descriptors per frame due to the high
overhead of pthread_mutex_{un}lock.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
All attachments must be at least as large as the framebuffer, using a
max operator is not compliant with Vulkan.
Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
NVIDIA currently seems to have some issues with bindless CBV on Vulkan,
which have been reported. Somehow, bindless SSBO works around black
screen on SotTR, as well as some rendering glitches on Control.
AMD won't care since UBOs and SSBOs are basically the same thing.
Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This method is meant to process d3d12 device caps after the
device itself has been fully initialized. This helps avoid
code duplication in certain instances and guarantees that we
know about all enabled Vulkan features.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Meant to bundle all d3d12 feature caps and options, of which
we're going to have to add more over time.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Used as a fallback for older Nvidia generations which do not
support bindless uniform buffers.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Logically split up descriptor pool allocation in three types:
- STATIC: Root descriptors and internal allocation.
- VOLATILE: For packed descriptor set which comes from heaps.
- IMMUTABLE_SAMPLER: For immutable samplers. This should be removed once
we start allocating sampler sets at sampler creation time.
Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
For now this is enbaled based on device capabilities, but future changes
may require this to be disabled for certain root signatures.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Will be used on implementations that do not support enough
push constants to hold all root signature data.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
When changing tables that only have bindless descriptors,
only update the push constants instead.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
We still need to pass binding info for each range to the shader compiler,
but bindless ranges will not contribute to the packed descriptor count.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Don't enable any bindless features for now so that we don't
introduce regressions as features get added.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Now that the binding code no longer makes any wild assumptions about
the exact binding layout, we can safely do this. Will make implementing
bindless a bit easier.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Uses the new data structures to iterate over descriptor
tables and populate the packed descriptor set.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Further changes will require a rework of how resource binding
works inside a command list, so for now, this is just a cleanup
that also removes some old code that is no longer needed.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Static samplers are embedded in the root signature, so we can create
a separate descriptor set layout and descriptor set which we only
need to rebind when the root signature itself changes.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Updates the root descriptor set or push descriptor at draw time.
This fixes a potential issue with shader-based clear/copy commands
invalidating previously bound root descriptors.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
- descriptor_index is the index of the descriptor within the packed
descriptor set or root descriptor set. Currently unused.
- binding_index should now index into the root_signature->bindings array.
- vk_set and vk_binding refer to the Vulkan descriptor set index and
binding number of packed descriptors or root descriptors.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>