Commit Graph

245 Commits

Author SHA1 Message Date
c37e07bc01 Geometry Nodes: improve dot graph export of lazy function graph
* Dim default input values.
* Print default input values instead of type name.
* Add node/socket names to group input/output nodes.
2022-12-16 12:18:49 +01:00
2155bdd500 Cleanup: Remove "done" variable from node runtime
The runtime storage is meant for more persistent things. These local
states for an algorithm are much better handled by an array now.
2022-12-02 14:14:14 -06:00
584089879c BLI: Follow up and fix recent span slicing change
a5e7657cee didn't account for slices of zero sizes, and the asserts
were slightly incorrect otherwise. Also, the change didn't apply to
`Span`, only `MutableSpan`, which was a mistake. This also adds "safe"
methods to `IndexMask`, and switches function calls where necessary.
2022-11-23 11:36:06 -06:00
14d0b57be7 Cleanup: Use array_utils to copy evaluated field array 2022-11-22 12:49:51 -06:00
0ebb7ab41f Geometry Nodes: disable unreachable nodes in evaluator
Nodes that were not connected to any output could still impact performance.
While they were never executed, sometimes their inputs could keep references
to geometries that other nodes want to modify. That caused unnecessary geometry
copies, because a geometry can only be modified if it is not shared.

Now, inputs that will never be used are tagged accordingly and they will never
have references to geometries that others might want to modify.
2022-11-16 14:26:11 +01:00
edcce2c073 Cleanup: correct inverted variable name 2022-11-16 13:19:23 +01:00
a6c822733a BLI: improve CPPType system
* Support bidirectional type lookups. E.g. finding the base type of a
  field was supported, but not the other way around. This also removes
  the todo in `get_vector_type`. To achieve this, types have to be
  registered up-front.
* Separate `CPPType` from other "type traits". For example, previously
  `ValueOrFieldCPPType` adds additional behavior on top of `CPPType`.
  Previously, it was a subclass, now it just contains a reference to the
  `CPPType` it corresponds to. This follows the composition-over-inheritance
  idea. This makes it easier to have self-contained "type traits" without
  having to put everything into `CPPType`.

Differential Revision: https://developer.blender.org/D16479
2022-11-12 18:33:31 +01:00
97746129d5 Cleanup: replace UNUSED macro with commented args in C++ code
This is the conventional way of dealing with unused arguments in C++,
since it works on all compilers.

Regex find and replace: `UNUSED\((\w+)\)` -> `/*$1*/`
2022-10-03 17:38:16 -05:00
333e41eac6 Cleanup: replace C-style casts with functional casts for numeric types
Use function style casts in C++ headers & source.
2022-09-26 17:58:36 +10:00
c6e70e7bac Cleanup: follow C++ type cast style guide in some files
https://wiki.blender.org/wiki/Style_Guide/C_Cpp#C.2B.2B_Type_Cast

This was discussed in https://devtalk.blender.org/t/rfc-style-guide-for-type-casts-in-c-code/25907.
2022-09-25 17:39:45 +02:00
f68cfd6bb0 Cleanup: replace C-style casts with functional casts for numeric types 2022-09-25 20:17:08 +10:00
5517c848bd Cleanup: spelling in comments 2022-09-21 12:00:01 +10:00
5c81d3bd46 Geometry Nodes: improve evaluator with lazy threading
In large node setup the threading overhead was sometimes very significant.
That's especially true when most nodes do very little work.

This commit improves the scheduling by not using multi-threading in many
cases unless it's likely that it will be worth it. For more details see the comments
in `BLI_lazy_threading.hh`.

Differential Revision: https://developer.blender.org/D15976
2022-09-20 11:08:05 +02:00
c8a18fd239 Cleanup: add hint that typedef is used as compiler bug workaround
https://developercommunity.visualstudio.com/t/Alias-template-inside-fold-expression-fa/10040507
2022-09-20 10:42:25 +02:00
95f05a6a4b Cleanup: spelling in comments 2022-09-16 18:14:33 +10:00
5c4295ee6f Workaround for msvc compiler bug
This is the same issue as in rB2e8089b6bf50.
2022-09-15 09:34:20 +02:00
2c53970bbf Cleanup: use doxy sections, remove outdated comment 2022-09-15 15:27:21 +10:00
f78219c9a8 Cleanup: spelling in comments 2022-09-13 18:03:09 +10:00
4130f1e674 Geometry Nodes: new evaluation system
This refactors the geometry nodes evaluation system. No changes for the
user are expected. At a high level the goals are:
* Support using geometry nodes outside of the geometry nodes modifier.
* Support using the evaluator infrastructure for other purposes like field evaluation.
* Support more nodes, especially when many of them are disabled behind switch nodes.
* Support doing preprocessing on node groups.

