Commit Graph

30 Commits

Author SHA1 Message Date
Jeroen Bakker
4d8581c7ee Vulkan: Add node to update buffers
This change adds the option to update a buffer via the render
graph via `vkCmdUpdateBuffer`. This is only enabled for
uniform buffers as they are small and aligned/sized correctly.

Pull Request: https://projects.blender.org/blender/blender/pulls/128416
2024-10-01 14:22:56 +02:00
Jeroen Bakker
d75cf2efd4 Vulkan: Refactor resource binding
Resource binding was over-complicated as I didn't understood the state
manager and vulkan to make the correct decisions at that time. This
refactor will remove a lot of the complexity and improves the performance.

**Performance**

The performance improvement is noticeable in complex grease pencil
scenes.

Grease pencil benchmark file picknick:
- `NVIDIA Quadro RTX 6000` 17 fps -> 24 fps
- `Intel(R) Arc(tm) A750 Graphics (DG2)` 6 -> 21 fps

**Bottle-neck**

The performance improvements originates from moving the update entry
point from state manager to shader interface. The previous implementation
(state manager) had to loop over all the bound resources and find in the
shader interface where it was located in the descriptor set. Ignoring
resources that were not used by the shader. But also making it hard
to determine if descriptor sets actually changed. Previous implementation
assumed descriptor sets always changed.

When descriptor set changed a new descriptor set needed to be allocated.
Most drivers this is a fast operation, but on Intel/Mesa this was measurable
slow. Using an allocation pool doesn't fit the Vulkan API as you are only
able to reuse when the layout matches exactly. Of course doable, but requires
another structure to keep track of the actual layouts.

**Solution**

By using the shader interface as entry point we can:
1. Keep track if there are any changes in the state manager. If not and the
   layout is the same, the previous shader can be reused.
2. In stead of looping over each bound resource, we loop over bind points.

**Future extensions**

Bundle all descriptor set uploads just before use. This would be more
in line with how 'modern' Vulkan should be implemented. This PR already
separates the uploading from the updating and technically allows to upload
more than one descriptor set.

Instead of looking 1 set back we should measure if we can handle multiple
or keep track of the different layouts resources to improve the performance
even further.

Optional use `VK_KHR_descriptor_buffer` when available.

Pull Request: https://projects.blender.org/blender/blender/pulls/128068
2024-09-26 10:59:45 +02:00
Jeroen Bakker
13fa6d6ae1 Vulkan: Refactor of descriptor set
Removes two levels of indirection when updating descriptor sets.
These are the easy ones to remove. Others will be removed in
a future PR.

This is part of reworking of how descriptor sets are used.
This PR Mostly reduces complexity.

Pull Request: https://projects.blender.org/blender/blender/pulls/127915
2024-09-24 10:03:16 +02:00
Jeroen Bakker
4353b7ffba Vulkan: Remove unused code
Vulkan backend has recently switched to a render graph approach. Many
code was left so we could develop the render graph beside the previous
implementation. Last week we removed the switch. This PR will remove
most of the unused code. There might be some left and will be removed
when detected.

Pull Request: https://projects.blender.org/blender/blender/pulls/123422
2024-06-20 11:34:19 +02:00
Jeroen Bakker
07ea6a5c23 Vulkan: Enable render graph
This PR hooks up the vulkan backend with the render graph
for drawing. It can run Blender better than the previous
implementation so we also flipped it to be the default
implementation.

**Some highlights**
- Adds support for framebuffer load/store operations
- Adds support for framebuffer subpass transitions
- Fixes workbench shadows
- Performance is just below OpenGL performance when comparing
  fps. But the screen feels more fluent when using complex
  scenes.
- Current performance is without doing any optimizations so
  will improve in the future.
- EEVEE will not crash but has artifacts and many parts that
  require more work.

**Related to**
- #121648
- #118330

**Known Limitation**
- Similar to previous implementation resources can be freed when
  still in use crashing Blender. This is typically the case when
  playing back an animation or updating a material icon.

