Commit Graph

195 Commits

Author SHA1 Message Date
Clément Foucault
16aee8efff Fix: #138928: Metal: Custom pyGPU shader has a compilation error in 4.4
This was caused by the removal of some compatibility code
in the metal backend.

This patch reintroduce this compatibility code in a cleaner
way than before.

This should be followed up by a documentation commit that
explains what is supported and what is not.

Pull Request: https://projects.blender.org/blender/blender/pulls/139185
2025-05-22 10:36:04 +02:00
Clément Foucault
caac241c84 GPU: Make Shader Specialization Constant API Thread Safe
This allows multiple threads to request different specializations without
locking usage of all specialized shaders program when a new specialization
is being compiled.

The specialization constants are bundled in a structure that is being
passed to the `Shader::bind()` method. The structure is owned by the
calling thread and only used by the `Shader::bind()`.
Only querying for the specialized shader (Map lookup) is locking the shader
usage.

The variant compilation is now also locking and ensured that
multiple thread trying to compile the same variant will never result
in race condition.

Note that this removes the `is_dirty` optimization. This can be added
back if this becomes a bottleneck in the future. Otherwise, the
performance impact is not noticeable.

Pull Request: https://projects.blender.org/blender/blender/pulls/136991
2025-05-19 17:42:55 +02:00
Clément Foucault
2ce71fca18 GPU: Shader Preprocess: Add support for template inside namespaces
And also support for template definition on single line.
2025-05-16 11:01:07 +02:00
Hans Goudey
91627b3d47 GPU: Remove int float fetch mode combination
This commit finishes removing the uses of the integer to float
vertex buffer fetch mode. Previous commits noted below already started
that process. The last usage was geometry attributes. Now integers are
converted to floats as part of the existing upload process.

The change makes the Vulkan vertex buffer type conversion unused, so
it's removed. That's nice because Vulkan vertex buffers go from 1040 to
568 bytes in size and have significantly less overhead on creation.

Related:
- 153abc372e
- 1e1ac2bb9b
- 617858e453

Pull Request: https://projects.blender.org/blender/blender/pulls/138873
2025-05-15 15:29:12 +02:00
Clément Foucault
617858e453 GPU: Unified DataFormat enum
This unifies vertex and texture data formats
into a single base enum class.

`TextureFormat` and `VertexFormat` then mask
the invalid format for their respective usage.

Having a base enum allows casting between
`TextureFormat` and `VertexFormat` possible
(needed for Buffer Textures).

It also makes it easier to write and read data
to buffers/textures as each format will have an
associated host type.

These enum is generated from MACRO expansion.
This allow to centralize all information about
the formats in one place. This avoid duplicating
the list of enums for each backend.

This only creates the new enum. Porting older enums will
be done in other PRs.

Normalized integer CPU format are missing and waiting for #130640

Rel #130632

Pull Request: https://projects.blender.org/blender/blender/pulls/138069
2025-05-13 17:08:32 +02:00
Clément Foucault
83a40ceae2 GPU: Shader Preprocess: Add support for BLI C++ vector functional swizzle
This allow to share more code between C++ and the shader
code base.

Pull Request: https://projects.blender.org/blender/blender/pulls/138820
2025-05-13 16:28:55 +02:00
Clément Foucault
5055770f5b GPU: Shader: Add support for basic namespace through preprocessor
Allows basic support for using `namespace X {}` and `X::symbol`
syntax.

Benefit:
- More sharing possible with host C++ code.
- Isolation of symbols when including shader files as C++.

Requirements:
- Nesting must be done using `namespace A::B{}` rather than
  `namespace A{ namespace B {}}`, which is unsupported.
- No support for `using namespace`.
- Support of `using X` and `using X = Y` inside of function scope.
- Support of `using X` and `using X = Y` inside of namespace scope.
  However, this is only to bring symbols from the same namespace
  declared in another block (potentially inside another file).
- Only support namespace elision for symbols defined and used
  inside of the same namespace scope.

Note that this is currently limited to blender GLSL files and
not for the shared headers. This is because we need to port a lot
of code to use namespaces before allowing this.

### Follow Up:
Nesting like `namespace A{ namespace B {}}` shouldn't be hard to
support and could be added if needed.

Rel #137446

Pull Request: https://projects.blender.org/blender/blender/pulls/137445
2025-05-07 10:41:47 +02:00
Clément Foucault
c2dc45ce5e GPU: Shader: Add support for function default arguments
This avoid manual code duplication and readability issues.