For more details see T98492.

There are fairly detailed comments in the code, but here is a high level overview
for how it works now:
* There is a new "lazy-function" system. It is similar in spirit to the multi-function
  system but with different goals. Instead of optimizing throughput for highly
  parallelizable work, this system is designed to compute only the data that is actually
  necessary. What data is necessary can be determined dynamically during evaluation.
  Many lazy-functions can be composed in a graph to form a new lazy-function, which can
  again be used in a graph etc.
* Each geometry node group is converted into a lazy-function graph prior to evaluation.
  To evaluate geometry nodes, one then just has to evaluate that graph. Node groups are
  no longer inlined into their parents.

Next steps for the evaluation system is to reduce the use of threads in some situations
to avoid overhead. Many small node groups don't benefit from multi-threading at all.
This is much easier to do now because not everything has to be inlined in one huge
node tree anymore.

Differential Revision: https://developer.blender.org/D15914
2022-09-13 08:44:32 +02:00
6bcda04d1f Geometry Nodes: Port sample curves node to new data-block
Use the newer more generic sampling and interpolation functions
developed recently (ab444a80a2) instead of the `CurveEval` type.
Functions are split up a bit more internally, to allow a separate mode
for supplying the curve index directly in the future (T92474).

In one basic test, the performance seems mostly unchanged from 3.1.

Differential Revision: https://developer.blender.org/D14621
2022-07-22 09:59:28 -05:00
ef8bb8c0d5 Functions: improve span buffer reuse in procedure execution
This potentially overallocates buffers so that they are usable
for more data types, which allows buffers to be reused more
easily. That leads to fewer separate allocations and improved
cache usage (in one of my test files the number of separate
allocations went down from 1826 to 1555).
2022-06-25 19:41:44 +02:00
b513c89e84 Functions: avoid using Map for small values
This leads to a 5-10% performance improvement in my benchmark
that runs a procedure many times on a single element.
2022-06-25 18:53:26 +02:00
3e5a4d1412 Geometry Nodes: Optimize selection for virtual array input
This makes calculation of selected indices slightly faster when the
input is a virtual array (the direct output of various nodes like
Face Area, etc). The utility can be helpful for other areas that
need to find selected indices besides field evaluation.

With the face area node used as a selection with 4 million faces,
the speedup is 3.51 ms to 3.39 ms, just a slight speedup.

Differential Revision: https://developer.blender.org/D15127
2022-06-23 11:51:33 -05:00
d48735cca2 Functions: speedup multi-function procedure executor
This improves performance of the procedure executor on secondary metrics
(i.e. not for the main use case when many elements are processed together,
but for the use case when a single element is processed at a time).

In my benchmark I'm measuring a 50-60% improvement:
* Procedure with a single function (executed many times): `5.8s -> 2.7s`.
* Procedure with 1000 functions (executed many times): `2.4 -> 1.0s`.

The speedup is mainly achieved in multiple ways:
* Store an `Array` of variable states, instead of a map. The array is indexed
  with indices stored in each variable. This also avoids separately allocating
  variable states.
* Move less data around in the scheduler and use a `Stack` instead of `Map`.
  `Map` was used before because it allows for some optimizations that might
  be more important in the future, but they don't matter right now (e.g. joining
  execution paths that diverged earlier).
* Avoid memory allocations by giving the `LinearAllocator` some memory
  from the stack.
2022-06-19 14:25:56 +02:00
c4e11122c5 Geometry Nodes: Use fields for delete geometry inversion
The separate geometry and delete geometry nodes often invert the
selection so that deleting elements from a geometry can be implemented
as copying the opposite selection of elements. This should make the two
nodes faster in some cases, since the generic versions of selection
creation functions (i.e. from d3a1e9cbb9) are used instead
of the single threaded code that was used for this node.

The change also makes the deletion/separation code easier to
understand because it doesn't have to pass around the inversion.
2022-06-05 16:46:20 +02:00
5c80bcf8c2 Functions: speedup preparing multi-function parameters
My benchmark which spend most time preparing function parameters
takes `250 ms` now, from `510 ms` before. This is mainly achieved by
doing less unnecessary work and by giving the compiler more inlined
code to optimize.

