Blender expects that only the filename is provided which is true
for internal shader sources.
Metal shaders can error and return a full path to a system shader.
This doesn't fit inside the reserved memory that Blender reserved
for logging filename and line number.
This out of bound write can be triggered when using `min`
where the parameters aren't of the same kind.
`uint min(uint, int)` for example.
This PR reserves more space to store the filename.
Pull Request: https://projects.blender.org/blender/blender/pulls/120967
In Vulkan, a Blender shader is organized in multiple
objects. A VkPipeline is the highest level concept and represents
somewhat we call a shader. A pipeline is an device/platform optimized
version of the shader that is uploaded and executed in the GPU device.
A key difference with shaders is that its usage is also compiled
in. When using the same shader with a different blending, a new pipeline
needs to be created.
In the current implementation of the Vulkan backend the pipeline is
re-created when any pipeline parameter changes. This triggers many
pipeline compilations. Especially when common shaders are used in
different parts of the drawing code.
A requirement of our render graph implementation is that changes
of the pipeline can be detected based on the VkPipeline handle.
We only want to rebind the pipeline handle when the handle actually
changes. This improves performance (especially on NVIDIA) devices
where pipeline binds are known to be costly.
The solution of this PR is to add a pipeline pool. This holds all
pipelines and can find an already created pipeline based on pipeline
infos. Only compute pipelines support has been added.
# Future enhancements
- Recent drivers replace `VkShaderModule` with pipeline libraries.
It improves sharing pipeline stages and reduce pipeline creation times.
- GPUMaterials should be removed from the pipeline pool when they are
destroyed. Details on this will be more clear when EEVEE support is
added.
Pull Request: https://projects.blender.org/blender/blender/pulls/120899
Due to an error in the hash function the specialization constants hash
wasn't optimal. This PR fixes the hash function implementation by replacing
the addition with an xor.
Pull Request: https://projects.blender.org/blender/blender/pulls/120964
Resource access info contains lists in a future setup the resource access info
will be kept in the VKContext and reused. This requires a reset function to
cleanup the instance for reuse.
Pull Request: https://projects.blender.org/blender/blender/pulls/120962
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
Compute shaders are required since 4.0. There was one occasion where
an older AMD driver failed and support was turned off. This driver
is now marked unsupported.
This PR includes:
- removing the check in viewport compositing
- remove properties from system info
- always construct draw manager.
- remove unused pass logic in draw hair/curves
- add deprecation warning when accessed from python
Pull Request: https://projects.blender.org/blender/blender/pulls/120909
Test cases that uses compute shaders were exited when run on platforms
not supporting compute shaders. Since 4.0 Blender requires a platform
that supports compute shaders.
We should eventually phase out `GPU_compute_shader_support` as it
would always return true. Note that in OpenGL a platform is mentioned
that doesn't support compute shaders, but that is from an old driver
and should be save to remove as well.
Pull Request: https://projects.blender.org/blender/blender/pulls/120907
There was a memory leak in the render graph where nodes where freed,
but not the data it could keep. Detected during adding support for
compute shaders and running the draw tests.
Pull Request: https://projects.blender.org/blender/blender/pulls/120906
The specialization constant default hash was implemented in gl_shader.hh
But the same implementation is needed for vulkan. This PR moves the
default hash to a common place where both backends can use it.
Pull Request: https://projects.blender.org/blender/blender/pulls/120889
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
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
f2ae04db10 introduces missing binding
tracking for SSBO and UBOs. Vulkan relies on validation layers to
report on missing bindings, but the binding information should still
be cleared in the context state manager.
Pull Request: https://projects.blender.org/blender/blender/pulls/120814
**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
Trying to narrow down why some tests are failing on windows, but not on
linux/mac. These tests use a string compare. This PR adds two modifications
to the current vk_to_string.
- use `std::endl` although not required, it is important to portability
- print vulkan handles in a uniform way.
Pull Request: https://projects.blender.org/blender/blender/pulls/120780
When reviewing the render graph core PR, we discussed where specific
backend tests should be located. The code style is clear that it
needs to be located in a tests folder next to the code it tests.
This PR moved the tests folder from next to the files they test to
a tests folder.
Pull Request: https://projects.blender.org/blender/blender/pulls/120777
This happened when the buffer was bound as a SSBO as the
slot was not marked as used.
We do not tag the unbind as we never call `unbind` for
SSBOs. Also we don't track what target type the UBO is
bound to. This could be improved later.
- Removed ignored message ids as this is also part of vkconfig which should be used
This is also adviced by the Vulkan Tools WG.
- Also initialize logging when platform doesn't have debugging extensions.
Pull Request: https://projects.blender.org/blender/blender/pulls/120776
This PR adds a context function to consider all
buffer bindings obsolete. This is in order to
track missing binds and invalid lingering states
accross `draw::Pass`es.
The functions `GPU_storagebuf_debug_unbind_all`
and `GPU_uniformbuf_debug_unbind_all` do nothing
more than resetting the internal debug slot bits
to zero. This is what OpenGL backend does as it
doesn't track the bindings themselves.
Other backends might have other way to detect
missing bindings. If not they should be
implemented separately anyway.
I renamed the function to `debug_unbind_all` to
denote that it actually does something related to
debugging.
This also add SSBO binding check for OpenGL as it
was also missing.
#### Future
This error checking logic is pretty much backend
agnostic. While it would be nice to move it at
`gpu::Context` level, we don't have the resources
for that now.
Pull Request: https://projects.blender.org/blender/blender/pulls/120716
Previously all shaders had its own descriptor set layout handle. This makes it
difficult to see if currently bound resources can be reused when switching shaders.
To work around this limitation, the vulkan backend rebound the resources over
and over again.
This PR is part of the render graph where changing shaders can reuse previous
bound resources. This PR only makes sure that the layout handles are the same
so we can identify 'compatible' pipelines. The behavior to limit rebinding of
resources will be added as part of the render graph in a later commit.
Pull Request: https://projects.blender.org/blender/blender/pulls/120562
This contains two thing:
- default (nothing connected to socket) uses the bounding box min axis.
- transform the value plugged to the socket to world space.
We arbitrarly choose to output the axis with the minimum extent since
it is the axis along which the object is usually viewed at.
Rel #120384
Pull Request: https://projects.blender.org/blender/blender/pulls/120607
- Expected results should come before actual result.
- Add test case for 8192 bytes as apple has a push constants size of 4096.
- Add more variation to the first order test data.
Improvements detected when working on vulkan backend and validated they
work on metal and opengl as well.
Pull Request: https://projects.blender.org/blender/blender/pulls/120557
A small logic issue caused all write-only image resources
to be tagged as read-write in all cases. This caused
correctness issues on Intel and AMD GPUs which
are resolved through this change.
Change also yields a small performance uplift
due to enabling improved non-dependent workload
scheduling.
Authored by Apple: Michael Parkin-White
Co-authored-by: Michael Parkin-White <mparkinwhite@apple.com>
Pull Request: https://projects.blender.org/blender/blender/pulls/120528
Adds support for subpass transition for AMD/Intel IMR
GPUs. This enables correct functioning of EEVEE Next
deferred lighting pass on AMD platforms.
The emulation is consistent with the OpenGL approach
of generating additional texture bindings in the shader
for subpass inputs, and splitting render passes across
sub-pass boundaries.
Authored by Apple: Michael Parkin-White
Pull Request: https://projects.blender.org/blender/blender/pulls/119784
MoltenVK original intent was to let developers work on a mac system developing
for the vulkan eco-system. MoltenVK doesn't support all the features that we
require and would require additional workarounds to be actually supported.
It is not expected that we will release Blender with MoltenVK for this reason.
But it still has value for shader developers to validate shaders on metal and
vulkan on a single platform.