This is implemented as simple copy pasting of the function
with the different argument count, calling the overload with
the next argument count for each overload.

A `#line` directive is added to each line make sure errors
still make sense and refer to the original line.

Example:
```cpp
int func(int a, int b = 0, const int2 c = int2(1, 0))
{
  /* ... */
}
```
Gets expanded to:
```cpp
int func(int a, int b, const int c)
{
  /* ... */
}
int func(int a, int b)
{
  return func(a, b, int2(1, 0));
}
int func(int a)
{
  return func(a, 0);
}
```

Rel #137446

Pull Request: https://projects.blender.org/blender/blender/pulls/138254
2025-05-06 15:25:16 +02:00
Clément Foucault
2513fbedca GPU: Shader: Add support for references
Implementation of #137341

This adds support for using references to any variable in a local scope
inside the shader codebase.

Example:
```cpp
int a = 0;
int &b = a;
b++; /* a == 1 */
```
Using `auto` is supported for reference definition as the type is not
preserved by the copy paste procedure. Type checking is done by the
C++ shader compilation or after the copy paste procedure during shader
compilation. `auto` is still unsupported for other variable declarations.

Reference to opaque types (`image`, `sampler`) are supported since
they are never really assigned to a temp variable.

This implements all safety feature related to the implementation being
copy pasting the definition string. That is:
- No `--`, `++` operators.
- No function calls.
- Array subscript index needs to be int constants or constant variable.

The copy pasting does not replace member access:
`auto &a = b; a.a = c;` becomes  `b.a = c;`
The copy pasting does not replace function calls:
`auto &a = b; a = a();` becomes  `b = a();`

While limited, this already allows for nicer syntax (aliasing) for
accessing SSBOs and the potential overhead of a copy semantic:
```cpp
ViewMatrices matrices  = drw_view_buf[0];
matrices.viewmat = float4x4(1);
drw_view_buf[0] = matrices;
```
Can now be written as;
```cpp
ViewMatrices &matrices  = drw_view_buf[0];
matrices.viewmat = float4x4(1);
```
Which expands to;
```cpp
drw_view_buf[0].viewmat = float4x4(1);
```

Note that the reference semantic is not carried through function call
because arguments are transformed to `inout` in GLSL. `inout` has
copy semantic but it is often implemented as reference by some
implementations.

Another important note is that this copy-pasting doesn't check if a
symbol is a variable. It can match a typename. But given that our
typenames have different capitalizations style this is unlikely to be
an issue. If that issue arise, we can add a check for it.

Rel #137446

Pull Request: https://projects.blender.org/blender/blender/pulls/138412
2025-05-06 13:36:59 +02:00
Clément Foucault
41ed07d55e GPU: Shader: Add support for basic template support through preprocessor
Allows basic usage of templated functions.
There is no support for templated struct.

Benefit:
- More readable than macros in shader sources.
- Compatible with C++ tools.
- More sharing possible with host C++ code.

Requirements/Limitations:
- No default arguments to template parameters.
- Must use explicit instantiation for all variant needed.
- Explicit instantiation needs to **not** use argument deduction.
- Calls to template needs to have all template argument explicit
  or all implicit.
- Template overload is not supported (redefining the same template
  with different template argument or function argument types).

Currently implemented as Macros inside the build-time pre-pocessor,
but that could change to copy-paste to allow better error reporting.
However, the Macros keep the shader code reduced in the final binary
and allow different file to declare different instantiation.

The implementation is done by declaring overloads for each explicit
instantiation.

If a template has arguments not present in function
arguments, then all arguments **values** are appended to the
function name. The explicit template callsite is then modified to use
`TEMPLATE_GLUE` which will call the correct function. This is
why template argument deduction is not supported in this case.

Rel #137446

Pull Request: https://projects.blender.org/blender/blender/pulls/137441
2025-05-06 10:41:25 +02:00
Clément Foucault
7aef8c2917 GPU: Shader Preprocess: Add utility to search for references
This utility will only match `&` character inside a
reference declaration. This is needed for speeding up the
regex matches.
2025-05-05 13:42:42 +02:00
Clément Foucault
74e6d2c575 GPU: Shader: Add support for basic loop unrolling through preprocessor
This adds basic unrolling support for 2 syntax:
- `[[gpu::unroll]]` which does full loop unrolling
- `[[gpu::unroll(x)]]` which unrolls `x` iteration

Nesting is supported.

This change is motivated by the added cost in compilation
and execution time that some loops have even if they have
compile time defined iteration counts.