* Reserve correct vector sizes and use unchecked `append` function.
* Construct `GVArray` parameters directly in the vector, instead of
  moving/copying them in the vector afterwards.
* Inline some constructors, because that allows the compiler understand
  what is happening, resulting in less code.

This probably has negilible impact on the user experience currently,
because there are other bottlenecks.

Differential Revision: https://developer.blender.org/D15009
2022-05-31 20:41:01 +02:00
427a2c920a Cleanup: spelling in comments, capitalize tags
Also add missing task-ID reference & remove colon after \note as it
doesn't render properly in doxygen.
2022-05-13 09:29:25 +10:00
2e8089b6bf Workaround for msvc compiler bug
https://developercommunity.visualstudio.com/t/Alias-template-inside-fold-expression-fa/10040507
2022-05-12 13:38:22 +02:00
dea5d22da1 Cleanup: remove warnings due to maybe-used variables
The variable was only used in some constexpr if-statements.
2022-05-12 13:03:12 +02:00
198a763944 Cleanup: spelling in comments
Also use back-slashes for doxy commands.
2022-04-28 14:03:49 +10:00
ae94e36cfb Geometry Nodes: refactor array devirtualization
Goals:
* Better high level control over where devirtualization occurs. There is always
  a trade-off between performance and compile-time/binary-size.
* Simplify using array devirtualization.
* Better performance for cases where devirtualization wasn't used before.

Many geometry nodes accept fields as inputs. Internally, that means that the
execution functions have to accept so called "virtual arrays" as inputs. Those
 can be e.g. actual arrays, just single values, or lazily computed arrays.
Due to these different possible virtual arrays implementations, access to
individual elements is slower than it would be if everything was just a normal
array (access does through a virtual function call). For more complex execution
functions, this overhead does not matter, but for small functions (like a simple
addition) it very much does. The virtual function call also prevents the compiler
from doing some optimizations (e.g. loop unrolling and inserting simd instructions).

The solution is to "devirtualize" the virtual arrays for small functions where the
overhead is measurable. Essentially, the function is generated many times with
different array types as input. Then there is a run-time dispatch that calls the
best implementation. We have been doing devirtualization in e.g. math nodes
for a long time already. This patch just generalizes the concept and makes it
easier to control. It also makes it easier to investigate the different trade-offs
when it comes to devirtualization.

Nodes that we've optimized using devirtualization before didn't get a speedup.
However, a couple of nodes are using devirtualization now, that didn't before.
Those got a 2-4x speedup in common cases.
* Map Range
* Random Value
* Switch
* Combine XYZ

Differential Revision: https://developer.blender.org/D14628
2022-04-26 17:12:34 +02:00
b9799dfb8a Geometry Nodes: better support for byte color attributes
Since {rBeae36be372a6b16ee3e76eff0485a47da4f3c230} the distinction
between float and byte colors is more explicit in the ui. So far, geometry
nodes couldn't really deal with byte colors in general. This patch fixes that.
There is still only one color socket, which contains float colors. Conversion
to and from byte colors is done when read from or writing to attributes.

* Support writing to byte color attributes in Store Named Attribute node.
* Support converting to/from byte color in attribute conversion operator.
* Support propagating byte color attributes.
* Add all the implicit conversions from byte colors to the other types.
* Display byte colors as integers in spreadsheet.

Differential Revision: https://developer.blender.org/D14705
2022-04-21 16:11:26 +02:00
c196ca3740 Functions: fix procedure executor not writing output in correct buffer
The issue was that the executor would forget about the caller provided
storage if the variable is destructed.
2022-04-21 15:29:18 +02:00
d1944dee86 Cleanup: remove unused multi-function 2022-04-12 11:59:23 +02:00
5e47056e8d Cleanup: malformed C-style comment blocks, spelling
- Missing star prefix.
- Unnecessary indentation.
- Blank line after dot-points
  (otherwise doxygen merges with the previous dot-point).
- Use back-slash for doxygen commands.
- Correct spelling.
2022-04-11 12:03:09 +10:00
67c42e7f03 Functions: optimize simple generated multi-functions
This implements two optimizations:
* Reduce virtual function call overhead when a non-standard virtual
  array is used as input.
* Use a lambda in `type_conversion.cc`.

In my test setup, which creates a float attribute filled with the index,
the running time drops from `4.0 ms` to `2.0 ms`.