Pull Request: https://projects.blender.org/blender/blender/pulls/117940
Removes the implicit USAGE_ATTACHMENT flag from
atomic fallback textures which are buffer-backed.
This usage flag results in a validation failure, and is
not required by these textures as they are cleared
via the backing buffer.
Authored by Apple: Michael Parkin-White
Pull Request: https://projects.blender.org/blender/blender/pulls/119785
This PR is another step in the refactor described by #116901.
This change applies to the triangle index buffer. The main improvement
is the ability to recognize when the mesh corner triangles index array
can be uploaded directly (when there is a single material and no hidden
faces). In that case the index data should be copied directly to the
GPU rather than to a temporary array owned by the IBO first. Though
that isn't implemented yet since it will be handled by the GPU module
later, the code is now structured to make that change simple from the
data extraction perspective.
Other than that, the main change is to not use the extractor iterator
framework anymore, and to set index data directly instead of using GPU
API functions. Though we're mainly bottlenecked by memory-bandwidth
anyway, it's nice to avoid function call overhead.
We also now avoid creating the array of sorted triangle indices when
there is a single material and no hidden faces. And we don't use
restart indices for the single-material case anymore. For Metal that's
nice because we can avoid `strip_restart_indices`.
I didn't notice significant performance improvements in my test files
beyond a few percent here and there. With a hacked implementation of
the copy-directly-to-the-gpu optimization, I did see more consistent
improvements though.
Pull Request: https://projects.blender.org/blender/blender/pulls/119130
Tune Metal compilation parameters for horizon scan
shaders for optimal performance. Selectively unrolling
loops and modifying compilation heuristics results in a
~25% uplift in tracing shader performance, due to
improved latency management.
Authored by Apple: Michael Parkin-White
Pull Request: https://projects.blender.org/blender/blender/pulls/119737
The Perlin noise algorithms suffer from precision issues when a coordinate
is greater than about 250000.
To fix this the Perlin noise texture is repeated every 100000 on each axis.
This causes discontinuities every 100000, however at such scales this
usually shouldn't be noticeable.
Pull Request: https://projects.blender.org/blender/blender/pulls/119884