Commit Graph

76 Commits

Author SHA1 Message Date
Clément Foucault
fe213f80a4 GPU: Shader: Make info files generated
This is the first step of moving the create infos
back inside shader sources.

All info files are now treated as source files.
However, they are not considered in the include tree
yet. This will come in another following PR.

Each shader source file now generate a `.info` file
containing only the create info declarations.

This renames all info files so that they do not
conflict with their previous versions that were
copied (non-generated).

Pull Request: https://projects.blender.org/blender/blender/pulls/146676
2025-09-25 10:57:02 +02:00
Clément Foucault
9b7086a422 GPU: Shader Preprocess: Port more function to use parser
This allows to share the parsed structure between each
preprocessing step if no mutation occurs.

Also remove `matrix_constructor_linting` as this is
now enforced by the C++ compilation. Same thing for
`array_constructor_linting`.

Pull Request: https://projects.blender.org/blender/blender/pulls/146666
2025-09-24 11:47:23 +02:00
Clément Foucault
50283b9573 GPU: Split GLSL, C++ and metal shader defines
This makes all the defines and boiler plate code use
the generated source include system.

This makes source hierarchy more understandable.

Pull Request: https://projects.blender.org/blender/blender/pulls/146289
2025-09-15 17:22:19 +02:00
Clément Foucault
680fec144c Cleanup: GPU: Remove prefix 'e' from enum types
_No response_

Pull Request: https://projects.blender.org/blender/blender/pulls/146034
2025-09-15 15:11:02 +02:00
Clément Foucault
1f94af6aa4 GPU: Shader: Add support for loop unroll using macros
It is usually nice to unroll loops with a different number of
iteration based on a macro. This commit adds this functionality
to our shader preprocessor so that we don't have to manually unroll
these loops.

Pull Request: https://projects.blender.org/blender/blender/pulls/146043
2025-09-11 12:42:11 +02:00
Clément Foucault
6148d50105 GPU: Shader: Remove section of code guarded by #if directives
These lines can be removed to avoid parsing them.
This allow to keep the same processing for shared host files.

Also removes a few lines of code to reduce the size of
shader sources.

This also contains a rewrite of the include parsing using
the shader parser.

Pull Request: https://projects.blender.org/blender/blender/pulls/146025
2025-09-10 16:35:41 +02:00
Clément Foucault
c302b7de7b Refactor: EEVEE: Simplify Gbuffer packing
Implementation of #145417

For more information see pull request.

Pull Request: https://projects.blender.org/blender/blender/pulls/145520
2025-09-10 12:17:21 +02:00
Clément Foucault
805e037df3 GPU: Shader: Use parser for loop unrolling
This refactor the loop unrolling mechanism and
replaces the use of regex by the new parser.

Pull Request: https://projects.blender.org/blender/blender/pulls/145956
2025-09-10 11:59:52 +02:00
Clément Foucault
62f5965dee Fix: GPU: Compilation failure on windows 2025-09-01 12:38:13 +02:00
Clément Foucault
e7bcec779d GPU: Shader: Use parser for namespace_mutation
Pull Request: https://projects.blender.org/blender/blender/pulls/145496
2025-09-01 11:56:03 +02:00
Clément Foucault
d47ad68b0c GPU: Shader: Use parser for using_mutation 2025-09-01 11:56:02 +02:00
Clément Foucault
278438e504 GPU: Shader: Use parser for assert processing 2025-09-01 11:56:02 +02:00
Clément Foucault
ebf095a4b9 GPU: Shader: Add string parsing and merging
This avoid issues when trying to use printf with
multiline string literals.
2025-09-01 11:56:02 +02:00
Clément Foucault
72e5d5066a GPU: Shader: Fix template in template support
Processing needed to be adapted to support this
use case.
2025-09-01 11:56:02 +02:00
Clément Foucault
ba4589e894 DRW: New Curve Drawing
Implementation of the design task #142969.

This adds the following:
- Exact GPU interpolation of curves of all types.
- Radius attribute support.
- Cyclic curve support.
- Resolution attribute support.
- New Cylinder hair shape type.
![image.png](/attachments/a8e7aea0-b0e5-4694-b660-89fb3df1ddcd)

What changed:
- EEVEE doesn't compute random normals for strand hairs anymore. These are considered legacy now.
- EEVEE now have an internal shadow bias to avoid self shadowing on hair.
- Workbench Curves Strip display option is no longer flat and has better shading.
- Legacy Hair particle system evaluates radius at control points before applying additional subdivision. This now matches Cycles.
- Color Attribute Node without a name do not fetch the active color attribute anymore. This now matches Cycles.

Notes:
- This is not 100% matching the CPU implementation for interpolation (see the epsilons in the tests).
- Legacy Hair Particle points is now stored in local space after interpolation.

The new cylinder shape allows for more correct hair shading in workbench and better intersection in EEVEE.