The syntax is inspired by `GL_EXT_control_flow_attributes`.
However, we might want to have our own prefix to show it is
a blender specific feature and that it differs from the standard.
I propose `[[gpu::unroll]]`.

In the future, we could extend this to support more directives that
can be expanded to backend specific extension / syntax. This would
avoid readability issue an error prone copy paste of large amount
of preprocessor directives.

Currently, given that GL's GLSL flavor doesn't support
any of these attributes, the preprocessor does some copy-pasting
that does the unrolling at the source level. Note that the added
`#line` allow for correct error logging.

For the `[[gpu::unroll]]` syntax, the `for` declaration
needs to follow a specific syntax to deduce the number
of loop iteration.
This variant removes the continue condition between iteration,
so all iterations are evaluated. This could be modified
using a special keyword.

For the `[[gpu::unroll(n)]]` syntax, the usercode needs
to make sure that `n` is large enough to cover all iterations
as the loop is completely removed.
We could add shader `assert` to make sure that there is
never a remaining iteration.
This behavior is usually different from what you see in other
implementation as we do not keep a loop at all. Usually, compilers
still keep the loop if it is not unrolled fully. But given we don't
have IR, this is the best we can do.

`break` and `continue` statement are forbidden at the unrolled loop
scope level. Nested loop and switch can contain these keywords.
This is accounted for by checks in the pre-processor.

Only `for` loops are supported for now. There are no real
incentive to add support for `while` given how rare it is
in the shader codebase.

Rel #137446

Pull Request: https://projects.blender.org/blender/blender/pulls/137444
2025-05-05 13:37:51 +02:00
Clément Foucault
a14fa6bfe5 GPU: Shader Preprocess: Add string utilities
Allow faster and more robust parsing / mutation.
2025-05-05 11:03:36 +02:00
Campbell Barton
43af16a4c1 Cleanup: spelling in comments, correct comment block formatting
Also use doxygen comments more consistently.
2025-05-01 11:44:33 +10:00
Clément Foucault
ab7731d05c Fix: GPU: Tests: Memory leak with vulkan backend tests 2025-04-29 18:16:10 +02:00
Clément Foucault
8b70166214 GPU: Tests: Avoid test not passing on certain platform
These tests were using exact comparison on data that
was going through lossy conversion steps. Adding
casting or epsilon value fixes the issue.
2025-04-29 15:27:58 +02:00
Clément Foucault
ca013ae67a GPU: Tests: Move context creation to SetUpTestSuite
This avoid recreating the GPU context for each individual
tests. This reduces the overhead drastically.

Excluding static_shaders and texture_pool tests I get for GPUVulkanTest:
`Before: 129 tests from 1 test suite ran. (26304 ms total) `
`After: 129 tests from 1 test suite ran. (6965 ms total) `

Including static_shaders and texture_pool tests I get for GPUMetalTest:
`Before: 124 tests from 1 test suite ran. (54654 ms total)`
`After: 124 tests from 1 test suite ran. (1870 ms total)`

Given the tests are run twice for the workarounds versions, the
speedup can be multiplied by 2.

Overall tests time is still largely dominated by shader compilation time.
However, there is still 3x improvement using this patch:

Including static_shaders and texture_pool tests I get for GPUVulkanTest,
GPUVulkanWorkaroundTest, GPUOpenGLTest, GPUOpenGLWorkaroundTest:
`Before: 516 tests from 4 test suites ran. (318878 ms total)`
`After: 516 tests from 4 test suites ran. (106593 ms total)`

Pull Request: https://projects.blender.org/blender/blender/pulls/138097
2025-04-29 14:02:38 +02:00
Clément Foucault
d819647538 GPU: Tests: Use GHOST_CreateSystemBackground
This will eventually allow to run tests on the buildbot.
2025-04-28 19:04:51 +02:00
Clément Foucault
d415d8ef09 GPU: Tests: Add missing context cleanup calls
These missing calls would modify the global context.
This is a problem when trying to batch tests
together.
2025-04-28 15:43:25 +02:00
Clément Foucault
98adf4db14 Cleanup: GPU: Tests: Avoid testing more than one value
Also avoid undefined values in vertex buffer.
2025-04-28 15:43:25 +02:00
Clément Foucault
58e1f05160 Fix: GPU: Broken blend mode tests
This is caused by 28ad3736e8
The new primitive was drawing 2 faces, doing the
blending twice. Reverting back to a quad fixes it.
2025-04-28 14:01:41 +02:00
Clément Foucault
59df50c326 GPU: Refactor Qualifier and ImageType
This allow to use types closer to GLSL in resource
declaration.