**Next steps**
- Remove old implementation
- Get EEVEE to work
- Fix double resource freeing
- Improve performance by identifying hotspots and change them

Pull Request: https://projects.blender.org/blender/blender/pulls/121787
2024-06-14 08:46:33 +02:00
Hans Goudey
da1ea4cdd1 Revert "Draw: Avoid temporary copy for mesh triangulation index buffer"
This reverts commit 108ab1df2d.

This causes issues when duplicating objects that I don't have time
to investigate right now.
2024-05-23 23:43:34 -04:00
Hans Goudey
108ab1df2d Draw: Avoid temporary copy for mesh triangulation index buffer
The mesh triangulation data is stored in CPU memory with the same format
as the triangles GPU index buffer. Because of that we can skip creating a
temporary copied owned by the GPU API. One way to do that is to just
upload the data directly and avoid keeping a reference to it. However, we
can only upload GPU data from the main thread with OpenGL, so instead
reference the data and keep track of whether to free it.

When drawing a mesh with a single material and 1.8 million faces, this
change gives a 12-15% improvement in framerate, from about 32 to 37 FPS.

Part of #116901.

Pull Request: https://projects.blender.org/blender/blender/pulls/122175
2024-05-23 19:59:36 +02:00
Jeroen Bakker
3f6e2ea915 Vulkan: Shader interface access mask
When building the resource access used when adding dispatch/draw commands
to the render graph, the access mask is required. This PR stores the
access mask in the shader interface. When binding the resources referenced
by the state manager, the resource access info struct is populated with
the access flags.

In the near future the resource access info will be passed when adding
a dispatch/draw node to the render graph to generate the links.

Pull Request: https://projects.blender.org/blender/blender/pulls/120908
2024-04-22 20:47:30 +02:00
Jeroen Bakker
ed9dea08b2 Vulkan: Render graph storage buffers
A developer can switch `vk_common.hh#use_render_graph` to enable render graph.
When enabled the buffers and images are tracked by the device resource state
tracker. The storage buffer commands are recorded to the context render graph.

The next unit tests will pass:
- GPUVulkanTest.storage_buffer_create_update_read
- GPUVulkanTest.storage_buffer_clear_zero
- GPUVulkanTest.storage_buffer_clear
- GPUVulkanTest.storage_buffer_copy_from_vertex_buffer

The pattern to migrate to render graph is:
- always construct CreateInfo for class.
- based on `use_render_graph` call `context.command_buffers.something`
  or `context.render_graph.add_node`.
- Hide calls to `context.flush` when `use_render_graph` is true.

Pull Request: https://projects.blender.org/blender/blender/pulls/120812
2024-04-19 12:08:57 +02:00
Jeroen Bakker
d09d93febf Vulkan: Store Vertex, Index and Storage Buffers on Device Memory
Currently all buffer types were stored in host memory, which is visible to the GPU as well.
This is typically slow as the data would be transferred over the PCI bus when used.

Most of the time Index and Vertex buffers are written once and read many times so it makes
more sense to locate them on the GPU. Storage buffers typically require quick access as they
are created for shading/compute purposes.

This PR will try to store vertex buffers, index buffers and storage buffers on device memory
to improve the performance.

Uniform buffers are still located on host memory as they can be uploaded during binding process.
This can (will) reset the graphics pipeline triggering draw calls using unattached resources.

In future this could be optimized further as in:
* using different pools for allocating specific buffers, with a fallback when buffers cannot be
  stored on the GPU anymore.
* store uniform buffers in device memory

Pull Request: https://projects.blender.org/blender/blender/pulls/115343
2023-11-24 13:52:48 +01:00
Jeroen Bakker
d638357d6f Fix: Vulkan Multi Indirect Drawing
Multi indirect drawing would bind an offset index buffer, but
indirect drawing parameters also offset the index buffer so
incorrect geometry was drawn.

Fixes drawing of meshes with multiple materials.

