Commit Graph

21 Commits

Author SHA1 Message Date
Jeff Moguillansky
75dc76bceb Vulkan: Add support for dynamic rendering local read
This will add support for `VK_KHR_dynamic_rendering_local_read` when supported.
The extension allows reading from an attachment that has been written to by a
previous command.

Per platform optimizations still need to happen in future changes. Change will
 be limited to Qualcomm devices (in a future commit).

On Qualcomm devices this provides an uplift of 16% when using shader_balls.blend

Pull Request: https://projects.blender.org/blender/blender/pulls/131053
2025-01-13 08:10:31 +01:00
Jiarui-Yan
b356c2bec1 Vulkan: Colored debug groups
This PR adds color to debug group so that RenderDoc can give color to different
debug groups and sub-groups in the parent debug group.

Ref: #124099

Pull Request: https://projects.blender.org/blender/blender/pulls/129340
2024-11-29 07:52:00 +01:00
Jeroen Bakker
faf2c6f0ca Vulkan: Add method to query debug group of node
When debugging render graph the debug group name can narrow down the
place where a node originates from. This PR adds a function to retrieve
the full debug group name of a specific node.

Pull Request: https://projects.blender.org/blender/blender/pulls/131081
2024-11-28 12:00:21 +01:00
Campbell Barton
b9f055459a Cleanup: ensure trailing space around comment blocks 2024-11-27 19:01:00 +11:00
Jeroen Bakker
fc5e38c9b6 Vulkan: Allow suspending/resuming of layer tracking
Layer tracking allows modifying specific layers of a bound texture to a
different layout. This was only supported when suspending/resuming was
not needed. However when using complex scenes EEVEE can trigger suspend/
resume rendering scopes. This resulted into several validation warnings
as images where in the incorrect state.

Fixes validation warnings:
- rain_restaurant.blend
- classroom.blend

Pull Request: https://projects.blender.org/blender/blender/pulls/130957
2024-11-26 12:13:52 +01:00
Jeroen Bakker
dfc0d97abf Fix #129678: Vulkan: Synchronization issue
Copying editors to the swap chain is done by a series of draw and copy.
When doing draw, copy, draw the swap chain layout was not matching the
draw command as it resumed previous rendering.

This is solved by validating the pipeline barriers when resuming rendering.
There are also other cases that required this which have been updated.

Pull Request: https://projects.blender.org/blender/blender/pulls/130721
2024-11-22 11:58:23 +01:00
Jeroen Bakker
c2695e2dcc Vulkan: Add support for legacy platforms
Dynamic rendering is a Vulkan 1.3 feature. Most platforms have support
for them, but there are several legacy platforms that don't support dynamic
rendering or have driver bugs that don't allow us to use it.

This change will make dynamic rendering optional allowing legacy
platforms to use Vulkan.

**Limitations**

`GPU_LOADACTION_CLEAR` is implemented as clear attachments.
Render passes do support load clear, but adding support to it would
add complexity as it required multiple pipeline variations to support
suspend/resume rendering. It isn't clear when which variation should
be used what lead to compiling to many pipelines and branches in the
codebase. Using clear attachments doesn't require the complexity
for what is expected to be only used by platforms not supported by
the GPU vendors.

Subpass inputs and dual source blending are not supported as
Subpass inputs can alter the exact binding location of attachments.
Fixing this would add code complexity that is not used.

Ref: #129063

**Current state**

![image](/attachments/9ce012e5-2d88-4775-a636-2b74de812826)

Pull Request: https://projects.blender.org/blender/blender/pulls/129062
2024-11-19 16:30:31 +01:00
Jeroen Bakker
ef3ceb3629 Vulkan: Resource Pools
This PR implements #126353; In short: keep discard list as part of swap chain images. This allows
better determination when resources are actually not in use anymore.

## Resource pool

Resource pools keep track of the resources for a swap chain image.

In Blender this is a bit more complicated due to the way GPUContext work. A single thread can have
multiple contexts. Some of them have a swap chain (GHOST Window) other don't (draw manager). The
resource pool should be shared between the contexts running on the same thread.

When opening multiple windows there are also multiple swap chains to consider.

### Discard pile

Resource handles that are deleted and stored in the discard pile. When we are sure that these
resources are not used on the GPU anymore these are destroyed.

### Reusable resources

There are other resources as well like:
- Descriptor sets
- Descriptor pools

## Open issues

There are some limitations that require future PRs to fix including:
- Background rendering
- Handling multiple windows
- Improve CPU/GPU synchronization
- Reuse staging buffers

Pull Request: https://projects.blender.org/blender/blender/pulls/126353
2024-08-19 15:37:48 +02:00
Jeroen Bakker
ca0e1d696a Vulkan: Layer tracking during render scope
EEVEE can bind layers of a texture that is also used as an attachment. When binding
the image layout of these specific layers can be different that the image layout of
the whole image.

