This checkin will use OIIO to replace the image save/load code for BMP,
DDS, DPX, HDR, PNG, TGA, and TIFF.
This simplifies our build environment, reduces binary duplication,
removes large amounts of hard to maintain code, and fixes some bugs
along the way.
It should also help reduce rare differences between Blender and Cycles
which already uses OIIO for most situations. Or potentially makes them
easier to solve once discovered.
This is a continuation of the work for #101413
Pull Request: https://projects.blender.org/blender/blender/pulls/105785
Issue caused by inconsistency in GPUFramebuffer viewport state
between Metal and OpenGL. The MTLFramebuffer code has been
modified such that framebuffer viewport/scissor state is retained
and only updated if attachments are modified during bind.
This is consistent with OpenGL. Previously, other updates to the
framebuffer in Metal would reset the viewport region, especially
if attachments were temporarily removed. This caused the color
picker selection to be misaligned.
Authored by Apple: Michael Parkin-White
Pull Request: https://projects.blender.org/blender/blender/pulls/106619
After investigating the crash logs it looked like the macro
unrolling wasn't working on Windows systems with these GPUs.
Macro unrolling was changed in order to cross compile to Metal and
in the future to Vulkan. The macro unrolling in OpenGL can be removed
by using a different naming scema.
This PR removes the macro unrolling by changing the generated GLSL
code:
**Before**
```
layout(std140) uniform _probe_block
{
ProbeBlock probe_block;
};
```
**After**
```
layout(std140) uniform probe_block
{
ProbeBlock _probe_block;
};
```
Some tweaks had to be done to the Eevee-shaders to make sure that
the macro unrolling is done correctly and could be compiled using
legacy opengl drivers.
Fix: #106278Fix: #106555
(and others)
Pull Request: https://projects.blender.org/blender/blender/pulls/106535
This PR adds debug information inside the spir-v assembly to enable
step-by-step debugging of Shaders using renderdoc. The debugging
information can be fairly large so are only generated when used
with the `--debug-gpu-renderdoc` feature.
During debugging shader optimizations are turned off.
Pull Request: https://projects.blender.org/blender/blender/pulls/106546
This patch refactors the texture samples code by mainly splitting the
eGPUSamplerState enum into multiple smaller enums and packing them
inside a GPUSamplerState struct. This was done because many members of
the enum were mutually exclusive, which was worked around during setting
up the samplers in the various backends, and additionally made the API
confusing, like the GPU_texture_wrap_mode function, which had two
mutually exclusive parameters.
The new structure also improved and clarified the backend sampler cache,
reducing the cache size from 514 samplers to just 130 samplers, which
also slightly improved the initialization time. Further, the
GPU_SAMPLER_MAX signal value was naturally incorporated into the
structure using the GPU_SAMPLER_STATE_TYPE_INTERNAL type.
The only expected functional change is in the realtime compositor, which
now supports per-axis repetition control, utilizing new API functions
for that purpose.
This patch is loosely based on an older patch D14366 by Ethan Hall.
Pull Request: https://projects.blender.org/blender/blender/pulls/105642
Renderdoc requires all calls/updates to originate from the same
context. It also doesn't support multithreading. For now we
enable main context workaround.
The renderdoc integration used to be behind the `--debug-gpu`
command line option. When using `--debug-gpu` outside renderdoc
error messages where displayed that aren't relevant.
This PR adds a specific command line option for the renderdoc
integration. This option will also enable `--debug-gpu`.
Pull Request: https://projects.blender.org/blender/blender/pulls/106541
OpenEXR has some dependecies that other other modules in Blender
requires. When disabling OpenEXR these dependecies could not match
and building blender would fail.
This PR disables the next options when `WITH_IMAGE_OPENEXR=Off`
- `WITH_OPENVDB`
- `WITH_ALEMBIC`
- `WITH_VULKAN_BACKEND`
- `WITH_CYCLES_OSL`
Additionally windows stores the IMath libraries in `IMATH_LIBRARIES`
Linux and Mac stored the IMath libraries in `IMATH_LIBRARY`. This
change will also adds `IMATH_LIBRARIES` variable to all platforms.
Pull Request: https://projects.blender.org/blender/blender/pulls/106209
Splitting workload dependency chains such that they
only exist within the context of a single frame.
Dependencies are required to ensure sequential
command buffer submissions execute in order,
but the additional dependencies between frames
could incur GPU timeouts, if a signal was delayed.
This could be triggered by both CPU/GPU cycles
texture updates and Viewport Compositor operations.
Should also resolve#106401
Authored by Apple: Michael Parkin-White
Pull Request: https://projects.blender.org/blender/blender/pulls/106443
The framebuffer default size was only set during the first bind. This
is because the `dirty_attachments_ tag` wasn't set and thus the
framebuffer size was never passed down to the GL.
Split to `default_size_set()` to not affect other code paths that use
`size_set()`.
Ensure compression is enabled by using shader_read
flag only. Also ensure that MTLTexture contents
remain in optimal layout for reading after any
data modifications.
Authored by Apple: Michael Parkin-White
Pull Request: https://projects.blender.org/blender/blender/pulls/106234
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.
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
This PR adds support for clearing framebuffers and scissor testing.
Tweaks had to be made to VKTexture to keep track of its layout
on the device. Based on the actual call the layout can switch
to a more optimum layout.
For example during upload of a texture the texture will be converted
to a transfer destination optimized layout. When reading from the
texture it will be converted to a transfer source optimized layout.
The order of the attachments in the framebuffer follows the next rules
- When only color attachments are there the color attachments will
be placed in the slot they are defined. This way it will match
the ShaderCreateInfo binding location.
- When a stencil/depth attachment is added it will be placed
right after the color attachments. When there isn't a color
attachment it will be the first attachment.
Pull Request: https://projects.blender.org/blender/blender/pulls/106044
IMath is required for building with vulkan. This patch adds
dependencies to shader_builder for now.
Currently there is a difference between windows and other OS's in
which variable the library is stored. Might be because imath isn't
a direct dependecy. As this is a compilation error I did the quickest
solution and check with platform module what would be the best solution.
Pull Request: https://projects.blender.org/blender/blender/pulls/106180
This patch implements the Anti-Aliasing node by porting SMAA from
Workbench into a generic library that can be used by the realtime
compositor and potentially other users. SMAA was encapsulated in an
algorithm to prepare it for use by other nodes that require SMAA
support.
Pull Request: https://projects.blender.org/blender/blender/pulls/106114
This PR adds basic support for texture update, read back and clearing
for Vulkan. In Vulkan we need to convert each data type ourselves as
vulkan buffers are untyped. Therefore this change mostly is about data
conversions.
Considerations:
- Use a compute shader to do the conversions:
- Leads to performance regression as compute pipeline can stall
graphics pipeline
- Lead to additional memory usage as two staging buffers are needed
one to hold the CPU data, and one to hold the converted data.
- Do inline conversion when sending the data to Vulkan using `eGPUDataFormat`
- Additional CPU cycles required and not easy to optimize as it the
implementation requires many branches.
- Do inline conversion when sending the data to Vulkan (optimized for CPU)
For this solution it was chosen to implement the 3rd option as it is fast
and doesn't require additional memory what the other options do.
**Use Imath/half.h**
This patch uses `Imath/half.h` (dependency of OpenEXR) similar to
alembic. But this makes vulkan dependent of the availability of
OpenEXR. For now this isn't checked, but when we are closer to
a working Vulkan backend we have to make a decision how to cope with
this dependency.
**Missing Features**
*Framebuffer textures*
This doesn't include all possible data transformations. Some of those
transformation can only be tested after the VKFramebuffer has been
implemented. Some texture types are only available when created for a
framebuffer. These include the depth and stencil variations.
*Component format*
Is more relevant when implementing VKVertexBuffer.
*SRGB textures*
SRGB encoded textures aren't natively supported on all platforms, in
all usages and might require workarounds. This should be done in a
separate PR in a later stage when we are required to use SRGB textures.
**Test cases**
The added test cases gives an overview of the missing bits and pieces of
the patch. When the implementation/direction is accepted more test cases
can be enabled/implemented.
Some of these test cases will skip depending on the actual support of
platform the tests are running on. For example OpenGL/NVidia will skip
the next test as it doesn't support the texture format on OpenGL, although
it does support it on Vulkan.
```
[ RUN ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI
[ SKIPPED ] GPUOpenGLTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI [ RUN ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI
[ OK ] GPUVulkanTest.texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI
```
Pull Request: https://projects.blender.org/blender/blender/pulls/105762
In Vulkan multiple commands can be in flight simultaneously.
These commands can share resources like descriptor sets or push
constants. When between commands these resources are updated
a new version of the resources should be created.
When a resource is updated it should check the submission id of the
command buffer. If this is different than last known by the resources,
the previous resources should be freed.
If the submission id is the same than previously it has to create a
new version of the resource to not intervene with other commands that
uses the resource before the update.
When the resource wasn't updated between multiple usages in the same
submission id it could reuse the previous resource.
This PR introduces a `ResourceTracker` and a `SubmissionTracker`.
A submission tracker can check if the command buffer is submitted.
In this case all resources of the resource tracker should be freed.
Unmodified resources in the same submission can be shared.
A resource tracker will keep track of all resources that are in
flight. After the resources are used (submission + execution) have
finished the resources can be cleared.
Pull Request: https://projects.blender.org/blender/blender/pulls/105183
This PR uses renderdoc for frame capturing when enabled.
It enabled an easier workflow for frame capturing.
- Capture GPU API calls from test cases
- Capture GPU API calls from background threads
- Capture GPU API calls from background rendering.
Renderdoc is an important GPU debugger used by the Eevee/
Viewport module. Previously we needed to change code in
order to record background rendering, that could on its own
lead to other side-effects.
The integration with renderdoc can be enabled using
`WITH_RENDERDOC=On` compiler option. `GPU_debug_capture_begin`
and `GPU_debug_capture_end` can be added to the section
of the code you want to debug. When running Blender inside
renderdoc this part will automatically be captured.
All GPU test cases are now guarded by these calls. In order
to capture the test cases you need to start the test cases
from renderdoc and the captured GPU API calls will appear
where each capture is a single test case.
Pull Request: https://projects.blender.org/blender/blender/pulls/105921
Implements #102359.
Split the `MLoop` struct into two separate integer arrays called
`corner_verts` and `corner_edges`, referring to the vertex each corner
is attached to and the next edge around the face at each corner. These
arrays can be sliced to give access to the edges or vertices in a face.
Then they are often referred to as "poly_verts" or "poly_edges".
The main benefits are halving the necessary memory bandwidth when only
one array is used and simplifications from using regular integer indices
instead of a special-purpose struct.
The commit also starts a renaming from "loop" to "corner" in mesh code.
Like the other mesh struct of array refactors, forward compatibility is
kept by writing files with the older format. This will be done until 4.0
to ease the transition process.
Looking at a small portion of the patch should give a good impression
for the rest of the changes. I tried to make the changes as small as
possible so it's easy to tell the correctness from the diff. Though I
found Blender developers have been very inventive over the last decade
when finding different ways to loop over the corners in a face.
For performance, nearly every piece of code that deals with `Mesh` is
slightly impacted. Any algorithm that is memory bottle-necked should
see an improvement. For example, here is a comparison of interpolating
a vertex float attribute to face corners (Ryzen 3700x):
**Before** (Average: 3.7 ms, Min: 3.4 ms)
```
threading::parallel_for(loops.index_range(), 4096, [&](IndexRange range) {
for (const int64_t i : range) {
dst[i] = src[loops[i].v];
}
});
```
**After** (Average: 2.9 ms, Min: 2.6 ms)
```
array_utils::gather(src, corner_verts, dst);
```
That's an improvement of 28% to the average timings, and it's also a
simplification, since an index-based routine can be used instead.
For more examples using the new arrays, see the design task.
Pull Request: https://projects.blender.org/blender/blender/pulls/104424
Implement GBuffer prepass and deferred lighting (lights only).
This decouple lighting from the material shaders making them lighter,
less expensive and faster to compile.
Trying to keep a nice data flow so we could potentially use the
subpass programable blending feature on tiled GPU arch.
Not everything is covered yet and #105880 is making the GBuffer layout
a bit awkward and not easily extendable.
Pull Request: https://projects.blender.org/blender/blender/pulls/105868
Adds two modes of GPU frame capture support for
enhanced debugging. GPU frame capture begin/end
allow instantaneous frame capture of all GPU commands
within the capture boundary.
GPU frame capture scopes allow several user-defined capture
regions which can wrap key parts of code. These scopes are
exposed to connected GPU tools allowing the user to manually
trigger a capture of a known scope at the desired time.
This is currently integrated with the Metal backend for
support with Xcode.
Related to #105591
Pull Request: https://projects.blender.org/blender/blender/pulls/105717
Fix race condition if several competing threads are inserting Metal
buffers into the MTLSafeFreeList simultaneously while a new list
chunk is being created.
Also raise the limit for an MTLSafeFreeListChunk size to optimize
for interactivity when releasing lots of memory simultaneously.
Authored by Apple: Michael Parkin-White
Pull Request: https://projects.blender.org/blender/blender/pulls/105254
Optimized node graphs do not get cached and were
not correctly freed once their reference count reached
zero, due to being excluded from the GPUPass garbage
collection.
Also suppress Metal shader warnings, which are prevalent
during material optimization.
Authored by Apple: Michael Parkin-White
Pull Request: https://projects.blender.org/blender/blender/pulls/105795
Metal buffer binding validation would trigger an error
when a given shader had an empty PushConstantBlock.
This patch removes the default uniform code gen if
no uniforms are present, to avoid any possible issues
with buffers being bound to a shader where the destination
data block is size zero.
Authored by Apple: Michael Parkin-White
Pull Request: https://projects.blender.org/blender/blender/pulls/105796
Crash when selecting objects on AMD platforms running
Metal. This was caused by shader compilation warnings
being treated as errors in macOS 10.15. Wrapping
compilation failure with success check resolves error.
Authored by Apple: Michael Parkin-White
Pull Request: https://projects.blender.org/blender/blender/pulls/105739
immDrawPixels performs significantly slower in Metal
than OpenGL. This was caused by two main factors. Firstly,
the additional overhead of tiled texture update, where all
memory needed to be kept in flight for each update, but
caused update to take a slow path. Avoiding tile update
with Metal is more efficient for both memory pressure
and GPU pipelining.
Secondly, on AMD platforms, the staging buffer used
for temporary texture data was page-faulting when
several texture updates would occur within one frame.
This is due to limitations of allocating one large contiguous
memory chunk. Using the Metal buffer pool for staging
data is more efficient.
Authored by Apple: Michael Parkin-White
Pull Request: https://projects.blender.org/blender/blender/pulls/105794