Pull Request: https://projects.blender.org/blender/blender/pulls/115190
2023-11-20 15:48:06 +01:00
Jeroen Bakker
782e2e5f9a Vulkan: Make Command Pool, Descriptor Sets Context Specific
In Blender a context should not be shared between threads. In Vulkan a
command pool must not be shared between threads. In the current
implementation the command pool are stored on device level and could
therefore be shared between multiple context which made the implementation
not matching these rules.

This PR moves the command pool from device to command buffers where it
would not conflict between other contexts. This PR doesn't make the Vulkan
backend fully multithreaded. The access to the queue is still missing.

Pull Request: https://projects.blender.org/blender/blender/pulls/114977
2023-11-16 15:03:47 +01:00
Jeroen Bakker
0a0689b0b7 Cleanup: Reduce overloaded-virtual warnings
Pull Request: https://projects.blender.org/blender/blender/pulls/114836
2023-11-14 13:55:37 +01:00
Jeroen Bakker
e77cf08b02 Cleanup: Vulkan: Replace FlagBits with Flags
Vulkan API uses Flags and FlagBits for enumerations. The FlagBits
contains the options that can be hold with the Flags data type.

This wasn't well understood at the beginning of the project and
the FlagBits where used where Flags should have been used. This cleanup
fixes this, improving the readability of the code where bit
manipulations where used.

Pull Request: https://projects.blender.org/blender/blender/pulls/114459
2023-11-03 14:42:12 +01:00
Jeroen Bakker
f35b0373d6 Vulkan: Separate DataTransfer, Compute, Graphics Commands
Goal is to reduce the number of command buffer flushes by tracking what is
happening in the different command queues. This is an initial step towards
advanced queue-ing strategies.

The new (intermediate) strategy records commands to different command
buffers based on what they do. There is a command buffer for data transfers,
compute pipelines and graphics pipelines.

When a compute command is recorded it ensures that all graphic commands
are finished. When a graphic command is recorded it ensures all compute
commands are finished. When a graphic or compute command is scheduled
all recorded data transfer commands are scheduled as well.

Some improvements are expected as multiple compute and data transfers
commands can now be scheduled at the same time and don't need to unbind
and rebind render passes. Especially when using EEVEE-Next which is
compute centric the performance change is visible for the user.

Pull Request: https://projects.blender.org/blender/blender/pulls/114104
2023-10-30 14:21:14 +01:00
Campbell Barton
e955c94ed3 License Headers: Set copyright to "Blender Authors", add AUTHORS
Listing the "Blender Foundation" as copyright holder implied the Blender
Foundation holds copyright to files which may include work from many
developers.

While keeping copyright on headers makes sense for isolated libraries,
Blender's own code may be refactored or moved between files in a way
that makes the per file copyright holders less meaningful.

Copyright references to the "Blender Foundation" have been replaced with
"Blender Authors", with the exception of `./extern/` since these this
contains libraries which are more isolated, any changed to license
headers there can be handled on a case-by-case basis.

Some directories in `./intern/` have also been excluded:

- `./intern/cycles/` it's own `AUTHORS` file is planned.
- `./intern/opensubdiv/`.

An "AUTHORS" file has been added, using the chromium projects authors
file as a template.

Design task: #110784

Ref !110783.
2023-08-16 00:20:26 +10:00
Jeroen Bakker
d84a64900f Vulkan: Device Context Resource Management
The current Vulkan resource management has some issues as context that
are not active can still use resources that are freed via another
context.

When this happens incorrect data can be read on the GPU and even crash
Blender. When trying to bind something that now contains other memory
pointers.

This change introduces that contexts are tracked via the device.
Context will be registered/unregistered with the device instance.
Unbinding of resources must pass the device and the device will check
all registered contexts. Binding of resources will happen via the active
context only.

On user perspective this now allowes:
- Opening/switching files
- Switching workspaces
- Switching render engines