This fixes the known synchronization issues inside EEVEE. wasp_bot, tree_creature and
wanderer scenes can be rendered without any synchronization issue reported by the
Vulkan validation layers.

Design task: #124214

When beginning to render the attachments are being evaluated. If there is an arrayed
texture (with multiple layers) the individual layers of that texture can be tracked
during until the rendering is ended.

When the same texture is bound to a shader it will be a different layer (otherwise
there is a feedback loop, which isn't allowed). The bound layers will typically need
a different layout the transition to the new layout is executed and recorded. When
the rendering ends, the layers are transitioned back to the layout the texture is
expected in.

It can happen that a layer is used multiple times during the same rendering. In
that case the rendering should be suspended to perform the transition. Image layout
transitions are not allowed during rendering.

There is one place where a layer needs to be transited multiple times that is when
EEVEE wants to extract the thickness from the shadow. The thickness is stored inside
the gbuffer_normal which is also used as an attachment. Eval then samples the thickness
from the gbuffer_normal as a sampler. To work around this issue we suspend the rendering
when a `GPU_BARRIER_SHADER_IMAGE_ACCESS` is signaled.

Pull Request: https://projects.blender.org/blender/blender/pulls/124407
2024-07-16 16:39:18 +02:00
Jeroen Bakker
08d365b810 Vulkan: Cleanup barrier state
Try to reduce the barrier state so we can be more flexible when adding
support for sub resource tracking.

Pull Request: https://projects.blender.org/blender/blender/pulls/124237
2024-07-08 12:28:11 +02:00
Jeroen Bakker
88f04e95c3 Vulkan: Fix HiZ synchronization
HiZ update performs a read/write on different buffers, this lead
to write-after-write hazards as the resources where added multiple
times in the same pipeline barrier with different access masks.
This is fixed by merging pipeline barriers based on their resource.

Pull Request: https://projects.blender.org/blender/blender/pulls/124036
2024-07-02 14:06:49 +02:00
Jeroen Bakker
e72e538fdd Vulkan: Fix sequential read hazard
When a buffer resource was read, and after that read from another
shader stage it would not generate the appropriate pipeline barrier.

This is fixed by keeping the last write action around and check
if the shader stage was already included in the previous barriers.

Pull Request: https://projects.blender.org/blender/blender/pulls/123845
2024-06-27 15:53:14 +02:00
Jeroen Bakker
f5b173188e Vulkan: Fix incorrect read image barrier
When having a sequential read image barriers for the same resource
and the second one requires an image layout transition the incorrect
barriers where generated.

This was fixed by aligning the implementation with write image barriers.

Pull Request: https://projects.blender.org/blender/blender/pulls/123712
2024-06-25 11:05:07 +02:00
Jeroen Bakker
dbd04310c7 Vulkan: Fix incorrect layout transition
When many text using BLF the glymp texture could be re-written.
In this case the new upload should be done in a separate render
graph node group. This wasn't the case and resulted in
validation warnings about the glyph texture being in an layout
that wasn't expected.

This PR simplifies the group extraction a bit by looking ahead
when the group ends.

Pull Request: https://projects.blender.org/blender/blender/pulls/123547
2024-06-21 13:26:52 +02:00
Jeroen Bakker
0643f495cd Vulkan: Fix incorrect write access mask in pipeline barriers
By adding the previous mask, masks could be used in pipeline
stages that don't support the mask. Fixed by limiting the
mask to the current node.

Pull Request: https://projects.blender.org/blender/blender/pulls/123381
2024-06-18 17:17:20 +02:00
Jeroen Bakker
22d352dacc Vulkan: Render graph drawing
This PR adds drawing support to the render graph. It adds support for
draw, indirect draw, indexed draw and indexed indirect draw.

Draw commands can only be executed within a rendering scope. Data
transfer commands and dispatch commands cannot be executed within a
rendering scope. Blender can still send in commands in any order and
the render graph needs to find out the best order to minimize context
switches (rendering/begin/end). This is the responsibility of the
scheduler.

The scheduler will push data transfer and dispatch commands outside the
rendering scope:
- data transfer and dispatch commands at the beginning are done before
  the rendering begin.
- data transfer and dispatch commands at the end are done after the
  rendering end.
- data transfer and dispatches in between draw commands will be pushed
  to the beginning if they are not yet being used.
- for all other data transfer and dispatch commands the rendering is
  suspenderd and will be continued afterwards.

Within a rendering context it is not allowed to perform synchronization
commands. Any synchronization commands inside a rendering scope will be
performed before the rendering scope begins. Nodes are now organized
in groups to simplify the code around this area.

Pull Request: https://projects.blender.org/blender/blender/pulls/123168
2024-06-13 09:37:17 +02:00
Jeroen Bakker
c3c4e948b1 Vulkan: Fixing issues in debugging groups
* Debugging groups were not being applied as that part of the code
  wasn't ported to the original patch
* Debugging groups didn't account for nodes that weren't owned by
  any debug group.

Pull Request: https://projects.blender.org/blender/blender/pulls/122136
2024-05-23 09:48:25 +02:00
Jeroen Bakker
488e74a209 Vulkan: Render graph debug groups
This PR implements debug groups in the render graph. Each node contains
a reference to the debug group they belong to. During scheduling the
nodes can be reordered and the correct debug group needs to be
activated.

This is done by keeping track of the current debug group. When a
different debug group is needed, the needed ends/begins are added
to the command buffer.

This mechanism also cleans up debug groups that are not used at all
as they don't have any nodes associated to it.

Pull Request: https://projects.blender.org/blender/blender/pulls/122054
2024-05-21 17:34:55 +02:00
Jeroen Bakker
b998697d4f Vulkan: Fix out of bound access in begin rendering
There is an implementation flaw in the render graph where local pointers
cannot be updated, but the data it refers to can be reallocated to
another location.

The cause of this is that the nodes use an union, which can only contain
simple constructed structs (eg memcpy). this union is stored in a vector
and can relocate the union. Any local pointers can (and will) become
invalid.

This PR is a quick fix by updating the pointers just before sending
them to the command buffer. In future a better fox needs to be done
as part of #121649.

Pull Request: https://projects.blender.org/blender/blender/pulls/121723
2024-05-13 09:35:36 +02:00
Jeroen Bakker
be75f1ac2b Vulkan: Render graph textures
This PR implements render graph for VKTexture. During the
implementation some tweaks to the render graph was done
to support depth and stencil textures.

The render graph will record the image aspect being used
for each node. This will then be used to generate barriers
for the correct aspect.

Also fixes an issue that uploading of array textures didn't
allocate a large enough staging buffer.

Pull Request: https://projects.blender.org/blender/blender/pulls/120821
2024-04-19 14:55:39 +02:00
Jeroen Bakker
adab06bc67 Vulkan: Render graph core
**Design Task**: blender/blender#118330

This PR adds the core of the render graph. The render graph isn't used.
Current implementation of the Vulkan Backend is slow by design. We
focused on stability, before performance. With the new introduced render
graph the focus will shift to performance and keep the stability at where
it is.

Some highlights:
- Every context will get its own render graph. (`VKRenderGraph`).
- Resources (and resource state tracking) is device specific (`VKResourceStateTracker`).
- No node reordering / sub graph execution has been implemented. Currently
  All nodes in the graph is executed in the order they were added. (`VKScheduler`).
- The links inside the graph describe the resources the nodes read from (input links)
  or writes to (output links)
- When resources are written to a resource stamp is incremented allowing keeping
  track of which nodes needs which stamp of a resource.
- At each link the access information (how does the node accesses the resource)
  and image layout (for image resources) are stored. This allows the render graph
  to find out how a resource was used in the past and will be used in the future.
  That is important to construct pipeline barriers that don't stall the whole GPU.

# Defined nodes

This implementation has nodes for:
- Blit image
- Clear color image
- Copy buffers to buffers
- Copy buffers to images
- Copy images to images
- Copy images to buffers
- Dispatch compute shader
- Fill buffers
- Synchronization

Each node has a node info, create info and data struct. The create info
contains all data to construct the node, including the links of the graph.
The data struct only contains the data stored inside the node. The node info
contains the node specific implementation.

> NOTE: Other nodes will be added after this PR lands to main.

# Resources

Before a render graph can be used, the resources should be registered
to `VKResourceStateTracker`. In the final implementation this will be owned by
the `VKDevice`. Registration of resources can be done by calling
`VKResources.add_buffer` or `VKResources.add_image`.

# Render graph

Nodes can be added to the render graph. When adding a node its read/
write dependencies are extracted and converted into links (`VKNodeInfo.
build_links`).
When the caller wants to have a resource up to date the functions
`VKRenderGraph.submit_for_read` or `VKRenderGraph.submit_for_present`
can be called.

These functions will select and order the nodes that are needed
and convert them to `vkCmd*` commands. These commands include pipeline
barrier and image layout transitions.

The `vkCmd` are recorded into a command buffer which is sent to the
device queue.

## Walking the graph

Walking the render graph isn't implemented yet. The idea is to have a
`Map<ResourceWithStamp, Vector<NodeHandle>> consumers` and
`Map<ResourceWithStamp, NodeHandle> producers`. These attributes can
be stored in the render graph and created when building the links, or
can be created inside the VKScheduler as a variable. The exact detail
which one would be better is unclear as there aren't any users yet. At
the moment the scheduler would need them we need to figure out the best
way to store and retrieve the consumers/producers.

# Unit tests

The render graph can be tested by enabling `WITH_GTEST` and use
`vk_render_graph` as a filter.

```
bin/tests/blender_test --gtest_filter="vk_render_graph*"
```

Pull Request: https://projects.blender.org/blender/blender/pulls/120427
2024-04-19 10:46:50 +02:00