|      | Strand | Strip | Cylinder |
| ---- | --- | --- | --- |
| Main | ![main_strand.png](/attachments/67d3b792-962c-4272-a92c-1c0c7c6cf8de) | ![main_strip.png](/attachments/f2aa3575-368e-4fbb-b888-74df845918f1) | N/A |
| PR   | ![pr_strand.png](/attachments/cc012483-25f0-491f-a06e-ad3029981d47) | ![pr_strip.png](/attachments/73fa2f5c-5252-4b30-a334-e935ed0fb938) | ![pr_cylinder.png](/attachments/3133b2d4-a6f2-41ee-8e2d-f6fd00db0c8d) |

|      | Strand | Strip | Cylinder |
| ---- | --- | --- | --- |
| Main | ![main_strand_closeup.png](/attachments/730bd79c-6762-446d-819b-3ea47961ff9f) |![main_strip_closeup.png](/attachments/d9ace578-cfeb-4895-9896-3625b6ad7a02) | N/A |
| PR   | ![pr_strand_closeup.png](/attachments/ac8f3b0c-6ef6-4d54-b714-6322f9865036)|![pr_strip_closeup.png](/attachments/8504711a-955b-4ab2-aa3d-c2d114baf9d4)| ![pr_cylinder_closeup.png](/attachments/1e2899a8-0a5c-431f-ac6c-5184d87e9598) |

Cyclic Curve, Mixed curve type, and proper radius support:
![image.png](/attachments/7f0bf05e-62ee-4ae9-aef9-a5599249b8d7)

Test file for attribute lookup: [test_attribute_lookup.blend](/attachments/1d54dd06-379b-4480-a1c5-96adc1953f77)

Follow Up Tasks:
- Correct full tube segments orientation based on tangent and normal attributes
- Correct V resolution property per object
- More attribute type support (currently only color)

TODO:
- [x] Attribute Loading Changes
  - [x] Generic Attributes
  - [x] Length Attribute
  - [x] Intercept Attribute
  - [x] Original Coordinate Attribute
- [x] Cyclic Curves
- [x] Legacy Hair Particle conversion
  - [x] Attribute Loading
  - [x] Additional Subdivision
- [x] Move some function to generic headers (VertBuf, OffsetIndices)
- [x] Fix default UV/Color attribute assignment

Pull Request: https://projects.blender.org/blender/blender/pulls/143180
2025-08-27 09:49:43 +02:00
Clément Foucault
06ddc55846 Cleanup: GPU: Fix french spelling of Dictionary
...baguette?
2025-08-26 15:38:33 +02:00
Clément Foucault
1f2c906e2a GPU: Shader: Always mute line directives for GLSL
This is motivated by the latest changes to the preprocessor
which outputs a lot of line directives when code is
generated or unrolled.

In this case the reported line would be correct but not
correctly displayed.

Moreover the system of outputing hashes inside the
`#line` directive proved to be incompatible with some
compilers and tools (renderdoc).

This commit always comments the line directives before
compilation (solves the compatibility issue).
When error logging, we then scan the commented
directives to output the correct filename and source
line. The log line is kept untouched and will show
the correct final generated code that triggered the
error.

This also fixed the error line parsing for vulkan.

Pull Request: https://projects.blender.org/blender/blender/pulls/145096
2025-08-26 12:46:46 +02:00
Clément Foucault
505e4fc3ae GPU: Shader: Add support for templated struct
This does a few things:
- Add support for templated struct.
- Change parsing of template scope.
  Now all template scope `<..>` are parsed properly.
- Rework to support better match syntax.
- Avoid warning from scope guard processing. Now initialize
  the return value to zero.

Pull Request: https://projects.blender.org/blender/blender/pulls/145132
2025-08-26 10:10:43 +02:00
Campbell Barton
85d5ade00f Cleanup: spelling in comments (make check_spelling_*) 2025-08-24 06:26:08 +00:00
Clément Foucault
e05089362c GPU: Shader: Add support for enum class
In the process, refactor the enum processing
using the new parser.

Pull Request: https://projects.blender.org/blender/blender/pulls/144704
2025-08-18 13:50:49 +02:00
Clément Foucault
dce0fa115f GPU: Shader: Preprocess: Improve error reporting
This makes the new parser code output correct errors.

Also simplify error logging.

Simplify a few things inside the parser interface.
Add debug string to the `Token` and `Scope`.

Pull Request: https://projects.blender.org/blender/blender/pulls/144708
2025-08-18 12:02:26 +02:00
Clément Foucault
3c3f21ec00 GPU: Shader: Replace template macro implementation by copy paste
Use the lately introduced parser for that.

This allows to use preprocessor directive inside them.
By extension, it alows having resource accessors inside
templates.
Also error report is less confusing on most shader compilers.

The counterpart is that the shader files that are shipped
with blender are inflated.

Pull Request: https://projects.blender.org/blender/blender/pulls/144588
2025-08-15 15:13:54 +02:00
Clément Foucault
831969f4f0 GPU: Shader: Rewrite default_argument_mutation using parser
This avoid failure cases from the regex.

Pull Request: https://projects.blender.org/blender/blender/pulls/144386
2025-08-12 10:10:12 +02:00
Clément Foucault
bbd2dcb02d GPU: Shader: Add support for full template specialization
As the title says.
The existing implementation did not support this.