Pull Request: https://projects.blender.org/blender/blender/pulls/108968
2023-06-15 08:14:37 +02:00
Sergey Sharybin
c1bc70b711 Cleanup: Add a copyright notice to files and use SPDX format
A lot of files were missing copyright field in the header and
the Blender Foundation contributed to them in a sense of bug
fixing and general maintenance.

This change makes it explicit that those files are at least
partially copyrighted by the Blender Foundation.

Note that this does not make it so the Blender Foundation is
the only holder of the copyright in those files, and developers
who do not have a signed contract with the foundation still
hold the copyright as well.

Another aspect of this change is using SPDX format for the
header. We already used it for the license specification,
and now we state it for the copyright as well, following the
FAQ:

    https://reuse.software/faq/
2023-05-31 16:19:06 +02:00
Jeroen Bakker
83a2904d1a Vulkan: IndexBuffer as Subrange
Add support for index buffers as subrange. When an index buffer
is a subrange it should bind the source buffer and use the index start
as an offset in the buffer.

Pull Request: https://projects.blender.org/blender/blender/pulls/107871
2023-05-12 12:12:43 +02:00
Jeroen Bakker
a0ea40034b Vulkan: Make ShaderInput Optional
ShaderInput lookup used to be explicit as in we know for sure that the
shader input exists. This was guarded by a assert. During development
of the graphics pipeline we came to the conclusion that this isn't
always the case due to its late bindings of resources.

This PR Makes the shader input lookup return an optional result.
This result can then be checked depending on the area where it is used
to validate the existence.

Pull Request: https://projects.blender.org/blender/blender/pulls/107735
2023-05-11 08:44:57 +02:00
Jeroen Bakker
f428fd8229 Vulkan: Share Device Between Contexts
Previous GHOST_ContextVK would create a logical device for each
context. Blender uses multiple contexts at the same time and wasn't able
to share resources between them as the logical device where different.

This patch will create a single logical device and share them between
multiple contexts. This allows sharing memory/shaders between contexts
and make sure that all memory allocations are freed from the device it
was allocated from.

Some allocations in Blender are freed when there isn't a context, this
was failing in the previous implementation. We didn't noticed it before
as we didn't test multiple contexts.

This patch also moves device specific data structures from VKContext to
VKDevice like the descriptor pools, debug layers etc.

Pull Request: https://projects.blender.org/blender/blender/pulls/107606
2023-05-04 10:06:48 +02:00
Jeroen Bakker
7691d19ad2 Vulkan: Index Buffer
This PR adds the binding of index buffers.

Pull Request: https://projects.blender.org/blender/blender/pulls/107358
2023-04-26 08:09:28 +02:00
Sergey Sharybin
a12a8a71bb Remove "All Rights Reserved" from Blender Foundation copyright code
The goal is to solve confusion of the "All rights reserved" for licensing
code under an open-source license.

The phrase "All rights reserved" comes from a historical convention that
required this phrase for the copyright protection to apply. This convention
is no longer relevant.

However, even though the phrase has no meaning in establishing the copyright
it has not lost meaning in terms of licensing.

This change makes it so code under the Blender Foundation copyright does
not use "all rights reserved". This is also how the GPL license itself
states how to apply it to the source code:

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software ...

This change does not change copyright notice in cases when the copyright
is dual (BF and an author), or just an author of the code. It also does
mot change copyright which is inherited from NaN Holding BV as it needs
some further investigation about what is the proper way to handle it.
2023-03-30 10:51:59 +02:00
Sergey Sharybin
d32d787f5f Clang-Format: Allow empty functions to be single-line
For example

```
OIIOOutputDriver::~OIIOOutputDriver()
{
}
```

becomes

```
OIIOOutputDriver::~OIIOOutputDriver() {}
```

Saves quite some vertical space, which is especially handy for
constructors.

Pull Request: https://projects.blender.org/blender/blender/pulls/105594
2023-03-29 16:50:54 +02:00
Jeroen Bakker
0ad06cd39d Vulkan: Automap Buffers.
It is recommended to map buffers once and not each time the
mapped memory is needed. This patch will map the buffer when
created and unmap the buffer when the buffer is freed.