These are aliased for clarity in the GPU
module (i.e. `isampler2D` is shortened to `Int2D`).

Rel #137446

Pull Request: https://projects.blender.org/blender/blender/pulls/137954
2025-04-24 14:38:13 +02:00
Brecht Van Lommel
fb2ba20b67 Refactor: Use more typed MEM_calloc<> and MEM_malloc<>
Pull Request: https://projects.blender.org/blender/blender/pulls/137822
2025-04-22 11:22:18 +02:00
Brecht Van Lommel
637c6497e9 Refactor: Use more typed MEM_calloc<>, avoid unnecessary size_t cast
Handle some cases that were missed in previous refactor. And eliminate
unnecessary size_t casts as these could hide issues.

Pull Request: https://projects.blender.org/blender/blender/pulls/137404
2025-04-21 17:59:41 +02:00
Clément Foucault
47d2dffe8c GPU: Shader CodeBase use constexpr instead of const
Do this only when applicable.

This allow better compile time checking in Shader C++ compilation.
Moreover, this allows to have `constexpr` in shared code between
C++ and GLSL.

After investigation the `const` keyword in GLSL has the same
semantic than C/C++.

Rel #137333 and #137446

Pull Request: https://projects.blender.org/blender/blender/pulls/137497
2025-04-15 11:36:53 +02:00
Clément Foucault
3b3a5731df GPU: Shader: Change vector and matrix type to use blender convention
This unify the C++ and GLSL codebase style.

The GLSL types are still in the backend compatibility
layers to support python shaders. However, the C++
shader compilation layer doesn't have them to enforce
correct type usage.

Note that this is going to break pretty much all PRs
in flight that targets shader code.

Rel #137261

Pull Request: https://projects.blender.org/blender/blender/pulls/137369
2025-04-14 13:46:41 +02:00
Miguel Pozo
7f724115f7 Fix: Tests: Init thread API for GPUTests
Required by GPUSecondaryContext.
2025-04-14 12:37:49 +02:00
Clément Foucault
9990273d04 GPU: Change Type enum to use lower case values
This is to help for future resource declaration
using macros.

Rel #137261

Pull Request: https://projects.blender.org/blender/blender/pulls/137367
2025-04-11 22:39:01 +02:00
Clément Foucault
bb52754652 GPU: Use f suffix for float literals
They are actually already some literals with the `f` suffix
that are in our shader codebase and we never had problem in
the past 5 years (or even 8 years).

So I think it is safe to do and improves convergence of codestyles.

Pull Request: https://projects.blender.org/blender/blender/pulls/137352
2025-04-11 18:28:45 +02:00
Clément Foucault
f8de6c31bc EEVEE: Move Object ID storage to gbuffer header layer
This allow to store the full object ID inside a `uint32`
buffer. This allows to get the per object data in deferred
passes and avoid to store object data inside the Gbuffer.

This data is only written if needed.

This had to modify the implementation of subpass input
for all backend to be able to bind layered texture.
This currently work because only the layer 0 is bound to the
framebuffer. This is fragile but I don't see a good builtin way
to fix it.

Rel #135935

#### Tasks
- [x] Replace light linking bits in Gbuffer
- [x] Replace Object ID in GBuffer for SSS
- [x] Conditional storage
- [x] Dummy storage if not needed

Pull Request: https://projects.blender.org/blender/blender/pulls/136428
2025-04-03 14:00:55 +02:00
Clément Foucault
30ccd6b179 GPU: Fix compilation of tests
Caused by missing include.
2025-02-25 18:12:05 +01:00
Hans Goudey
d0a6189b50 Refactor: DRW: Centralize and clean up packed normals conversion
Move the code dealing with converting float3 to GPU normals
out of the vertex format header into a separate header. Use a
proper C++ namespace and remove duplication by only using
the more recently added C++ templated conversions.

Most of the diff comes from the removal of the indirect includes
from GPU_vertex_format.hh. A lot of files ended up mistakenly
depending on that.

Pull Request: https://projects.blender.org/blender/blender/pulls/134873
2025-02-24 16:08:30 +01:00
Clément Foucault
28ad3736e8 DRW: Move cube batch generation to GPU module
Avoid access on global DRWShapeCache and still
share the code for batch creation.
Each module is then responsible owner of their
own batch.
2025-02-17 12:36:34 +01:00
Clément Foucault
6138ee64a9 GPU: TexturePool: Add texture pool functionality to the GPU module
This patch adds the texture pool functionality that was previously
only available in the DRW module to the GPU module.