Differential Revision: https://developer.blender.org/D14585
2022-04-07 18:48:29 +02:00
e5c7f37223 Cleanup: make CustomMF_* implementations more similar 2022-04-07 11:51:47 +02:00
2aff04917f Functions: parallelize materializing arrays after field evaluation
This improves performance e.g. when creating an integer attribute
based on an index field. For 4 million vertices, I measured a speedup
from 3.5 ms to 1.2 ms.
2022-04-07 09:48:07 +02:00
ee3f71d747 Functions: allow for better compiler optimization
This extracts the inner loops into a separate function.
There are two main reasons for this:
* Allows using `__restrict` to indicate that no other parameter
  aliases with the output array. This allows for better optimization.
* Makes it easier to search for the generated assembly code,
  especially with the `BLI_NOINLINE`.
2022-04-04 11:57:58 +02:00
3c6c15d676 Functions: move loops into function builders
This simplifies debugging, and can help improve performance
by making it easier for the compiler.

More optimization might still be possible by using `__restrict` in
a few places.
2022-03-29 10:11:49 +02:00
7bd614d431 Cleanup: use value initialization instead of copying default value
Value-initialization has the potential to be more efficient.
Also, the code becomes simpler.
2022-03-29 09:29:09 +02:00
d3a1e9cbb9 Geometry Nodes: Multi-thread creation of selection from field
When boolean fields are evaluated and used as selections, we create
a vector of indices. This process is currently single-threaded, but
226f0c4fef added a more optimized multi-threaded version
of this process. It's simple to use this in the field evaluator.

I tested this with the set position node and a random
value node set to boolean mode on a Ryzen 2700x:
|              | Before  |  After  | Improvement |
| 10% Selected | 40.5 ms | 29.0 ms | 1.4x        |
| 90% Selected | 115 ms  | 45.3 ms | 2.5x        |

In the future there could be a specialized version for non-span
virtual array selections that uses `materialize` to lower virtual
call overhead.

Differential Revision: https://developer.blender.org/D14436
2022-03-24 18:48:38 -05:00
3e16f3b3ef BLI: move generic data structures to blenlib
This is a follow up to rB2252bc6a5527cd7360d1ccfe7a2d1bc640a8dfa6.
2022-03-19 08:26:29 +01:00
2252bc6a55 BLI: move CPPType to blenlib
For more detail about `CPPType`, see `BLI_cpp_type.hh` and D14367.

Differential Revision: https://developer.blender.org/D14367
2022-03-18 10:57:45 +01:00
aa500c4fca Cleanup: use back-slash for doxygen commands, color after parameters 2022-03-02 12:11:08 +11:00
f4d80ecdfd Cleanup: Typo in comment 2022-02-24 12:01:22 -05:00
7393cc1db7 Cleanup: Remove repeated word in comments 2022-02-23 18:24:37 +11:00
c434782e3a File headers: SPDX License migration
Use a shorter/simpler license convention, stops the header taking so
much space.

Follow the SPDX license specification: https://spdx.org/licenses

- C/C++/objc/objc++
- Python
- Shell Scripts
- CMake, GNUmakefile

While most of the source tree has been included

- `./extern/` was left out.
- `./intern/cycles` & `./intern/atomic` are also excluded because they
  use different header conventions.

doc/license/SPDX-license-identifiers.txt has been added to list SPDX all
used identifiers.

See P2788 for the script that automated these edits.

Reviewed By: brecht, mont29, sergey

Ref D14069
2022-02-11 09:14:36 +11:00
e7912dfa19 Attributes: Infrastructure for generic 8-bit integer data type
This commit adds infrastructure for 8 bit signed integer attributes.
This can be useful given the discussion in T94193, where we want to
store spline type, Bezier handle type, and other small enums as
attributes.

This is only exposed in the interface in the attribute lists, so it
shouldn't be an option in geometry nodes, at least for now.
I expect that this type won't be used directly very often, it
should mostly be cast to an enum type. However, with support
for 8 bit integers, it also makes sense to add things like mixing
implementations for consistency.

Differential Revision: https://developer.blender.org/D13721
2022-02-04 10:29:11 -06:00
b4563ab2df Cleanup: avoid generating some functions in all translation units
Every translation unit that included the modified headers generated
some extra code, even though it was not used. This adds unnecessary
compile time overhead and is annoying when investigating the
generated assembly.
2022-02-04 17:18:56 +01:00