This patch will reduce the overhead where the Vulkan driver or
the virtual memory manager needs to be accessed.

Pull Request: https://projects.blender.org/blender/blender/pulls/105588
2023-03-09 09:27:42 +01:00
Jeroen Bakker
8c03410ebd Vulkan: Refactor shader interface.
Descriptor set locations are now determined in the
VKShaderInterface. Issues with the previous solution:

- Due to legacy code in GPU module the locations/bindings
  must be the same. Using one for something else might
  result in undesired lookups, incorrect resource
  bindings.
- Images/Textures reuses the same namespace, that didn't
  work as expected when looking up the resources via
  its binding.

This refactoring is required for adding support for
push constants.

Pull Request #105073
2023-02-22 14:42:01 +01:00
Jeroen Bakker
7fb1f060ff Vulkan: Initial Compute Shaders support
This patch adds initial support for compute shaders to
the vulkan backend. As the development is oriented to the test-
cases we have the implementation is limited to what is used there.

It has been validated that with this patch that the following test
cases are running as expected
- `GPUVulkanTest.gpu_shader_compute_vbo`
- `GPUVulkanTest.gpu_shader_compute_ibo`
- `GPUVulkanTest.gpu_shader_compute_ssbo`
- `GPUVulkanTest.gpu_storage_buffer_create_update_read`
- `GPUVulkanTest.gpu_shader_compute_2d`

This patch includes:
- Allocating VkBuffer on device.
- Uploading data from CPU to VkBuffer.
- Binding VkBuffer as SSBO to a compute shader.
- Execute compute shader and altering VkBuffer.
- Download the VkBuffer to CPU ram.
- Validate that it worked.
- Use device only vertex buffer as SSBO
- Use device only index buffer as SSBO
- Use device only image buffers

GHOST API has been changed as the original design was created before
we even had support for compute shaders in blender. The function
`GHOST_getVulkanBackbuffer` has been separated to retrieve the command
buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order
to do correct command buffer processing we needed access to the queue
owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles`
function.

Open topics (not considered part of this patch)
- Memory barriers & command buffer encoding
- Indirect compute dispatching
- Rest of the test cases
- Data conversions when requested data format is different than on device.
- GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices.
  NVIDIA doesn't seem to support 1d textures.

Pull-request: #104518
2023-02-21 15:04:52 +01:00
Jeroen Bakker
f828ecf4ba GPU: Use same read back API as SSBOs
The GPU module has 2 different styles when reading back data from
GPU buffers. The SSBOs used a memcpy to copy the data to a
pre-allocated buffer. IndexBuf/VertBuf gave back a driver/platform
controlled pointer to the memory.

Readback is done for test cases returning mapped pointers is not safe.
For this reason we settled on using the same approach as the SSBO.
Copy the data to a caller pre-allocated buffer.

Reason why this API is currently changed is that the Vulkan API is more
strict on mapping/unmapping buffers that can lead to potential issues
down the road.

Pull Request #104571
2023-02-13 08:34:19 +01:00
Campbell Barton
79c82fc1c5 Cleanup: trailing space 2023-01-31 15:49:04 +11:00
Jeroen Bakker
0e6f2d9fe0 GPU: Add placeholder for Vulkan backend.
This patch adds a placeholder for the vulkan backend.
When activated (`WITH_VULKAN_BACKEND=On` and `--gpu-backend vulkan`)
it might open a blender screen, but nothing should be visible as
none of the functions are implemented or otherwise crash on a nullptr.

This is expected as this is just a placeholder. The goal is to add shader compilation
+validation to this backend as one of the next steps so we can validate
changes to existing shaders on OpenGL, Metal and Vulkan at the same time.

Reviewed By: fclem

Differential Revision: https://developer.blender.org/D16338
2022-10-31 16:01:15 +01:00