This allows to not rely on global `DST` variable for the managment
of these temporary textures.

Moreover, this can be extended using dedicated GPU backend
specific behavior to reduce the amount of memory needed
to render.

The implementation is mostly copy pasted from the draw implementation
but with more documentation. Also it is simplified since the
`DRW_texture_pool_query` functionality is not needed.

Pull Request: https://projects.blender.org/blender/blender/pulls/134403
2025-02-11 18:58:46 +01:00
Clément Foucault
954b800c3f GPU: Add test for byte pattern clearing of storage buffers 2025-02-07 12:23:50 +01:00
Brecht Van Lommel
c7502b092d Cleanup: Various clang-tidy warnings in gpu
Pull Request: https://projects.blender.org/blender/blender/pulls/133734
2025-01-31 17:03:18 +01:00
Jeroen Bakker
16a739dc8a GPU: Add unpack row length tests
This PR adds 2 test cases to test uploading sub texture with and
without unpack row length.

Ref #130977

Pull Request: https://projects.blender.org/blender/blender/pulls/131791
2024-12-12 12:58:16 +01:00
Jeroen Bakker
567595e850 Fix: GPU: OpenGL texture tests
Some texture roundtrip tests are not supported on OpenGL. This PR will
skip these tests.

Pull Request: https://projects.blender.org/blender/blender/pulls/131792
2024-12-12 12:57:41 +01:00
Campbell Barton
b9f055459a Cleanup: ensure trailing space around comment blocks 2024-11-27 19:01:00 +11:00
Jeroen Bakker
e440828221 Fix #130588: Vulkan: Depth stencil readback
Functionality like snapping cursor requires readback of depth stencil
textures. This was not supported yet. This PR will add readback of depth
stencil textures to float.

Fixes: #128624, #130588

Pull Request: https://projects.blender.org/blender/blender/pulls/130717
2024-11-22 09:45:38 +01:00
Clément Foucault
e9252f206b GPU: Comment out test not compatible with metal backend
These test are either not compatible because of the
spec or are just broken in the current state of the backend.

These should be dealt with soon.
2024-11-10 15:16:34 +01:00
Clément Foucault
8260e3aa81 GPU: Simplify framebuffer tests 2024-11-10 15:16:34 +01:00
Clément Foucault
9b91a42240 GPU: Improve fetch mode tests to cover GPU_FETCH_INT_TO_FLOAT_UNIT 2024-11-09 21:50:37 +01:00
Clément Foucault
2738e33a58 GPU: Silence invalid fetch mode tests on Metal
These vertex buffer setup are invalid on metal.
For now simply disable them on Apple hardware.
2024-11-09 21:50:37 +01:00
Clément Foucault
ef8ea88f5f Fix: GPU: Tests not passing on Metal with ASAN on
Fixes a few stack overflow error, reduce framebuffer size
to avoid errors flooding the output.
2024-11-09 21:50:37 +01:00
Jeroen Bakker
a4529f0e17 Merge branch 'blender-v4.3-release' 2024-11-07 14:01:32 +01:00
Jacques Lucke
3688a2919b Merge branch 'blender-v4.3-release' 2024-11-07 14:00:52 +01:00
Jeroen Bakker
da767bcbdc Fix: Vulkan: Enable interleaved tests
Interleaved tests where disabled for Vulkan, but interleaving has been
implemented. This PR enabled these tests.

Pull Request: https://projects.blender.org/blender/blender/pulls/129957
2024-11-07 14:00:51 +01:00
Jeroen Bakker
e0f699abdb Fix: Vulkan: Read & write outside of bounds
When running test cases
`test_texture_roundtrip__GPU_DATA_10_11_11_REV__GPU_R11F_G11F_B10F`
would read and write outside of allocated memory. This is an error in
the test case itself the GPU API doesn't have a public function to get
the desired byte and component size.

Pull Request: https://projects.blender.org/blender/blender/pulls/129958
2024-11-07 13:59:53 +01:00
Clément Foucault
9c0321ae9b Metal: Simplify MSL translation
Move most of the string preprocessing used for MSL
compatibility to `glsl_preprocess`.

Enforce some changes like matrix constructor and
array constructor to the GLSL codebase. This is
for C++ compatibility.

Additionally reduce the amount of code duplication
inside the compatibility code.

Pull Request: https://projects.blender.org/blender/blender/pulls/128634
2024-10-07 12:54:10 +02:00