Note that this doesn't support partial specialization.

See #137441 for the original implementation.

This is needed for #143582.

Pull Request: https://projects.blender.org/blender/blender/pulls/144212
2025-08-11 14:26:58 +02:00
Clément Foucault
02503cd41a GPU: Shader Preprocess: Add support for guarded scope using return value
This removes one limitation of the guarded scopes that needed to
not have return statement. Now a dummy return statement is created.

See #139233 for original implementation.
2025-08-08 16:55:02 +02:00
Clément Foucault
628a10a9fb GPU: Shader Preprocess: Add basic support for struct methods
This adds the following features:
- `class` keyword support: checked by C++, mutated to struct for shader.
- `private` and `public` keywords: checked by C++, removed for shader.
- `static` methods.
- `const` and non-const methods.

What is not supported:
- Constructors
- Destructors
- operators
- Method definition outside of class definition
- member reference without `this` keyword.

This is implemented using a very simple lexer/parser allowing semantic traversal.

Pull Request: https://projects.blender.org/blender/blender/pulls/144025
2025-08-08 16:49:15 +02:00
Campbell Barton
cccc2c77c5 Cleanup: consistent for C-style comment blocks 2025-08-08 07:37:33 +10:00
Campbell Barton
5e3db5fbb0 Cleanup: consistent use of back-ticks in code-comments 2025-07-23 20:59:16 +10:00
Campbell Barton
ec8751f826 Cleanup: white-space around C-style comment blocks
Also use C++ style comments for disabling code.
2025-07-13 21:58:53 +10:00
Clément Foucault
a5dc8026ee GPU: Shader: Add runtime dependency resolution
This allows to generate source file that will
be injected in a predefined source dependance tree.

This allow much cleaner shader workflow where
all sources are explicitly referenced from the
main source file.

Pull Request: https://projects.blender.org/blender/blender/pulls/140047
2025-06-10 17:22:58 +02:00
Clément Foucault
368a64f386 GPU: Shader: Add support for shader entry points
This works by wrapping the entry point call inside a
`main` function.

Since resources are still defined in global space,
function accessing these are marked with a custom
attribute. This custom attribute expands in a
`#ifdef` guard for the matching stage.
This is a temporary solution and will eventually
be lifted once we support SRD.

### TODO
- [ ] Implement `[[gpu::vertex/fragment_function]]`.

Pull Request: https://projects.blender.org/blender/blender/pulls/139233
2025-06-10 12:37:20 +02:00
Campbell Barton
50f3240abd Cleanup: spelling & duplicate terms (check_spelling.py) 2025-05-30 11:03:56 +10:00
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
c7c3ed9fbf GPU: Shader Preprocess: Assert pragma once in lib
This avoid forgetting to add `pragma once` inside
shader library files and have different include
behavior between C++ and shader code.
2025-05-19 09:20:31 +02:00
Clément Foucault
e1ac6a75d5 GPU: Shader Preprocess: Escape more character in regex strings
This is trying to fix a reported issue on some compilern with
regex not matching the template definitions
2025-05-19 00:07:40 +02:00
Clément Foucault
84298a8fd8 GPU: Shader Preprocess: Add error check for conditional include
These are not supported, so make it an error to use them.
2025-05-19 00:02:28 +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
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
Campbell Barton
5e75a9c1e8 Cleanup: spelling in comments 2025-05-11 17:00:47 +10: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
9bef8741a9 Fix: GPU: Shader Preprocess: Undefined behavior in variable_reference_mutation
This is because the `match` can be referenced by the
`report_error` callback. If the string is reallocated,
the callback could read freed memory.
2025-05-06 15:02:45 +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
Campbell Barton
fd6ac498b0 Cleanup: spelling in comments, strings (make check_spelling_*)
Also replace some triple-quoted non-doc-string strings with commented
blocks in examples.
2025-05-06 00:18:39 +00:00
Clément Foucault
f844ed7869 GPU: Shader Preprocess: Processing time optimizations
Guarding expensive regex computation by much
cheaper checks to reduce compilation time.

Compiling `time ninja -j 1 bf_draw_shaders`

On MacOS M1 Max (debug build with glsl_preprocess optimization turned on):
Before 13.01 sec
After  9.08 sec

Pull Request: https://projects.blender.org/blender/blender/pulls/138336
2025-05-05 15:14:16 +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
Clément Foucault
d24b0e4a4e GPU: Remove runtime parsing of GLSL source
See #129009 for context.

The preprocessor parses metadata and writes a header file containing
an inline function that inits the `GPUSource` with the metadata.

These header files are then included inside `gpu_shader_dependency.cc`.

This still keep the usage of the `metadata` enums and classes to avoid
pulling the whole blender module inside the preprocessor executable.

This speeds-up startup time in Debug build:
`gpu_shader_dependency_init`
- Before : 37ms
- After : 4ms

I didn't measure release, but it is unlikely to be noticeable (in the
order of 4ms > 1ms).

Pull Request: https://projects.blender.org/blender/blender/pulls/138070
2025-04-29 15:32:36 +02:00