Compare commits

..

880 Commits

Author SHA1 Message Date
a903e7bb32 Merge remote-tracking branch 'origin' into microfacet_hair 2023-03-07 14:59:54 +01:00
b7070df8a7 Merge remote-tracking branch 'origin' into microfacet_hair 2023-03-07 14:20:17 +01:00
7f5d1fb05a Merge branch 'blender-v3.5-release' into main 2023-03-07 13:23:43 +01:00
4eb88bca58 Gitea: use full URL for referencing pull requests
For easy clicking in commit logs.

Pull Request: blender/blender#105493
2023-03-07 13:21:51 +01:00
a668e3b73a I18n: do not translate a message already translated using iface_()
This follows #105417, which allowed detection of this message.

Pull Request #105420
2023-03-07 12:32:00 +01:00
ae530592fe I18n: disambiguate messages
- "Lines" in the sense of number of lines
- "Number" can mean "amount, count" or "index, offset"
- "Second" can be an ordinal number or a unit
- "Root": add the brush curve to the "square root falloff" sense
- "Strip" can be a sequence or a type of hair rendering
- "Constant" in the sense of a value, for the Geometry Nodes add
  submenu (#105447).

Additionally, extract:
- "Press a key" from the Keymap preferences.
- "MaskLayer", upon new mask layer creation

Ref #43295, #105447
2023-03-07 12:31:59 +01:00
2a3d945dc5 Armature drawing: prevent crash on unknown draw type
While developing a new armature draw type, I was switching between
branches and opening the same test file. It would crash Blender because
it assumed that the `else` clause could only mean `(arm->drawtype ==
ARM_OCTA)`. This is now explicitly tested for.

The result is that an armature with unknown draw type is not drawn at
all, but I prefer that over either resetting the draw type to something
valid (thus altering the blend file) or downright crashing.
2023-03-07 11:48:26 +01:00
5ed8d3537b Merge branch 'blender-v3.5-release' 2023-03-07 11:34:07 +01:00
e7606139ba Fix #105467: NaN values resulting from curve editing with collision
This was caused by an incorrect assumption in the solver:
It tries to solve both collision and length constraints simultaneously,
using the projected movement of a point as a slide direction along the surface.
This only works if the distance of the previous curve point to the surface
is less than the allowed segment length. Otherwise the segment will
exceed the allowed length even with zero slide and NaN values are computed.

The case of larger surface distance can occur if the previous segment
solve was already stretching the current segment and then the point
moves further away. In this case we can simply clamp the segment length
without violating the contact constraint.

Pull Request #105499
2023-03-07 11:30:07 +01:00
64faa31bb7 Revert "Fix for NaN values resulting from curve editing with collision"
This reverts commit 98b56aadec.

Causes a compile error due to incomplete rename, and should go to release branch.
2023-03-07 11:18:05 +01:00
067fc67bdd Merge branch 'blender-v3.5-release' 2023-03-07 11:06:19 +01:00
98b56aadec Fix for NaN values resulting from curve editing with collision
This was caused by an incorrect assumption in the solver:
It tries to solve both collision and length constraints simultaneously,
using the projected movement of a point as a slide direction along the surface.
This only works if the distance of the previous curve point to the surface
is less than the allowed segment length. Otherwise the segment will
exceed the allowed length even with zero slide and NaN values are computed.

The case of larger surface distance can occur if the previous segment
solve was already stretching the current segment and then the point
moves further away. In this case we can simply clamp the segment length
without violating the contact constraint.

Fixes #105467

Pull Request #105499
2023-03-07 11:05:04 +01:00
38cba7a843 Cleanup: remove old AST code in I18n message extraction
Pre-Python 3.8, the string nodes in an AST were of type ast.Str.
Post, they are of type ast.Constant.

Remove the old naming.

Pull Request #105418
2023-03-07 10:41:57 +01:00
2e5452ee87 I18n: do not extract messages explicitly marked as not translatable
Some UI functions have a "translate" argument, which if set to False
specifies that the message is not to be translated. This sometimes
means that it was already translated beforehands.

But many messages were still getting extracted, sometimes twice in
different contexts. Some featured errors because the arguments of
various functions would be concatenated, such as:

```
col.label(text=iface_("Branch: %s") % bpy.app.build_branch.decode('utf-8', 'replace'), translate=False)
```

which would get extracted as:

```
msgid "Branch: %sutf-8replace"
```

Pull Request #105417
2023-03-07 10:41:18 +01:00
5a004ccc6a Cleanup: use function style casts, nullptr 2023-03-07 15:59:14 +11:00
5b152a4880 Docs: correct doc-string for wmEvent::customdata
Also cross-reference custom-data with GHOST_TEventType.
2023-03-07 15:57:18 +11:00
dbb4c4a687 Cleanup: use gz_prop_type for wmGizmoPropertyType
This is already the convention, missed renaming this case.
2023-03-07 15:18:18 +11:00
0e64d1e652 Docs: add comments to bNodeType init & free callbacks
When investigating ID user-count issues, it wasn't clear how nodes
were meant to handle user-count for ID's. Specifically that the
initfunc should _not_ increment the ID's user count.
2023-03-07 15:13:06 +11:00
90dc655951 Cleanup: spelling in comments 2023-03-07 15:00:05 +11:00
175b1b449e Fix #105433: Offset Tracking Shortcut no longer working
Regression caused by 03f17c42d0

The `TFM_MODAL_TRANSLATE` is used in a special way in the tracking
transformation.
2023-03-06 19:38:46 -03:00
91e191bd21 Transform: split tracking conversion
The conversion of curve tracking points is not integrated into `Tracks`
and `PlaneTracks` so its logic can be separated from the file.
2023-03-06 19:38:35 -03:00
1658de6769 Merge branch 'blender-v3.5-release' 2023-03-06 23:14:18 +01:00
83f28793c0 Fix missing data role in color management fallback
This would show as warning in gtests. Does not affect normal operation as
OpenColorIO should have a valid configuration file for Blender itself.
2023-03-06 23:01:50 +01:00
a3b0a77f50 Cleanup: UV: simplify types
No functional changes.
2023-03-07 10:33:06 +13:00
b309feb71c Cleanup: format 2023-03-07 10:24:05 +13:00
51cd560b47 Fix PLY exporter test writing files to install directory
Doing such writes leaves dangling file in the installation directory which
then is packaged as well. Not only this makes it so a random file gets
packaged for installation, it also makes notarization process to fail because
of not-so-clear reason.

The `ply_exporter_ply_data_test.SuzanneLoadPLYDataUV` fixture seems to be
unreliable and fails at random, even before this change. This makes it
hard to reliably get green light on all tests.

Pull Request #105504
2023-03-06 22:07:14 +01:00
b756915206 Cleanup: Avoid recursion for node parenting
Don't call recursion where it's redundant. The recursive algorithm
can carry dangerous behavior due to stack growth and overflow. The
probability is low for something like the frame nodes. But using a loop
is cheap, providing O(N = const) memory cost. A loop through the links
in a singly linked list is sufficient. The use of 2D vectors for
location mapping and other things can be separate.

Pull Request #105394
2023-03-06 18:39:20 +01:00
a23102528c Fix failing test after own recent commit regarding Main freeing function.
3e5ce23c99 introduced a regression in case the freed Main was part of a
list, and was supposed to be removed from it, since calling
`BLI_remlink` does _not_ clear the `prev`/`next` pointers of the removed
link.

This commit also contains a few more tweaks to recent related b3f42d8e98
commit.

Pull Request #105485
2023-03-06 16:11:35 +01:00
1f2823291a Cleanup: Add warning to ListBase's BLI_remlink regarding not cleared prev/next pointers.
While this behavior can be useful in some cases, it can also create
issues (as in one of own recent commits, 3e5ce23c99), since it
implicetly keeps the removed linknode 'linked' to the listbase.

At least warn about it in the documentation of `BLI_remlink`.
2023-03-06 16:08:45 +01:00
08bd6deb57 Fix #99836: Blender SEGV when open .blend file in blender.
Use recent 'abort file reading' mechanism to simply not try to load such
purposedly broken .blend files at all.
2023-03-06 16:08:45 +01:00
f49a995b2c Add a mechanism to abort a blend file reading on critical error.
This commit introduces a new Main boolean flag that marks is as invalid.

Higher-level file reading code does checks on this flag to abort reading
process if needed.

This is an implementation of the #105083 design task.

Given the extense of the change, I do not think this should be
considered for 3.5 and previous LTS releases.
2023-03-06 16:08:45 +01:00
f1df811899 Fix (unreported) potential leak in Main freeing function.
Could happen in case a 'split-by-libraries' Main is passed to
`BKE_main_free`.
2023-03-06 16:08:45 +01:00
c26566ad27 Drivers: Introduce the Context Properties
Drivers: Introduce the Context Properties

The goal: allow accessing context dependent data, such as active scene camera
without linking to a specific scene data-block. This is useful in cases when,
for example, geometry node setup needs to be aware of the camera position.

A possible work-around without changes like this is to have some scene
evaluation hook which will update driver variables for the currently evaluating
scene. But this raises an issue of linking: it is undesirable that the asset
scene is linked to the shot file.
Surely, it is possible to have post-evaluation handler to clear the variables,
but it all starts to be quite messy. Not to mention possible threading
conflicts.

Another possibility of introducing a way to achieve the goal is to make it so
the dependency graph somehow parses the python expression where artists can
(and already are trying to) type something like:

  depsgraph.scene.camera.matrix_world.col[3][0]

But this is not only tricky to implement properly and reliably, it hits two
limitations:

- Currently dependency graph can only easily resolve dependencies to a RNA
  property.

- Some properties access which are valid in Python are not considered valid
  RNA properties by the existing property resolution functions:

  `camera.matrix_world[3][0]` is a valid RNA property, but
  `camera.matrix_world.col[3][0]` is not.

Using driver variables allows to have visual feedback when the path resolution
fails, and there is no way to visualize errors in the python expression itself.

This change introduces the new variable type: Context Property. Using this
variable type makes allows to choose between Active Scene and Active View
Layer. These scene and view layer are resolved during the driver evaluation
time, based on the current dependency graph.

This allows to create a driver variable in the following configuration:

- Type: Context Property
- Context Property: Active Scene
- Path: camera.matrix_world[3][0]

The naming is a bit confusing. Tried my best to keep it clear keeping two
aspects in mind: using UI naming when possible, and follow the existing
naming.

A lot of the changes are related on making it so the required data is available
from the variable evaluation functions. It wasn't really clear what the data
would be, and the scope of the changes, so it is done together with the
functional changes.

It seems that there is some variable evaluation logic duplicated in the
`bpy_rna_driver.c`. This change does not change it. It is not really clear why
this separate code path with much more limited scope of supported target types
is even needed.

There is also a possible change in the behavior of the dependency graph: it
is now using ID of the resolved path when building driver variables. It used
to use the variable ID. In common cases they match, but when going into nested
data-blocks it is actually correct to use relation to the resolved ID. Not sure
if there was some code to ensure that, which now can be resolved. Also not sure
whether it is still needed to ensure the ID specified in the driver target is
build as well. Intuitively it is not needed.

Pull Request #105132
2023-03-06 16:01:47 +01:00
4fb6e45b37 Curves: change default font offset from 1.0 to 0.0
Currently, curves have a default offset of 1.0, while the initial (and
expected) value is 0.0. When resetting this value to its default, the
curve is now modified unexpectedly. This is most noticeable with text
objects: when resetting the offset of a new text, it will look very
broken.

Internally the value is stored with an offset of 1.0, with custom
setter and getter adding and subtracting 1.0 respectively. To give
this property a default of 0.0, we also need to add 1.0 to the initial
value upon curve creation.

Pull Request #105182
2023-03-06 14:28:40 +01:00
4dc59c7311 I18n: add per-socket translation contexts for nodes
In order to properly translate UI messages, they sometimes need to be
disambiguated using translation contexts. Until now, node sockets had
no way to specify contexts and collisions occurred.

This commit adds a way to declare contexts for each socket using:
`.translation_context()`

If no context is specified, the default null context is used.

Pull Request #105195
2023-03-06 14:24:36 +01:00
214b24e025 Cleanup: Fix incorrectly formatted multi-line docstring
This has the effect that the message is cut off at the end of the
first line. I copied the solution from other similar docstrings
elsewhere in the code.

As far as my regex-fu can tell, there are no other occurrences of this
in the codebase.

Issue reported by Joan Pujolar in #43295.

Pull Request #105474
2023-03-06 14:09:44 +01:00
61b457d390 Vulkan: Push constants
**What are push constants?**

Push constants is a way to quickly provide a small amount of uniform data to shaders.
It should be much quicker than UBOs but a huge limitation is the size of data - spec
requires 128 bytes to be available for a push constant range.

**What are the challenges with push constants?**

The challenge with push constants is that the limited available size. According to
the Vulkan spec each platform should at least have 128 bytes reserved for push
constants. Current Mesa/AMD drivers supports 256 bytes, but Mesa/Intel is only 128
bytes.

**What is our solution?**

Some shaders of Blender uses more than these boundaries. When more data is needed
push constants will not be used, but the shader will be patched to use an uniform
buffer instead. This mechanism will be part of the Vulkan backend and shader
developers should not see any difference on API level.

**Known limitations**

Current state of the vulkan backend does not track resources that are in the
command queue. This patch includes some test cases that identified this issue as
well. See #104771.

Pull Request #104880
2023-03-06 12:28:55 +01:00
08db6bf215 IO: factor out axis validation logic between OBJ and PLY
The up_axis_update/forward_axis_update was the same logic between
the two, so factor that out.

Also use the same time reporting logic in PLY as in OBJ/USD/Alembic.
2023-03-06 10:22:01 +02:00
62c4dce83b Merge remote-tracking branch 'upstream/blender-v3.5-release' 2023-03-06 09:18:42 +01:00
c3fdb02b91 Updated translations from SVN trunk (r6369). 2023-03-06 09:17:14 +01:00
4e32864786 Cleanup: Remove compilation warning.
In MTLTexture it was checked that this was valid. What in that
case should always be true.
2023-03-06 08:40:30 +01:00
5a20c63975 Fix #104534: Image editor doesn't refresh after render.render.
When render is triggered from python and the render result is displayed
it isn't being updated as it wasn't tagged as being invalid.

Pull Request #105480
2023-03-06 08:38:53 +01:00
3674de160d Fix #105395: Handle quoted paths better in the OBJ importer
If the texture image path in the MTL is a "quoted" absolute path, the importer will fail to find the
file. It was only attempting to un-quote the path for the relative case. Now we attempt to un-quote
in all cases.

Pull Request #105478
2023-03-05 21:32:24 -08:00
049027d697 Cleanup: Fix a few messages in the UI
Issues reported by Joan Pujolar in #43295.

- uv -> UV everywhere.
- Wrong plurals.

Pull Request #105473
2023-03-05 21:32:23 -08:00
68d5784802 Fix #105395: Handle quoted paths better in the OBJ importer
If the texture image path in the MTL is a "quoted" absolute path, the importer will fail to find the
file. It was only attempting to un-quote the path for the relative case. Now we attempt to un-quote
in all cases.

Pull Request #105478
2023-03-06 06:29:40 +01:00
507c442289 Cleanup: UV: simplify types
No functional changes.
2023-03-06 17:27:45 +13:00
96263368b5 Cleanup: Unused variables, missing includes in PLY IO 2023-03-05 22:31:43 -05:00
3c5a15db57 Cleanup: Small tweaks to new PLY code
- Add missing braces for if statements
- Tweak variable naming to use snake case
- Use more common name for `MLoop`s of a face
- Use `std::move` when appending an array
- Use const for a few variable declarations
2023-03-05 22:12:26 -05:00
9eee008691 Fix Cycles oneAPI build error due to conflicting CONSTANT define 2023-03-06 00:13:21 +01:00
7d5754b8b6 Cycles: Reuse random variable for principled hair BSDF sampling
This lets us skip the hash and use a proper stratified variable instead.
Suggested by Christophe Hery.
2023-03-06 00:09:04 +01:00
f3c5fda899 Cleanup: Fix a few messages in the UI
Issues reported by Joan Pujolar in #43295.

- uv -> UV everywhere.
- Wrong plurals.

Pull Request #105473
2023-03-05 23:16:26 +01:00
71c366f5cc PLY: fixing tests 2023-03-05 21:50:25 +02:00
ca4486bfa1 Cleanup: format 2023-03-05 19:53:40 +01:00
9139983f94 Cycles: Implement MaterialX OSL microfacet closures
This commit implements three OSL microfacet closures that are needed to support
MaterialX: dielectric_bsdf, conductor_bsdf and generalized_schlick_bsdf.

Internally these map to existing microfacet closures, only the Fresnel term is
different.
2023-03-05 19:52:07 +01:00
014f6e4309 Cycles: Make Fresnel term independent of microfacet closure type
Currently, we use the closure type to encode the type of microfacet distribution
(GGX/Beckmann/Sharp/MultiGGX), the lobes we're interested in
(Reflection/Refraction/both) AND the Fresnel type (None or Principled v1).

This results in the mess of dozens of options that we currently have. Since
adding Principled v2 and the MaterialX OSL closures will involve adding more
Fresnel types, this clearly doesn't scale.

But, since the earlier Fresnel rework (D17101), the Fresnel type only matters
in one place now. This allows to significantly clean up the closure type
handling. To do this, MicrofacetBsdfs now separately store their Fresnel type,
and instead of a single MicrofacetExtra we have one struct per Fresnel type
(unless no extra data is needed).

Further, instead of having one _setup() function per combination, the Fresnel
setup is also split into separate functions. This decouples the implementation
of new Fresnel terms from most of the Microfacet logic, and makes it a very
simple and clean operation.
2023-03-05 19:52:07 +01:00
5f9b518a8b Cycles: Use per-microfacet Fresnel term for Glass closures
This commit replaces the current Glass approach, where Glass is a virtual closure
that gets replaced with a Glossy and a Refractive closure, with a combined
closure that handles Fresnel after sampling the microfacet. That way, the Fresnel
term is more accurate since it accounts for the microfacet normal, not the
shading normal.

Also updates the BSDF sampling to use a 3D sampler now, since we need two
dimensions to pick the microfacet normal and then a third dimension to pick
reflection/refraction. This can also be used to get rid of the LCG in the
Principled Hair BSDF, which means we can remove it altogether once MultiGGX is
gone.

Also, "sharp" is now supported as a microfacet distribution in OSL, and 2
is supported as the "refract" argument to microfacet() in order to get glass.
2023-03-05 19:52:07 +01:00
a30abe9c2e IO: minor tweaks to the new C++ PLY importer/exporter
Address some issues discussed in PR #104404:
- Vertex color options changed to None/sRGB/Linear, default is sRGB
  to match the existing Python addon.
- Change name to "Stanford PLY" from "PLY" in the menu item.
- Default "Export UVs" to on.
- After importing vertex colors, they are set as enabled for render.
2023-03-05 20:44:53 +02:00
Nathan Rozendaal
43e9c90061 IO: New C++ PLY importer/exporter
New (experimental) Stanford PLY importer and exporter written in C++.

Handles: vertices, faces, edges, vertex colors, normals, UVs. Both
binary and ASCII formats are supported.

Usually 10-20x faster than the existing Python based PLY
importer/exporter.

Additional notes compared to the previous Python addon:
- Importing point clouds with vertex colors now works
- Importing PLY files with non standard line endings
- Exporting multiple objects (previous exporter didn't take the vertex
  indices into account)
- The importer has the option to merge vertices
- The exporter supports exporting loose edges and vertices along with
  UV map data

This is squashed commit of PR #104404
Reviewed By: Hans Goudey, Aras Pranckevicius

Co-authored-by: Arjan van Diest
Co-authored-by: Lilith Houtjes
Co-authored-by: Bas Hendriks
Co-authored-by: Thomas Feijen
Co-authored-by: Yoran Huzen
2023-03-05 20:44:53 +02:00
b4d36b3efe GPU: Compute: Document and cleanup header
No fonctional changes.
2023-03-05 18:14:17 +01:00
4862d56a0e GPUFrameBuffer: Document and cleanup header
No fonctional changes.
2023-03-05 17:57:51 +01:00
d782569682 Cleanup: GPU: Improve eGPUBarrier documentation 2023-03-05 17:57:51 +01:00
0a10571501 GPU: Replace GPU_finish by correct memory barrier 2023-03-05 17:57:51 +01:00
1b815678aa msgfmt: fix runtime requirements
msgfmt has a TBB dependency though bf_blenlib, now for a release build
The MSVC linker is smart enough to realize none of the TBB code is
actually used and discards it. In debug mode the linker is a bit more
conservative and doesn't, leaving msgfmt with a runtime dependency
on TBB. The problem here is, we only copy the runtime dlls during
the install phase, and msgfmt runs long long before that.

For this reason when we run msgfmt we should make sure any runtime
needs it could have are met in the path, there already is a handy
variable for that since oslc has similar requirements.

Pull Request #105048
2023-03-04 17:39:49 -07:00
38407b319a CMake/Win32: Install boost dlls during install phase
During install all dlls should copy to the blender.shared
folder regardless if the dependency is on or off, creators
CmakeLists.txt already did this correctly, but for boost
the BOOST_POSTFIX and BOOST_DEBUG_POSTFIX variables were
not set causing the boost dll's not to be copied.

This change takes the setting of these variables out of the
WITH_BOOST block, but still guards it with a
WITH_WINDOWS_FIND_MODULES block so we don't break the build
for people building with that on.
2023-03-04 14:07:17 -07:00
adacf5a706 Merge branch 'blender-v3.5-release' 2023-03-04 04:12:20 -08:00
5a4872bd4e Fix #105341 Hard freeze in scene space stroke code
Note: the entire paint stroke code needs to be rewritten to
work properly in world space.  At least it now freezes in
one less edge case.
2023-03-04 04:08:18 -08:00
4b0f5c2aad Fix build error introduced in previous commit.
Fix build error introduced in 57742c7868 due to int/float conversion.
2023-03-04 08:04:35 +01:00
f5e9a78216 GPU: Fix wrong barrier in tests
Texture and buffer reads were using the incorrect barrier.
2023-03-04 07:44:34 +01:00
fcedc97d11 GPU: Add GPU_BARRIER_BUFFER_UPDATE barrier type
This barrier types is needed for correct readback of buffers GPU memory
to CPU memory.
2023-03-04 07:44:34 +01:00
57742c7868 Fix: Wrong text clipping in the frame node
When drawing text with multiple lines inside a frame node, depending
on the zoom level some lines would wrongly get clipped despite being
inside the clipping region.

This was caused by the clipping check in `blf_glyph_draw` not accounting
for the font’s aspect.

Pull Request #105389
2023-03-04 07:12:14 +01:00
e22eb23bc2 Cleanup: match header/source arguments & quiet cppheck warnings 2023-03-04 15:19:00 +11:00
7cb3a79246 Cleanup: remove unused arguments 2023-03-04 15:10:39 +11:00
d0cfbc23db Merge branch 'blender-v3.5-release' 2023-03-03 15:37:11 -08:00
c02feb6773 Fix failing VSE test
Caused by b4100ed377. Image strips with only 1 frame of content do
expect any timeline frame to be translated into frame index of 0.

Check this case and return 0 explicitly.
2023-03-03 23:56:12 +01:00
89c3ead7c6 Fix #105388: Default Font Accidentally Kerning
Move the code that disables kerning for the default font so it can't be
re-enabled by the cache subsystem.

Pull Request #105415
2023-03-03 23:17:20 +01:00
6749593aec Fix mistake in previous commit
Fix error in b4100ed377

`seq_retiming_evaluate()` returns range from 0 to 1, to which framerate
correction was applied. this is incorrect, and correction should be
applied to function input.
2023-03-03 23:03:59 +01:00
c066035907 Cleanup: Deduplicate node parent checking functions
Unify both functions in one, with a more telling name,
to be sure of the order of the arguments. Some functional
cleanup of the using code to make it more explicit.

Pull Request #105413
2023-03-03 22:38:49 +01:00
b4100ed377 Fix VSE clamping strip content length incorrectly
When movie framerate does not match scene, content length was clamped to strip
length in scen framerate. This also caused issues with retiming which behaved in
similar way. Retiming was modified to use frame index of strip content, so even
when scene framerate is changed, retiming data is preserved in correct
proportions. This means, that handles are mapped to time in seconds rather than
to frames.
2023-03-03 22:32:37 +01:00
a95eaf0ec1 Build: Make OpenImageIO a required dependency
During the discussion for #101413 there was consensus that we could make
OIIO a mandatory dependency. This patch does just that.

The `idiff` testing tool remains optional.

Pull Request #105111
2023-03-03 21:53:34 +01:00
d0eeb3d155 Cleanup: Remove mesh normals function, deprecate in RNA
Since normals are calculated when they are accessed if necessary, this
was a no-op. Related to cfa53e0fbe and 6a3c3c77b3.
2023-03-03 15:18:29 -05:00
0d080d1a07 Fix: Build with FFmpeg 6.0
Pull Request #105377
2023-03-03 18:42:35 +01:00
915ff8d152 Cleanup: Use references for mesh poly variables
Similar to the previous commit, this simplifies future refactoring
to change the way edges are stored, and further differentiates
single poly variables from array pointers.
2023-03-03 11:40:43 -05:00
45cff837bc Cleanup: Use simpler iterator for mesh polygons
Avoid incrementing a pointer, use only indices as a source of truth.
This should ease refactors to change the way polys are stored.
2023-03-03 11:40:43 -05:00
e1a0c09f06 Merge branch 'blender-v3.5-release' 2023-03-03 16:55:20 +01:00
e7ba8247de Merge branch 'blender-v3.5-releas' into main 2023-03-03 16:45:45 +01:00
513d31360f Fix #105329: Keyframe handles staying in place when using slider operators
The issue was that when using the `HD_ALIGNED` handle type,
Blender would not automatically move the keyframe handles with the key.
Instead one handle would get stuck in place.
To remedy that manually move the keyframe handles in case the type is `HD_ALIGNED`
This makes it consistent with moving a key with G

Pull Request #105401
2023-03-03 16:41:14 +01:00
549cc568b0 Fix various issues with modifiers and edge display in edit mode
Consistently use edge draw flag instead of original index to determine if an
edge should be drawn or not.

In GPU subdivision the edge original index was used for both edge optimal
display and selection mapping to coarse edges, but they are not the same.
Now match the CPU subdivision logic and use a separate edge draw flag VBO.

For cage display, match Blender 3.3 behavior more in showing/hiding of edges
in wireframe mode. That is edges without a mapping to an original edge are
always hidden when there is no distinct cage, and drawn otherwise. This is
not ideal for e.g. the bevel modifier where it will always show some edges on
corners despite all edges being hidden by the user. But we currently have
no good information to decide if these should be hidden or not, so err on
the side of showing too much as it did before.

Fie #103706: bevel modifier edges not drawn correctly
Fix #103700: optimal display can't be turned of with GPU subdivision
Fix wrong edge display with GPU subdivision preceded by other modifiers

Pull Request #105384
2023-03-03 16:38:27 +01:00
05b141e67f Merge remote-tracking branch 'upstream/blender-v3.5-release' 2023-03-03 15:27:07 +01:00
d66672e17a WM: Fix invalid memory access in wmTimer handling code.
Timer management code often loops over the list of timers, calling
independant callbacks that end up freeing other timers in the list. That
would result in potentail access-after-free errors, as reported in #105160.

The typical identified scenario is wmTimer calling wmJob code, which
calls some of the job's callbacks (`update` or `end` e.g.), which call
`WM_report`, which removes and add another timer.

To address this issue on a general level, the deletion of timers is now
deferred, with the public API `WM_event_remove_timer` only marking the
timer for deletion, and the private new function
`wm_window_delete_removed_timers` effectively removing and deleting all
marked timers.

This implements design task #105369.

Pull Request #105380
2023-03-03 15:24:26 +01:00
e0732b640a Fix: Build with FFmpeg 6.0
Pull Request #105377
2023-03-03 13:51:45 +01:00
a2d988b5da Cleanup: function style casts for C++, use nullptr 2023-03-03 23:28:18 +11:00
a2cc7e1511 Merge branch 'blender-v3.5-release' 2023-03-03 23:16:32 +11:00
24f3cb9b5c Fix #105381: Alt-Tab causes Alt to stick with multiple monitors on WIN32
Window activation events on Windows-10 don't seem to be reliable as it's
possible for Alt-Tab to trigger WM_ACTIVATE on a window when switching
away from it. As detecting the keys which are held relies on a valid
active state - this meant Alt could become stuck when using Alt-Tab
to switch between windows.

Disable reading modifiers on activation for WIN32, activating the window
now clears modifiers on WIN32. This isn't ideal as held modifiers wont
be detected, re-introducing the error reported in #40059.
2023-03-03 23:12:28 +11:00
5bb3dc84c1 Merge branch 'blender-v3.5-release' 2023-03-03 12:31:25 +01:00
d3cbfc96e0 Metal: Ensure explicit UBO bind indices
Previously, UBO bind locations were linearly incremented and
relied on  the correct uniform location being queried. This fix
is a future requirement for EEVEE next, however, pulling forward
due to Issue #105280 highlighting a possible flaw with expected
uniform locations.

Authored by Apple: Michael Parkin-White

Ref #96261
Pull Request #105311
2023-03-03 12:03:43 +01:00
06cf84f77f EEVEE: Resolve artifacts in EEVEE with Intel GPUs on macOS.
Intel GPUs exhibit a number of rendering artifacts.
The most substantial being incorrect resolve of reflections.
Splitting the reflections_resolve shader into two passes,
one for SSR and one for light probes ensures correct rendering
and optimal performance on this GPU.

Also resolves an artifact with ambient occlusion wherein
the pow(a, b) function causes excessive precision loss.
Using an alternative method for power calculation on these
platforms resolves the issues.

Authored by Apple: Michael Parkin-White

Ref T96261
Pull Request #105240
2023-03-03 11:53:15 +01:00
9801f7def8 Fix #105280: DRW: Allow UBO bindpoint of 0 for clipping data.
The check was testing against 0 instead of -1
(invalid location).

Authored by Apple: Michael Parkin-White

Ref #96261
Pull Request #105310
2023-03-03 11:24:31 +01:00
7ebe721557 Refactor: Move motion tracking related files to C++
A bulk change, to make things moving as quickly as possible, instead of
doing per-modified-file basis.

This is pretty much direct translation of C code to C++, is not really
"proper" C++ usage. That could happen on a more case-by-cases basis.

Pull Request #105376
2023-03-03 11:09:33 +01:00
48aac51c35 Fix: EEVEE: Lightcache texture usage flags
Metal backed requires HOST_READ texture usage flag
for irradiance grid. This was correctly in place for the
basic grid, but not for grid_prev.

Authored by Apple: Michael Parkin-White

Ref #96261
Pull Request #105312
2023-03-03 11:02:37 +01:00
7e5cb36e0c Metal: Fix erroneous outvar replacements.
Resolves issue with node_holdout perfomring an outvar
replacement on a function, causing shader compilation
failure.

Ref #96261
Pull Request #105396
2023-03-03 11:01:36 +01:00
aa82afaaf7 Cleanup: regenerate the default theme file
Re-run ./tools/utils/blender_theme_as_c.py
2023-03-03 16:32:38 +11:00
f0257aa71b Cleanup: use camel-case for struct name, wrap function arguments 2023-03-03 16:29:43 +11:00
2eaa55272d Cleanup: use function style casts, nullptr in C++ 2023-03-03 16:29:36 +11:00
b4eef99973 Cleanup: use C-style code comments, format 2023-03-03 16:29:22 +11:00
37c0b0b2b8 Cleanup: format 2023-03-03 13:42:21 +13:00
dcad51dfc3 DRW: Retopology Overlay
Add overlay option for retopology, which hides the shaded mesh akin to Hidden Wire, and offsets the edit mesh overlay towards the view.

Related Task #70267
Pull Request #104599
2023-03-03 00:35:45 +01:00
55ea58ff5b BLI_string: correct size for BLI_str_format_int_grouped, update tests
Ensure the defines match the longest strings in tests.
2023-03-03 10:25:47 +11:00
05324e2e3c Cleanup: spelling in comments 2023-03-03 10:09:20 +11:00
99e90615d7 Cleanup: compiler warnings 2023-03-03 09:53:23 +11:00
d130f81a22 Cleanup: Use const arguments in node.cc
Cleanup, try to always use const.
Many function signatures still have incorrect argument order
(constants, mutables). But this is a larger other cleanup.

Pull Request #104937
2023-03-02 23:14:59 +01:00
118ec54ec7 Cleanup: Move five mesh related files to C++
To faciliate further mesh data structure refactoring. See #103343.

Pull Request #105354
2023-03-02 23:14:33 +01:00
15375b0845 Docs: improve comments in linux_rocky8_setup.sh 2023-03-02 21:30:22 +01:00
2a9f792c9e Draw Next: Fix shader orco computation 2023-03-02 17:57:30 +01:00
8c29d84139 BLI: Prevent Overflow in Grouped Number Output
Increase the buffer sizes used for `BLI_str_format_uint64_grouped` to
prevent overflow on strings representing numbers within the uint64
range. Also creates and uses defines for all the formatted string
buffer sizes.

Pull Request #105263
2023-03-02 17:38:36 +01:00
ff6ce25926 Add a basic support to BKE library linking code to generate liboverrides.
This commit adds the ability to generate liboverrides of linked data at
the `BKE_blendfile_link_append` BKE level, and through the Python API
(the `BPY_library_load` context manager, aka `bpy.data.libraries.load`).

The python API was updated essentially to allow easy testing of the new
code. This commit also adds tests for the new 'override' behavior, and
for existing basic link one.

Current code only generates 'basic' overrides, without any handing of
hierarchies or dependencies, as for brush assets only the Brush ID needs
to be overridden.

That new feature does not aim at being exposed to user through the
link/append operations in its current state, as it is way too simplistic.

This change is a requirement for the Brush Asset project (#101908).

Pull Request #104746
2023-03-02 17:22:42 +01:00
f5c56b4cd6 Animation: Remove the 'Weight Paint: Fix Deforms' operator
The code of the 'Fix Deforms' operator was hard to read and inefficient, doing `O(num_vertices * num_vertex_groups)` evaluations of the mesh. It caused multiple issues and got in the way of improvements to Blender, and seems to be used very little (if ever).

It was decided in [last week's module meeting](https://devtalk.blender.org/t/2023-02-23-animation-rigging-meeting/27757#patch-review-decision-time-5) that this operator should be removed.

Pull Request #105237
2023-03-02 16:58:14 +01:00
00ca7c5221 Fix #105109: Pick selection with multi object edit
Pick selection for the Curves object was not considering multi
object editing. Only the active object was considered.

This fix introduces pick selection for Curves for multi object editing.

Pull Request #105184
2023-03-02 15:43:15 +01:00
1d3a2fb5bb Merge branch 'blender-v3.5-release' 2023-03-02 15:15:11 +01:00
422f3d0b0f Fix #105278: IDProperty UI missing library overridable toggle
The toggle (for anything but float and int types) was swallowed in
bf948b2cef. Also seems ef68a37e5d discarded
`property_overridable_library_set` for bools.

Now treat the overridable toggle as a general property for all property
types.

Pull Request #105370
2023-03-02 15:13:52 +01:00
fa044c453f Cleanup: Unused fields and API for tracks map
The map is used to, well, map localized copy of the tracks used by the
tracing thread to the original tracks in the movie clip. There seems to
be some accumulated stuff in there which is no longer used by the current
state of code.

There should be no functional changes.

Pull Request #105374
2023-03-02 15:09:50 +01:00
81b56f8bbc Cleanup: Refactor BKE_nlatrack_add to multiple methods to handle adding a new NLA track to the track list. Insert before, after, head, and tail
This PR removes the BKE_nlatrack_add, and adds new:

* BKE_nlatrack_insert_before
* BKE_nlatrack_insert_after
* BKE_nlatrack_new_before_and_set_active
* BKE_nlatrack_new_after_and_set_active
* BKE_nlatrack_new_head_and_set_active
* BKE_nlatrack_new_tail_and_set_active

methods to easily add new NLA tracks in relation to the existing track list.

Pull Request #104929
2023-03-02 15:02:30 +01:00
12854fdfd6 Fix: Frame Channels fails when no keys in range
Under the following circumstances
* keys on 1, 3 and 5
* preview range set to 10-20

The frame channel operator would zoom into nothingness.
because no keys were found in the preview range.
(Only the `ANIM_OT_channel_view_pick` operator though)
This PR fixes it and notifies the user with a warning.

Pull Request #105179
2023-03-02 13:04:57 +01:00
f97542e5a2 Merge branch 'blender-v3.5-release' 2023-03-02 11:04:17 +01:00
9e5275791f Fix #105343: id.make_local() doesn't work for overridden data.
RNA `make_local` call isfairly low-level and by-passes
`BKE_library_make_local`, so it also needs to handle the liboverride
case itself.
2023-03-02 11:02:16 +01:00
4de2cf4136 Merge branch 'blender-v3.5-release' 2023-03-02 09:53:58 +01:00
2eeec49640 Fix #105339: grease pencil selection can toggle object selection
Grease Pencil (when not in object mode) implements its own selection
opertor. This operator (`gpencil.select`) returns
`OPERATOR_PASS_THROUGH`, then falls though to `view3d.select` which can
toggle object selection (when using shift-click picking).

Removing `OPERATOR_PASS_THROUGH` would fix the object toggling, but this
was added in 62c73db734 with good reason (the tweak tool would not
work then).

Now prevent `view3d.select` from acting on Grease Pencil (when not in
object mode).

NOTE: longer term we could have grease pencil use view3d.select to avoid having to add these awkward exceptions

Pull Request #105342
2023-03-02 09:52:35 +01:00
b02b2589e2 Merge branch 'blender-v3.5-release' 2023-03-02 16:37:59 +11:00
bb77d6934c Merge branch 'blender-v3.5-release' 2023-03-02 16:37:55 +11:00
944a6e78f5 Fix #105277: Alt key suck after Alt-Tab on Windows 11
Windows 11 has strange behavior with Alt-Tab.
In some cases an Alt-Press event is sent to the window immediately
after it is de-activated (both Left & Right Alt keys for some reason
even when only one is held).

This meant that:

- Modifiers could be enabled for de-activated windows
  (so we can't assume de-activated windows have modifiers released).

- Releasing the modifier key would not be sent to the inactive window
  causing the modifier key to be stuck.

- Button events over an inactive window are generated before activation,
  so even though activation reads the correct modifier state,
  the button event uses the "stuck" modifier state.

Now button & drop events on inactive windows always read the modifier
state first instead of relying on the modifier state to be cleared.

This has some advantages:

- If modifiers are held, they will be used as part of the click action.

- While modifier keys on inactive windows should be rare,
  in the case this does happen - stuck keys are avoided.
  So it makes sense to apply these changes for all platforms.
2023-03-02 16:35:46 +11:00
b43f520a82 Cleanup: Move UV parameterizer to blender::geometry namespace
The current API makes more sense as part of a class, but for now, keep
consistency with the other geometry module headers and move the code
to the proper namespace, removing the `GEO_` prefix which is only meant
for C code.

Pull Request #105357
2023-03-02 06:10:26 +01:00
2d6921198a Cleanup: Remove unnecessary struct and using keywords in C++ 2023-03-02 06:10:25 +01:00
aea53c771d Cleanup: Move UV parameterizer header to C++
See #103343
2023-03-02 06:10:25 +01:00
b61807ebcf Cleanup: split logic for updating event modifiers into functions
Also remove USE_WIN_ACTIVATE & USE_WIN_DEACTIVATE defines as they
were only added when changes to modifier handling failed on WIN32.

This logic has now been tested to work on all platforms.
2023-03-02 16:08:14 +11:00
8cae7a0dcc Cleanup: remove/comment unused defines 2023-03-02 15:05:52 +11:00
ae086deaa5 Docs: note that "Effect" and related types are deprecated
Also use comments to identify "Effect" members which must be used
by all structs.
2023-03-02 15:05:52 +11:00
93508ab2df Cleanup: Make mesh validation functions static
These functions used internal values and only really make sense in
the context of the mesh validation process where they're used to remove
invalid elements from the mesh.
2023-03-01 22:30:47 -05:00
fcaf12f07a Cleanup: format 2023-03-02 16:23:17 +13:00
52d20c6a0e Fix #105331: Assert in solidify extrude after recent cleanup
Use indices instead of pointers to avoid accessing elements beyond
the end of the result mesh arrays.
2023-03-01 22:21:08 -05:00
6b8cdd5979 Fix #103469: Update UV Sphere Projection with Seam support.
Note: Applies to both UV Sphere Projection and UV Cylinder Projection.

Adds a new boolean option "Preserve Seams" to UV Sphere Projection.

With "Preserve Seams" active, the Sphere projection will do a
greedy flood fill over the 3D topology, stopping at 3D boundaries
and also stopping at edges where "Mark Seam" has been used in the
3D Viewport.

During the flood fill, each face is mapped using the spherical
projection and then adjusted along the U axis so the UV map is
continuous across the shared edge.

With careful seam placement, this allows for the creation of a
spiral-cut-orange-peel unwrap, where a sphere can be unwrapped
into a single long continuous strip, wrapping multiple times around
the object.

Finally, if the flood fill process creates multiple UV Islands,
they are spaced along the `U` axis to prevent overlaps.

Pull Request #104847
2023-03-02 00:48:34 +01:00
7de2f21001 Fix: Debug build error after recent variable rename cleanup
Also adjust some comment formatting as penance.
2023-03-01 18:08:41 -05:00
3022a805ca Cleanup: Standardize mesh edge and poly naming
With the goal of clearly differentiating between arrays and single
elements, improving consistency across Blender, and using wording
that's easier to read and say, change variable names for Mesh edges
and polygons/faces.

Common renames are the following, with some extra prefixes, etc.
 - `mpoly` -> `polys`
 - `mpoly`/`mp`/`p` -> `poly`
 - `medge` -> `edges`
 - `med`/`ed`/`e` -> `edge`

`MLoop` variables aren't affected because they will be replaced
when they're split up into to arrays in #104424.
2023-03-01 15:58:01 -05:00
0f61497e20 Cleanup: Use spans for mesh render data
This offers overflow checking in debug builds, avoids implicit
conversion to pointers, slicing features for future convenience,
and clarifies ownership. Also switch naming to plural like most
other arrays for further clarification.
2023-03-01 15:58:01 -05:00
f1f47df56b Cleanup: Remove unused variable 2023-03-01 15:58:01 -05:00
2324eb4f8c Fix: Use of uninitialized variable after recent cleanup 2023-03-01 15:58:01 -05:00
d939ecc46f Cleanup: Access mesh data with spans
Similar to cb62ab5b28, in newly C++ files.
2023-03-01 15:58:01 -05:00
7ca63d40dc Revert #105225: WM Check for lack of active window
This check is no longer needed as Campbell has removed the need to
pass around the active window.  This check could potential be error-
hiding so best removed if not needed.

Pull Request #105351
2023-03-01 21:44:41 +01:00
59b9bb0849 Draw: Custom IDs
This pull request adds a new tipe of resource handles (thin handles).
These are intended for cases where a resource buffer with more than one
entry for each object is needed (for example, one entry per material
slot).
While it's already possible to have multiple regular handles for the
same object, they have a non-trivial overhead in terms of uploaded
data (matrix, bounds, object info) and computation (visibility
culling).
Thin handles store an indirection buffer pointing to their "parent"
regular handle, therefore multiple thin handles can share the same
per-object data and visibility culling computation.

Thin handles can only be used in their own Pass type (PassMainThin),
so passes that don't need them don't have to pay the overhead.

This pull request also includes the update of the Workbench Next
pre-pass to use PassMainThin, which is the main reason for the
implementation of this feature.

The main change from the previous PR is that the thin handles are now
stored directly in the main resource_id_buf, to avoid wasting an extra
 bind slot.

Pull Request #105261
2023-03-01 21:42:25 +01:00
03f17c42d0 Fix #100129: Status bar incorrectly shows "[G] Move" after pressing G
Add specific modal keyitem for `Vert/Edge Slide` and `TrackBall`.
So they don't need to reuse modal items from other operators.

Note that there is a workround to avoid repeated keys in the status bar.
2023-03-01 16:06:20 -03:00
515cb14056 Fix: Don't create undo step for empty box select in VSE
In `gesture_box_apply`, check if `exec` function returns
`OPERATOR_CANCELLED` and return 0 to prevent any undo items from being
created.

Pull Request #105065
2023-03-01 18:47:46 +01:00
d449539cd2 Cleanup: Move five modifier files to C++
See #103343

Pull Request #105345
2023-03-01 17:32:12 +01:00
4d58f01424 Add LSAN suppression rules config file.
This file has been tested on linux, other platforms may need some
tweaks, and/or dedicated files.

This is used to suppress errors with builds integrating ASAN sanitazing
tools, regarding memleaks detected in some third party libraries.

To use it, define the envvar option like that:

`LSAN_OPTIONS=print_suppressions=false:suppressions=/path/to/blender/source/tools/config/analysis/lsan.supp`

This is especially usefull when running ctest.

NOTE: Will also update https://wiki.blender.org/wiki/Tools/Tests/Setup
and https://wiki.blender.org/wiki/Tools/Debugging/ASAN_Address_Sanitizer
accordingly.
2023-03-01 16:24:59 +01:00
3006140718 Refactor: Replace DNA_DEPRECATED attribute with _legacy suffix
Applied for the motion tracking data data structures.

There are two advantages of doing so:

- More explicit and platform independent way of indicating that
  something is legacy and is not to be accessed outside of the
  versioning code.

- Simplifies conversion to C++ where having deprecated fields
  triggers warning in implicitly defined assign operator.

Pull Request #105340
2023-03-01 15:18:54 +01:00
1ba0494e33 Fix failing test after own recent commit regarding Main freeing function.
3e5ce23c99 introduced a regression in case the freed Main was part of a
list, and was supposed to be removed from it, since calling
`BLI_remlink` does _not_ clear the `prev`/`next` pointers of the removed
link.

This commit also contains a few more tweaks to recent related b3f42d8e98
commit.
2023-03-01 15:17:33 +01:00
3ff2cbe708 Cleanup: Add warning to ListBase's BLI_remlink regarding not cleared prev/next pointers.
While this behavior can be useful in some cases, it can also create
issues (as in one of own recent commits, 3e5ce23c99), since it
implicetly keeps the removed linknode 'linked' to the listbase.

At least warn about it in the documentation of `BLI_remlink`.
2023-03-01 15:17:33 +01:00
565acb639c WM: use the window associated with an area for initialization
The active window was used by the NLA and the Graph editor however
this is not always available and not necessarily the window that
contains the area being initialized. Potentially causing the graph and
NLA spaces to be initialized with the wrong scene.

Active window access caused various awkward fixes in the past
([0], [1], [2]) which worked around the active window not being set.
Use a lookup for the window instead of accessing the active window.

Note that passing the window is an option too however this is only
used for versioning older files and is not be needed in most cases.

[0]: 20788e1747
[1]: 42f6aada98
[2]: 480e467ac9
2023-03-02 00:39:29 +11:00
124b41a877 Cleanup: unused variables 2023-03-02 00:39:28 +11:00
cccf91ff83 Mesh: Move edge UV seams to a generic attribute
As part of #95966, move the `ME_SEAM` flag on mesh edges
to a generic boolean attribute, called `.uv_seam`. This is the
last bit of extra information stored in mesh edges. After this
is committed we can switch to a different type for them and
have a 1/3 improvement in memory consumption.

It is also now possible to see that a mesh has no UV seams in
constant time, and like other similar refactors, interacting with
only the UV seams can be done with less memory.

The attribute name starts with a `.` to signify that the attribute,
like face sets, isn't meant to be used in arbitrary procedural
situations (with geometry nodes for example). That gives us more
freedom to change things in the future.

Pull Request #104728
2023-03-01 14:13:05 +01:00
66c9c19466 Cleanup: add missing CMake headers & sort file lists 2023-03-01 22:46:04 +11:00
01e711749b pyproject: remove tools/pyproject.toml
Rely on ./pyproject.toml. This file was only separated because it was in
an external repository.
2023-03-01 22:18:28 +11:00
e1ab9e352c Cleanup: autopep8 2023-03-01 22:12:18 +11:00
bd0aa88909 Fix invalid path references after moving tools & scripts 2023-03-01 22:00:46 +11:00
1ed783eed3 Fix #99836: Blender SEGV when open .blend file in blender.
Use recent 'abort file reading' mechanism to simply not try to load such
purposedly broken .blend files at all.
2023-03-01 11:50:50 +01:00
b3f42d8e98 Add a mechanism to abort a blend file reading on critical error.
This commit introduces a new Main boolean flag that marks is as invalid.

Higher-level file reading code does checks on this flag to abort reading
process if needed.

This is an implementation of the #105083 design task.

Given the extense of the change, I do not think this should be
considered for 3.5 and previous LTS releases.
2023-03-01 11:50:50 +01:00
3e5ce23c99 Fix (unreported) potential leak in Main freeing function.
Could happen in case a 'split-by-libraries' Main is passed to
`BKE_main_free`.
2023-03-01 11:50:50 +01:00
e35afd8a1d Merge branch 'blender-v3.5-release' 2023-03-01 21:16:37 +11:00
e9fefcd298 Merge branch 'blender-v3.5-release' 2023-03-01 21:16:33 +11:00
ff89dfd6d2 Fix #105328: unit system does not affect cavity 2023-03-01 21:15:11 +11:00
cf572f1a64 Python: Add range and instance drawing to GPUBatch
GPUBatch.draw supports basic drawing methods. Although all
supported GPU backends support range based and instance based drawing.

This patch adds 2 methods to GPUBatch to add support to range based and
instance based drawing.

my_batch.draw_range(my_shader, elem_start=10, elem_count=5)
Will draw my_batch using my_shader. From the attached index buffer
elements 10-14 will be drawn.

my_batch.draw_instance_range(my_shader, instance_start=0, instance_count=10)
will draw my_batch using my_shader 10 times. Inside the vertex
shader the current instance number is held by gl_InstanceID.

Pull Request #104457
2023-03-01 10:23:38 +01:00
52064bf5da Fix #104824: GPencil natural drawing building with 1 subdivision very slow
1. Changes the subdivision function to not fill in time but add 0 to fix bug #104824
2. Fixes a bug in sanitization function noticed while fixing this bug.

Pull Request #105306
2023-03-01 10:09:23 +01:00
159958e52b Cleanup: Simplify storage and comments in UV Unwrapper.
Rename `single_pin_uv` to `origin`.

Remove `PChartPack`.

No functional changes.
2023-03-01 20:38:41 +13:00
c7d38b643b Cleanup: Simplify storage and comments in UV Unwrapper.
Simplify PChart handling of area_uv and area_3d.
2023-03-01 20:01:40 +13:00
6766a7911f UV: Merge both UV Packing engines into one.
Affects Geometry Nodes:
* UV Unwrap
* UV Pack

No functional changes.

Pull Request #105286
2023-03-01 07:28:28 +01:00
09c4d6bd7b Cleanup: avoid looping over layer collections again when freeing 2023-03-01 15:14:50 +11:00
ea97bb1641 Use hash for Collection.gobject lookup, speedup object linking
Add a hash for faster look-ups on collection->gobject,
This avoids a full list lookup for every object added via Python's
CollectionObject.link as well as linking via BKE_collection_object_add_*
functions.

While the speedup is non-linear, linking & unlinking 100k objects from
Python is about 50x faster. Although unlinking all objects in order
(a best-case for linked lists) is approximately the same speed.

Ref !104553.
2023-03-01 12:34:45 +11:00
e65671c1ed Merge branch 'blender-v3.5-release' 2023-03-01 11:21:02 +11:00
337e68aeb5 Test: update bl_rna_defaults
- Remove Group test
- Add Brush, Collection, GreasePencil, HairCurves,
  LightProbe, PointCloud, Volume tests

Ref !105172.
2023-03-01 11:18:47 +11:00
6f4d36ca8f Python: Change console banner color-style to info
Update the style of the Python Console banner to "INFO" instead of
"OUTPUT".

This change makes it easier to difference user generated output from the
initial banner text.

This also has an advantage that "Copy as Script" excludes the banner.

Ref !105188.
2023-03-01 11:10:06 +11:00
6fe2fabbff Merge branch 'blender-v3.5-release' 2023-02-28 17:47:10 -05:00
d90d6f8674 Fix #105259: Copy & paste boolean custom property as driver doesn't work
A copy and paste mistake in ef68a37e5d.
2023-02-28 17:46:26 -05:00
71a79a7a7c Cleanup: Small cleanups to flip faces node
Decrease indentation, simplify variable names, use IndexRange more.
2023-02-28 17:30:25 -05:00
ce25209e26 Cleanup: Clarify mirror modifier copying and face flipping
Rewrite the logic to depend less on local variables and prefer spans
and indices over points and pointer arithmetic. Also make use of the
IndexRange type for some basic logic, correct the mesh that the
sharp edge layer was chosen from, and reduce variable scope.
2023-02-28 17:29:35 -05:00
f2ea7ae751 Fix #105319: Crash in weighted normal modifier after recent cleanup 2023-02-28 16:44:26 -05:00
8aa1a7db3e Cleanup: Use clearer variable names in mirror modifier
It wasn't clear what "max" referred to.
2023-02-28 16:03:49 -05:00
eb5e7b1b4e Merge branch 'blender-v3.5-release' 2023-02-28 15:39:55 -05:00
079dbf4d1b Fix #105162: Array modifier cap material index ignored
The material indices from the caps were only copied if the base mesh had
a material index attribute. Fix that by copying them manually if the cap
has the attribute.
2023-02-28 15:39:19 -05:00
f911a9280b Merge branch 'blender-v3.5-release' 2023-02-28 14:03:22 -05:00
15f59470a3 Fix #105314: Custom node groups missing sockets
`ShaderNodeCustomGroup` and others lost their UI with
7026096099 without a dynamic declaration callback.
2023-02-28 13:59:28 -05:00
4ffae99d6d Cleanup: Remove unnecessary declarations in laplacian smooth modifier 2023-02-28 13:03:42 -05:00
08e20376b1 Cleanup: Use simpler for loop syntax for mesh polys in two modifiers 2023-02-28 13:03:42 -05:00
62c6eb12bf Fix #105165: Weighted normal modifier crash after recent cleanup
Mistake in cb62ab5b28
2023-02-28 13:03:42 -05:00
9b67e883dd Fix #105257: Incorrect Search Region Size
Search list's region is having its size members (winx and winy) set
to values that are one pixel too small. This causes text to look bad
as they are slightly off their pixel alignment.

See #105308 for more details and an illustration of the issue.

Pull Request #105308
2023-02-28 18:21:07 +01:00
8fbc80be8f Merge branch 'blender-v3.5-release' 2023-02-28 11:36:20 -05:00
076a33ccd1 Fix #104219: Node links dragged from wrong socket after selection
Nodes are sorted based on the selection. In some cases (even depending
on processor speed, nodes can be selected and reordered, and another
operation can run before the next redraw). That gives a window where
operators mapped to the same input as selection can run with invalid
socket locations (which aren't updated after the nodes are reordered,
since they are stored in a separate array).

To fix this, move the socket locations from the node editor runtime
data to the node tree, tag them as invalid when the nodes are
reordered, and check for that status in a few more places.

A better longer term solution is not reordering nodes based on
UI status and instead storing the UI drawing order separately.

Pull Request #104420
2023-02-28 11:35:32 -05:00
480e467ac9 Fix #104726: Allow loading of 2.48 file without active window
Add check to WM_check for lack of wmWindowManager->winactive. Sets it
if there is a window and makes that one wmWindow->active as well.

Pull Request #105225
2023-02-28 17:08:30 +01:00
eb68334b58 Cleanup: Mesh: Access looptris with Span
Similar to cb62ab5b28 but for mesh triangulation.

Pull Request #105297
2023-02-28 14:52:31 +01:00
3c94e2ab4c Cleanup: split 'transform_gizmo_3d.cc' in more specific units
Split `transform_gizmo_3d.cc` in:
- `transform_gizmo_3d.cc`
- `transform_gizmo_3d_cage.cc`
- `transform_gizmo_3d_shear.cc`

Split `transform.h` in:
- `transform.h`
- `transform_gizmo.h`

Also:
- Move functions `gimbal_axis_pose` and `gimbal_axis_object` to
`transform_orentations.c` (they are not used in `transform_gizmo_3d.cc`)

Pull Request #105256
2023-02-28 14:12:14 +01:00
5edca02d08 Fix cage2d gizmo setting uniform size when uniform scaling is required 2023-02-28 13:00:20 +01:00
30a81f1b55 GPencil: UV parameters for the first point in sample modifier.
Simplify modifier sample mode failed to transfer uv parameters for the first point, now fixed.

Continuation of #104942

Pull Request #105284
2023-02-28 12:15:50 +01:00
7842347ec8 Cycles: Fix hanging unit tests when MetalRT is enabled
This patch fixes hanging unit tests when MetalRT is enabled. It simplifies and fixes the kernel selection logic by baking the MetalRT-specific options into `kernels_md5` rather than expanding out and testing MetalRT bit flags explicitly.

Pull Request #105270
2023-02-28 11:42:08 +01:00
0786b05175 Cleanup: More clear variable name in File Browser drawing 2023-02-28 11:29:59 +01:00
09e848deec Cleanup: use term "filepath" instead of "name" / "fname" 2023-02-28 17:31:08 +11:00
707af21afd Merge branch 'blender-v3.5-release' 2023-02-28 17:14:02 +11:00
9fccd2dc24 Fix #100819: Built-in VFont has an additional user by default
New built-in fonts would have an additional user when added for the
first time.

BKE_vfont_builtin_get now always borrows the reference.
2023-02-28 17:08:23 +11:00
3cba2911e0 Vulkan: Add Initial VKFrameBuffer.
This was backported from tmp-vulkan. When disabling the fence check
in ghost it is able to start blender. It will show a black screen
so not usable for users.
2023-02-28 06:20:12 +01:00
c2df623e86 Merge branch 'blender-v3.5-release' 2023-02-28 16:01:42 +11:00
1e6aaf5f65 Merge branch 'blender-v3.5-release' 2023-02-28 16:01:26 +11:00
9cee0eb7fa Cleanup: format 2023-02-28 15:44:49 +11:00
e885973ea9 Fix #104894: Toggle comments assumes '#' prefix (failing for OSL)
Add comment line prefix to format struct so each language can define
it's own comment prefix.

Ref !104953.
2023-02-28 15:43:11 +11:00
8d9819e07f Fix: Not all vulkan code-paths where compiled.
Fix issue where old `WITH_VULKAN` was still used. It should
have used `WITH_VULKAN_BACKEND`.
2023-02-28 05:36:06 +01:00
8859b1cd3c Cleanup: quiet mypy type checking warnings
- make_update.external_script_add_origin_if_needed
  returned None or an empty string. As neither where checked simply
  return None.
- git_get_remote_url had an incorrect annotation.
2023-02-28 15:12:04 +11:00
cca5f18303 Fix path for check_mypy_config 2023-02-28 15:11:27 +11:00
466d160424 Cleanup: replace an integer array with booleans for RNA type validation 2023-02-28 14:53:48 +11:00
9ac0cc48b9 Cleanup: use _ separator for variable names including dummy
Names such as `dummyult` and `dummyet` didn't read very well,
underscore separate these names.

Also rename some variables that used old conventions which missed
being updated (`mpr` for manipulator instead of `gz` for gizmo).
2023-02-28 14:39:41 +11:00
6d5e834857 Merge branch 'blender-v3.5-release' 2023-02-28 14:11:25 +11:00
52f521dec4 Fix #105063: Registering existing RNA types overwrote built-in types
When an RNA type was registered, any existing dynamic types with the
same name were unregistered. This didn't account for built-in types
which cannot be unregistered in (most cases) allowing duplicate
operators for e.g. to be registered with the same name as existing
built-in operators (asserting with debug builds with GHash duplicates).

In practice the newly registered operator would be called unless
adding operators caused the GHash to be resized which could cause the
original operator to be used.

As registered RNA type identifiers are meant to be unique, don't allow
duplicate names in the first place. Now all dynamically registerable
RNA types prevent this situation, raising an error when scripts
attempt to register a type with an identifier matching the name of a
type that could not be removed.
2023-02-28 13:58:40 +11:00
4675ee3c73 Merge branch 'blender-v3.5-release' 2023-02-28 10:31:07 +11:00
0965341dcf Fix #105229: Operator tooltips are cut short
Shortened in [0], increase to 1024 with the following changes:

- Use BKE_ST_MAXNAME for translation_context.
- Use OP_MAX_TYPENAME for wmOperatorType.name.

Both these limits were already used elsewhere but happened to use
RNA_DYN_DESCR_MAX (incorrectly).

[0]: f403d9a2b1
2023-02-28 10:28:34 +11:00
a58caeb4b3 Cleanup: quiet struct declaration warning 2023-02-28 10:17:17 +11:00
e4f0e29bab Merge branch 'blender-v3.5-release' 2023-02-28 10:12:51 +11:00
de12ea7226 Cleanup: quiet unused warnings 2023-02-28 10:10:12 +11:00
d291955665 Fix setting the active vertex color when assigning false
Oversight in c517e4a501.
2023-02-28 10:10:12 +11:00
cb1af1fbd9 UV: Migrate UV packing from Editor to bf_geometry.
No functional changes.

Pull Request #105212
2023-02-27 22:41:10 +01:00
c3d803c2ef Cleanup: Use consistent "positions" term for mesh update tag functions
Consistent with naming from 1af62cb3bf. Keep the "coord"
naming in the "vert_coords_alloc" set of functions since they should be
removed (see #103789).
2023-02-27 16:08:48 -05:00
b37111c574 Cleanup: Use consistent "vert" term for mesh normals
Use "vert" instead of "vertex" when referring to mesh normals. This was
discussed as part of 1af62cb3bf but never completely
implemented.
2023-02-27 15:52:29 -05:00
baa27d0aef Fix: Explode modifier cycles test failure after recent cleanup
Caused by 96abaae9ac. Just keep the old argument
in the `_ex` version of the function for now. It can be removed
when the explode modifier is removed in 4.0.
2023-02-27 15:29:52 -05:00
5ea41a9942 UI: Added Edge Width option in preferences for 3DView and UV/Image Editor
Previously [D16255](https://developer.blender.org/D16255)
There is no option to adjust the edge_width like there is in the preferences for vertex_size and face_dot_size.

I only added the option for 3DView and UV/Image Editor, and limited both to a max size of 5 pixel, since the edges do not look very nice with too high values.
In the UV Editor only, there are always black outlines on the edges, I could not find a way to reduce the increasing thickness of these black outlines.

The default edge_width of 1 pixel:

![shows the marked new attribute with a value of 1 in the settings for the UV/Imageeditor](/attachments/f48fc1e5-2b49-4337-bd86-f2ad4aca42c3)

Here the edge_width with a falue of 3:

![shows the marked new attribute with a value of 3 in the settings for the UV/Imageeditor](/attachments/d0b0b1ea-5967-46b2-80a2-ccae18933638)

And here the visible increase of the dark border of the edges and their overlap (even at the maxed size of 5):

![shows the marked new attribute with a value of 5 in the settings for the UV/Imageeditor and points out the thicker border in the left side UV Editor](/attachments/1590965f-af2a-49d0-a11e-1afecaabf940)

Lastly for the 3DView the max edge_width of 5 looks like this:

![shows the marked new attribute with a value of 5 for the settings for the 3DView and it's resulting wider lines in the right side visible 3DView](/attachments/fcd35341-97a5-4db6-8bbf-c5ce5333e5aa)

Pull Request #104741
2023-02-27 20:02:37 +01:00
f37077ae5a Mesh: Clear loose edges bitmap with count of zero
When there are no loose edges, the loose edge bitmap shouldn't be used.
That was already documented in the loose edge storage struct, but the
bit vector wasn't actually cleared.
2023-02-27 13:09:45 -05:00
52104c1a0c Mesh: Avoid recalculating bounds after some operations
Share the bounds cache across the input and output meshes of some
mesh operations that don't change the min and max positions: simple
subdivision, edge/face deletion, and triangulation. If the source mesh's
bounds are computed, or if the mesh is persistent, this can save
recalculation of the bounding box, which takes a few milliseconds
for large meshes.
2023-02-27 12:31:09 -05:00
96abaae9ac Cleanup: Remove legacy argument from mesh creation functions
The legacy `tessface_len` argument was only used for the explode
modifier. Remove it and copy the legacy face data manually there.
2023-02-27 11:24:22 -05:00
494becdec9 Cleanup: Remove redundant parenthesis 2023-02-27 16:56:46 +01:00
17e92711d3 UI: Refactor path dropping so logic doesn't depend on icons
No behavior change intended.

Many file drag & drop handlers used the icon assigned for dragging to
determine what type of data is dragged. This is fragile, for example
changing an icon would break drag & drop (!). This happened a few times,
e.g. see 3788003cda. It's also causing problems with #104830, which
changes how file browser drag data is handled.

Instead use the file extension to determine the file type.
2023-02-27 16:44:47 +01:00
1d4abfb537 Merge remote-tracking branch 'upstream/blender-v3.5-release' 2023-02-27 16:28:23 +01:00
4d5e68a638 Updated i18n PO files from SVN trunk (r6355). 2023-02-27 16:26:22 +01:00
5bd63e0fa5 Merge remote-tracking branch 'upstream/blender-v3.5-release' 2023-02-27 16:20:18 +01:00
3dd071e39b Usual i18n/UI messages fixes. 2023-02-27 16:19:16 +01:00
d69e2dba34 Merge branch 'blender-v3.5-release' 2023-02-27 16:14:43 +01:00
e6af81c536 Fix #105028: No update exiting curves edit mode
Exiting curves edit mode (going to object mode) would not update the
screen.

The fix adds a case to `ED_object_editmode_load_free_ex` for CURVES
to make sure the function returns properly. This then correctly adds the
notifier in `ED_object_editmode_exit_ex` to update the screen.

Pull Request #105252
2023-02-27 16:14:05 +01:00
0ade3dfc14 Merge branch 'blender-v3.5-release' 2023-02-27 15:23:56 +01:00
c5bbc5db6f I18n: disambiguate a few messages
- "Value" in the sense of color lightness is not the same word in
  Japanese as other usages. See #105113.
- "Double" as a data type vs. a value.

Also extract "Custom Color Presets" in the tracking UI.
Run clang-format as well.

Pull Request #105187
2023-02-27 15:21:00 +01:00
8cc11bc5f2 Fix #105226: Transform Gizmo with tncorrect offSets
Error in Commit a85b62bbc

Offsets were incorrectly being accumulated.
2023-02-27 11:09:22 -03:00
07f5d9bf2a Merge branch 'blender-v3.5-release' 2023-02-27 14:13:29 +01:00
1f6c710463 Fix #105230: Crash when reloading a library when one of its scene is active.
Scene and viewlayers pointers in the link/append context data need to be
updated after reload, otherwise they would keep pointing to old freed
IDs.
2023-02-27 14:12:50 +01:00
c79c35b4d3 Merge branch 'blender-v3.5-release' 2023-02-27 14:02:56 +01:00
79bce99260 Fix #104857: crash when datafiles/assets folder does not exist
This adds some simple null checks to avoid the crash. It might still
be good to improve the error message, but also does not seem as
important as avoiding the crash. Typically, users should not run into
this issue because the assets are shipped with Blender.
2023-02-27 14:02:03 +01:00
b558fff5b8 Outliner: New Grease Pencil filter
Actually is impossible to filter the Grease Pencil object type in the Outliner because only Meshes, Cameras and Lights are supported. This patch adds the Grease Pencil filter that allows artists to select only this type of objects. This filter is very handy for storyboarding.

Pull Request #104473
2023-02-27 13:07:14 +01:00
9044ba0ae5 Compositor: Compositor Output should Follow Active Node.
When using multiple compositor output nodes, compositing would fail
, showing a completely black output as it doesn't respect the active
node.

This patch will equalize the implementation with the viewer nodes.

Patch created by @OmarEmaraDev

Fixes: #86836

Pull Request #105235
2023-02-27 12:58:25 +01:00
8aedc03aa2 Vulkan: Calculate Correct Host and Device Memory Size.
Due to an error in GPU module we fixed the memory size in the
Vulkan backend. Last week the error has been fixed in the GPU module
so we can remove the temp fixes in the Vulkan backend.

Pull Request #105244
2023-02-27 12:56:05 +01:00
f738843362 Metal: Fix possible uniform lookup issue.
Similar to recent issues with gl_shader_interface,
ShaderInput lists need to be sorted to ensure correct
and efficient uniform lookup by name.

Authored by Apple: Michael Parkin-White

Ref #96261
Pull Request #105239
2023-02-27 12:33:28 +01:00
1812f5cb92 Merge branch 'blender-v3.5-release' 2023-02-27 12:03:42 +01:00
0c67a90e4f #99807: USD IO: Add support for exporting to USDZ
This commit adds the default .usdz export capability.

The importer already supports usdz so no change is required other than updating the text in menu to match the updated exporter text.

On export, a .usd/a/c file has to be created first, and then converted to .usdz. A weird change of directory is required because of a quirk with the USD conversion to usdz. If an absolute filepath is passed into the `UsdUtilsCreateNewUsdzPackage` function, the usd files inside the usdz archive will have the same directory structure, i.e. if one tries to create a file at `C:\code\BlenderProjects\file.usdz`, when the usdz file is created, inside it will have the structure `\code\BlenderProjects\file.usdc`.

This is counteracted by setting the current working directory to the temporary session directory where both the usdc and usdz files are created, and just passing the file name to `UsdUtilsCreateNewUsdzPackage` without any filepath. Once the usdz file is created it is moved to the intended directory.

There is a separate `UsdUtilsCreateNewARKitUsdzPackage` capability for exporting usdz for iOS devices that will be implemented in a follow up patch as it will require some more small UI changes.

Co-authored-by: Charles Wardlaw (@CharlesWardlaw)
Co-authored-by: Sonny Campbell (@SonnyCampbell_Unity)
Co-authored-by: Bastien Montagne (@mont29)

Pull Request #105185, based on #104556.

Pull Request #105223
2023-02-27 11:59:57 +01:00
f6c9fb27d5 Cleanup: remove .orig file added by accident 2023-02-27 21:52:26 +11:00
efb86b75ee Cleanup: comment block formatting 2023-02-27 21:51:57 +11:00
f240a16037 Cleanup: format 2023-02-27 21:34:53 +11:00
9a1ab6bd14 Cleanup: function style casts for C++, use nullptr 2023-02-27 21:34:53 +11:00
347cbbff2d Fix path in check_licenses utility 2023-02-27 21:34:53 +11:00
16aab1508d Cleanup: comment out unused parameters from last commit 2023-02-27 02:04:55 -08:00
a1c3061812 Fix OSX implementation of BLI_current_working_dir and improve tests.
While some implementations of `getcwd` may return an allocated string
instead of the given char buffer in some cases, this is not the expected
behavior of the BLI wrapper. Not to mention the danger of returning a
pointer to a static char buffer...

Improve `ChangeWorkingDirectoryTest` to be more 'full check' regarding
behavior of both `BLI_current_working_dir` and `BLI_change_working_dir`.
Also move call to `BLI_threadapi_init` into proper `SetUp` method (to
have correct symmetry with the call to `BLI_threadapi_exit` in the
`TearDown` one).

Based on investigation by Charles Wardlaw (@CharlesWardlaw).

Pull Request #105220
2023-02-27 11:03:42 +01:00
c4791ee009 Fix tests for macOS storage_apple.mm functions.
Pull Request #105000
2023-02-27 11:03:42 +01:00
DESKTOP-ON14TH5\Sonny Campbell
561e50f6c6 BLI: add function for changing working directory
Add `BLI_change_working_dir(path)` to change the current working directory.

This change is required for adding USDZ support to Blender. When exporting to that format, we are required to do a weird change of directory because of a quirk with the USD library's USDZ functionality. If an absolute filepath is passed into the `UsdUtilsCreateNewUsdzPackage` function, the USDZ archive will store that full path.

macOS uses `NSFileManager` through some new Mac-only wrapper functions.

Ref #99807

Pull Request #104525
2023-02-27 11:03:42 +01:00
08af0f1204 Fix setting the active vertex color when assigning false
Oversight in c517e4a501.
2023-02-27 21:00:30 +11:00
30db096cc8 Cleanup: quiet compiler warnings 2023-02-27 21:00:30 +11:00
dc08ff3c2e Cleanup: spelling in comments 2023-02-27 21:00:30 +11:00
40a11c7404 Merge branch 'blender-v3.5-release' 2023-02-27 10:59:30 +01:00
931b832fb2 Fix make update when local branch exists
Apparently `git checkout -t` is only allowed to happen for new branches.
Added a code which checks whether the branch already exists and it so
uses the `git checkout <branch>`.

Pull Request #105234
2023-02-27 10:58:58 +01:00
b4ee936627 Sculpt: Add support for last operator panel to color filter operator
* Refactored the color filter op to have an ->exec callback.
* Added nullptr checks to the filter cache API to support
  running outside of a view3d context.
* Redo panel displays the active filter type's name in the
  header.
2023-02-27 01:51:36 -08:00
6c03339e48 Cycles: reduce mesh memory usage by unflattening
To improve mesh upload speeds and reduce the size of the scene data which allows larger scenes to be rendered.

The meshes in Cycles are currently stored as flattened meshes, where each triangle is stored as a set of 3 vertices. Unflattening writes out the vertices in a list according to the index buffer. This uses a lot of memory and for current hardware does not provide a noticeable benefit. This change unflattens the mesh by directly using the meshes vertex and index buffers directly and skips the unflattening. This change allows for larger scenes and also a reduction in the sizes of the meshes. Further it results in a decrease the amount of time it takes to upload the data to a GPU. This is especially important for when multiple GPUs are used in a single machine.

Pull Request #105173
2023-02-27 10:39:19 +01:00
79d64bfde3 Geometry Nodes: Remove unnecessary position copying in delete node
In Edges and Edges & Faces modes, the node copied the positions once
with the other generic attributes and another time specifically just as
the positions. This is now unnecessary since positions are stored as
a generic attribute (1af62cb3bf). In a simple test this saved
2ms out of a total 12 in these modes.
2023-02-26 22:16:58 -05:00
ca2c0da79e Merge branch 'blender-v3.5-release' 2023-02-26 18:09:18 -05:00
97a8bb450c Fix #103387: Radius affects curves bounding box
e8f4010611 unified the bounds computation for the new curves
object type and the rest of the curves system used by geometry nodes.
In the process, it made bounds affected by the control point radius.
In theory that makes sense; the bounds are supposed to be the extents
of the visible geometry. But in practice the change wasn't expected,
for a few reasons:
 - The radius has never affected the bounds for the legacy curve type
 - The default radius of legacy curve objects is absurdly large at 1.0m
 - Only the new curve object has visible radius, and only in "strip"
   mode or when rendering with Cycles

Currently the bounds are only used for the "Bounding Box" geometry node
and the panel in the 3D viewport sidebar, so there isn't any incentive
to choose less intuitive behavior yet.

Long term, the correct behavior is probably to include the radius in
the bounds, but this commit postpones that change to when it works
better with the rest of the curves system.

Pull Request #105154
2023-02-27 00:01:01 +01:00
3db246a3ce Fix #104915: Race condition writing subsurf optimal display edges
Writing to a bitmap from multiple threads causes races when writing to
bits within the same integer. Instead, write to a separate boolean
array while subdividing, then move that to the final mesh bit vector.

Notes:
 - The final copy to the bit vector could be replaced by a generic
   `copy_from(Span<bool>)` call in the future.
 - Theoretically we could entirely replace the `BitVector` with an
   `Array<bool>`, but 1/8 the memory use for edges is likely worth it.

Pull Request #105156
2023-02-26 23:59:02 +01:00
3b59163b02 Subdiv: Simplify final vertex counting
The initial subdivision context counting ended up using unnecessarily
complicated logic to count the number of final vertices. In a first pass
it added vertices for every coarse edge. Then it added the same number
of vertices for every loose edge. That adds up to the same number of
vertices for the edges, so the separation is redundant and can be
replaced with a single multiplication.

The bitmap doesn't need to be cleared then, since it isn't used now.

In a test of a mesh with 2 million faces and 3 million vertices, this
saved 2.8ms (though the whole subdivision process takes around 700ms).

Pull Request #105159
2023-02-26 23:57:49 +01:00
8b543bfa3a Merge branch 'blender-v3.5-release'
# Conflicts:
#	source/blender/gpu/metal/mtl_immediate.mm
2023-02-26 17:44:31 +01:00
bf27a239c7 Fix: segfault when setting value in empty bit span 2023-02-26 17:26:12 +01:00
9335150f8c Cleanup: move some function implementations out of header
It's not really worth having them in the header and compiling them
in every translation unit where they are used.
2023-02-26 17:26:12 +01:00
54f672cbfa #99807: USD IO: Add support for exporting to USDZ
This commit adds the default .usdz export capability.

The importer already supports usdz so no change is required other than updating the text in menu to match the updated exporter text.

On export, a .usd/a/c file has to be created first, and then converted to .usdz. A weird change of directory is required because of a quirk with the USD conversion to usdz. If an absolute filepath is passed into the `UsdUtilsCreateNewUsdzPackage` function, the usd files inside the usdz archive will have the same directory structure, i.e. if one tries to create a file at `C:\code\BlenderProjects\file.usdz`, when the usdz file is created, inside it will have the structure `\code\BlenderProjects\file.usdc`.

This is counteracted by setting the current working directory to the temporary session directory where both the usdc and usdz files are created, and just passing the file name to `UsdUtilsCreateNewUsdzPackage` without any filepath. Once the usdz file is created it is moved to the intended directory.

There is a separate `UsdUtilsCreateNewARKitUsdzPackage` capability for exporting usdz for iOS devices that will be implemented in a follow up patch as it will require some more small UI changes.

Co-authored-by: Charles Wardlaw (@CharlesWardlaw)
Co-authored-by: Sonny Campbell (@SonnyCampbell_Unity)
Co-authored-by: Bastien Montagne (@mont29)

Pull Request #105185, based on #104556.
2023-02-26 16:36:49 +01:00
a8cc5f6919 Fix #104906: GPU: Fix signed/unsigned mismatches in shader code
Fix error message "initializer of type int cannot be assigned to
variable of type uint" on Blender startup.

Pull Request #105153
2023-02-26 16:13:55 +01:00
ec6e7d97ca Fix OSX implementation of BLI_current_working_dir and improve tests.
While some implementations of `getcwd` may return an allocated string
instead of the given char buffer in some cases, this is not the expected
behavior of the BLI wrapper. Not to mention the danger of returning a
pointer to a static char buffer...

Improve `ChangeWorkingDirectoryTest` to be more 'full check' regarding
behavior of both `BLI_current_working_dir` and `BLI_change_working_dir`.
Also move call to `BLI_threadapi_init` into proper `SetUp` method (to
have correct symmetry with the call to `BLI_threadapi_exit` in the
`TearDown` one).

Based on investigation by Charles Wardlaw (@CharlesWardlaw).

Pull Request #105220
2023-02-26 15:52:19 +01:00
2b7707b0d0 Fix #105059: Fix Grease pencil fill tool with Metal.
GPencil 3D stroke rendering uses a geometry shader.
This is unsupported by the Metal backend, so implement
fix for this failing compilation by shifting geometry shader
logic into the Vertex shader for Metal backend.

Authored by Apple: Michael Parkin-White

Ref #96261
Pull Request #105143
2023-02-26 15:22:13 +01:00
9f42888552 Fix #104016: Resolve Metal LineLoop emulation.
Metal LineLoop emulation path does not correctly apply
when using SSBO vertex fetch mode alongside 3D line
rendering.

Patch moves line emulation above SSBO
vertex fetch setup to ensure the correct emulation
parameters are passed to the shader.

Authored by Apple: Michael Parkin-White

Ref #96261
Pull Request #105142
2023-02-26 15:21:54 +01:00
fb63e484b9 Fix #103398: Fix Icon sampler initialization in Metal backend.
Resolves issue with nearest filtering on UI Icons. Note that as
Metal does not support LOD bias as a parameter on a sampler
object, the original code has been modified to perform LOD
biasing at the shader level.

As GPU_SAMPLER_ICON is not  widely used, it is more
efficient to apply directly to the  affected shaders, rather
than workaround passing in the sampler LOD bias as a
separate value e.g. uniform or push constant.

Original PR feedback addressed to also refactor ICON
shaders to use consistent style for single and multi
Icon rendering.

Authored by Apple: Michael Parkin-White

Ref #96261
Pull Request #105145
2023-02-26 13:23:40 +01:00
86ceb6722f Cleanup: format 2023-02-26 11:55:22 +13:00
52ded6ab56 GPUTexture: Make sure all available texture format are supported
This remove default casses from the `switch` statements to catch where
the missing cases are.

Uncomment unimplemented cases for the sake of completeness. Improving the
overall API.

This make the format conversion lists exhaustive and documented.

This replace `validate_data_format_mtl` by the common version as they
don't differ at all now.
2023-02-25 21:47:00 +01:00
5b2b114a2a Fix #105198: Ensure Frame and Reroute nodes are searchable
Set the new `gather_add_node_search_ops` member for these two special
node types.

Pull Request #105201
2023-02-25 21:32:23 +01:00
7eef746270 Merge branch 'blender-v3.5-release' 2023-02-25 23:13:05 +05:30
f9bcd8c7e8 Fix #104992: Crash on calling operation search in outliner
After 7eda9d8dda, crash occurs when operation search is called and no
active tree element is present. Add missing null check in new poll
function to fix the crash.

Pull Request #105004
2023-02-25 18:36:24 +01:00
afb6336857 Workbench: Remove unecessary GPU_TEXTURE_USAGE_ATTACHMENT flag
The dummy 3D textures are read only and never used as framebuffer targets.
2023-02-25 13:13:21 +01:00
9fb1f32f06 Cleanup: GPUTexture: Remove _ex suffix from texture creation
It isn't relevant anymore now that usage flags are mandatory.

Pull Request #105197
2023-02-25 11:39:54 +01:00
3d6578b33e GPUTexture: Add texture usage flag to all texture creation
All usages are currently placeholder GPU_TEXTURE_USAGE_GENERAL.
2023-02-25 11:39:53 +01:00
e01b140fb2 GPUTexture: Remove data_format from 3D texture creation function
For every other texture types this is expected to be implicitly
`GPU_DATA_FLOAT`. There is only one case where this is not the case.

I believe this was previously needed because the data type was
conditionning the texture creation. This is not the case anymore.
2023-02-25 11:39:53 +01:00
75e3371aef GPUTexture: Remove obsolete GPU_texture_bind_ex argument set_number
This was previously used when the binding number wasn't always stored
inside the texture itself.
2023-02-25 11:39:53 +01:00
73da5ee90d Cleanup: GPUTexture: Rename some functions with more descriptive names
List of renames:
GPU_texture_generate_mipmap > GPU_texture_update_mipmap_chain
GPU_texture_orig_width > GPU_texture_original_width
GPU_texture_orig_height > GPU_texture_original_height
GPU_texture_orig_size_set > GPU_texture_original_size_set
GPU_texture_format_description > GPU_texture_format_name
GPU_texture_array > GPU_texture_is_array
GPU_texture_cube > GPU_texture_is_cube
GPU_texture_depth > GPU_texture_has_depth_format
GPU_texture_stencil > GPU_texture_has_stencil_format
GPU_texture_integer > GPU_texture_has_integer_format
2023-02-25 11:39:53 +01:00
584e514561 Cleanup: GPUTexture: Improve function parameters name 2023-02-25 11:39:53 +01:00
7974557f0b GPUTexture: Add header documentation and reorganize sections 2023-02-25 11:39:53 +01:00
6166dac3ee Gizmo: support scaling of light gizmos with zero size
Zero-sized gizmos were not shown because GPU does not draw filled
triangles with zero area. This problem is resolved by drawing lines or
points in these degenerated cases.
Scaling is supported via computing the original and the new size, then
treat the case with zero original size separately, instead of only
computing the scale itself.
Actually applies to all `cage2d` gizmos, but not compatible when
translate flag is set.
2023-02-24 22:54:24 +01:00
0f09678036 Merge branch 'blender-v3.5-release' 2023-02-24 11:47:39 -08:00
01d4c8462d Fix #104006 Sculpt box/lasso trim projection errors 2023-02-24 11:46:29 -08:00
a843a9c9bb Sculpt: Add trim orientation to sculpt box trim UI 2023-02-24 11:28:23 -08:00
6cd9604a91 Merge branch 'blender-v3.5-release' 2023-02-24 11:10:56 -08:00
c517e4a501 Fix #104803: Fix broken deprecated vertex color RNA APIs
Fixed:
* mesh.vertex_colors.active
* mesh.vertex_colors.active_index
* MeshLoopColorLayer.active
* MeshLoopColorLayer.active_render
* MeshVertColorLayer.active
* MeshVertColorLayer.active_render
2023-02-24 11:07:53 -08:00
e3538546f2 Merge branch 'blender-v3.5-release' 2023-02-24 22:36:18 +05:30
b789980e27 Fix #105009: Restore GPencil layer drawing in dopesheet
After 49ad91b5ab, an extra visibility
toggle is being drawn for grease pencil layer in dopesheet. In this PR,
a condition is added to skip drawing of visibility toggle for GPencil
layer. Also, Grease pencil does not support pinning so restore the offset
added to channel for drawing the pin icon.

Pull Request #105080
2023-02-24 18:02:35 +01:00
82ff277528 Fix #100066: Cycles hangs when MSL->AIR compilation fails
This fixes [#100066](blender/blender#100066) by failing hard when front-end MSL->AIR compilation errors are encountered.

Pull Request #105122
2023-02-24 17:55:27 +01:00
626c233dd2 Fix #104087: Cycles crashes (Metal / AMD)
This is a workaround for [issue #104087](blender/blender#104087). We encounter crashes when using shader binary archives on AMD, so this disables them while we investigate a proper fix. Kernels will still be cached automatically by the OS file system cache. This cache may occasionally be purged due to external factors, in which case kernels will get compiled again.

Pull Request #105186
2023-02-24 17:52:35 +01:00
12cc3ccd72 Merge branch 'blender-v3.5-release' 2023-02-24 17:09:29 +01:00
f30c395a7c Fix make_update switching branches with multiple upstreams
If repository has multiple remotes with the same name of branch
checking out to the branch using simple `git checkout branch` exists
with an error: this is because there is ambiguity w.r.t which remote
to track.

Now the code explicitly provides remote to track, preferring to use
"origin" first (which is to be used for Blender style of workflow,
and Github style workflow when there is a fork available), and use
"upstream" if there is no origin.

Pull Request #105176
2023-02-24 17:08:46 +01:00
be94fefeb1 Merge branch 'blender-v3.5-release' 2023-02-24 16:43:17 +01:00
2c5434c3f5 Fix: crash in Spline Parameter node with single-point-curves
This was caught by our tests when they are run in a debug build with asserts.
2023-02-24 16:42:02 +01:00
45bbee340e Cleanup: Draw Manager: Update outdated comment 2023-02-24 16:30:10 +01:00
30efdbfc62 Merge branch 'blender-v3.5-release' 2023-02-24 16:27:26 +01:00
3d10dfb0a3 Fix #105166: Sample UV Surface node does not take index mask into account
The `call` method was reading from and writing to memory that it was
not supposed to access based on the passed in `mask`.
2023-02-24 16:26:07 +01:00
3e0a1cafa7 Merge branch 'blender-v3.5-release' 2023-02-24 15:53:18 +01:00
9b70039014 Fix paths in the auto-formatting tools
Those got missed in the submodule change commit.

Pull Request #105178
2023-02-24 15:52:34 +01:00
d5e45c8b92 Merge branch 'blender-v3.5-release' 2023-02-24 13:20:39 +01:00
b8359ede7d Fix #105168: Entering vertexpaint creates a non-default color attribute
Caused by 6514bb05ea

The new attribute was set active, but not default (camera icon).
Now set it default as well.

Pull Request #105169
2023-02-24 13:19:10 +01:00
ac93598dd1 Fix #105011: Cannot remove user preset when its name is translated
The preset names were translated before building the UI. This meant
that the translated name was passed to the operator responsible for
deleting the preset file, instead of the original name.

Pull Request #105155
2023-02-24 03:39:08 -08:00
47d4ec5aef Fix #105011: Cannot remove user preset when its name is translated
The preset names were translated before building the UI. This meant
that the translated name was passed to the operator responsible for
deleting the preset file, instead of the original name.

Pull Request #105155
2023-02-24 12:00:19 +01:00
718f78cfca Sculpt: Fix #104618 (again).
SculptAttributeParams.stroke_only wasn't being
    applied to existing attributes properly.
2023-02-24 00:04:50 -08:00
cb7d450de6 Sculpt: Fix 104618: Topology automasking errors
Sculpt island tags are now invalidated whenever the PBVH
    is rebuilt.
2023-02-24 00:04:03 -08:00
0534fff5ab Sculpt: fix 104174, clicking over empty space always pushes undo.
This was actually caused by two problems.  The first is that the
    code actually deliberately detects if nothing happened and pushed
    an undo step, a bugfix for a problem that no longer exists.

    The second was that SCULPT_test_location sometimes does a closest
    point search instead of ray casting and didn't check the result
    against the brush radius.
2023-02-24 00:01:41 -08:00
e9bb3510a1 Sculpt: Fix #104475, data transfer not respecting vgroup for float colors
This might've been a merge error, the result of color mixing
    was being overwritten by a simple copy of source to destination
    inside of layerCopyValue_propcol.
2023-02-24 00:00:22 -08:00
2491cd5e16 Cleanup: Move two subdiv headers to C++ 2023-02-23 18:30:47 -05:00
cfb112edcb UI: Widen Search Boxes When Necessary
Make floating search boxes wider when there is a linked scene or are
otherwise showing more information than a simple list.

Pull Request #104603
2023-02-24 00:07:16 +01:00
470e8ce1f4 BLF: Revert Glyph Clipping Changes
Revert #104679. We are just too used to the old behavior, especially
the incorrect vertical clipping. Some uses rely on setting the min and
max of the clipping rect the same. Will have to revisit this later
to only correct for horizontal positioning for full hinting.

Pull Request #105157

Own Code.
2023-02-23 23:44:17 +01:00
1b72712283 Fix: Global buffer overflow of enum property items on startup
RNA enum items arrays need to end with a null entry.
2023-02-23 15:53:10 -05:00
5b1f94f05a Fix: Use of uninitialized mesh size variables after recent cleanup 2023-02-23 15:52:42 -05:00
c065e8dd7f Merge branch 'blender-v3.5-release' 2023-02-23 15:31:29 -05:00
f9f29eefc7 Fix #105150: Mesh.vertex_colors.new() returns existing active layer
In 6514bb05ea I misinterpreted the function's intended
behavior when there was already an existing active layer. The data from
the active layer is just meat to be copied, the function should always
add a new attribute.
2023-02-23 15:30:27 -05:00
2bd097a58d Fix: Debug build failure and warnings after recent cleanup commit 2023-02-23 13:21:24 -05:00
4369627e71 Mesh: replace 'BKE_mesh_merge_verts' algorithm
Blender currently has 2 algorithms for merging vertices:
- `BKE_mesh_merge_verts`;
- `blender::geometry::create_merged_mesh`

`BKE_mesh_merge_verts` has a simplified algorithm to work with Array,
Mirror and Screw modifiers. It doesn't support merge results that would
create new faces. However it has shortcuts to be more efficient in
these modifiers.

`blender::geometry::create_merged_mesh` tries to predict all possible
outcomes. So it's a more complex. But it loses in performance to
`BKE_mesh_merge_verts` in some cases.

The performance comparison between these two depends on many factors.
`blender::geometry::create_merged_mesh` works with a context that has
only the affected geometry. Thus a smaller region of the mesh is read
for duplicate checking. Therefore, the smaller the affected geometry,
the more efficient the operation.

By my tests `blender::geometry::create_merged_mesh` beats
`BKE_mesh_merge_verts` when less than 20% of the geometry is affected
in worst case `MESH_MERGE_VERTS_DUMP_IF_EQUAL` or 17% in case of
`MESH_MERGE_VERTS_DUMP_IF_MAPPED` .

For cases where the entire geometry is affected, a 30% loss was noticed,
largely due to the creation of a context that represents the entire mesh.

Co-authored-by: Germano Cavalcante <germano.costa@ig.com.br>
Pull Request #105136
2023-02-23 19:10:01 +01:00
8e50539f1b Merge branch 'blender-v3.5-release' into main 2023-02-23 17:26:52 +01:00
a1f899754b Fix #105106: inconsistent order of settings in 3D viewport shading popover
Put compositing settings at the bottom for both Cycles and Eevee.
2023-02-23 17:24:45 +01:00
b88428a301 Fix: Frame Channel when using normalized view
When using the frame channel operators from #104523
the framing would fail under the following circumstance.
* In the graph editor
* Using normalized view
* with a curve that has a y-extent of less than the focus threshold of 0.01

The issue was the the clamping code was
before the normalization multiplication.

Pull Request #105121
2023-02-23 17:23:03 +01:00
8a8c1988bd Fix: Using "Frame Channel" in Dope sheet resets view to top
When using the "Frame Channel" operator in the Dope Sheet
the view would always go back to the top.

Fix it by copying the y bounds when in the Dope Sheet.

Pull Request #105123
2023-02-23 17:17:26 +01:00
cb62ab5b28 Cleanup: Access mesh edges, faces, and loops with spans
Using spans instead of raw pointers helps to differentiate ararys from
pointers to single elements, gives bounds checking in debug builds, and
conveniently stores the number of elements in the same variable.

Also make variable naming consistent. For example, use `loops` instead
of `mloop`. The plural helps to clarify that the variable is an array.

I didn't change positions because there is a type mismatch between
C and C++ code that is ugly to manage. All remaining code can be
converted to C++, then that change will be simpler.

Pull Request #105138
2023-02-23 17:14:03 +01:00
a74fd9f2ae Cleanup: Remove unnecessary copying of mesh data outside CustomData
This code seems to be left over from before edges, polys, and loops were
stored in CustomData. They are already copied by the CustomData copy
calls directly above, which already deal with every other layer.
2023-02-23 17:14:02 +01:00
1851a69014 Merge branch 'blender-v3.5-release' 2023-02-23 15:57:34 +01:00
763f1897c2 Fix #103865: keep IDProperties overridable when setting them with Python
Previously, the overridable status was lost when assigning a new value
to a custom property.

Pull Request #105130
2023-02-23 15:55:42 +01:00
6403bc28cd Merge branch 'blender-v3.5-release' 2023-02-23 15:16:33 +01:00
e2f0a63e55 Fix #105118: Wrong point size in sculpt density overlay
Missed the GPU_program_point_size call in acd5889e50
2023-02-23 15:15:35 +01:00
25a5ff7670 Merge branch 'blender-v3.5-release' into main 2023-02-23 14:57:40 +01:00
afd0ab5cce Vulkan: Initial VKUniformBuffer.
Only supports uploading data to a uniform buffer.
Requirement for push constants #104880.

Pull Request #105129
2023-02-23 14:51:34 +01:00
f5c0b2433f Vulkan: Resolve Builtin Uniform(Block).
Resolving builtin uniforms and uniform blocks when creating
shader interface. This maps builtin uniforms to uniforms
defined by the shader. Works the same as the OpenGL
builtin uniforms.

Pull Request #105128
2023-02-23 14:50:49 +01:00
dc9e0f300e GPU: Fix Potential Error in Builtin Resolution.
When using ShaderCreateInfo with builtin uniform(blocks) there are
cases where the current implementation could not find an existing
block. The reason is that it uses name matching and name matching
requires that the shader inputs are sorted based on the name hash.

This change fixes this by first for the sorting of the shader
inputs before resolving the builtins.

Pull Request #105127
2023-02-23 14:40:40 +01:00
4bfe4e5d49 Fix: Cycles display without OpenColorIO not working for Metal
Cycles fallback display shader previously did not use viewport.
This would crash or cause the display not to show when using
GPU backends other than OpenGL, if another display shader
was unavailable.

Now use ShaderCreateInfo for Cycles fallback display.

Authored by Apple: Michael Parkin-White

Ref #96261

Pull Request #104987
2023-02-23 14:25:08 +01:00
90f5b2f0ce Vulkan: Get access to physical device limits.
This patch will give access to the physical device limits
of the device associated with the context. In vulkan each
device has different limits and the application is
responsible to match these limits as the vulkan driver
just ignores calls that don't match these limits.

Those limits are GPUBackend specific and therefore are not
added to GPU_capabilities.

Pull Request #105125
2023-02-23 13:47:29 +01:00
fcdfc0a85b Fix #105089: Curves sculpt add creates invalid resolution
If the resolution attribute exists, it needs to be set to a non-zero
value for the newly added curves. While it might also make sense
to interpolate the value from neighbor curves, for now it's
simplest to just set it to the default value of 12.

Pull Request #105094
2023-02-23 13:46:39 +01:00
78a54f23db Merge branch 'blender-v3.5-release' 2023-02-23 13:30:53 +01:00
059ba28b29 Fix #105026: Texture space operators in transform menu
In curves edit mode, the "Move Texture Space" and "Scale Texture Space"
operators where shown in the "Curves > Transform" menu.

Since these are not implemented, the fix removes these operators
from the menu.
2023-02-23 13:30:15 +01:00
be777c9657 Fix: remove unnecessary assert
The code below has to handle the case when `sample_length` is greater
or equal to the total length already anyway, so we can just make that
a valid input. Currently, the snake hook brush for curves also makes
use of passing in larger sample lengths which current results in crashes
in debug builds.
2023-02-23 13:18:05 +01:00
e2ba7f902d Merge branch 'blender-v3.5-release' 2023-02-23 13:15:44 +01:00
2e7bd1dfb1 Fix #105044: Crash when rotating hair curves
When trying to rotate in curves edit mode using proportional editing
and connected only mode, Blender would crash.

This was because the `TransData` structs for disconnected elements
did not have the location field populated, resulting in a null pointer
access.

The fix skips these elements entirely using `TD_SKIP`.
2023-02-23 13:14:00 +01:00
f93f743ffc Fix #105043: Add shortcut for proportional editing 2023-02-23 12:24:23 +01:00
061d191677 Fix #105043: Add shortcut for proportional editing 2023-02-23 12:21:39 +01:00
c8ed48d5ca Merge remote-tracking branch 'origin/blender-v3.5-release' 2023-02-23 11:28:02 +01:00
f2250b7a5b Fix #105078: Regression: Memory leak in driver UI drawing code
Just a missing call to `MEM_freeN()`.

The issue was introduced in c592bff047.
2023-02-23 11:22:04 +01:00
482fb791ce Fix #105100: Metal using wrong kernels in multi-pass renders
This fixes issue [#105100](blender/blender#105100) where multi-pass renders can be incorrect due to kernels using stale specialisation constants (e.g. when rendering Pokedstudio).

This patch adds a new group of md5 hashes (`global_defines_md5`) to track whether the injected block of #defines is stale and regenerate the source string as appropriate. It also renames the existing group of md5 hashes from `source_md5` to `kernels_md5` to clarify that these refer to a specific kernel set rather than just the source (which might build an arbitrarily large number of kernel sets).

Pull Request #105103
2023-02-23 11:07:28 +01:00
4cd00b1a71 Merge branch 'blender-v3.5-release' 2023-02-23 10:44:54 +01:00
e410fb4d3c Fix #105067: Error drawing Copy Rotation Constraint UI
The translation contexts module wasn't imported after c7611d61e8,
which caused an error and prevented some constraints' UI from being
displayed.

Pull Request #105095
2023-02-23 10:42:03 +01:00
7267682017 Animation: Paste Keys in Graph Editor with value offset
Extend the `GRAPH_OT_paste` operator with an enum to define the value offset.

Options are:

| Option              | Effect                                                                        |
| ------------------- | ----------------------------------------------------------------------------- |
| No Offset           | use the same key values as the copied keys                                    |
| Cursor Value        | align the leftmost key with the cursor value                                  |
| Current Frame Value | Evaluate the curve under the cursor align the leftmost key with it            |
| Right Key           | Align the rightmost key with the first key that is to the right of the cursor |
| Left Key            | Align the leftmost key with the first key that is to the left of the cursor   |

Pull Request #104512
2023-02-23 09:46:47 +01:00
8756671084 Animation: Add Slider operators to hotkey menu
Before that patch, the slider operators for the Graph Editor are not easily accessible since they don't have a hotkey.
This adds the "d" hotkey for the already existing slider operator menu.

Using the popup menu means that your last used operator will always be under the cursor, so it's quick to access.

Pull Request #104530
2023-02-23 09:29:18 +01:00
ddcf718640 Sculpt: Fix #104475, data transfer not respecting vgroup for float colors
This might've been a merge error, the result of color mixing
was being overwritten by a simple copy of source to destination
inside of layerCopyValue_propcol.
2023-02-22 23:31:44 -08:00
45731fd987 Refactor: Weight Paint Select Linked Faces
When implementing the operator to select linked vertices in weight paint mode, the new `AtomicDisjointSet` was used.
In order to keep the code consistent, and also prepare it to add things like Extending/Shrinking selection, the select linked faces logic was also updated.

It now also makes use of the `AtomicDisjointSet` by connecting all edges of each poly. In order to find connecting Faces you then have to check if edges of that poly share a connection.

Pull Request #104577
2023-02-23 08:26:32 +01:00
2c391f8877 GPU: Patch GPencil shader for metal support.
The stoke shader of grease pencil uses a geometry shader stage. Apple
devices don't support shaders with geometry shader stage. In the
OpenGL driver there was a pass-through implemented so it didn't fail.

When using the metal backend this needs to be solved more explicitly.
This change patches the grease pencil shader to support both the
backends supporting a geometry stage and those without.

Fixes #105059

Pull Request #105116
2023-02-23 08:26:01 +01:00
4eb90fc15c Sculpt: Fix #104618 (again).
SculptAttributeParams.stroke_only wasn't being
applied to existing attributes properly.
2023-02-22 23:04:53 -08:00
7f256e0d33 Sculpt: fix 104174, clicking over empty space always pushes undo.
This was actually caused by two problems.  The first is that the
code actually deliberately detects if nothing happened and pushed
an undo step, a bugfix for a problem that no longer exists.

The second was that SCULPT_test_location sometimes does a closest
point search instead of ray casting and didn't check the result
against the brush radius.
2023-02-22 22:37:28 -08:00
e497a50aa2 Merge branch 'blender-v3.5-release' 2023-02-22 21:03:17 +01:00
c760248fc5 Metal: Improve AMD EEVEE Performance
Complex EEVEE nodegraphs, particularly those combining
multiple principledBSDF shader nodes have a tendancy
to require a large number of simultaneous live registers
due to function call depth. In some instances, this
causes substantial performance drop and corruption if
the stack gets too large.

To mitigate this, splitting calls to closure_eval such
that only a single individual closure is evaluated in each
call reduces the number of live registers required. This
is preferred over using compound closure evaluation
functions which require a large amount of in-flight data.

Note that this is generally not more optimal, if the stack
does not spill, as there is an increased instruction count.
The specific trade-off depends on the exact architecture
in question. Hence, this is limited to AMD GPUs.

Authored by Apple: Michael Parkin-White

Ref #96261
Pull Request #104985
2023-02-22 20:57:24 +01:00
8693f1fdd2 Merge branch 'blender-v3.5-release' 2023-02-22 13:36:04 -05:00
defd95afcd Win32: Auto-Raise and -Focus Windows on Hover
On the Windows platform, raise windows and give them focus as the mouse
hovers over them. This allows keyboard shortcuts for the area under the
mouse without having to click the window caption to make them active.

Pull Request #104681
2023-02-22 10:26:43 -08:00
11766574a4 Fix #104842: Incorrect cyclic curve parameter node factor
66dda2b902 made an incorrect change to account for the special
case for NURBS. Instead, make the step that turns the lengths into
parameters more explicit, and pass the correct total length for each
curve, even in the cyclic case.

Pull Request #105079
2023-02-22 13:16:30 -05:00
8b45f583a2 Fix: No default for NURBS weights in realize instances and join nodes
This resulted in disappearing NURBS curves when joining them with other
curve types in some cases. The attribute has to be handles similarly to
the radius and resolution attributes rather than as simple generic data.
2023-02-22 13:10:29 -05:00
4ba73b50d0 Fix: Set curve type node creates unnecessary nurbs weight attribute
The attribute was retrieved when converting to Bezier curves when it
wasn't necessary. Instead copy it like a regular attribute if any of the
result curves are NURBS. Also fix a check for an empty span for the
attribute which was never false.
2023-02-22 13:10:29 -05:00
54fa3b124f BLF: Glyph Clipping Corrections
Improvements to how glyphs are tested against the font clipping rect.

Pull Request #104679
2023-02-22 10:00:37 -08:00
967662eda4 Merge branch 'blender-v3.5-release' 2023-02-22 18:50:54 +01:00
6466c247c9 Fix: Overlay regression after d165d6aa2a 2023-02-22 18:50:04 +01:00
acd5889e50 Fix #105042: Regression: Sculpt density overlay not working
Fix regression after d165d6aa2a
2023-02-22 18:49:47 +01:00
915e436574 Merge branch 'blender-v3.5-release' 2023-02-22 18:43:17 +01:00
423291eaf2 Fix #102882: Geometry Nodes: crash when using viewer in invalid group
Invalid node trees (e.g. when nodes are linked in a cycle) can not be
evaluated and the viewer is not available in them. This commit just adds
some null checks to handle this case more gracefully.
2023-02-22 18:42:15 +01:00
775b51a847 Merge branch 'blender-v3.5-release' 2023-02-22 17:38:59 +01:00
cbb4f8a9ba UI: Add color selector to Bone Groups list
Expose the color selector on each item in the list, so it's easier to see
at a glance the Bone Groups color theme and change it.

Also avoids having color widgets grayed out when not in Custom Colors mode.

Pull Request #105036
2023-02-22 17:34:44 +01:00
18614b6b0b Fix #103269: node group asset description not showing as tooltip in the Add menu
Pull Request #104968
2023-02-22 17:33:04 +01:00
Sonny Campbell
1b7076bd4f USD import: extract read_mesh params into a struct.
This is a small initial refactor to extract the
USDGeomReader::read_mesh parameters into a separate struct.
This will allow for adding extra parameters to handle importing
velocities for #104462 which was brought over from

https://archive.blender.org/developer/D15430

Original patch was being reviewed here:

https://archive.blender.org/developer/D15435

Pull Request 104459
2023-02-22 11:22:48 -05:00
d58e422ac3 UI: Properly cancel dragging on escape or right-click
This is refering to drag & drop within Blender which is using the
drop-box system.

Previously Escape would cancel the dragging, but still pass on the event
to other event handlers, which could trigger other behavior. For example
cancelling dragging a file in a file browser dialog would also cancel
the file browser operation and close the window. Right-click didn't
cancel anything even though we usually use both Escape and right-click
as a way to cancel the operation.

Now both escape and right-click both cancel the dragging and the event
is not passed on further.

Pull Request: #104838
2023-02-22 16:54:07 +01:00
11f52a4017 Cleanup: Remove wrapper functions in spline parameter node
Do the domain check directly in the field input class to avoid the need
for another function to do it elsewhere. Also move one function to
be closer to a similar one, rename some functions, and avoid the need
for two intermediate span variables.
2023-02-22 10:41:11 -05:00
629fe69c4c Fix #104918: EEVEE: Resolve cache warming assertion.
Erroneous cache warming case where the generated material is
identical to default material and cached shader is re-used,
resulting in case where the parent shader is identical to the
source.

Authored by Apple: Michael Parkin-White

Ref #96261
2023-02-22 16:37:00 +01:00
d6a61bc864 Merge branch 'blender-v3.5-release' 2023-02-22 15:27:57 +01:00
acfafeed88 Fix #103761: creating a color attribute doesn't make it active
Originally caused by 6514bb05ea

More cases where the active/default color attributes were not set
correctly:

[1] Using the old Python vertex_colors API (vertex_colors.new)
[2] OBJ importer
[3] Collada importer
[4] Data Transfer layout (both standalone operator and "Generate Data
    Layers" from the modifier)

Similar to 101d04f41f.

Brought over from https://archive.blender.org/developer/D16977, see
discussion there why some of the code for data transfer is not for the
genereal attribute API.

Pull Request #105020
2023-02-22 15:18:15 +01:00
8c03410ebd Vulkan: Refactor shader interface.
Descriptor set locations are now determined in the
VKShaderInterface. Issues with the previous solution:

- Due to legacy code in GPU module the locations/bindings
  must be the same. Using one for something else might
  result in undesired lookups, incorrect resource
  bindings.
- Images/Textures reuses the same namespace, that didn't
  work as expected when looking up the resources via
  its binding.

This refactoring is required for adding support for
push constants.

Pull Request #105073
2023-02-22 14:42:01 +01:00
709013dca4 Cleanup: Move rna_access.c to C++
See #103343

Pull Request #105060
2023-02-22 14:04:57 +01:00
140a663f6f Cleanup: Move area.c to C++
See #103343

Pull Request #105061
2023-02-22 14:04:23 +01:00
e1f6587f12 VSE: Add retiming tool
This tools allows to change strip playback speed by manipulating
retiming handles. More handles can be added to single strip to create
variable playback speed.

This tool replaces Speed Factor property in time panel, with exception
of sound strips. Support for sound strips is still in review.

Pull Request #104523
2023-02-22 13:16:32 +01:00
50ebe21dd3 Merge branch 'blender-v3.5-release' 2023-02-22 11:37:42 +01:00
e5a0a14a27 Fix #101518: Curves sculptmode Stabilize Stroke misses indicator line
Drawing code `paint_draw_smooth_cursor` would be called correctly, it
was just the color not being initialized.

This is usually done with `BKE_paint_init`, but in the case of curves
sculpting brushes this would create an additional (unnamed) brush which
should be avoided since the workspace toolsystem creates the "right"
brush anyways.

So this patch just does the minimal work to get the Stabilize Stroke
indicator line to draw (which is initializing the color).

Brought over from https://archive.blender.org/developer/D16793

(cherry picked from commit 612a4382c443bcd02e0bb5ffd1b1fdbb251f6e7b)

Pull Request #105021
2023-02-22 11:31:40 +01:00
ad124d15e2 Merge remote-tracking branch 'upstream/blender-v3.5-release' 2023-02-22 10:05:03 +01:00
14368f4d09 Fix/Update to the i18n module settings after git submodule changes. 2023-02-22 10:02:27 +01:00
612965497e Curves: Avoid unnecessary allocation when calculating offsets
Arrays for curve handle types were allocated even when there were no
Bezier curves. This saves 0.5ms of the total 0.9ms spent creating the
evaluated curve offsets, which happens every time the topology
of non-poly curves change.
2023-02-21 22:32:36 -05:00
05637254da Cleanup: Use simpler syntax to return panel open status 2023-02-21 21:45:41 -05:00
8b63966236 Revert 104438: Windows Spanning Multiple Monitors
Revert of commits that allowed non-temp Blender windows to be saved
and restored that spanned multiple monitors on the Windows platform.
This causes problems with temp windows (like Preferences & Render) that
cannot currently be fixed.

See 104956 for much more details.

This change is being redone after it was accidentally reverted.

Differential Revision: blender/blender#104956

Reviewed by Ray Molenkamp
2023-02-21 15:45:45 -08:00
b874a0ead8 msgfmt: fix runtime requirements
msgfmt has a TBB dependency though bf_blenlib, now for a release build
The MSVC linker is smart enough to realize none of the TBB code is
actually used and discards it. In debug mode the linker is a bit more
conservative and doesn't, leaving msgfmt with a runtime dependency
on TBB. The problem here is, we only copy the runtime dlls during
the install phase, and msgfmt runs long long before that.

For this reason when we run msgfmt we should make sure any runtime
needs it could have are met in the path, there already is a handy
variable for that since oslc has similar requirements.

Pull Request #105048
2023-02-21 23:00:34 +01:00
7216eb8879 UI: UIList Hover Highlighting
Add mouse hover highlighting for items in UILists, in both list mode
and preview tile mode.

See 104677 for more details

Differential Revision: blender/blender#104677

Reviewed by Brecht Van Lommel
2023-02-21 13:03:17 -08:00
ac160a270f Merge branch 'blender-v3.5-release' 2023-02-21 19:29:13 +01:00
6693c50ace Fix #104947: Missing depsgraph update on UV map deletion
Since changing UV map deletion to be handled via the attribute api,
the object wasn't tagged for depsgraph updating.

Pull Request #105040
2023-02-21 19:27:23 +01:00
e82d4f1f93 Merge branch 'blender-v3.5-release' 2023-02-21 18:41:43 +01:00
e28a9a87c9 Fix references to the /release/scripts directories
Those were moved to the /scripts
2023-02-21 18:40:47 +01:00
720dbea429 Fix #104902: Use forward compatible integers for boolean RNA properties
Write RNA properties backed by IDProperties with the `IDP_INT` type like
before ef68a37e5d. That keeps forward compatibility, because
earlier versions don't support the boolean type. At some point in a future
release we can remove the forward compatibility. 4.0 is a good time to
do that because forward compatibility will be broken in other ways.

This commit also adds support for reading integer arrays for boolean
property defaults, which was only half-way supported before.

Pull Request #104995
2023-02-21 11:59:15 -05:00
1b96dd535a Merge branch 'blender-v3.5-release' 2023-02-21 17:20:34 +01:00
d355f3ed2b Cleanup: Spelling in warning message 2023-02-21 17:20:03 +01:00
78825783cc Merge branch 'blender-v3.5-release' 2023-02-21 17:18:47 +01:00
144f74230f Make update: Fix empty message of "Blender repository skipped" 2023-02-21 17:17:46 +01:00
ade37c0212 Merge branch 'blender-v3.5-release' into main 2023-02-21 17:13:43 +01:00
46153f1898 Fix #104899: Gpencil rotation of dots fails using subdivision
The values were not calculated in the subdivision modifier.
2023-02-21 17:12:27 +01:00
996eb1bd5f Cleanup: Remove unused UV map deletion functions
The attribute API is now used instead.
2023-02-21 10:53:29 -05:00
7fe42ea566 Merge branch 'blender-v3.5-release' 2023-02-21 16:50:35 +01:00
dd65e9901f Fix Light Tree option causing wrong renders on macOS AMD
The light tree itself is disabled on the AMD GPUs due to a compiler issue.

There are couple of places where this was not fully checked:

- The `light_sample` function in the kernel.
- The light threshold during synchronization

The former one is solved as easy as just adding an ifdef block.
The latter one is solved by delaying the threshold assignment for
later on.

Pull Request #105022
2023-02-21 16:50:06 +01:00
b02778147d Merge branch 'blender-v3.5-release' 2023-02-21 10:46:45 -05:00
d1b6f16906 Fix #104980: Apply All Shape Keys operator not working
Caused by inverted arguments to `memcpy` in 1af62cb3bf.
Replace with use of spans to make the copying direction more obvious.
2023-02-21 10:43:15 -05:00
ecb88eff7e Merge branch 'blender-v3.5-release' 2023-02-21 16:41:47 +01:00
03806d0b67 Re-design of submodules used in blender.git
This commit implements described in the #104573.

The goal is to fix the confusion of the submodule hashes change, which are not
ideal for any of the supported git-module configuration (they are either always
visible causing confusion, or silently staged and committed, also causing
confusion).

This commit replaces submodules with a checkout of addons and addons_contrib,
covered by the .gitignore, and locale and developer tools are moved to the
main repository.

This also changes the paths:
- /release/scripts are moved to the /scripts
- /source/tools are moved to the /tools
- /release/datafiles/locale is moved to /locale

This is done to avoid conflicts when using bisect, and also allow buildbot to
automatically "recover" wgen building older or newer branches/patches.

Running `make update` will initialize the local checkout to the changed
repository configuration.

Another aspect of the change is that the make update will support Github style
of remote organization (origin remote pointing to thy fork, upstream remote
pointing to the upstream blender/blender.git).

Pull Request #104755
2023-02-21 16:39:58 +01:00
92dc89e28a Fix tests for macOS storage_apple.mm functions.
Pull Request #105000
2023-02-21 16:06:42 +01:00
6a5caf9d88 Vulkan: Fix mismatch in shader and resource types. 2023-02-21 15:36:11 +01:00
e9f8020f75 Cleanup: added empty line between methods. 2023-02-21 15:36:11 +01:00
a55e38e05d Fix duplicated code after merge from release branch
a280554b75 was committed to fix this in main, b5fa180d5d for the release
branch. Only one is needed though :)
2023-02-21 15:27:51 +01:00
7fb1f060ff Vulkan: Initial Compute Shaders support
This patch adds initial support for compute shaders to
the vulkan backend. As the development is oriented to the test-
cases we have the implementation is limited to what is used there.

It has been validated that with this patch that the following test
cases are running as expected
- `GPUVulkanTest.gpu_shader_compute_vbo`
- `GPUVulkanTest.gpu_shader_compute_ibo`
- `GPUVulkanTest.gpu_shader_compute_ssbo`
- `GPUVulkanTest.gpu_storage_buffer_create_update_read`
- `GPUVulkanTest.gpu_shader_compute_2d`

This patch includes:
- Allocating VkBuffer on device.
- Uploading data from CPU to VkBuffer.
- Binding VkBuffer as SSBO to a compute shader.
- Execute compute shader and altering VkBuffer.
- Download the VkBuffer to CPU ram.
- Validate that it worked.
- Use device only vertex buffer as SSBO
- Use device only index buffer as SSBO
- Use device only image buffers

GHOST API has been changed as the original design was created before
we even had support for compute shaders in blender. The function
`GHOST_getVulkanBackbuffer` has been separated to retrieve the command
buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order
to do correct command buffer processing we needed access to the queue
owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles`
function.

Open topics (not considered part of this patch)
- Memory barriers & command buffer encoding
- Indirect compute dispatching
- Rest of the test cases
- Data conversions when requested data format is different than on device.
- GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices.
  NVIDIA doesn't seem to support 1d textures.

Pull-request: #104518
2023-02-21 15:04:52 +01:00
02c2970983 Cycles: add NanoVDB support for Metal on Apple Silicon
Contributed by Yulia Kuznetcova at Apple.

NanoVDB is patched to give add address spaces required by Metal. We hope that
in the future Metal will support the generic address space.

For AMD and Intel this is currently not available since it causes a performance
regression also on scenes without volumes.

Pull Request #104837
2023-02-21 15:03:52 +01:00
8b8d8acc84 Merge branch 'blender-v3.5-release' 2023-02-21 08:45:46 -05:00
3e721195b0 Fix #104975: Essentials assets missing from node link-drag search
Alternatively this could use `ASSET_LIBRARY_ALL` like
`add_node_search.cc`, but then it would need a different
method for skipping duplicate local assets.
2023-02-21 08:44:52 -05:00
b5fa180d5d Fix: Missing essentials path in internal assets function 2023-02-21 08:42:02 -05:00
68a8f96cca Merge branch 'blender-v3.5-release' 2023-02-21 13:21:13 +01:00
2fef2f707a Fix: Unable pick select first point/curve in Curves
Because of an off-by-one error, it was not possible
to select the fist point or curve using the pick_select
operator in the Curves object.
2023-02-21 13:20:47 +01:00
a280554b75 Fix new essentials asset library not being covered in library path query 2023-02-21 12:20:09 +01:00
a91c6e71db Brush: Add writing and reading ID preview for Brushes.
Mandatory change for the Brush Assets project, from quick test does not
seem to break anything (more) in existing 'old' brushes...

Re. #101908.

Pull Request #105016
2023-02-21 12:15:33 +01:00
fdf6252b5a Merge branch 'blender-v3.5-release' 2023-02-21 12:04:30 +01:00
6583acb880 Fix Cycles MetalRT access of macOS 11 features when unavailable
After recent changes in 2d994de.

Pull Request #104976
2023-02-21 12:03:21 +01:00
6eccea7a6f Gitea: more updates for new scoped label syntax 2023-02-21 11:16:52 +01:00
5b0cb65a56 Gitea: update for new scoped label syntax 2023-02-21 11:13:22 +01:00
8a135a9a5f Curves: Add cursor snapping support
This adds support for cursor snapping for the new curves object.

It implements a function `transverts_from_curves_positions_create` (to separate the logic from the `Curves` object type). That function is then C wrapped by `ED_curves_transverts_create` and finally used in `ED_transverts_create_from_obedit`.

Pull Request #104967
2023-02-21 11:04:40 +01:00
ad7f8a1fa5 Merge branch 'blender-v3.5-release' 2023-02-21 11:02:30 +01:00
33cbd063d3 Curves: Fix proportional editing not working
This adds proper support for proportional editing for the Curves object.

Co-authored-by: Hans Goudey <h.goudey@me.com>
Pull Request #104620
2023-02-21 11:01:30 +01:00
e1b58be9e2 Merge branch 'blender-v3.5-release' 2023-02-21 10:17:13 +01:00
5db40f5747 Cleanup: Mark overriden virtual call as such
Fixes the `-Winconsistent-missing-override` warning.

In theory the `virtual` is redundant in such case, but this is how
it is done in may other areas of USD code.

Pull Request #104977
2023-02-21 10:16:30 +01:00
c38cac9682 Merge branch 'blender-v3.5-release' into main 2023-02-21 10:05:50 +01:00
f1f3ff0237 Fix #104979: GPencil Dot-hash only affects first frame with Time mod
The active frame must be recovered using `BKE_gpencil_frame_retime_get`
2023-02-21 10:04:45 +01:00
4ab91dc0c9 Fix: Channel clamping when markers are used
Previously when markers were used, the newly introduced clamping code (#104516) would stop the last channel from being shown.

This patch fixes that by modifying the `v2d->tot.ymin` calculation.

This is a bit counterintuitive since the `v2d->tot` height is calculated in `action_draw.c`. But the advantage of doing it there is that it also works for the channels region.

Pull Request #104892
2023-02-21 09:23:59 +01:00
2d34a09043 Tests: Address imbuf_save failures on ARM64 builds
This does 2 things to address the ARM64 failures:
- Increases the threshold to be inline with what Cycles uses
- Disables the 2 problematic WebP variations (#105006 will track)
2023-02-20 21:36:19 -08:00
ece43dd716 Cleanup: format 2023-02-21 17:07:02 +13:00
7699c7407d Tests: Add tests for image format saving and loading
This adds saving and loading tests for our supported image formats.

**Saving - bf_imbuf_save.py**
There are 2 template images which are loaded anew for each file save
attempt.  One is an 8-bit RGBA image and the other 32-bit. This is
required as many formats use a variety of factors to determine which of
`ibuf->rect` or `ibuf->rectfloat` to use for processing.  The templates
are constructed to have alpha transparency as well as values > 1 (or
clamped to 1 for the case of the 8-bit template).

Test flow:
 - Load in an appropriate template image
 - Save it to the desired format with the desired set of options
 - Compare against the reference image

Notes:
 - 98 references are used totaling ~3.6MB
 - 10-12 second test runtime
 - Templates can be reconstructed with the create-templates.blend file

**Loading - bf_imbuf_load.py**
Test flow:
 - Load in each of the reference images
 - Save them back out as .exr
 - Save additional metadata to a secondary file (alpha mode, colorspace etc)
 - Compare the saved out .exr with another set of reference .exrs
 - Compare the saved out file metadata with set of reference metadata

Notes:
 - 98 exr references are used totaling ~10MB
 - 10-12 second test runtime as well

A HTML report is not implemented. The diff output organization is very
similar to the other tests so it should be somewhat easy to do in the
future if we want.

The standard set of environment variables are implemented for both:
BLENDER_TEST_UPDATE, BLENDER_VERBOSE, and BLENDER_TEST_COLOR

Pull Request #104442
2023-02-20 19:06:38 -08:00
ff3fd5f1ce Sculpt: Implement mesh filter cancel
Added new function sculpt_mesh_filter_cancel in sculpt_filter_mesh.cc
for cancelling mesh filters. It currently is unused pending a
revamped modal map for mesh filter (see pull req 104718).
2023-02-20 18:09:05 -08:00
3e049973ee BMesh: fix invalid existence check in BM_mesh_bm_to_me
Remember that the null customdata layer index is -1,
not 0.
2023-02-20 17:46:45 -08:00
07ae1feed2 Fix test
Pull Request #104934
2023-02-20 23:04:10 +01:00
ba6c9a6f59 BLI_math: fix parameter aliasing in mul_m3_series and mul_m4_series
No functional changes.
2023-02-20 23:04:10 +01:00
7c1e26dd64 Merge branch 'blender-v3.5-release' 2023-02-20 21:24:48 +01:00
5a86193b1c Fix #82936: Make Geometry Nodes modifier icon blue in outliner
In the outliner, the icons for modifiers are tinted blue. This didn't
work for the geometry nodes modifier icon.

Defining the icon with the macro `DEF_ICON_MODIFIER` also
defines the appropriate theme color so it's now tinted blue
when drawn in the outliner like the other modifier icons.

Pull Request #104957
2023-02-20 21:22:11 +01:00
cc925b9282 Nodes: Allow adding multiple search items per type in add menu
Add a per node type callback for creating node add search operations,
similar to the way link drag search is implemented (11be151d58).

Currently the searchable strings have to be separate items in the list.
In a separate step, we can look into adding invisible searchable text
to search items if that's still necessary.

Resolves #102118

Pull Request #104794
2023-02-20 19:17:03 +01:00
DESKTOP-ON14TH5\Sonny Campbell
ceba1854f9 BLI: add function for changing working directory
Add `BLI_change_working_dir(path)` to change the current working directory.

This change is required for adding USDZ support to Blender. When exporting to that format, we are required to do a weird change of directory because of a quirk with the USD library's USDZ functionality. If an absolute filepath is passed into the `UsdUtilsCreateNewUsdzPackage` function, the USDZ archive will store that full path.

macOS uses `NSFileManager` through some new Mac-only wrapper functions.

Ref #99807

Pull Request #104525
2023-02-20 15:58:38 +01:00
8abef86217 Merge branch 'blender-v3.5-release' 2023-02-20 15:37:02 +01:00
c7d7175270 Cleanup: Remove check for this pointer not being nullptr
The check was triggering the 'this' pointer cannot be null in
well-defined C++ code

We do not check for this pointer in any other areas. If it is
needed due to possible opaque pointer cast to the check prior
to the cast.

Pull Request #104974
2023-02-20 15:35:24 +01:00
9b7eb57cf7 Merge branch 'blender-v3.5-release' 2023-02-20 15:33:44 +01:00
46b9dbc3f8 Cleanup: Remove unused fields from ShadowPunctual
Pull Request #104973
2023-02-20 15:32:06 +01:00
5a85b62bbc Transform Gizmo: calculate matrix_offset when creating the gizmos
That way the `matrix_base` doesn't need to depend on the axis
simplifying the code.

This also fixes an issue in plane scaling gizmos with non-orthogonal
matrix.
2023-02-20 11:28:11 -03:00
82ab491ab5 Merge branch 'blender-v3.5-release' 2023-02-20 12:59:47 +01:00
5fd4d47206 Fix unused variable warnings in release build
The asserts are not needed in this case. Basically includes 77c273ee37,
but in the release branch there was a second one.
2023-02-20 12:56:12 +01:00
e55f8b0b52 Merge branch 'blender-v3.5-release' 2023-02-20 12:47:13 +01:00
c7611d61e8 I18n: add disambiguation contexts
After rBdb87e2a638f9, two contexts were missing:

- VirtualReality, to be used in an add-on
- Constraint, used in the constraints UI

The latter was actually used without being added, which caused errors.
It was reverted in rB31a640027982.
2023-02-20 12:45:00 +01:00
f2121d94bb I18n: make some boid physics messages translatable
A few UI messages were not extracted in the particle physics panels.
2023-02-20 12:32:12 +01:00
79c1dc65a7 I18n: write messages of the vertex group lock operator explicitly
The operator's description used a format string like:

```
BLI_sprintfN(TIP_("%s %s vertex groups of the active object"),
             action_str, target_str)
```

which is almost guaranteed to be impossible to properly localize to
some languages -- I know there are a couple of issues for French
already.

So instead of hoping formatting works, write all possible strings
explicitly, even if it looks stupidly verbose.
2023-02-20 12:22:52 +01:00
dfbbf411d9 Merge branch 'blender-v3.5-release' 2023-02-20 12:13:14 +01:00
248d81fcbf GPencil: Include UV information in simplify->sample modifier.
Simplify modifier sample mode didn't transfer UV parameters, now fixed.

(This is the corrected commit, previous one has multiple other commits merged.)

Pull Request #104964
2023-02-20 12:11:34 +01:00
c437a8aea8 Revert release branch only commit after merge
This is a revert of a revert, because the initial revert is only
supposed to be in the release branch.

This reverts commit 3eed00dc54.
2023-02-20 11:51:16 +01:00
74be1acc7a Merge branch 'blender-v3.5-release' 2023-02-20 11:35:11 +01:00
3eed00dc54 Revert "GPencil: Include UV information in simplify->sample modifier."
This reverts commit 19222627c6.

Something went wrong here, seems like this commit merged the main branch
into the release branch, which should never be done.
2023-02-20 11:20:07 +01:00
87e5d7212c Mac: Enable Metal as default gpu backend.
Currently Metal is more stable then the OpenGL backend on apple
devices. Also the Metal backend supports more features then the
OpenGL backend. For example the viewport compositor and rendering
of production files.

This has been validated with users and studios.

This patch will default to the Metal backend when starting
Blender 3.5 for the first time or when loading factory startup. It
is still possible to switch to OpenGL via the user preferences.

It will not automatically select the Metal backend when there is
already user preferences available for Blender 3.5.
2023-02-20 11:03:11 +01:00
c25c46b77b Merge branch 'blender-v3.5-release' 2023-02-20 10:56:00 +01:00
25e57c39b1 Fix 104920: crash when creating node group from script node 2023-02-20 10:49:55 +01:00
488a757c83 Icons: Minor maintenance for the icons source SVG
No design or functional changes. Just rename the layers for the last
two icons that were added so that they follow the naming pattern.
Also, update the layer order for another icon (was not alphabetic).

Pull Request #104954
2023-02-20 10:41:31 +01:00
74bf0c834b Python: Add scissor functions to gpu.state.
This is a missing part of the Metal backend. Metal backend doesn't
support the bgl commands, but it was not possible to use the gpu
module to use scissor testing.

Without this change addon developers would not be able to migrate
their addons to support the Metal backend.

This patch adds:
- `gpu.state.scissor_set`
- `gpu.state.scissor_get`
- `gpu.state.scissor_test_set`

Fix #104911
2023-02-20 09:13:20 +01:00
695b6e3ede Sculpt: Fix workflow issue VDM textures.
Texture clamping is by default off, but for VDM textures this leads
to several artifacts.
- Clamping is done when the image is sampled and when the brush strenght
  is applied.
- VDM textures have negative values that are lost due to clamping
  when clamping during sampling.

This patch fixes this by changing the default clamping of newly
created textures to not clamp anymore.

Textures are mostly being used by sculpt brushes, where clamping is also
implemented on brush level.

Fix #104747
2023-02-20 08:07:55 +01:00
e1e2dae317 Revert 104438: Windows Spanning Multiple Monitors
Revert of commits that allowed non-temp Blender windows to be saved
and restored that spanned multiple monitors on the Windows platform.
This causes problems with temp windows (like Preferences & Render) that
cannot currently be fixed.

See 104956 for much more detail

Differential Revision: blender/blender#104956

Reviewed by Ray Molenkamp
2023-02-19 19:28:08 +01:00
19222627c6 GPencil: Include UV information in simplify->sample modifier.
Simplify modifier sample mode didn't transfer UV parameters, now fixed.

Pull Request #104942
2023-02-19 11:45:22 +01:00
e61566137b Merge branch 'blender-v3.5-release' 2023-02-18 16:44:25 +11:00
46e13cf8a5 Fix #104817: Camera lens gizmo out of sync when navigating via gizmos
Regression in [0] which caused interacting with 2D gizmos not to
update 3D gizmos once the gizmo finished it's modal interaction.

This caused the cameras lens gizmo not to update when navigating using
the viewport navigation buttons.

Resolve by detecting this case and flagging other draw steps to be
updated.

[0]: fb27a9bb98
2023-02-18 16:38:36 +11:00
cc4587a9b4 Merge branch 'blender-v3.5-release' 2023-02-18 05:14:33 +01:00
5cd2be7d54 Fix #104806: Graphical glitches in VSE timeline region
Region background was drawn, but color was set to fully transparent.
2023-02-18 05:09:17 +01:00
be9104f7aa Cleanup: spelling, capitalize tags, use C-style comments & clarification 2023-02-18 14:33:28 +11:00
6bd058189c Cleanup: quiet mypy warnings 2023-02-18 14:22:34 +11:00
162e6c7951 Fix error in project_info when make wasn't found
The warning referenced an undeclared variable.
2023-02-18 14:21:56 +11:00
da9dff053e Build: fix error building xvidcore on Linux
The file renaming seems only to be needed on Windows,
so don't attempt it on other platforms.
2023-02-18 14:10:59 +11:00
d9398bb53f Fix #104188: Screw modifier edges invisible in edit mode wireframe view
Caused by 25237d2625, when the new "template" mesh created
in the modifier started to use the proper default value for CD_ORIGINDEX
layers rather than just zero. Zero isn't correct because it refers to
the first element, not "no element". For that we need to remove the
original index mapping arrays completely. There is some gray area
about whether that is allowed too, but it's best here to just keep the
old behavior working for now.
2023-02-17 16:24:49 -05:00
2ee5560b3f Spreadsheet: Add original indices to mesh debug information
Add the `CD_ORIGINDEX` layer to the columns potentially displayed
with the Blender debug value of 4001 from the debug menu. Also
separate the debug columns to separate functions.
2023-02-17 16:24:49 -05:00
2cd7e70c18 Fix #104604: Potential crash when relinking node links
In the first loop is safe to remove the current element.
The second loop can remove any element, potentially the next.
This triggers a read after freed.

Pull Request #104897
2023-02-17 21:23:35 +01:00
dd2ab55507 Fix 104816: Ensure Win32 visible title bar
When creating Win32 windows, ensure that the caption bar is visible.

Differential Revision: blender/blender#104848

Reviewed by Ray Molenkamp
2023-02-17 20:11:44 +01:00
8806d7551d Merge branch 'blender-v3.5-release' 2023-02-17 13:54:16 -05:00
8b416f7f60 Fix #104869: Crash converting UV maps to legacy format
When the new UV to legacy format conversion happens, the mesh is in
the middle of being written and is an at best "complicated", at worst
invalid state. The attribute API looks at other domains and is a bit
less forgiving in that respect, and shouldn't really be used here. Use
the CustomData API instead. Also sort the layers the same way as
b642dc7bc7.
2023-02-17 13:41:44 -05:00
d6774174e9 Fix compile error due to previous changes 2023-02-17 19:14:47 +01:00
4b6ce4512c Merge remote-tracking branch 'origin/blender-v3.5-release' 2023-02-17 18:50:52 +01:00
d891b38776 Fix #104850: Create Geometry Nodes operators fails if not in English
Note that the node group has its sockets names translated, while the
built-in nodes don't. So we need to use data_ for the built-in nodes
names, and the sockets of the created node groups.

Pull Request #104889
2023-02-17 18:49:36 +01:00
4ec9aff2af Revert "Fix #104850: Create Geometry Nodes operators fails if not in English"
This reverts commit 68181c2560.

I merged 3.6 into 3.5 by mistake. Basically I had a PR against main,
 then changed it in the last minute to be against 3.5 via the
 web-interface unaware that I shouldn't do it without updating the
 patch.

 Original Pull Request: #104889
2023-02-17 18:45:42 +01:00
68181c2560 Fix #104850: Create Geometry Nodes operators fails if not in English
Note that the node group has its sockets names
translated, while the built-in nodes don't.

So we need to use data_ for the built-in nodes names,
and the sockets of the created node groups.

Pull Request #104889
2023-02-17 18:39:17 +01:00
d7dd7ee24c Animation: Add "Frame Channel" operators
When animating it is often useful to frame the Graph Editor/Dope Sheet to whatever frames are in a given channel.
This patch adds the option to frame on selected channels OR frame on whatever channel is under the cursor.

If a preview range is set it will only focus on keys in that range.

Supports FCurve and keyframe data

Frame to selected is called with
* Right click in the channel section -> Frame Selected Channels
* or in Channel → Frame Selected Channels
* or hitting . on the numpad

Frame to channel under cursor is done with

ALT + Middle Mouse Button

Co-authored-by: Christoph Lendenfeld <chris.lenden@gmail.com>
Pull Request #104523
2023-02-17 18:10:58 +01:00
e95ba8a70e Nodes: Add 'Online Manual' to context menu
Finding the documentation for nodes can be time consuming.
By adding the online manual to the right click context menu in the node
editor the user gets easier access to the documentation.

Can also be used by custom nodes add-ons by registering a manual-map.

Pull Request #104833
2023-02-17 16:59:30 +01:00
a797c0c05c Merge branch 'blender-v3.5-release' 2023-02-17 16:44:32 +01:00
64189ea52f UI: "vertex keys" -> "shape keys"
These are generally referred to as "shape keys"

Pull Request #104887
2023-02-17 16:43:26 +01:00
0e4312ceec Merge branch 'blender-v3.5-release' 2023-02-17 16:33:59 +01:00
2753cc6e39 Fix: python error in Particle Properties without a psys
Code added in 94a54ab554 wasnt checking if there was a particle system
on the object at all.

Pull Request #104819
2023-02-17 16:32:37 +01:00
08f24553dc Cleanup: Remove accidentally merged TODO comment 2023-02-17 15:05:39 +01:00
9b129e5533 Fix #104347: Loop Cut Tool becomes impressive with GPU Subdivision
When updating a mesh, the GPU Subdivision code makes calls to
`GPU_indexbuf_bind_as_ssbo()`.

This may cause the current VAO index buffer to change due to calls from
`glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id_)` in
`GPU_indexbuf_bind_as_ssbo()`.

The solution is to unbind the VAO (by calling `glBindVertexArray(0)`)
before creating the index buffer IBO.

Co-authored-by: Germano Cavalcante <grmncv@gmail.com>
Pull Request #104873
2023-02-17 10:53:39 -03:00
7838eb12c6 Merge branch 'blender-v3.5-release' 2023-02-17 14:37:35 +01:00
54b1e71dda Make update: Allow amd64 architecture
Apparently, the 65bit Intel architecture is presented differently
on Linux and Windows.

Allow both variants for the command line, so that semantically the
command line argument can be seen as a lower case platform.machine.
2023-02-17 14:35:53 +01:00
69677827ff Fix #104347: Loop Cut Tool becomes impressive with GPU Subdivision
When updating a mesh, the GPU Subdivision code makes calls to
`GPU_indexbuf_bind_as_ssbo()`.

This may cause the current VAO index buffer to change due to calls from
`glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id_)` in
`GPU_indexbuf_bind_as_ssbo()`.

The solution is to unbind the VAO (by calling `glBindVertexArray(0)`)
before creating the index buffer IBO.

Co-authored-by: Germano Cavalcante <grmncv@gmail.com>
Pull Request #104873
2023-02-17 14:30:29 +01:00
42f636f7e8 Merge branch 'blender-v3.5-release' 2023-02-17 13:43:17 +01:00
60abeddc55 Make update: Add --architecture command line attribute
Possible values are x86_64 and arm64.

Allows to use make_update.py in a cross-compile environment, like
building x86_64 macOS Blender from Apple Silicon machine.

Pull Request #104863
2023-02-17 13:42:15 +01:00
cb95f8aea7 Animation: Clamp V2D so keyframes cannot go offscreen
In the Dope Sheet and the Timeline, it was possible to drag the view until the keyframes were completely out of view.
(Important to drag in the region with the keyframes, dragging in the channel box already did clamping)

This patch adds a clamping mechanism matching that of the channel box. That means the last channel will stick to the bottom of the view.

Co-authored-by: Christoph Lendenfeld <chris.lenden@gmail.com>
Pull Request #104516
2023-02-17 12:47:45 +01:00
d4480fdfa3 Merge branch 'blender-v3.5-release' 2023-02-17 11:45:49 +01:00
6ffaee8d9a Fix #95400: Crash when running Euler Filter on baked Curves
Fix a crash when using the Euler Filter from the Graph Editor on baked curves.

The crash happened because baked curves have no bezt array.
Skipping any curves where that was missing fixes the issue.

Co-authored-by: Christoph Lendenfeld <chris.lenden@gmail.com>
Pull Request #104858
2023-02-17 11:45:11 +01:00
bf7ccd43ca Cleanup: use PI and PI/2 in compatible_eul
3.2 and 1.6 where used as rough equivalents to M_PI & M_PI_2, however
this raised questions about the significance of these values.

Running thousands of tests with generated euler inputs I wasn't able to
detect a difference so use M_PI & M_PI_2 instead.
2023-02-17 21:18:30 +11:00
773903f43c Docs: add doc-string for compatible_eul & improve code-comments 2023-02-17 21:18:30 +11:00
9b3ce950e6 Fix #95400: Crash when running Euler Filter on baked Curves
Fix a crash when using the Euler Filter from the Graph Editor on baked curves.

The crash happened because baked curves have no bezt array.
Skipping any curves where that was missing fixes the issue.

Co-authored-by: Christoph Lendenfeld <chris.lenden@gmail.com>
Pull Request #104858
2023-02-17 11:05:57 +01:00
f6c6805226 Merge branch 'blender-v3.5-release' 2023-02-17 10:56:41 +01:00
a4b92a6814 Fix #104829: Clip editor has poor performance when Metadata panel is closed
According to the report it is a regression since 3.2, but it is tricky
to pin-point which exact commit caused it.

The root of the issue is that under certain circumstances frame might
be read and processed twice, depending on the order in which panels and
the main area is drawn: the footage information panel skips cache, so
it it is drawn prior to the main area it leads to 2 frame reads. Opening
the Metadata panel triggers code path which forces frame to be put to
the cache, solving the double frame read.

Solution is simple: do not skip cache when acquiring image buffer for
the footage information: the same frame will be needed for the main
area as well.

Pull Request #104860
2023-02-17 10:56:10 +01:00
932148ec54 Merge branch 'blender-v3.5-release' 2023-02-17 10:15:28 +01:00
09b9106e3d Make update: Use BKE_blender_version to detect release branches
On a user level there are no expected changes, other than being able
to update submodules and libraries from a main repository at a detached
HEAD situation (which did not work before).

On the infrastructure level of things this moves us closer to ability
to use the main make_update.py for the buildbot update-code stage, and
to remove the update-code section from the pipeline_config.yaml.

The initial idea of switching make_update to the pipeline config did
not really work, causing duplicated work done on blender side and the
buildbot side. Additionally, it is not easy to switch make_update.py
to use pipeline_config.yaml because the YAML parser is not included
into default package of Python.

There will be few more steps of updates to this script before we can
actually clean-up the pipeline_config: the changes needs to be also
applied on the buildbot side to switch it to the actual make_update.

Switching buildbot to the official make_update.py allows to much more
easily apply the submodules change as per #104573.
2023-02-17 10:04:37 +01:00
0250b40750 Cleanup: Silence compiler warning in VKShader. 2023-02-17 09:54:57 +01:00
c6ea00de3c BLI_math: correct the threshold for wrapping rotation in compatible_eul
Having a threshold well above PI would result in discontinuity in some
cases.

The discontinuity can be measured by generating euler values (both
random and interpolated rotations), then comparing the accumulated
difference.
Changing the threshold for wrapping rotations produces at least as good
or more compatible results.

This was reported as #17297 and fixed in [0], however the change was
only applied for the game-engine.

Ref !104856

[0]: ab44742cf3
2023-02-17 19:52:15 +11:00
1a6943d553 Merge branch 'blender-v3.5-release' 2023-02-17 09:38:18 +01:00
c624e56ffc Fix #104810: Appending a camera does not pull in background movie clip
This was broken even before 0649e63716 and was always expanding the
`Image`, not the movie clip (even if the source was set to
`CAM_BGIMG_SOURCE_MOVIE`)

Now the rule here seems to be to always expand unconditionally, so
remove checking the source and always expand image and movie clip.

Co-authored-by: Philipp Oeser <philipp@blender.org>
Pull Request #104815
2023-02-17 09:36:16 +01:00
5de9a5dea5 Sculpt: Fix 104618: Topology automasking errors
Sculpt island tags are now invalidated whenever the PBVH
is rebuilt.
2023-02-16 22:37:20 -08:00
9808d6abd8 Cleanup: loop over axes in compatible_eul
There is no need to inline the loop.
2023-02-17 16:18:43 +11:00
6b84636ff2 Cleanup: unused warning 2023-02-17 16:18:31 +11:00
a52c0a252f Cleanup: fix warnings from last commit 2023-02-16 21:14:27 -08:00
c352eeb213 Sculpt: Add support for last operator panel to mesh filter operator
* Repeat last operator now works for mesh filters.
* Added an iteration_count property to repeat the filter.
  This is especially useful when compounded with the repeat
  last operator tool.
* The mouse event history is stored for mesh filters
  with more advanced user input (mostly Smooth and Relax
  filters).
2023-02-16 20:54:56 -08:00
ef60b13c1f Deps: Optimize meson based deps
meson defaults to debug builds [0] unless you tell it differently, this
diff changes the options for

- epoxy
- fribidi
- harfbuzz
- wayland
- wayland_protocols

to be optimized, mesa was already optimized

[0] https://mesonbuild.com/Builtin-options.html#core-options

Pull Request #104802
2023-02-17 01:43:25 +01:00
9c79875f65 Cleanup: use BitSpan instead of BitVector where possible
Passing a `BitSpan` is generally better because then the caller is not
forced to allocate the bits with a `BitVector`. Also, the `BitSpan` can
be stored in the stack, which removes one pointer indirection compared
to accessing bits through a `BitVector &`.
2023-02-17 00:47:02 +01:00
891f47b801 BLI: new bit span data structure
This adds `BitSpan` and `MutableBitSpan`. They work essentially the same as
the normal `Span` and `MutableSpan`, but work on individual bits instead
(the smallest type `Span` can handle is one byte large).

This also splits up `BLI_bit_vector.hh` and introduces two new headers:
`BLI_bit_ref.hh` and `BLI_bit_span.hh`.

The goal here is to make working with dynamically sized bit masks more
convenient. I'm mainly working on this because I might want to use this
in #104629. It can also be used to cleanup function signatures that
currently take a reference to a `BitVector`. Like with `Span` vs. `Vector`,
it is better to pass a `BitSpan` to function than a `const BitVector &`.

Unit tests for the new code are included.

Pull Request #104671
2023-02-17 00:42:44 +01:00
8094d389f7 Cleanup: format 2023-02-17 11:41:12 +13:00
09d3ebfd72 Merge branch 'blender-v3.5-release' 2023-02-16 17:00:18 -05:00
efc2e5134f Fix #104841: Split function for Cycles for sharp edges ignores attribute
Cycles uses the "split faces" mesh function to support sharp edges
and auto-smooth. However, 75ad8da1ea updated that
function to ignore the edges that are explicitly tagged as sharp and
only use the edge angle. Fix by taking the attribute into account too.
2023-02-16 16:59:58 -05:00
4ebb66864a Fix #104826: Mesh to BMesh with shape keys can corrupt layers
The custom data layer mappings from dfacaf4f40 were created
*before* the BMesh shape key layers were added, invalidating the BMesh
data offsets they stored. Fix by creating the mappings after all layers
have been created.
2023-02-16 16:30:59 -05:00
8a51d61b44 Merge branch 'blender-v3.5-release' 2023-02-16 15:20:00 -05:00
eb5fead5ac Fix: Use proper types in compare node link drag search options
Clean up logic to make it more clear and formalize the way to choose
fixed node data type based on operation. This make possible to more
easily fix wrong node data type for color type and less than ops.

Pull Request #104617
2023-02-16 15:18:56 -05:00
b2a536e9d7 Fix: Remove the rest of the tracks in the BKE_nlatrack_remove_and_free to free up the memory
Fix: The BKE_nlatrack_remove_and_free (#104752) unit test leaks a little memory. Cleaning up the rest of the track list to ensure everything is freed.
Co-authored-by: Nate Rupsis <nrupsis@gmail.com>
Pull Request #104839
2023-02-16 20:24:33 +01:00
77c273ee37 Fix unused variable in release builds
Assert is not needed in this case.
2023-02-16 18:57:50 +01:00
4cdf27cd96 Merge branch 'blender-v3.5-release' 2023-02-16 12:50:11 -05:00
9f41f95c8e Fix #104785: Quick fur keeps asset status of appended node groups
Use the recently added "clear_asset_data" option in the append operator.

Pull Request #104828
2023-02-16 18:14:47 +01:00
c2a0decbf3 Cleanup: Use Span to iterate over nodes instead of ListBase
Similar to 5b8e2ebd97.
2023-02-16 12:12:38 -05:00
851de8170d Cleanup: Nodes: Avoid unnecessary const cast, use early return 2023-02-16 12:11:20 -05:00
4e7a7e613a Cleanup: Fix operator description 2023-02-16 17:47:04 +01:00
bf5a89f4e0 Cleanup: Adding in NLA Track Remove / Remove and free BKE methods
This PR adds 2 new methods:
* BKE_nlatrack_remove
* BKE_nlatrack_remove_and_free

and modifies the existing `BKE_nlatrack_free` to remove the track list parameter.

This refactor splits out the removal / freeing into it's own methods, and provides a higher order method (BKE_nlatrack_remove_and_free) to conveniently call both.

Co-authored-by: Nate Rupsis <nrupsis@gmail.com>
Pull Request #104752
2023-02-16 17:31:09 +01:00
81b53aa507 WM: Add option for clearing asset data to append operator
When appending assets it often isn't expected for the asset tags and
meta-data to be included. Add an option to the append operator to
disable appending the asset data, exposing existing internal options.
2023-02-16 11:17:02 -05:00
55843cd64b Curves: Add select more/less
This adds the "Select More/Less" operators for Curves. Both operators use the `select_adjacent` function to (de)select adjacent points.

Pull Request #104626
2023-02-16 17:02:43 +01:00
1e9564864c Cleanup: Refactor File/Asset Browser button dragging code
Code to set the dragging data for a button was mostly duplicated, they
share it now. The followup commit also needs an easy way to reuse the
logic, which is possible now.
2023-02-16 16:57:10 +01:00
6da512f0bc UI: Refactor how draggable part of button is determined
No longer use the existance of an image pointer inside the button, or
the the type of a button to decide if the entire button should be
draggable, or only its icon. This was rather sneaky, undocumented
behavior. Instead make this a proper option in the public UI API, and
enable it by default in specific cases to match the previous behavior.

This at least makes the behavior known and controllable in the API, and
not something that's just "secretly" done deep down in the button
handling code. I'd argue we should just use the entire button width by
default for dragging, but that would be a bigger change.
2023-02-16 16:57:10 +01:00
9edb1d0a7c Fix #104166: Add redraw for asset marking and unmarking
When the users click the "Mark as Asset" with the mouse hover the fake
user button, the button was not refreshed. In fact, the areas are not
listening to the "NC_ID NA_EDITED", which is the signal emitted after
an asset is marked/unmarked. Because of this, the areas aren't redrawn
(especially the ID buttons).

This little patch adds the event listening for the areas where this
problem is happening  node editor and properties editor.

Pull Request #104694
2023-02-16 16:26:23 +01:00
2ccb820c7e Merge branch 'blender-v3.5-release' 2023-02-16 15:27:40 +01:00
47934b5c2b Curves: Add remove_selection function
This adds a `remove_selection` function that can be used by other
objects that make use of `CurvesGeometry`.

Pull Request #104813
2023-02-16 15:26:13 +01:00
be6847e773 Cleanup: Remove read-only attribute type
After the removal of the "normal" attribute providers, we no longer
use the concept of read-only attributes. Removing this status simplifies
code, clarifies the design, and removes potentially buggy corner cases.

Pull Request #104795
2023-02-16 15:08:28 +01:00
300c673a64 Geometry Nodes: Remove "normal" attribute
The "normal" was added before fields existed because we needed a
way to expose the data to geometry nodes. It isn't really an attribute,
because it's read-only and it's derived rather than original data.

No features have relied on the "normal" attribute existing, except
for the corresponding column in the spreadsheet. However, the
column in the spreadsheet is also inconsistent, since it isn't an
attribute but looks just like the other columns. The normal is
always visible in the spreadsheet.

Pull Request #104795
2023-02-16 15:08:28 +01:00
368559647f Merge branch 'blender-v3.5-release' 2023-02-16 15:01:29 +01:00
c785e7431e Themes: Fix several issues in Blender Light theme
* Fix #92539: Hard to read the breadcrumbs.
* Fix View Item active, hover, and text color (e.g. count numbers in the
  Spreadsheet were almost unreadable).
* Fix mismatching node type colors with the default theme.
  Blender Light is meant to be simply a brighter version of the default,
  so screenshots and tutorials can be followed with both themes.
* Use the same outline color for widgets, so they match when aligned in a row.
* Make panels standout (not fully transparent), like in the default theme.
2023-02-16 14:39:41 +01:00
d705c8ed57 Merge branch 'blender-v3.5-release' 2023-02-16 08:30:52 -05:00
9d15b3f424 Fix #104697: Curves Sculpt: Setting brush shortcuts does not work
The active tools in `_defs_curves_sculpt` don't use names that are
exactly the same as the corresponding brush name with "builtin_brush."
at the beginning, instead they use more standard identifiers without
capitals or spaces.

The "brush_select" utility operator assumed the names matched though.
That can be fixed by manually mapping the brushes to the active tools.

Pull Request #104792
2023-02-16 13:48:39 +01:00
c9285f83ab Fix #104698: Assert and failure adding shortcuts to curves sculpt tools
The keymap name in `WM_keymap_guess_from_context` didn't match the
name of the keymap in the Blender default keymap (`km_sculpt_curves`).
Fix by changing the utility function to match the keymap name.

Before right clicking on any tool in curves sculpt mode gave an assert,
now it shows a context menu.

Pull Request #104791
2023-02-16 13:47:13 +01:00
c39b81d832 UI: Improvement to screen_find_area_xy
In BKE_screen_area_map_find_area_xy (find a ScrArea by 2D location),
ignore edges by using screen verts instead of totrct

Differential Revision: blender/blender#104680

Reviewed by Brecht Van Lommel
2023-02-16 02:38:57 +01:00
6e7242f00c Merge branch 'blender-v3.5-release' 2023-02-16 00:53:04 +01:00
4cb119f533 Fix #104584: Reassigning effect strip input does not update its position
Lookup cache was not invalidated, to update attached effects position, a handle
of a input strip is touched.

To update attached effects, currently the code only does that when strip
position is changed. This is, because effect strip updating is done internally
in sequencer module code and ideally shouldn't be done at all. A TODO comment
with further explanation is added.
2023-02-16 00:48:52 +01:00
10c0c2a156 Windows: allow windows to span multiple monitors
On the Windows platform allow Blender windows to be created that are
spread over multiple adjacent monitors.

---

On Windows we are quite feature-complete and stable for the creation and placement of multiple (non-temp) Blender windows. We correctly do so across multiple monitors no matter their arrangement, resolution, and scale.

However, there is another way that Blender could use multiple monitors - suggested by a core dev - which is to size a window so that it comprises multiple monitors. There are some advantages to this way of working because the one window remains constantly active and in focus. It also allows a single region (like a node editor) to be as large as possible.

But this way of working is not currently possible. That is because during window creation we constrain them to fit within the confines of the nearest single monitor. This has mostly been done for simplicity and safety. We don't want to restore a saved window to a position where it cannot be seen or used.

This patch addresses that. It allows windows to span multiple monitors, and does so safely by constraining the four corners of the window to be within the working area of any active monitor.  This means it allows the creation of single windows as shown below in blue (left two), but does not allow the one in orange (right):

![image.png](/attachments/b2a9dfca-d54c-467a-ab95-717df3b25051)

Note this has been previously (before gitea) reviewed and approved by Brecht.

Co-authored-by: Harley Acheson <harley.acheson@gmail.com>
Pull Request #104438
2023-02-16 00:41:26 +01:00
ab63fe9eab Cleanup: format 2023-02-16 10:04:09 +11:00
a2551f23ad Cleanup: document & improve naming for Wayland's pending window actions 2023-02-16 10:02:23 +11:00
f178e3f849 Merge branch 'blender-v3.5-release' 2023-02-15 23:56:58 +01:00
7a76f2ae77 Fix #104370: Draw: Don't request the same attribute more than once
Avoid running out of attributes when multiple material slots use the same one.

Cleanup:
Removes the return value from drw_attributes_add_request since it shouldn't be modified afterward and it's never used.
Avoid making copies of DRW_AttributeRequest in drw_attributes_has_request.

Co-authored-by: Miguel Pozo <pragma37@gmail.com>
Pull Request #104709
2023-02-15 23:54:51 +01:00
b1abc23899 Fix: Skip anonymous CustomData layers for the python API
Now that the UV map names are read from the evaluated mesh the names of
the anonymous layers would show up in the UV Map node and be accessible
via the python interface.

This changes the collection definition to skip anonymous layers.

Pull Request #104783
2023-02-15 23:54:50 +01:00
043bff144d Merge branch 'blender-v3.5-release' 2023-02-15 17:40:15 -05:00
d465b92823 Cleanup: Make format, fix missing static warning 2023-02-15 17:39:53 -05:00
7ad1d3156c Cleanup: Use simpler attribute transfer API in duplicate elements node
Instead of retrieving which attributes to transfer from the geometry set
which exists at a different abstraction level, get them from accessors
directly with a newer utility function. This removes boilerplate code
and makes the logic clearer for a future even more generic attribute
propagation API.
2023-02-15 17:38:47 -05:00
2cad80b0e5 Merge branch 'blender-v3.5-release' 2023-02-15 16:13:35 -05:00
Colin Marmond
c59d2f3f2d Fix #102529: De-duplicate add node search items with assets
Fix a little omission. The id name has a 2 char prefix which has
to be removed in order to compare to the real name.

Pull Request #104793
2023-02-15 16:10:37 -05:00
1e6ed77896 Merge branch 'blender-v3.5-release' 2023-02-15 13:27:49 -05:00
72a2229848 Fix #104690: Evaluated positions user-after-free for copied poly curves
The evaluated positions cache can live longer than a specific
`CurvesGeometry`, but for only-poly curves, it pointed to the positions,
which are freed when the curves are. Instead, use the same pattern
as the evaluated offsets and don't store the positions span, just return
it when retrieving evaluated positions.
2023-02-15 13:26:06 -05:00
b7e39acfcd Fix #104789: uv_layers.remove() always raises error
A simple typo from 6c774feba2. Also return
so nothing happens when the UV map isn't found.
2023-02-15 13:25:46 -05:00
b07085fe3c Fix #104690: Evaluated positions user-after-free for copied poly curves
The evaluated positions cache can live longer than a specific
`CurvesGeometry`, but for only-poly curves, it pointed to the positions,
which are freed when the curves are. Instead, use the same pattern
as the evaluated offsets and don't store the positions span, just return
it when retrieving evaluated positions.
2023-02-15 11:38:27 -05:00
753eb9c20e Cycles: disable AMD GPU rendering binaries due to compiler bugs
There are known bugs in HIP compiler that are causing random build failures
when making changes to the Cycles kernel. This is preventing developers from
efficiently making improvements to Cycles.

For now Cycles AMD GPU rendering is disabled in Blender 3.6 until a good
solution is found, so that ongoing work like Principled v2 is not blocked.
We hope this can be resolved later on in the 3.6 release cycle.

Ref #104786
2023-02-15 17:24:37 +01:00
05b177b0b3 Revert changes to align asset library labels in menus
This reverts 1116d821dc and part of 5bac672e1a.

The solution was made specifically for the 3.5 release, to avoid
breaking other cases. The previous commit addressed the problem properly
by letting the general menu code align labels where needed.
2023-02-15 16:09:08 +01:00
58752ad93c UI: Ensure menus with icons align all menu item labels
Usually in Blender, we try to align the labels of items within a menu,
if necessary by adding a blank icon for padding. This wasn't done for
menus generated from enum properties (RNA or custom property enums). Now
we do it whenever there is at least one item with an icon.
2023-02-15 16:09:08 +01:00
0f29a65744 Merge branch 'blender-v3.5-release' 2023-02-15 15:59:34 +01:00
1116d821dc Fix weird icon padding in asset library selector menu button
Since the menu doesn't automatically align the labels like other menus
and pulldowns in Blender, I manually made them align using the blank
icon. However the menu button would also include this blank icon now.

This is a specific fix for the 3.5 release. In the main branch I will
replace it with proper support for automatically aligning labels in such
menus.
2023-02-15 15:59:12 +01:00
b9bf4700b0 Fix weird icon padding in asset library selector menu button
Since the menu doesn't automatically align the labels like other menus
and pulldowns in Blender, I manually made them align using the blank
icon. However the menu button would also include this blank icon now.

This is a specific fix for the 3.5 release. In the main branch I will
replace it with proper support for automatically aligning labels in such
menus.
2023-02-15 15:58:40 +01:00
Matti-Ranta
0b63136e63 Cleanup: delete .arcconfig
Now that https://developer.blender.org/ has been decommissioned, arcconfig is no longer needed.

Pull Request #104768
2023-02-15 15:49:22 +01:00
7ae5bc142b Merge branch 'blender-v3.5-release' 2023-02-15 15:37:47 +01:00
a7ccb3df3e Fix possible compiler warning and linker error
Type was forward declared as class, but is a struct. GCC is quiet about this
Clang gives a warning about potential linker errors on MSVC.
2023-02-15 15:37:30 +01:00
a6ebe0ca62 Fix possible compiler warning and linker error
Type was forward declared as class, but is a struct. GCC is quiet about this
Clang gives a warning about potential linker errors on MSVC.
2023-02-15 15:09:22 +01:00
d8112ec1ea Revert "Splash screen for Blender 3.5"
This reverts commit a0b4da2bd0.
2023-02-15 14:17:00 +01:00
6417da28a8 Revert "Blender 3.5 Beta:"
This reverts commit 904b7e4e41.
2023-02-15 14:16:43 +01:00
33193093b1 Merge branch 'blender-v3.5-release' 2023-02-15 14:16:25 +01:00
a0b4da2bd0 Splash screen for Blender 3.5
Credits: Nicole Morena
2023-02-15 14:14:14 +01:00
904b7e4e41 Blender 3.5 Beta:
* BLENDER_VERSION_CYCLE set to beta
* Update pipeline_config.yaml to point to 3.5 branches and svn tags
* Update and uncomment BLENDER_VERSION in download.cmake
2023-02-15 13:56:14 +01:00
d5d48a986b Release cycle: Bump version to 3.6. 2023-02-15 13:49:56 +01:00
5bac672e1a Asset Browser: Add separator line & icon padding for import method menu
Usually when a menu item displays an icon, we indent all other items
with an empty icon so items align nicely. Now with more built-in asset
libraries (the new "Essentials" library), this inconsistency becomes
more apparent.

Also add a separator line between the "All" asset library and the
others, makes the menu look more organized.
2023-02-15 13:11:10 +01:00
e3b5a2ae15 Asset Browser: Hide import method menu for essentials
Essentials always use "Append (Reuse Data)", displaying the menu to
change that doesn't make sense.
2023-02-15 13:03:36 +01:00
0d798ef57c Assets/UI: Use UI-list for asset library preferences UI
The Preferences for asset libraries are becoming more than a simple name
+ path. E.g. there is now an Import Method options, and we previously
also considered a Relative Paths option (which we may still want to
add). The previous UI, while consistent with the Auto Run Python Scripts
UI isn't well suited for less than trivial cases. Using UI lists makes
the UI more scalable and follows usual list UI patterns more. There is
also more space for the path button now.

Part of #104686.
2023-02-15 13:00:17 +01:00
972f58c482 Asset Browser: Rename "Import Type" to "Import Method"
"Type" sounds like you're selecting a thing, not a behavior. So "Method"
should be better. Part of 104686.
2023-02-15 12:58:15 +01:00
ae84a2956e Assets: Preference for default import method for an asset library
The default import method for an asset library can now be determined in
the Preferences. The Asset Browser has a new "Follow Preferences" option
for the importing. The essentials asset library still only uses "Append
(Reuse Data)".

This is part of #104686, which aims at improving the import method
selection, especially for the introduction of the new essentials library
(which doesn't support certain import methods). Further changes are
coming to improve the UI, see #104686.

Pull Request: #104688
2023-02-15 12:51:23 +01:00
4387dbf03e Curves: Replace quick fur operator, add to add menu
The quick fur operator now uses the new hair system. It adds a new
curves object for every selected mesh, and adds geometry nodes
modifiers from the essentials assets that generate curves. A few
settings are exposed in the redo panel, including an option for whether
to apply the modifier to generate the initial curves so that there is
original editable data.

The point of the operator is to give people a sense of how to use the
node groups and to give a very fast way to build a basic setup for
further tweaking.

Pull Request #104764
2023-02-15 12:13:34 +01:00
837ba82402 Fix #90629: VSE: Split selection is determined by menu position
Use the right hand side selection, as it fits the typical workflow
the best.

Arguably, the same would need to be done for the k-shortcut, but
that is another issue to be tackled. As well as making the selection
active.

Pull Request #104777
2023-02-15 12:05:37 +01:00
1a94457586 Fix #104760: GPencil Fill Gap circles no longer disappear when blue line appear
The problem was the alpha channel was set wrongly and the original 0 value was replaced with 1 by error.
2023-02-15 11:55:32 +01:00
35cde8b5fd Curves: move edit mode out of experimental
We (Dalai, Hans, Falk, Simon and me) decided that the curves edit mode
is useful enough to justify moving it out of experimental now. So far it
supports the following features:
* Various selection tools. The selections are synced with sculpt mode.
* Transform tools.
* Delete curves/points.

More functionality of the old curve edit mode will be ported over in
future releases.
2023-02-15 11:43:55 +01:00
ef46f735f3 Cleanup: LineArt: Remove lineart_cpp_bridge.cc
Removed this file because lineart_cpu.cc is already c++.

Pull Request #104736
2023-02-15 11:33:37 +01:00
7481a36d51 EEVEE: Remove unnecessary material optimization assertion.
Fix unreported assert in basic scenes.

Authored by Apple: Michael Parkin-White

Pull Request #104775
2023-02-15 11:27:25 +01:00
3807a0981e Curves: Add delete operator to edit mode
This implements the delete operator in curves edit mode. The behavior
is similar to the delete operator in the edit mode of legacy curves,
i.e. it's actually dissolving and doesn't split curves. This is also
the behavior that we generally want for the hair use case.

The operator is added to the `Curves` menu and can be accessed via
the keyboard using `X` or `Del`.

Pull Request #104765
2023-02-15 10:50:01 +01:00
ddc6815b1a Curves: add Curve Parameter Falloff to comb brush
This adds a new `Curve Falloff` popover to the comb brush tool settings.
The curve control allows changing the brush weight along the curve to
e.g. affect the tip more than the root. This is a relative way to get
something like stiffness for short hair.

This functionality could potentially be added to some other brushes,
but the comb brush is the most important one, so that is added first.

I did add the buttons add the buttons to choose a curve map preset.
However, I did not add the preset dropdown, because that just adds
some unnecessary complexity in the code now and is redundant.

Pull Request #104589
2023-02-15 10:42:30 +01:00
fc6d13eced Cleanup: extract the check to save a blend file into a function
Part of D11422 by @filedescriptor, makes it convenient to run a funciton
when the file cannot be saved.
2023-02-15 16:19:49 +11:00
e424931cf7 Cleanup: rename Byte to Bytes in Python string utilities
These functions operate on byte arrays, not a single byte,
match naming for CPython's PyBytes_AS_STRING.
2023-02-15 16:19:14 +11:00
6661342dc5 Mesh: Set active attribute values edit mode operator
This patch adds a simple operator to set values of the active
attribute for the selected element. The aim is to give simple control
over attribute values in edit mode rather than to provide the fastest
workflow for most cases. Eventually this operator might be less
important compared to more advanced attribute editing tools, but for
now, exposing a little bit of functionality is low hanging fruit and
will help to see the possibilities.

The implementation mostly consists of boilerplate to register the
necessary property types for the operator and draw their UI.
Beyond that, we just loop over selected elements and set a value.

Pull Request #104426
2023-02-15 04:34:53 +01:00
02c3889b1c Cleanup: quiet clang warnings
Quiet unused argument, shadow, array-bounds & range-loop-bind-reference
warnings.
2023-02-15 13:26:54 +11:00
8d35b28f2a Cleanup: spelling in comments 2023-02-15 13:11:14 +11:00
00a7344f27 Cleanup: quiet warnings from shellcheck, correct indentation 2023-02-15 13:11:06 +11:00
8de121ffc6 Cleanup: use 'show_' prefix for RNA sculpt booleans
Follow naming conventions from
https://wiki.blender.org/wiki/Source/Architecture/RNA
2023-02-15 13:11:04 +11:00
c3b53abc10 Fix #84057: Delete operator removes unexpected strip
Caused by strips being flagged for removal, but the flag was never
cleared. As far as I can tell, this issue is not reproducible anymore,
but there may be files with this flag still set.
2023-02-15 01:25:38 +01:00
dcc80748d3 Fix overlay_uniform_color_clipped inheritance
overlay_uniform_color_clipped was inheriting from overlay_depth_only, which doesn't
make much sense.
I've changed it to inherit from overlay_uniform_color instead, which is consistent
with other \*\_clipped variants of shaders.

Pull Request #104761
2023-02-14 22:21:59 +01:00
7b9d1cb51f Eevee: GPU Material node graph optimization.
Certain material node graphs can be very expensive to run. This feature aims to produce secondary GPUPass shaders within a GPUMaterial which provide optimal runtime performance. Such optimizations include baking constant data into the shader source directly, allowing the compiler to propogate constants and perform aggressive optimization upfront.

As optimizations can result in reduction of shader editor and animation interactivity, optimized pass generation and compilation is deferred until all outstanding compilations have completed. Optimization is also delayed util a material has remained unmodified for a set period of time, to reduce excessive compilation. The original variant of the material shader is kept to maintain interactivity.

Also adding a new concept to gpu::Shader allowing assignment of a parent shader from which a shader can pull PSO descriptors and any required metadata for asynchronous shader cache warming. This enables fully asynchronous shader optimization, without runtime hitching, while also reducing runtime hitching for standard materials, by using PSO descriptors from default materials, ahead of rendering.

Further shader graph optimizations are likely also possible with this architecture. Certain scenes, such as Wanderer benefit significantly. Viewport performance for this scene is 2-3x faster on Apple-silicon based GPUs.

Authored by Apple: Michael Parkin-White

Ref T96261
Pull Request #104536
2023-02-14 21:51:03 +01:00
db2eaa5c86 OBJ: fixed some faces wrongly skipped in invalid face validation logic (#104593)
The logic for looping over imported OBJ faces and checking whether any
of them are "invalid" (duplicate vertices) was wrongly skipping
validation of the next face right after some invalid face. It
was the previously invalid face, moving the last into its place,
but then the loop was incrementing the face index and that just-moved
face was not properly validated.

Fixes #104593 - importing attached obj file (which contains some faces
that have duplicate indices). Added test coverage with a much smaller
obj file.
2023-02-14 21:49:25 +02:00
e1a29b58bb Fix: Curve resolution input node missing default
When the attribute doesn't exist, the node should give the default
of 12, as defined by the accessor method for `bke::CurvesGeometry`.

Pull Request #104674
2023-02-14 19:59:37 +01:00
87f96b7664 Fix wrong variable being used as plan in 'gizmo_3d_dial_matrixbasis_calc'
A plane must be `float[4]`.
2023-02-14 15:39:32 -03:00
a755e6e63f Revert "MSVC: lower C4100 warning level from 4 to 3"
This reverts commit db4e7616f3.

Caused many issues when compiling mantaflow.
2023-02-14 15:36:35 -03:00
f72d28d7e7 Gizmo: use the final matrix for the dial3D clip plane
Dial3D uses the `matrix_basis` for the clip plane.

This can cause inconsistencies if the gizmo has `matrix_offset` or
`matrix_space`.
2023-02-14 15:31:30 -03:00
db4e7616f3 MSVC: lower C4100 warning level from 4 to 3
This better aligns with OSX/Linux warnings.

Although `__pragma(warning(suppress:4100))` is not the same as
`__attribute__((__unused__))` in gcc (which only affects the attribute
instead of the line), it still seems to be better to use it than to
hide the warning entirely.
2023-02-14 14:38:18 -03:00
f4db58844d GPU: Fix wrong 2D shader used from 3D drawing
Regression introduced by d165d6aa2a.
2023-02-14 18:32:42 +01:00
acf7f46b77 Fix #104748: GPencil: Fill tool is not working at all
Caused by missing color uniform update.
2023-02-14 18:32:42 +01:00
4fbc9c42e5 Curves: Add transform tools to toolbar
This commit also makes `ED_transform_calc_gizmo_stats` work
for curves.

Pull Request #104750
2023-02-14 18:24:24 +01:00
5ca65001ea Geometry Nodes: Operator to wrap a modifier's node group
As described in #104171, add an operator that creates a new node group
that contain the current node group and named attribute nodes to deal
with the outputs. This saves manual work when moving a high-level
modifier to the node editor for better procedural control.

Pull Request #104546
2023-02-14 18:21:50 +01:00
c9f02569c7 Curves: cage overlay for sculpt mode
This adds a new overlay for curves sculpt mode that displays the curves that the
user currently edits. Those may be different from the evaluated/original curves
when procedural deformations or child curves are used.

The overlay can clash with the evaluated curves when they are exactly on top of
each other. There is not much we can do about that currently. The user will have
to decide whether the overlay should be shown or not on a case-by-case basis.

Pull Request #104467
2023-02-14 18:10:11 +01:00
eb9647c53d Cleanup: rename vertex buffer attribute to be more specific
This renames `data` and `color` to `selection`. This is better because
it's actually what the corresponding buffers contain. Using this
more correct name makes sharing vertex buffers between different
gpu batches for different shaders easier.
2023-02-14 17:53:20 +01:00
7ba59c8a62 Assets: show all assets by default instead of current file
The "current file" mode is only useful when creating new assets.
However, the far more common use case and the one that should require
fewer steps is to use existing assets.

There is a risk that this causes freezing if the file browser preview
caching does not work properly. So we'll have to keep an eye on the bug
tracker to see if this is an issue in practice.

Pull Request #104749
2023-02-14 17:44:41 +01:00
b3fb73f325 Assets: bundle Essentials with Blender
This patch adds an "Essentials" asset library that is bundled with Blender.
Also see #103620. At build time, the `lib/assets/publish` folder is copied
to `datafiles/assets` in the build directory.

In the UI, the "Essentials" library can be accessed like other custom asset
libraries with the exception that assets from that library cannot be linked.

The immediate impact of this is that Blender now comes with some geometry
node groups for procedural hair grooming.

Pull Request #104474
2023-02-14 17:35:29 +01:00
459c210154 Fix #104652: UV Face Dots randomized
Match the check from before 75db4c082b,
where we just checked that the face dots bitmap wasn't null.
2023-02-14 11:27:34 -05:00
715acf758c Curves: Use deformed points in edit mode overlay
Uses the deformed crazyspace to populate the position buffer for Curves edit mode overlay.

Pull Request #104705
2023-02-14 16:33:38 +01:00
cfe828b452 OBJ: Support polylines with more than 2 vertices.
The OBJ spec (page B1-17) allows "l" entries to specify
polylines with more than 2 vertices, optionally with texture
coordinates.

Previously, only the first 2 vertices of each polyline
were read and added as loose edges, failing when texture
coordinates were present.

This adds support for proper polylines, reading but ignoring
texture coordinates.

Pull Request #104503
2023-02-14 16:30:50 +01:00
4cc94679dd MSVC: suppress additional warnings out of external headers
In 161908157d we moved all warnings
coming out of the library folder to /W0 as many of them do not follow
our code-style nor can we force them to.

When i made this change, i took `/external:templates-` to mean
"and that goes for you too, templates" and it decisively does the
opposite leading to /W3 warnings coming out of openvdb

This change removes the flag as it should have never have been added
in the first place.
2023-02-14 07:56:14 -07:00
Robin Hohnsbeen
39f63c8c08 Sculpting: Vector displacement for the sculpting draw brush
Sculpt: Added vector displacement for the sculpting draw brush (area plane mapping only for now)

Vector displacement maps (VDM) provide a way to create complex displacements that can have overhangs in one brush dab.
This is unlike standard displacement with height maps that only displace in the normal direction.
Forms like ears, curled horns, etc can be created in one click if VMDs are used.
There is a checkbox on the draw brush in the texture settings "Vector Displacement" that enables/disables this feature.

Technical description: The RGB channels of a texture in a brush stroke are read and interpreted as individual vectors, that are used to offset vertices.
As of now, this is only working for the draw brush using the area plane mapping. Symmetry and radial symmetry are working.

A few things to consider when making VD-Maps:
* UVs need to stay intact for the bake mesh (e.g. voxel remeshing can't be used to create VD Meshes)
* When exporting a VD Map it should be in the file format OpenEXR (for positive and negative floating point values).
* Export resolution can be 512x512 or lower (EXR files can get very large, but VDM brushes don't need a high resolution)

And when using them:
* Inside Blender clamping needs to be unchecked on the texture
* The brush falloff should be set to constant (or nearly constant)

This patch was inspired by this [right-click-select proposal](https://blender.community/c/rightclickselect/WqWx/) Thanks for the post!

(Moved [this patch](https://archive.blender.org/developer/D17080) to here.)

Co-authored-by: Robin Hohnsbeen <robin@hohnsbeen.de>
Pull Request #104481
2023-02-14 15:29:27 +01:00
d4f7f1dfe4 Fix memory leak in view3d_select
There was an unintentional early return in the click select
execute function that caused the operator properties not
to be freed.
2023-02-14 14:59:07 +01:00
a76b5d3a07 Curves: change collision radius for consistency with default radius
Offset distance for curve collision  will be matched with default curve
radius for better visibility.

Pull Request #104648
2023-02-14 14:15:04 +01:00
59b9a88a35 Fix: duplicate elements node does not update curve type counts
Curve type counts are updated eagerly but it was missing in this
node leading to a crash further down the line where the counts
were expected to be correct.
2023-02-14 13:32:00 +01:00
4126284e46 Allocator: Fail building when trying to MEM_delete a void pointer
`MEM_delete()` is designed for type safe destruction and freeing, void
pointers make that impossible.
Was reviewing a patch that was trying to free a C-style custom data
pointer this way. Apparently MSVC compiles this just fine, other
compilers error out. Make sure this is a build error on all platforms
with a useful message.
2023-02-14 12:48:26 +01:00
1fd0c80725 Build: correct forwarding jobs argument to make_deps_wrapper.sh 2023-02-14 22:26:59 +11:00
5215543280 Constraints: use a dimensionless unit prop for Maintain Volume
The Volume property of the Maintain Volume constraint was marked as a
distance, which made it confusing--especially with non-metric units.

The volume can actually be understood as a factor of the initial
volume, so it should be dimensionless.

Additionally, the volume had a range of 0.001 to 100.0. This is wide
enough in most cases, but sometimes you may need to go orders of
magnitude higher or lower to consider vast or thin objects, and there
should be no drawback to extending the limits, provided they stay
positive.

Pull Request #104489
2023-02-14 12:19:53 +01:00
1e449bee21 Cycles: Temporary fix for Principled Hair albedo
The proper fix (bb9eb262d4) caused compilation problems with HIP, so we're
delaying it until 3.6.
To fix the original bug report (#104586), this is a quick workaround that'll
hopefully not upset the compiler.

Pull Request #104723
2023-02-14 12:18:10 +01:00
5040c39d1a Fix T103354: Author extents on UsdGeomMesh
A properly authored USD file will have the extent attribute authored on all prims conforming to UsdGeomBoundable.
This cached extent information is useful because it allows the 3D range of prims to be quickly understood without reading potentially large arrays of data. Note that because the shape of prims may change over time, extent attributes are always evaluated for a given timecode.

This patch introduces support for authoring extents on meshes and volumes during export to USD.

Because extents are common to multiple kinds of geometries, the main support for authoring extents has been placed in USDAbstractWriter, whose new author_extent method can operate on any prim conforming to pxr::UsdGeomBoundable. The USD library already provides us the code necessary to compute the bounds for a given prim, in pxr::UsdGeomBBoxCache::ComputeLocalBound.
Note that not all prims that are imageable are boundable, such as transforms and cameras.

For more details on extents, see https://graphics.pixar.com/usd/release/api/class_usd_geom_boundable.html#details.

Note that when new types of geometries are introduced, such as curves in https://developer.blender.org/D16545, we will need to update the USD writer for that geometry such that it calls this->author_extent.

Update on Feb 2: This patch has been updated to include a unit test to ensure authored extents are valid. This test requires new test assets that will need to be submitted via svn. The test assets are attached in the d16837_usd_test_assets.zip file. To use, unzip and merge the contents of this zip into the lib/tests/usd folder.

This unit test also addresses #104269 by validating compliance of exported USD via UsdUtils.ComplianceChecker.

Pull Request #104676
2023-02-14 12:11:53 +01:00
a3e6cb5dab Gizmo: press shift key to scale cage2d gizmo uniformly
Reviewed by: Campbell Barton
Pull Request #104418
2023-02-14 11:08:54 +01:00
fe0a219b5b Revert: Formatting changes space_toolsystem_toolbar 2023-02-14 10:30:49 +01:00
09498264f6 Deps: build one at a time, each using all available cores on Linux
Use a MAKE wrapper for 'make deps' on Linux that ensures dependencies
are built one at a time. This is preferable because building many
dependencies at once made troubleshooting impractical and had the
downside that large deps such as LLVM would bottleneck on a single core.

This may be used for macOS, so far it's only tested on Linux.
2023-02-14 16:37:04 +11:00
46c34ba1f6 GNUmakefile: include install directory in 'make deps' message
Avoids uncertainly, ensure deps are copied from the right place.
2023-02-14 13:26:30 +11:00
d02f863b18 Update RNA to User manual mappings 2023-02-14 13:19:18 +11:00
d851c91856 PyDocs: update links in generated API docs for GITEA migration
- Correct broken link for undocumented modules.
  Point to the contributing page, it seems #51062 was lost with the
  GITEA task migration.
- Correct Blender Version link to the SHA1.
2023-02-14 12:41:51 +11:00
a6dcf6e6cb Cleanup: avoid redundant sqrt when picking reroute nodes 2023-02-14 12:26:29 +11:00
818c16ef1f Cleanup: pass a const argument to CustomData_get_elem_size 2023-02-14 12:26:01 +11:00
750e278fd1 Cleanup: line wrapping in USERPREF_PT_experimental_new_features
Changing from Phabricator links caused poor formatting.
Also remove blank lines between comment and it's function.
2023-02-14 12:13:04 +11:00
85f8ba9db7 Cleanup: include missing header, sort CMake file lists 2023-02-14 11:52:14 +11:00
1ac80e8338 Cleanup: quiet unreachable-code warning, use ARRAY_SIZE macro 2023-02-14 11:50:00 +11:00
6dc88682ea License headers: add missing license identifier 2023-02-14 11:47:13 +11:00
36937e523a Fix #66863: Bisect plane rotation behavior bugged for side/cut view
The matrix of the rotation gizmo is somewhat confusing.

Attaching to the Z axis has more predictable results.
2023-02-13 21:15:38 -03:00
0fa34aa0ec Cleanup: spelling in comments, reference enum types in doc-strings
Also use doxy formatting for structs in sculpt_uv.c.
2023-02-14 10:29:48 +11:00
e928dd300b Cleanup: format 2023-02-14 10:29:46 +11:00
dc46465490 Cleanup: use typed enum (eDirEntry_SelectFlag) where appropriate 2023-02-14 10:29:44 +11:00
1d7bf4f826 BLI_utildefines: add ^= operator to ENUM_OPERATORS macro 2023-02-14 10:29:42 +11:00
Erik Abrahamsson
526f2273c6 Docs: improve online manual lookup time time
Matching the RNA id's to the search pattern is slow because
of the function `fnmatchcase`. This patch first checks the string
prefix without any special characters used by fnmatch,
if the `startswith` check fails, there is no need to check `fnmatchcase`.
Before the optimization, an online manual lookup took about 400ms
which is quite noticeable, with this patch applied it's under 10ms.

Ref !104581.
2023-02-14 10:29:40 +11:00
bb9eb262d4 Revert "Cycles: Clean up the Principled Hair BSDF implementation"
This reverts commit cb77865c21.

Appears to break HIP compilation, so delay until 3.6.
2023-02-13 23:32:53 +01:00
1f615690e6 Cycles: Add support for CUDA 12
CUDA 12 no longer supports sm_3*, in particular 35 and sm_37,
so skip building those if only CUDA 12+ is available.

Pull Request #104713
2023-02-13 23:04:02 +01:00
6a0b1eae8c Fix #104097: re-enable Cycles AMD Vega support
The internal compiler error appears to be gone. Unclear why it appeared in the
first place and why it's gone now. Just random kernel code changes causing it.

Pull Request #104719
2023-02-13 22:53:08 +01:00
cb77865c21 Cycles: Clean up the Principled Hair BSDF implementation
- Rename roughness variables for more clarity - before, the SVM/OSL code would
  set s and v to the linear roughness values, and the setup function would over-
  write them with the distribution parameters. This actually caused a bug in the
  albedo code, since it intended to use the linear roughness value, but ended up
  getting the remapped value.
- Deduplicate the evaluation and sample functions. Most of their code is the
  same, only the middle part is different.
- Changed albedo computation to return the sum of the intensities of the four
  BSDF lobes. Previously, the code applied the inverse of the color->sigma
  mapping from the paper - this returns the color specified in the node, but
  for very dark hair (e.g. when using the Melanin controls) the result is
  extremely low (e.g. 0.000001) despite the hair still reflecting a significant
  amount of light (since the R lobe is independent of sigma). This causes issues
  with the light component passes, so this change fixes #104586.
- There's quite a few computations at the start of the evaluation function that
  are needed for sampling, evaluation and albedo computation, but only depend on
  the view direction. Therefore, just precompute them - we still have space in
  PrincipledHairExtra after all.
- Fix a tiny bug - the direction sampling code did not account for the R lobe
  roughness modifier.

Pull Request #104669
2023-02-13 22:49:01 +01:00
7dbf2e2e95 Curves: Draw point overlay only in point selection mode
In case the selection domain is `ATTR_DOMAIN_CURVE` then do not draw the points.

Pull Request #104715
2023-02-13 22:25:06 +01:00
c92c52f0c9 Cleanup: Move draw_attributes.hh to C++
In order to experiment with different storage types for `DRW_Attributes`
and for general cleanup (see #103343). Also move a curves header to C++.

Pull Request #104716
2023-02-13 20:56:24 +01:00
dfacaf4f40 Fix: Incorrect BMesh to Mesh attribute copying
The existing logic to copy `BMesh` custom data layers to `Mesh`
attribute arrays was quite complicated, and incorrect in some cases
when the source and destinations didn't have the same layers.
The functions leave a lot to be desired in general, since they have
a lot of redundant complexity that ends up doing the same thing for
every element.

The problem in #104154 was that the "rest_position" attribute overwrote
the mesh positions since it has the same type and the positions weren't
copied. This same problem has shown up in boolean attribute conversion
in the past. Other changes fixed some specific cases but I think a
larger change is the only proper solution.

This patch adds preprocessing before looping over all elements to
find the basic information for copying the relevant layers, taking
layer names into account. The preprocessing makes the hot loops
simpler.

In a simple file with a 1 million vertex grid, I observed a 6%
improvement animation playback framerate in edit mode with a simple
geometry nodes modifier, from 5 to 5.3 FPS.

Fixes #104154, #104348

Pull Request #104421
2023-02-13 20:52:02 +01:00
0dfc102531 Fix #104588: Initialize Face Sets from edit mode selection broken
Mistake in da4bd24c3e
2023-02-13 14:16:23 -05:00
1e794d9a92 BMesh: Add flexibility for future lazily created UV selection
Don't crash on nonexisting uv selection layers. Add an assert
because for now it is a bug if they don't exist. But when converting
back to Mesh it is preferable to accept in release mode, as opposed to
crashing.

Pull Request #104600
2023-02-13 20:08:30 +01:00
684789c815 Fix #104501: Clear CD_FLAG_NOCOPY after use
When generating a Mesh from a BMesh the uv map bool layers are not
copied if all elements are false. To suppress the copying the flag
CD_FLAG_NOCOPY is set in the layer flags. However these layers *do*
need to be copied to other BMeshes (for example undo steps). So we
need to clear them afterwards.
2023-02-13 20:08:29 +01:00
72a85d976a USD Import: USD Shapes support
This commit adds the ability to import USD Shape primitives (Gprims).
They are imported as Blender Meshes using the USD API to convert, so
that they appear the same as they would in other applications. USD
Shapes are important in many workflows, particularly in gaming, where
they are used for stand-in geometry or for collision primitives.

Pull Request #104707
2023-02-13 19:49:24 +01:00
8d20db0594 Curves: Fix curve segment selection
Make sure that in curve selection mode, the segments are checked
for intersection instead of only the points.

Pull Request #104703
2023-02-13 19:05:28 +01:00
64f83f80c6 Fix #104373: Motion Tracker solve with anamorphic footage not working
The issue was caused by rather recent refactor in 7dea18b3aa.

The root of the issue lies within the fact that the optical center was updated
on the Blender side after the solution was run. There was a mistake in the code
which double-corrected for the pixel aspect ratio.

Added a comment in the code about this, so that it does not look suspicious.

Pull Request #104711
2023-02-13 18:49:45 +01:00
9b7d71cec2 Cleanup: Remove redundant translation markers in context poll message
`CTX_wm_operator_poll_msg_set()` is covered by the translation script
and always translates these strings. Checked with Bastien, he prefers
not having the redundancy here.
2023-02-13 18:41:38 +01:00
64e4aede7f Fix bug report including rB commit hash prefix not needed for Gitea 2023-02-13 18:34:13 +01:00
675717eb79 Cleanup: fix a few typos in UI messages
Issues reported by @Joan-Pujolar in #43295.

Pull Request #104672
2023-02-13 18:24:53 +01:00
c2a5c592fe Fix #103397: Vector UI control shader UBO alignment fix.
Replace float3 with packed_float3 when using additional type padding.

Authored by Apple: Michael Parkin-White

Ref #96261
Pull Request #104699
2023-02-13 18:16:38 +01:00
0e1a6f6033 Cleanup: Add in NLAStrip / NLATrack remove / clean methods
## Cleanup: Refactor NLATrack / NLAStrip Remove

This PR adds 3 new methods:
* BKE_nlatrack_remove_strip
* BKE_nlastrip_remove
* BKE_nlastrip_remove_and_free

These named BKE methods are really just replacements for BLI_remlink, but with some added checks, and enhanced readability.

Co-authored-by: Nate Rupsis <nrupsis@gmail.com>
Pull Request #104437
2023-02-13 18:10:13 +01:00
d42c803f5b Cleanup: add comment explaining #interpf is performing lerp 2023-02-13 17:32:19 +01:00
218a909dec GPencil: Fix unreported Eyedropper color difference in Materials
The color selected was converted wrongly for materials. The undo of the conversion must be done only for palettes.

Also, some code cleanup done.
2023-02-13 17:30:20 +01:00
bea1eff3a5 Fix: No update setting curve selection domain with all selected
Send a notification and tag for an update even if the selection doesn't
exist, which is still necessary for drawing that depends on the
selection domain.
2023-02-13 11:22:31 -05:00
d5c60fb685 Cleanup: add comment to cage gizmo scaling regarding the boundary 2023-02-13 17:08:23 +01:00
9fecf1f8b8 Cycles: Replace resolution divider loop with an analytical formula
As a side effect of this change, more resolution divisions are now available.
Before this patch the possible resolution divisions were all powers of two.
Now the possible resolution divisions are the multiples of pixel_size.

This increase in possible resolution divisions is the same idea proposed in https://archive.blender.org/developer/D13590.
In that patch there were concerns that this will increase the time between a user navigating
and seeing the 1:1 render. To my knowledge this is a non-issue and there should be
little to no increase in time between those two events.

Pull Request #104450
2023-02-13 13:02:47 +01:00
99e71ec1f2 Assets: Store pointer to owning asset library in asset representation
This is needed to be able to query asset library information from an
asset. This again is relevant especially for the "All" asset library,
where you can't just directly access the library itself, which is
different for different assets.

The current design is that an asset representation is owned by exactly
one asset library, so having this pointer is perfectly compatible with
the design.

Reviewed by: Julian Eisel
2023-02-13 12:57:03 +01:00
4f19e99cb1 Tests: add unit test for BLI_strnlen
It wasn't there. Now it is.
2023-02-13 12:54:35 +01:00
147c75b831 Cleanup: EEVEE-Next: Fix typo 2023-02-13 12:49:51 +01:00
0d9fbfe7fe GPUShader: Fix compilation caused by designated initializers in C++ 2023-02-13 12:49:22 +01:00
da0c182a61 Cycles: Fix compilation after recent GPU cleanups 2023-02-13 12:17:46 +01:00
dd171f7743 Cleanup: GPUShader: Rename GPU_shader_uniform_vector
Rename to `GPU_shader_uniform_float/int_ex` to make more sense as a
general purpose function.
2023-02-13 11:22:38 +01:00
b68bac7ced Cleanup: GPUShader: Remove GPU_shader_uniform_int/float
Simplify the API, leaving only one function to set uniform without the
uniform name.
2023-02-13 11:22:38 +01:00
173a8f4ac9 GPU: Removes GPU_shader_get_builtin_ssbo
Simplify the API. Use hardcoded ssbo location instead.
2023-02-13 11:22:38 +01:00
164f591033 Cleanup: GPU: Rename some functions for consistency 2023-02-13 11:22:38 +01:00
83a6642045 Cleanup: GPU: Move eGPUKeyframeShapes to shader shared
Removes code duplication.
2023-02-13 11:22:38 +01:00
158f87203e Cleanup: GPUShader: Reorganize GPU_shader.h to separate depecated API
This avoid confusion to what to use nowadays.
Also improves documentation.
2023-02-13 11:22:38 +01:00
d92c28582a Cleanup: GPUShader: Split Builtins to their own header
Also improve documentation and cleanup.
2023-02-13 11:22:38 +01:00
d165d6aa2a GPU: Remove GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR
This replaces `GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR` by
GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA`.

None of the usage made sense to not use the AA shader.
Scale the point size to account for the rounded shape.
2023-02-13 11:22:38 +01:00
5f3c97b999 GPU: Move gpu_shader_builtin.c to C++
This also removes all unused part of it now that we have converted all
shaders to use create infos.
2023-02-13 11:22:38 +01:00
afd6358fc0 Gizmo: add gizmos for spot and point light radius
Ref #104280

Pull Request #104410
2023-02-13 11:18:21 +01:00
701f90c677 Gizmo: make cage gizmo follow the cursor exactly when scaling
Ref #104280
The scaling of area light / spot light blend was wrong because it is
calculated for pivot at the edges. The new implementation in theory
works for all `abs(pivot) <= 0.5f`, although we only have -0.5, 0, and
0.5.
- Axis constraint for box cage was only applied when there is translate
flag, now the same logic is applied regardless of the translate flag,
this means when dragging the edge, the scaling in the other axis stays
the same; when dragging the corners, it applies free-form scaling.
- Due to the existence of margin, `data->orig_mouse` does not lie
exactly on the boundary. Using that value to compute the scaling causes
the error to accumulate over distance. The new implementation uses the
original dimension of the object instead, and only uses
`data->orig_mouse` to determine the side of the original cursor relative
to the pivot.
- For circular gizmo with unsigned scaling, the gizmo only follow the
cursor exactly when the cursor stays in the original quadrant, otherwise
it's hard to handle the logic when we should clamp the scaling.
2023-02-13 10:48:31 +01:00
9f4ee75c9b Fix #80307: Underline shortcut not working in enum context menus
The buttons of enum context menus are of type `UI_BUT_ROW`. They
are part of the set of buttons we create underline shortcuts for in
`ui_menu_block_set_keyaccels`.
But since they weren't handled in `ui_handle_button_activate_by_type`,
pressing the underline shortcuts didn't do anyting in those cases.

Co-authored-by: Leon Schittek <leon.schittek@gmx.net>
Co-authored-by: Brecht Van Lommel <brecht@noreply.localhost>
Pull Request #104433
2023-02-13 10:43:36 +01:00
2e19aa1399 UI: add camera passepartout color to theme
Currently the passepartout color is hardcoded to black. While a
sensible default for cinema, it may make less sense for other media,
whether video, print, web, etc. It greatly affects viewing conditions
of the image and should be user selectable, much like painting
programs allow.

Pull Request #104486
2023-02-13 09:15:34 +01:00
918cf6cd77 Fix #104341: Handle edge case in Curve to Mesh node
Don't create caps when using cyclic profile splines with two or fewer
points.
This case wasn't handled, yet, leading to invalid meshes or crashes.

Co-authored-by: Leon Schittek <leon.schittek@gmx.net>
Pull Request #104594
2023-02-13 09:03:00 +01:00
af8941e6a8 Vulkan: Use guardedalloc for driver allocations.
Vulkan has a pluggable memory allocation feature, which allows internal
driver allocations to be done by the client application provided
allocator. Vulkan uses this for more client application allocations
done inside the driver, but can also do it for more internal oriented
allocations.

VK_ALLOCATION_CALLBACKS initializes allocation callbacks for host allocations.
The macro creates a local static variable with the name vk_allocation_callbacks
that can be passed to vulkan API functions that expect
const VkAllocationCallbacks *pAllocator.

When WITH_VULKAN_GUARDEDALLOC=Off the memory allocation implemented
in the vulkan device driver is used for both internal and application
oriented memory operations.

For now this would help during the development of Vulkan backend to
detect hidden memory leaks that are hidden inside the driver part
of the stack. In a later stage we need to measure the overhead and
if this should become the default behavior.

Pull Request #104434
2023-02-13 08:37:35 +01:00
f828ecf4ba GPU: Use same read back API as SSBOs
The GPU module has 2 different styles when reading back data from
GPU buffers. The SSBOs used a memcpy to copy the data to a
pre-allocated buffer. IndexBuf/VertBuf gave back a driver/platform
controlled pointer to the memory.

Readback is done for test cases returning mapped pointers is not safe.
For this reason we settled on using the same approach as the SSBO.
Copy the data to a caller pre-allocated buffer.

Reason why this API is currently changed is that the Vulkan API is more
strict on mapping/unmapping buffers that can lead to potential issues
down the road.

Pull Request #104571
2023-02-13 08:34:19 +01:00
86b3073c9e Cleanup: Quiet unused variable warning
Also name another argument for consistency.
2023-02-12 22:27:07 -05:00
2a7440176e Fix: Missing const specifier for curve field input
Mistake in 000e722c7d, which probably made the viewer node
auto-domain detection behave differently when the special case was used.
2023-02-12 20:17:41 -05:00
6ea3fdebc8 Fix: Workbench Next: Extruded frustum binding 2023-02-12 23:40:28 +01:00
77963ff778 Fix #104637: EEVEE Displacement regression after #104595
Keep using the 3 evaluations dF_branch method for the Displacement output.
The optimized 2 evaluations method used by node_bump is now on its own macro (dF_branch_incomplete).
displacement_bump modifies the normal that nodetree_exec uses, so even with a refactor it wouldn’t be possible to re-use the computation anyway.
2023-02-12 23:06:21 +01:00
f0669ff8ba BLI: use larger integer type in BitVector
Using larger integer types allows for more efficient code, because we
can use the hardware better. Instead of working on individual bytes,
the code can now work on 8 bytes at a time. We don't really benefit
from this immediately but I'm planning to implement some more optimized
bit vector operations for #104629.

Pull Request #104658
2023-02-12 18:00:48 +01:00
3f40962414 Cleanup: use sized int types for polyfill_2d
Also correct building when USE_CLIP_EVEN is disabled.
2023-02-12 16:35:24 +11:00
32149f8d7a Tests: add polyfill2d test to ensure the result has no zero area tris
Add a test to address the issue raised in #103913, where zero area
triangles could be created from polygons that have co-linear edges
but were not degenerate.
2023-02-12 16:26:34 +11:00
91346755ce Cleanup: use '#' prefix for issues instead of 'T'
Match the convention from Gitea instead of Phabricator's T for tasks.
2023-02-12 14:56:05 +11:00
a02fa6c40d Cleanup: spelling in comments 2023-02-12 14:23:16 +11:00
10354b043f Fix crash selecting faces in wire-frame mode
Regression in [0] didn't account for the mesh not having
subdivision surface is applied.

[0]: 75db4c082b
2023-02-12 14:20:52 +11:00
c7456272b1 Cleanup: EEVEE-Next: Add LIGHT_FOREACH macros to clang-format exceptions 2023-02-12 01:41:54 +01:00
77aa9e8809 Cleanup: GPU: Remove commented lines without any comments or purpose
These were added during a big refactor. They were supposed to be
uncommented at some point but the new code does not even need a default
world.
2023-02-12 01:21:53 +01:00
d33960aead Cleanup: remove whole-archive linking for USD
Since USD is no longer statically linked these linker tricks
are no longer needed.

Co-authored-by: Ray Molenkamp <github@lazydodo.com>
Pull Request #104627
2023-02-11 19:48:47 +01:00
085c854b2a Fix curves selection toggling 2023-02-11 19:23:48 +01:00
82867753cf Transform: Hide trackball gizmo while dragging
It was accidentally displayed in a38d99e0b2.
2023-02-11 15:22:57 -03:00
232e02282e Fix circular transform gizmo always displaying Global orientation
The Global orientation comes from the mode's default orientation
(without the constraints).

It's not really exposed.
2023-02-11 15:20:38 -03:00
b9fa32cccd Fix #104587: 'Extrude To Cursor' snapping ignoring 'Target Selection'
Although not a transform operator, `Extrude to Cursor` depends on some
snapping settings.

So it should use the `Target Selection` options as well.
2023-02-11 14:50:37 -03:00
197eee6e04 Fix transform gizmos not changing in Automatic Constraint mode 2023-02-11 13:56:06 -03:00
e732580fcc Nodes: change order of Hide Value and Hide in Modifier
Based on the review comment in #104517.
2023-02-11 16:14:38 +01:00
158f809dcb Geometry Nodes: Add option to hide input in modifier
When building a node group that's meant to be used directly in the
node editor as well as in the modifier, it's useful to be able to have
some inputs that are only meant for the node editor, like inputs that
only make sense when combined with other nodes.

In the future we might have the ability to only display certain assets
in the modifier and the node editor, but until then this simple solution
allows a bit more customization.

Pull Request #104517
2023-02-11 16:11:10 +01:00
19ea673260 Cleanup: Remove const keyword in declarations 2023-02-11 15:05:55 +01:00
b723a398f3 Curves: initial surface collision for curves sculpt mode
During hair grooming in curves sculpt mode, it is very useful when hair strands
are prevented from intersecting with the surface mesh. Unfortunately, it also
decreases performance significantly so we don't want it to be turned on all the time.

The surface collision is used by the Comb, Pinch and Puff brushes currently.
It can be turned on or off on a per-geometry basis.

The intersection prevention quality of this patch is not perfect yet. This can
be improved over time using a better solver. Overall, perfect collision detection
at the cost of bad performance is not necessary for interactive sculpting,
because the user can fix small mistakes very quickly. Nevertheless, the quality
can probably still be improved significantly without too big slow-downs depending
on the use case. This can be done separately from this patch.

Pull Request #104469
2023-02-11 13:46:37 +01:00
0f708fa2e3 Geometry Nodes: use smooth normals in Distribute Points on Faces node
Previously, the node used the "true" normal of every looptri. Now it uses the
"loop normals" which includes e.g. smooth faces and custom normals. The true
normal can still be used on the points by capturing it before the Distribute node.

We do intend to expose the smooth normals separately in geometry nodes as well,
but this is an important first step.

It's also necessary to generate child hair between guide hair strands that don't
have visible artifacts at face boundaries.

For perfect backward compatibility, the node still has a "Legacy Normal" option
in the side bar. Creating the exact same behavior with existing nodes isn't
really possible unfortunately because of the specifics of how the Distribute
node used to compute the normals using looptris.

Pull Request #104414
2023-02-11 13:25:59 +01:00
6478eb565a Cleanup: format 2023-02-11 14:26:56 +11:00
fefc6a73b3 Fix pep8 checker operating on dot-files
Temporary editor files were included which could make the checker fail.
2023-02-11 14:12:43 +11:00
9f4edf8c2a Cleanup: remove unused variables 2023-02-11 14:04:35 +11:00
ce44953933 Cleanup: various C++ cleanups 2023-02-11 14:04:35 +11:00
343bb4a5a3 Cleanup: Use const char * for layer names in collada exporter
CustomData layer names should not be written except via the CusomData
api. Therefore use const char * instead of char * when referencing the
layer name.

Pull Request #104585
2023-02-11 01:13:38 +01:00
efabe81c91 Fix #103903: Bump Node performance regression
Avoid computing the non-derivative height twice.
The height is now computed as part of the main function, while the height at x and y offsets are still computed on a separate function.
The differentials are now computed directly at node_bump.

Co-authored-by: Miguel Pozo <pragma37@gmail.com>
Pull Request #104595
2023-02-10 21:06:53 +01:00
0e6da74e98 Fix #104282: Resolve Depth read for D24_S8 types in Metal.
Fixes incorrect spotlight gizmo orientation when moving.

Authored by Apple: Michael Parkin-White

Related to #96261

Pull Request #104537
2023-02-10 20:40:07 +01:00
8a32d56056 Tests: Fix device list of benchmark script only showing a single GPU
Pull Request #104583
2023-02-10 19:38:37 +01:00
7351f533e0 Curves: Add lasso and circle select
This adds a `select_lasso` and a `select_circle` function for the Curves object. It is used in the `view3d_lasso_select` and `view3d_circle_select` operator.

Co-authored-by: Falk David <falkdavid@gmx.de>
Pull Request #104560
2023-02-10 19:06:08 +01:00
5c4e1ed578 UI: Make text nomenclature and ordering consistent
"Center" -> "Middle" when describing vertical alignment.
"Align X" -> "Horizontal Alignment"
"Align Y" -> "Vertical Alignment"
Vertical alignment options rearranged to be consistently top-most to
bottom-most.

---

Co-authored-by: joshua-maros <60271685+joshua-maros@users.noreply.github.com>
Pull Request #104493
2023-02-10 19:05:37 +01:00
6f8c441950 Curves: Add select linked
This adds a new `select_linked` function that selects all the points
on a curve if there is at least one point already selected.
This also adds a keymap for the operator.

Co-authored-by: Falk David <falkdavid@gmx.de>
Pull Request #104569
2023-02-10 18:58:08 +01:00
d411be8a99 Cleanup: Use utility function to find groups in node tree
Add `contains_group` method in python api for `NodeTree` type, cleanup
`ntreeHasTree` function, reuse `ntreeHasTree` in more place in code.
The algorithm has been changed to not recheck trees by using set.

Performance gains from avoiding already checked node trees:
Based on tests, can say that for large files with a huge number
of trees, the response speed of opening the search menu in the
node editor increased by ~200 times (for really large projects
with 16 individual groups in 6 levels of nesting). Group insert
operations are also accelerated, but this is different in some cases.

Pull Request #104465
2023-02-10 17:30:55 +01:00
fae661a1ab Revert "Un-ignore modules in .gitmodules configuration"
This reverts commit aab707ab70.

A different solution to the submodule problem is being considered in #104573.
Revert to the previous behavior that developers are familiar with for now.
2023-02-10 17:15:28 +01:00
923152d180 Geometry Nodes: improve parallelization in Delete/Separate Geometry node
This just adds `threading::parallel_for` and `threading::parallel_invoke` in a few
places where it can be added trivially. The run time of the `separate_geometry`
function changes from 830 ms to 413 ms in my test file.

Pull Request #104563
2023-02-10 17:14:30 +01:00
0ea15a6fbb Fix: Inaccessible default for node group image sockets
The type was just skipped when drawing defaults for the image sockets.
2023-02-10 09:22:45 -05:00
284cdbb6cf Cleanup: Use lambdas in mesh mapping callback, remove unused arguments
Using callback functions didn't scale well as more arguments are added.
It got very confusing when to pass tehmarguments weren't always used.
Instead use a `FunctionRef` with indices for arguments. Also remove
unused edge arguments to topology mapping functions.
2023-02-10 08:37:50 -05:00
bad2c3b9ef Geometry Nodes: Experimental option for Volumes
Adds an experimental option under "New Features" in preferences,
which enables visibility of the new Volume Nodes.
Right now this option does nothing but will be used during development.
See #103248

Pull Request #104552
2023-02-10 14:21:01 +01:00
88f9c55f7f Sculpt: Fix Dyntopo Warnings
Because of T95965, some attributes are stored as generic attributes
in Mesh but have special handling for the conversion to BMesh.

Expose a function to tell whether certain attribute names are handled
specially in the conversion, and refactor the error checking process
to use it. Also check for generic attributes on the face domain which
wasn't done before.

Author: Hans Goudey
Reviewed By: Joseph Eagar

Co-authored-by: Joseph Eagar <joeedh@gmail.com>
Pull Request #104567
2023-02-10 13:16:10 +01:00
dc9f7fe64f Fix #104514: GPencil merge down layer misses some frames
When merging two gpencil layers, if the destination layer had a keyframe
where the source layer did not, strokes of the previous keyframe
in source layer were lost in that frame.

This happened because the merge operator was looping through
frames of the source layer and appending strokes in the
corresponding destination layer, but never completing
other frames than the ones existing in the source layer.

This patch fixes it by first adding in source layer
all frames that are in destination layer.

Co-authored-by: Amelie Fondevilla <amelie.fondevilla@les-fees-speciales.coop>
Pull Request #104558
2023-02-10 12:55:06 +01:00
Lucas Tadeu Teixeira
5d30c3994e Sequencer: Don't create undo step when click-select does nothing
When the sequencer is empty (i.e., there are no sequences),
we would have the deselect_all variable set to true called
ED_sequencer_deselect_all to select any existing sequences.

Ref !104453
2023-02-10 21:49:42 +11:00
51ceeb506f Fix #104026: Click-Drag to select graph editor channels no longer working
Box-Selecting channels in the dope sheet with click-drag was no longer possible as of Blender 3.2

Due to the removal of tweak events the box select operator was always shadowed by the click operator.

Original Phabricator discussion here: https://archive.blender.org/developer/D17065

Use `WM_operator_flag_only_pass_through_on_press` on click operator to fix it

Co-authored-by: Christoph Lendenfeld <chris.lenden@gmail.com>
Pull Request #104505
2023-02-10 11:36:01 +01:00
01480229b1 Cycles: Fix MetalRT checkbox not hooked up to device on AMD
(Follow on from D17043)
On AMD Navi2 devices the MetalRT checkbox was not hooked up properly and had no effect. This patch fixes it.

Co-authored-by: Michael Jones <michael_p_jones@apple.com>
Pull Request #104520
2023-02-10 10:55:39 +01:00
b77c82e2bb Tests: minor updates to make bl_rna_manual_reference more useful
- Avoid flooding the output with every match that succeeds.
- Report patterns listed in the manual that don't match anything in
  Blender.
- Disable external URL lookups, this is too slow.
  Instead use a LOCAL_PREFIX (a local build of the manual)
  or skip the test.
2023-02-10 14:04:15 +11:00
c2c62c3618 RNA: return a dummy language value when WITH_INTERNATIONAL=OFF
Without this, every access to "language" would warn that the enum
value didn't match a value in the enum items.

This made the bl_rna_manual_reference.py test output practically
unusable.
2023-02-10 13:18:33 +11:00
a8d951abdd Docs: remove malformed patterns for RNA mapping
The generator now skips these with a warning, they will need to be
corrected in the user manual.

This caused tests/python/bl_rna_manual_reference.py to fail looking
up URL's.
2023-02-10 13:04:27 +11:00
4cbe0bff34 Cleanup: spelling in comments 2023-02-10 11:34:20 +11:00
48d9363fa7 Cleanup: quiet clang compiler warnings
- undeclared variable warning.
- unreachable-code-return warnings.
- array-parameter, mismatch bound.
- 'requires' is a keyword in C++20, (rename to requires_flag).
2023-02-10 11:27:30 +11:00
8ac3096e24 Fix add-on & manual link in Help menu ignoring the current language
Use bpy.utils.manual_language_code() create manual URL's instead of
assuming English.
2023-02-10 11:02:45 +11:00
2ee9c12a23 PyAPI: add bpy.utils.manual_locale_code()
Move the function for getting the language code associated with the
user manual into a utility function (from the generated
rna_manual_reference.py).

This allows other parts of Blender to create a manual URL based on the
current locale preferences and environment.

Ref !104494
2023-02-10 11:01:02 +11:00
2d351e9ee3 Cleanup: format 2023-02-10 10:48:50 +11:00
7e0e07657c GPU: Cleanup GPU_batch.h documentation and some of the API for consistency
Documented all functions, adding use case and side effects.

Also replace the use of shortened argument name by more meaningful ones.

Renamed `GPU_batch_instbuf_add_ex` and `GPU_batch_vertbuf_add_ex` to remove
the `ex` suffix as they are the main version used (removed the few usage
of the other version).

Renamed `GPU_batch_draw_instanced` to `GPU_batch_draw_instance_range` and
make it consistent with `GPU_batch_draw_range`.
2023-02-09 22:46:35 +01:00
5c8edbd99b Cleanup: Move 6 sculpt-session-related files and header to C++
To allow further mesh data structure refactoring. See #103343

Pull Request #104540
2023-02-09 20:35:50 +01:00
2cfc4d7644 Fix #104383: don't update declaration for clipboard copy
When nodes are copied to the clipboard, they don't need their declaration.
For nodes with dynamic declaration that might depend on the node tree itself,
the declaration could not be build anyway, because the node-clipboard does
not have a node tree.

Pull Request #104432
2023-02-09 19:20:39 +01:00
bc0d3c91b1 Fix #104435: Fix rna_NlaStrip_new add strip logic to be correct boolean expression
Fixed #104435: Use correct conditional logic when testing if a new NLA strip can be added in the rna_NlaStrip_new method
2023-02-09 19:09:27 +01:00
50918d44fb Cleanup: Fix const correctness warning in recent commit 2023-02-09 11:26:38 -05:00
Kevin C. Burke
1649921791 Fix: Sequencer "Pan" label using incorrect keyword 'heading_ctxt'
Oversight in db87e2a638

Reviewed By: ISS
Differential Revision: https://archive.blender.org/developer/D17213
2023-02-09 16:33:50 +01:00
50dfd5f501 Geometry Nodes: Edges to Face Groups Node
Add a new node that groups faces inside of boundary edge regions.
This is the opposite action as the existing "Face Group Boundaries"
node. It's also the same as some of the "Initialize Face Sets"
options in sculpt mode.

Discussion in #102962 has favored "Group" for a name for these
sockets rather than "Set", so that is used here.

Pull Request #104428
2023-02-09 16:27:20 +01:00
bfa7f9db0e Assets: Implement viewport drag and drop for geometry nodes
Currently there's no way to assign a geometry node group from the asset
browser to an object as a modifier without first appending/linking it
manually. This patch adds a drag and drop operator that adds a new
modifier and assigns the dragged tree.

Pull Request #104430
2023-02-09 16:04:14 +01:00
b8e15a4a84 Fix: Add missing "-" in logic to get the channel height
This was missed when doing the refactoring in #104500
It didn't seem to have any effect until I worked on clamping the view
2023-02-09 15:59:57 +01:00
7ca651d182 Mesh: Remove unnecessary edge draw flag
As described in #95966, replace the `ME_EDGEDRAW` flag with a bit
vector in mesh runtime data. Currently the the flag is only ever set
to false for the "optimal display" feature of the subdivision surface
modifier. When creating an "original" mesh in the main data-base,
the flag is always supposed to be true.

The bit vector is now created by the modifier only as necessary, and
is cleared for topology-changing operations. This fixes incorrect
interpolation of the flag as noted in #104376. Generally it isn't
possible to interpolate it through topology-changing operations.

After this, only the seam status needs to be removed from edges before
we can replace them with the generic `int2` type (or something similar)
and reduce memory usage by 1/3.

Related:
- 10131a6f62
- 145839aa42

In the future `BM_ELEM_DRAW` could be removed as well. Currently it is
used and aliased by other defines in some non-obvious ways though.

Pull Request #104417
2023-02-09 15:56:05 +01:00
3bed78ff59 Curves: Add box selection
This adds a `select_box` function for the `Curves` object. It is used in the `view3d_box_select` operator.

It also adds the basic selection tools in the toolbar of Edit Mode.

Authored-by: Falk David <falkdavid@gmx.de>
Pull Request #104411
2023-02-09 15:53:42 +01:00
22edf04458 I18n: use format strings for Cycles version error messages
The required version numbers for various devices was hardcoded in the
UI messages. The result was that every time one of these versions was
bumped, every language team had to update the message in question.

Instead, the version numbers can be extracted, and injected into the
error messages using string formatting so that translation updates
need happen less frequently.

Pull Request #104488
2023-02-09 15:48:19 +01:00
666c2ea012 Refactor: remove yscale from bAnimContext
`bAnimContext` had a float property called `yscale_fac` that was used to define the height of the keyframe channels.

However the property was never set, only read so there really is no need to have it in the struct.

Moreover it complicated getting the channel height because `bAnimContext` had to be passed in.

Speaking of getting the channel height. This was done with macros. I ripped them all out and replaced them with function calls.

Originally it was introduced in this patch: https://developer.blender.org/rB095c8dbe6919857ea322b213a1e240161cd7c843

Co-authored-by: Christoph Lendenfeld <chris.lenden@gmail.com>
Pull Request #104500
2023-02-09 14:28:04 +01:00
ca183993a5 Fix freeing uninitialized pointer in GHOST/Wayland + X11 fallback
Freeing the timer manager didn't account for Wayland being partially
initialized.
2023-02-09 23:41:03 +11:00
0e196bab76 Build: disable LTO for Python builds
LTO compiled libpython3.10.a failed to link with GCC 12.0,
disable since these libraries are intended for developers to link
against.
2023-02-09 23:00:08 +11:00
f222fe6a3a Build: enable Python optimizations (PGO & LTO) on Linux
This is used for most Python release builds and has been reported to
give a modest 5-10% speedup (depending on the workload).

This could be enabled on macOS too but needs to be tested.
2023-02-09 20:59:08 +11:00
8b35db914e GPU: Fix assert when using light gizmo.
Blender was reporting that the GPU_TEXTURE_USAGE_HOST_READ wasn't set.
This is used to indicate that the textures needs to be read back to
CPU. Textures that don't need to be read back can be optimized by the
GPU backend.

Found during investigation of #104282.
2023-02-09 08:36:27 +01:00
1883e782cb Spelling: Assert message in GPU_texture_read. 2023-02-09 08:11:11 +01:00
7effc6ffc4 Cleanup: solve compiler warnings.
Classes were predefined as structs.
2023-02-09 08:01:33 +01:00
f3d7de709f Cycles: update Intel Graphics Compiler to 1.0.13064.7 on Linux
Linux side of 8afcecdf1f.

Reviewed by: LazyDodo, sergey, campbellbarton
Ref !104458, 16984
2023-02-09 15:43:23 +11:00
3c8f7b1a64 Cleanup: Remove unused/redundant includes from BKE_curves.hh
Avoid including headers that are obviously redundant, and don't
include BLI_task.hh in the header file, since it isn't really related.
2023-02-08 20:29:52 -05:00
0381fe7bfe Cleanup: update username in code-comments: campbellbarton -> ideasman42
Gitea migration changed my username, update code-comments.
2023-02-09 11:33:48 +11:00
5f842ef336 Cleanup: spelling in comments 2023-02-09 11:24:50 +11:00
5b110548eb Cleanup: enum conversion compiler warnings 2023-02-09 11:18:32 +11:00
9fd71d470e PyAPI: minor change to rna_manual_reference loading
- Use bpy.utils.execfile instead of importing then deleting from
  sys.modules.
- Add a note for why keeping this cached in memory isn't necessary.

This has the advantage of not interfering with any scripts that import
`rna_manual_reference` as a module.
2023-02-09 11:18:15 +11:00
94d280fc3f EEVEE-Next: Shadows: Add global switch
This allow to bypass all cost associated with shadow mapping.

This can be useful in certain situation, such as opening a scene on a
lower end system or just to gain performance in some situation (lookdev).
2023-02-09 00:48:33 +01:00
9103978952 EEVEE-Next: Shadow: Fix issue with last merge
The merge with master updated the code to use the new matrix API. This
introduce some regressions.

For sunlights make sure there is enough tilemaps in orthographic mode
to cover the depth range and fix the level offset in perspective.
2023-02-08 23:45:12 +01:00
9c03a1c92f Fix Cycles link error with debug/asan builds after recent bugfix
Pull Request #104487
2023-02-08 23:20:29 +01:00
a0f5240089 EEVEE-Next: Virtual Shadow Map initial implementation
Implements virtual shadow mapping for EEVEE-Next primary shadow solution.
This technique aims to deliver really high precision shadowing for many
lights while keeping a relatively low cost.

The technique works by splitting each shadows in tiles that are only
allocated & updated on demand by visible surfaces and volumes.
Local lights use cubemap projection with mipmap level of detail to adapt
the resolution to the receiver distance.
Sun lights use clipmap distribution or cascade distribution (depending on
which is better) for selecting the level of detail with the distance to
the camera.

Current maximum shadow precision for local light is about 1 pixel per 0.01
degrees.
For sun light, the maximum resolution is based on the camera far clip
distance which sets the most coarse clipmap.

## Limitation:
Alpha Blended surfaces might not get correct shadowing in some corner
casses. This is to be fixed in another commit.
While resolution is greatly increase, it is still finite. It is virtually
equivalent to one 8K shadow per shadow cube face and per clipmap level.
There is no filtering present for now.

## Parameters:
Shadow Pool Size: In bytes, amount of GPU memory to dedicate to the
shadow pool (is allocated per viewport).
Shadow Scaling: Scale the shadow resolution. Base resolution should
target subpixel accuracy (within the limitation of the technique).

Related to #93220
Related to #104472
2023-02-08 21:18:44 +01:00
0ab3ac7a41 BLI: Math: Fix vector operator * with MutableMatView
This was caused by operator priority trying to use
`friend VecBase operator*(const VecBase &a, FactorT b)`.

Adding tests as these were not covered.
2023-02-08 19:38:53 +01:00
a1282ab015 Fix Cycles debug build error after host falback changes
Introduced in dcfb6df9ce6.

Co-authored-by: Lucas Tadeu Teixeira <lucas@lucastadeu.com>

Pull Request #104454
2023-02-08 19:27:40 +01:00
43f308f216 Make update: Ignore submodules
The previous change in the .gitmodules made it so the `make update`
rejects to do its thing because it now sees changes in the submodules
and rejected to update, thinking there are unstaged changes.

Ignore the submodule changes, bringing the old behavior closer to
what it was.
2023-02-08 14:05:50 +01:00
aab707ab70 Un-ignore modules in .gitmodules configuration
The meaning of the ignore option for submodules did change since our
initial Git setup was done: back then it was affecting both diff and
stage families of Git command. Unfortunately, the actual behavior did
violate what documentation was stating (the documentation was stating
that the option only affects diff family of commands). This got fixed
in Git some time after our initial setup and it was the behavior of the
commands changed, not the documentation. This lead to a situation when
we can no longer see that submodules are modified and staged, and it is
very easy to stage the submodules.

For the clarity: diff and status are both "status" family, show and
diff are "diff" family.

Hence this change: since there is no built-in zero-configuration way
of forbidding Git from staging submodules lets make it visible and
clear what the state of submodules is.

We still need to inform people to not stage submodules, for which
we can offer some configuration tips and scripts but doing so is
outside of the scope of this change at it requires some additional
research. Current goal is simple: make it visible and clear what is
going to be committed to Git.

This is a response to an increased frequency of incidents when the
submodules are getting modified and committed without authors even
noticing this (which is also a bit annoying to recover from).

Differential Revision: https://developer.blender.org/D13001
2023-02-08 11:32:32 +01:00
4ed8a360e9 Fix references to the main branch in the .gitmodules 2023-02-08 11:01:01 +01:00
4d3bfb3f41 Subdivision Surface: fix a serious performance hit when mixing CPU & GPU.
Subdivision surface efficiency relies on caching pre-computed topology
data for evaluation between frames. However, while eed45d2a23
introduced a second GPU subdiv evaluator type, it still only kept
one slot for caching this runtime data per mesh.

The result is that if the mesh is also needed on CPU, for instance
due to a modifier on a different object (e.g. shrinkwrap), the two
evaluators are used at the same time and fight over the single slot.
This causes the topology data to be discarded and recomputed twice
per frame.

Since avoiding duplicate evaluation is a complex task, this fix
simply adds a second separate cache slot for the GPU data, so that
the cost is simply running subdivision twice, not recomputing topology
twice.

To help diagnostics, I also add a message to show when GPU evaluation
is actually used to the modifier panel. Two frame counters are used
to suppress flicker in the UI panel.

Differential Revision: https://developer.blender.org/D17117

Pull Request #104441
2023-02-08 10:27:22 +01:00
d781e52ee0 Cleanup: use enum literals, order likely case first in polyfill_2d 2023-02-08 17:06:54 +11:00
09eb4fe19a Fix #103913: Triangulate sometimes creates degenerate triangles
The ear clipping method used by polyfill_2d only excluded concave ears
which meant ears exactly co-linear edges created zero area triangles
even when convex ears are available.

While polyfill_2d prioritizes performance over *pretty* results,
there is no need to pick degenerate triangles with other candidates
are available. As noted in code-comments, callers that require higher
quality tessellation should use BLI_polyfill_beautify.
2023-02-08 16:59:42 +11:00
6aa1b5d031 Cleanup: format 2023-02-08 00:21:57 +01:00
5c994d7846 Fix #104297: Cycling geometry nodes viewer ignores sockets
Sockets after the geometry socket were ignored when cycling through
the node's output sockets. If there are multiple geometry sockets, the
behavior could still be refined probably, but this should at least make
basic non-geometry socket cycling work.
2023-02-07 16:01:54 -05:00
53b057aa09 Cleanup: Move 18 sculpt files to C++
To allow further mesh data structure refactoring. See #103343

Pull Request #104436
2023-02-07 21:56:45 +01:00
e817cff009 Release: support generating LTS release notes from Gitea
Now a single script to generate both links and release notes. It also includes
the issue ID for the LTS releases, so only the release version needs to be
specified.

Pull Request #104402
2023-02-07 21:23:24 +01:00
41ddd3d732 Fix: Experimental Panel links modified for Gitea
Modifies the links to point to the new developer site.

Pull Request #104425
2023-02-07 19:54:43 +01:00
f5552d759c Fix compiler error 2023-02-07 18:32:24 +01:00
f01bf82480 Curves: Add select pick operator
This adds the `select_pick` function for to `Curves` objects.
It is used in the common `view3d_select` operator.

Pull Request #104406
2023-02-07 17:50:39 +01:00
8d9d16fb53 Fix #104396: Blender crashes when moving Keyframes in Graph Editor
`t->region->gizmo_map` can be `nullptr`.

Caused by 19b63b932d
2023-02-07 12:59:35 -03:00
349350b304 Fix T104390: Regression: Object selection in viewport is not working
Caused by alignment difference between C and C++. Asan caught the issue
on startup.

Removing the unused view matrix storage copy avoids this problem.
2023-02-07 16:45:47 +01:00
cb5318b651 Docs: change Git URLs to point projects.blender.org instead of git.blender.org 2023-02-07 14:23:05 +01:00
bd6b0bac88 Update references to the new projects platform and main branch 2023-02-07 14:18:19 +01:00
3002670332 Fix T104368: Incorrect tooltip text in Blender 3.4.1's Preferences > File Paths > Scripts field.
Use backticks to cleary identify 'path' parts of this tooltip.
2023-02-07 09:50:50 +01:00
f086cf3cea Cleanup: remove redundant parenthesis 2023-02-07 17:34:20 +11:00
2609ca2b8e Cleanup: tweaks to cycles/metal preferences
- Auto-format.
- Use raw string for regex.
- Remove redundant assignment.
- Remove duplicate arm64 check.
- Break early out of loop.
2023-02-07 17:30:13 +11:00
b-init
7e8153b07d Keymap: support default shortcut to toggle overlays in all space-types
UV Editor, Image Editor & Sequencer didn't have a shortcut for toggling
overlays. Use the same shortcut as the 3D viewport.

Ref D16959
2023-02-07 16:54:06 +11:00
622cad7073 Cleanup: minor tweak to recent fix for T10438
Minor change to [0], prefer calling em_setup_viewcontext,
even though there is no functional difference at the moment,
if this function ever performs additional operations than assigning
`ViewContext.em`, it would have to be manually in-lined in
`view3d_circle_select_recalc`.

[0]: 430cc9d7bf
2023-02-07 16:18:30 +11:00
44daeaae7d Cleanup: use arg instead of param for generated sphinx docs 2023-02-07 15:14:22 +11:00
db8b5a2316 PyDoc: remove deprecated dpi argument from BLF example 2023-02-07 15:12:05 +11:00
dbca0cc9d5 Fix crash on exit under Wayland
Order of free error from [0] caused the timer manager
to be freed before the timer.

[0]: 7de1a4d1d8
2023-02-07 15:12:05 +11:00
e4f77c1a6c Cleanup: format 2023-02-07 16:57:35 +13:00
Jon Denning
e27c89c7c7 Docs: added missing documentation for WindowManager methods
Added missing documentation for `draw_cursor_add` and
`draw_cursor_remove` methods for `WindowManager`.

Differential Revision: https://developer.blender.org/D14860
2023-02-06 22:40:10 -05:00
af5706c960 Docs: improve doc-string for WM_operator_flag_only_pass_through_on_press
The doc-string didn't provide any context for how the funciton is
intended to be used.
2023-02-07 14:18:59 +11:00
a99022e22d Cleanup: spelling in comments 2023-02-07 14:17:01 +11:00
d5af895419 Fix missing matrix includes 2023-02-07 14:07:21 +11:00
Jason Fielder
8703db393b Metal: Ensure explicit return after discard to eliminate differences in behaviour between GPUs.
Discard is not always treated as an explicit return and flow control can continue for required derivative calculations. This behaviour is different in Metal vs OpenGL. Adding return after discards ensures consistency in expectation as behaviour is well-defined.

Authored by Apple: Michael Parkin-White

Ref T96261

Reviewed By: fclem

Maniphest Tasks: T96261

Differential Revision: https://developer.blender.org/D17199
2023-02-07 00:58:06 +01:00
Jason Fielder
f152159101 Metal: Guard advanced command buffer debugging behind OS version flag.
Authored by Apple: Michael Parkin-White

Ref T96261

Reviewed By: fclem

Maniphest Tasks: T96261

Differential Revision: https://developer.blender.org/D17181
2023-02-07 00:51:16 +01:00
d3500c482f Cleanup: Move DRW_pbvh.h header to C++
For continued refactoring of the Mesh data structure. See T103343.
2023-02-06 16:52:02 -05:00
3a1583972a Fix T104256: Curve to points node skips curve domain attributes
7536abbe16 forgot to port the curve domain attributes.
2023-02-06 16:30:25 -05:00
6dcfb6df9c Cycles: Abstract host memory fallback for GPU devices
Host memory fallback in CUDA and HIP devices is almost identical.
We remove duplicated code and create a shared generic version that
other devices (oneAPI) will be able to use.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D17173
2023-02-06 22:19:32 +01:00
b0b9e746fa BLI: Use BLI_math_matrix_type.hh instead of BLI_math_float4x4.hh
Straightforward port. I took the oportunity to remove some C vector
functions (ex: copy_v2_v2).

This makes some changes to DRWView to accomodate the alignement
requirements of the float4x4 type.
2023-02-06 21:25:45 +01:00
5926f69f39 Format comment 2023-01-23 12:20:11 +01:00
167b3bb17d Add paper citation and format comments 2023-01-23 12:15:22 +01:00
035ee375ac Use functions in bsdf_microfacet.h 2023-01-23 11:58:15 +01:00
05e7caed94 Merge branch 'master' into microfacet_hair 2023-01-23 10:22:28 +01:00
33ff1ce7b2 Merge code for circular and elliptical cross-sections 2023-01-20 20:11:30 +01:00
46bc834a3d Merge branch 'master' into microfacet_hair 2023-01-20 15:18:29 +01:00
0383da5f44 Cleanup: unify notations: O for outgoing direction, I for incoming/viewing/camera direction 2023-01-16 18:53:21 +01:00
935f500501 Reuse albedo functions in principled hair BSDF 2023-01-16 16:49:52 +01:00
9e5c1787a5 Remove empirical scaling to match microfacet and principled hair BSDF 2023-01-16 16:20:00 +01:00
f0529cfabc Add support for OSL shader to microfacet hair model 2023-01-16 16:16:58 +01:00
e69877c217 Cleanup: renaming and formatting comments 2023-01-12 19:52:24 +01:00
5c9581920e Remove node input "Blur" 2023-01-12 18:40:43 +01:00
0da0f29c17 Replace legacy custom fields with node storage struct 2023-01-12 17:55:01 +01:00
9b99cc216b Add description to shader node inputs 2023-01-11 20:09:31 +01:00
f7f0888635 Renaming R lobe to Reflection 2023-01-11 18:42:52 +01:00
f88b91fe61 Split model_type into cross_section_type and distribution_type
Also disable analytical GGX R because it seems confusing
2023-01-11 18:23:04 +01:00
08684b2601 Merge branch 'master' into microfacet_hair 2023-01-10 13:24:52 +01:00
c1413e64d1 Deal with cases where derivatives = 0 2023-01-09 18:26:53 +01:00
8ee7e626a5 Interpolate between the curvature vector and the minimal twist vector
with custom weight
2023-01-09 17:32:17 +01:00
74cab3ea05 Cleanup: remove unneeded variable 2023-01-06 14:26:13 +01:00
148e954dbb Add comment to failed test 2023-01-06 13:04:53 +01:00
b47fc535f1 Merge branch 'master' into microfacet_hair 2023-01-06 11:44:26 +01:00
6b5f323b90 Small modification to comment 2023-01-05 18:27:57 +01:00
5015c8219b Compute hair normal with minimal total potential energy
Although computed in the geometry node, this normal is specific for
hairs is only implemented for Catmull-Rom splines. Questions remain
whether this should be generalized, also a few design ideas are obscure.
{F14115834}
2023-01-05 17:46:59 +01:00
8af16fd087 Fix compiler error in the normal and tangent computation 2023-01-02 16:14:42 +01:00
93e0559f54 WIP: calculate normals aligned with the curvature vector
Only works for Catmull-Rom and poly curve types for now
2023-01-02 15:49:28 +01:00
c574ddc104 Fix wrong interval numbers in composite Simpson's method 2022-12-28 12:41:33 +01:00
767eb3cd6a Only add normal attributes for elliptical hairs 2022-12-27 13:52:25 +01:00
8bad526d51 Fix normal attribute was defined per curve instead of per key 2022-12-27 13:51:58 +01:00
4990122abb Merge branch 'master' into microfacet_hair 2022-12-27 11:07:13 +01:00
b1c549059d Cleanup: remove unused variables 2022-12-22 18:49:09 +01:00
4415ebc336 Cleanup: rename eccentricity -> aspect ratio 2022-12-22 18:47:21 +01:00
e73d4734f9 Switch normal and binormal if aspect ratio larger than 1 2022-12-22 18:35:54 +01:00
f4987bdb06 Treat hair as transparent if intersection lies outside of the radius 2022-12-22 18:24:58 +01:00
9c59a200b5 Add TODO for curve API 2022-12-22 15:55:04 +01:00
c80ff8a39d Add comments to normal computations 2022-12-22 15:21:39 +01:00
ba62e31b45 Compute normal for new hair system 2022-12-22 15:13:07 +01:00
8125657606 Pass dummy normal to elliptical hairs 2022-12-22 15:05:00 +01:00
5e21a0909c Cleanup: formatting and fast_sincosf() call 2022-12-20 12:05:35 +01:00
63d51d3305 Cleanup: formatting float 2022-12-19 20:22:37 +01:00
a8608aab3d Merge branch 'master' into microfacet_hair 2022-12-19 20:09:43 +01:00
d96320c2da Cleanup: pass pointer of variable that will be modified 2022-12-19 20:08:36 +01:00
028918661a Fix variable passed to fresnel() being NaN sometimes 2022-12-19 20:03:03 +01:00
bf0075f886 Cleanup: delete unused variables 2022-12-19 19:22:29 +01:00
0c07582169 Cleanup: minor API change for sample_wh()` 2022-12-19 19:18:42 +01:00
b08064d867 Start with less parameters 2022-12-19 17:09:20 +01:00
5be12da189 Merge branch 'master' into microfacet_hair 2022-12-16 15:43:44 +01:00
f15010bbe6 Remove unnecessary Jacobians 2022-12-15 16:16:13 +01:00
7bd7538b25 Revert to original implementation (needs investigation) 2022-12-14 15:18:43 +01:00
1edaee9926 Cleanup: renaming a few functions and variables 2022-12-14 15:13:15 +01:00
4234a8017e Merge branch 'master' into microfacet_hair 2022-12-13 11:47:00 +01:00
e5dc796da9 Cleanup: remove unused variables in fresnel() 2022-12-07 18:08:09 +01:00
cc7317af53 Cleanup: adjust the usage and naming of a few utility functions 2022-12-07 17:20:15 +01:00
68573757bc Cycles: initial commit of microfacet hair bsdf
This is an implementation of the paper [A Microfacet-based Hair Scattering Model](https://onlinelibrary.wiley.com/doi/full/10.1111/cgf.14588) by Weizhen Huang, Matthias Hullin, and Johannes Hanika.
Original implementation in [Mitsuba 2](https://github.com/RiverIntheSky/roughhair) by Weizhen Huang.
Adapted to Cycles by Olivier Maury D16682 and Christophe Hery.
2022-12-06 18:43:56 +01:00
2354 changed files with 2111884 additions and 26914 deletions

View File

@@ -1,8 +0,0 @@
{
"project_id" : "Blender",
"conduit_uri" : "https://developer.blender.org/",
"phabricator.uri" : "https://developer.blender.org/",
"git.default-relative-commit" : "origin/master",
"arc.land.update.default" : "rebase",
"arc.land.onto.default" : "master"
}

View File

@@ -236,6 +236,8 @@ ForEachMacros:
- LOOP_UNSELECTED_POINTS
- LOOP_VISIBLE_KEYS
- LOOP_VISIBLE_POINTS
- LIGHT_FOREACH_BEGIN_DIRECTIONAL
- LIGHT_FOREACH_BEGIN_LOCAL
- LISTBASE_CIRCULAR_BACKWARD_BEGIN
- LISTBASE_CIRCULAR_FORWARD_BEGIN
- LISTBASE_FOREACH

View File

@@ -2,4 +2,4 @@ ${CommitTitle}
${CommitBody}
Pull Request #${PullRequestIndex}
Pull Request: https://projects.blender.org/blender/blender/pulls/${PullRequestIndex}

View File

@@ -1,3 +1,3 @@
${PullRequestTitle}
Pull Request #${PullRequestIndex}
Pull Request: https://projects.blender.org/blender/blender/pulls/${PullRequestIndex}

View File

@@ -1,9 +1,9 @@
name: Bug Report
about: File a bug report
labels:
- "type::Report"
- "status::Needs Triage"
- "priority::Normal"
- "Type/Report"
- "Status/Needs Triage"
- "Priority/Normal"
body:
- type: markdown
attributes:

View File

@@ -1,7 +1,7 @@
name: Design
about: Create a design task (for developers only)
labels:
- "type::Design"
- "Type/Design"
body:
- type: textarea
id: body

View File

@@ -1,7 +1,7 @@
name: To Do
about: Create a to do task (for developers only)
labels:
- "type::To Do"
- "Type/To Do"
body:
- type: textarea
id: body

View File

@@ -1,5 +1,4 @@
This repository is only used as a mirror of git.blender.org. Blender development happens on
https://developer.blender.org.
This repository is only used as a mirror. Blender development happens on projects.blender.org.
To get started with contributing code, please see:
https://wiki.blender.org/wiki/Process/Contributing_Code

3
.github/stale.yml vendored
View File

@@ -15,8 +15,7 @@ staleLabel: stale
# Comment to post when closing a stale Issue or Pull Request.
closeComment: >
This issue has been automatically closed, because this repository is only
used as a mirror of git.blender.org. Blender development happens on
developer.blender.org.
used as a mirror. Blender development happens on projects.blender.org.
To get started contributing code, please read:
https://wiki.blender.org/wiki/Process/Contributing_Code

20
.gitignore vendored
View File

@@ -39,7 +39,7 @@ Desktop.ini
/doc/python_api/rst/bmesh.ops.rst
# in-source lib downloads
/build_files/build_environment/downloads
/build_files/build_environment/downloads/
# in-source buildbot signing configuration
/build_files/buildbot/codesign/config_server.py
@@ -48,4 +48,20 @@ Desktop.ini
waveletNoiseTile.bin
# testing environment
/Testing
/Testing/
# Translations.
/locale/user-config.py
# External repositories.
/scripts/addons/
/scripts/addons_contrib/
# Ignore old submodules directories.
# Eventually need to get rid of those, but for the first time of transition
# avoid indidents when the folders exists after bisect and developers staging
# them by accident.
/release/scripts/addons/
/release/datafiles/locale/
/release/scripts/addons_contrib/
/source/tools/

20
.gitmodules vendored
View File

@@ -1,20 +0,0 @@
[submodule "release/scripts/addons"]
path = release/scripts/addons
url = ../blender-addons.git
branch = master
ignore = all
[submodule "release/scripts/addons_contrib"]
path = release/scripts/addons_contrib
url = ../blender-addons-contrib.git
branch = master
ignore = all
[submodule "release/datafiles/locale"]
path = release/datafiles/locale
url = ../blender-translations.git
branch = master
ignore = all
[submodule "source/tools"]
path = source/tools
url = ../blender-dev-tools.git
branch = master
ignore = all

View File

@@ -331,7 +331,6 @@ option(WITH_MOD_REMESH "Enable Remesh Modifier" ON)
option(WITH_MOD_OCEANSIM "Enable Ocean Modifier" ON)
# Image format support
option(WITH_OPENIMAGEIO "Enable OpenImageIO Support (http://www.openimageio.org)" ON)
option(WITH_IMAGE_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON)
option(WITH_IMAGE_OPENJPEG "Enable OpenJpeg Support (http://www.openjpeg.org)" ON)
option(WITH_IMAGE_TIFF "Enable LibTIFF Support" ON)
@@ -358,6 +357,7 @@ option(WITH_MATERIALX "Enable MaterialX Support" OFF)
# Disable opencollada when we don't have precompiled libs
option(WITH_OPENCOLLADA "Enable OpenCollada Support (http://www.opencollada.org)" ON)
option(WITH_IO_WAVEFRONT_OBJ "Enable Wavefront-OBJ 3D file format support (*.obj)" ON)
option(WITH_IO_PLY "Enable PLY 3D file format support (*.ply)" ON)
option(WITH_IO_STL "Enable STL 3D file format support (*.stl)" ON)
option(WITH_IO_GPENCIL "Enable grease-pencil file format IO (*.svg, *.pdf)" ON)
@@ -524,7 +524,7 @@ endif()
if(NOT APPLE)
option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" ON)
option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF)
set(CYCLES_HIP_BINARIES_ARCH gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 gfx1035 gfx1100 gfx1101 gfx1102 CACHE STRING "AMD HIP architectures to build binaries for")
set(CYCLES_HIP_BINARIES_ARCH gfx900 gfx906 gfx90c gfx902 gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 gfx1035 gfx1100 gfx1101 gfx1102 CACHE STRING "AMD HIP architectures to build binaries for")
mark_as_advanced(WITH_CYCLES_DEVICE_HIP)
mark_as_advanced(CYCLES_HIP_BINARIES_ARCH)
endif()
@@ -625,8 +625,10 @@ mark_as_advanced(
# Vulkan
option(WITH_VULKAN_BACKEND "Enable Vulkan as graphics backend (only for development)" OFF)
option(WITH_VULKAN_GUARDEDALLOC "Use guardedalloc for host allocations done inside Vulkan (development option)" OFF)
mark_as_advanced(
WITH_VULKAN_BACKEND
WITH_VULKAN_GUARDEDALLOC
)
# Metal
@@ -890,8 +892,6 @@ set_and_warn_dependency(WITH_IMAGE_TIFF WITH_HARU OFF)
# auto enable openimageio for cycles
if(WITH_CYCLES)
set(WITH_OPENIMAGEIO ON)
# auto enable llvm for cycles_osl
if(WITH_CYCLES_OSL)
set(WITH_LLVM ON CACHE BOOL "" FORCE)
@@ -952,21 +952,6 @@ endif()
# -----------------------------------------------------------------------------
# Check if Sub-modules are Cloned
if(WITH_INTERNATIONAL)
file(GLOB RESULT "${CMAKE_SOURCE_DIR}/release/datafiles/locale")
list(LENGTH RESULT DIR_LEN)
if(DIR_LEN EQUAL 0)
message(
WARNING
"Translation path '${CMAKE_SOURCE_DIR}/release/datafiles/locale' is missing, "
"This is a 'git submodule', which are known not to work with bridges to other version "
"control systems."
)
set(TRANSLATIONS_FOUND OFF)
set_and_warn_library_found("Translations" TRANSLATIONS_FOUND WITH_INTERNATIONAL)
endif()
endif()
if(WITH_PYTHON)
# While we have this as an '#error' in 'bpy_capi_utils.h',
# upgrading Python tends to cause confusion for users who build.
@@ -982,14 +967,14 @@ if(WITH_PYTHON)
)
endif()
file(GLOB RESULT "${CMAKE_SOURCE_DIR}/release/scripts/addons")
file(GLOB RESULT "${CMAKE_SOURCE_DIR}/scripts/addons")
list(LENGTH RESULT DIR_LEN)
if(DIR_LEN EQUAL 0)
message(
WARNING
"Addons path '${CMAKE_SOURCE_DIR}/release/scripts/addons' is missing, "
"This is a 'git submodule', which are known not to work with bridges to other version "
"control systems: * CONTINUING WITHOUT ADDONS *"
"Addons path '${CMAKE_SOURCE_DIR}/scripts/addons' is missing. "
"This is an external repository which needs to be checked out. Use `make update` to do so. "
"* CONTINUING WITHOUT ADDONS *"
)
endif()
endif()
@@ -1098,13 +1083,6 @@ if(NOT WITH_FFTW3 AND WITH_MOD_OCEANSIM)
endif()
if(WITH_CYCLES)
if(NOT WITH_OPENIMAGEIO)
message(
FATAL_ERROR
"Cycles requires WITH_OPENIMAGEIO, the library may not have been found. "
"Configure OIIO or disable WITH_CYCLES"
)
endif()
if(WITH_CYCLES_OSL)
if(NOT WITH_LLVM)
message(
@@ -1955,8 +1933,7 @@ if(FIRST_RUN)
info_cfg_option(WITH_IMAGE_OPENEXR)
info_cfg_option(WITH_IMAGE_OPENJPEG)
info_cfg_option(WITH_IMAGE_TIFF)
info_cfg_option(WITH_OPENIMAGEIO)
info_cfg_text("Audio:")
info_cfg_option(WITH_CODEC_AVI)
info_cfg_option(WITH_CODEC_FFMPEG)

View File

@@ -69,7 +69,7 @@ Static Source Code Checking
* check_cmake: Runs our own cmake file checker which detects errors in the cmake file list definitions.
* check_pep8: Checks all Python script are pep8 which are tagged to use the stricter formatting.
* check_mypy: Checks all Python scripts using mypy,
see: source/tools/check_source/check_mypy_config.py scripts which are included.
see: tools/check_source/check_mypy_config.py scripts which are included.
Documentation Checking
@@ -85,7 +85,7 @@ Spell Checkers
* check_spelling_osl: Check for spelling errors (OSL only).
* check_spelling_py: Check for spelling errors (Python only).
Note: an additional word-list is maintained at: 'source/tools/check_source/check_spelling_c_config.py'
Note: an additional word-list is maintained at: 'tools/check_source/check_spelling_c_config.py'
Note: that spell checkers can take a 'CHECK_SPELLING_CACHE' filepath argument,
so re-running does not need to re-check unchanged files.
@@ -299,7 +299,11 @@ else
ifneq ("$(wildcard $(DEPS_BUILD_DIR)/build.ninja)","")
DEPS_BUILD_COMMAND:=ninja
else
DEPS_BUILD_COMMAND:=make -s
ifeq ($(OS), Darwin)
DEPS_BUILD_COMMAND:=make -s
else
DEPS_BUILD_COMMAND:="$(BLENDER_DIR)/build_files/build_environment/linux/make_deps_wrapper.sh" -s
endif
endif
endif
@@ -398,7 +402,7 @@ endif
deps: .FORCE
@echo
@echo Configuring dependencies in \"$(DEPS_BUILD_DIR)\"
@echo Configuring dependencies in \"$(DEPS_BUILD_DIR)\", install to \"$(DEPS_INSTALL_DIR)\"
@cmake -H"$(DEPS_SOURCE_DIR)" \
-B"$(DEPS_BUILD_DIR)" \
@@ -486,22 +490,22 @@ check_smatch: .FORCE
$(PYTHON) "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_smatch.py"
check_mypy: .FORCE
@$(PYTHON) "$(BLENDER_DIR)/source/tools/check_source/check_mypy.py"
@$(PYTHON) "$(BLENDER_DIR)/tools/check_source/check_mypy.py"
check_wiki_file_structure: .FORCE
@PYTHONIOENCODING=utf_8 $(PYTHON) \
"$(BLENDER_DIR)/source/tools/check_wiki/check_wiki_file_structure.py"
"$(BLENDER_DIR)/tools/check_wiki/check_wiki_file_structure.py"
check_spelling_py: .FORCE
@cd "$(BUILD_DIR)" ; \
PYTHONIOENCODING=utf_8 $(PYTHON) \
"$(BLENDER_DIR)/source/tools/check_source/check_spelling.py" \
"$(BLENDER_DIR)/release/scripts"
"$(BLENDER_DIR)/tools/check_source/check_spelling.py" \
"$(BLENDER_DIR)/scripts"
check_spelling_c: .FORCE
@cd "$(BUILD_DIR)" ; \
PYTHONIOENCODING=utf_8 $(PYTHON) \
"$(BLENDER_DIR)/source/tools/check_source/check_spelling.py" \
"$(BLENDER_DIR)/tools/check_source/check_spelling.py" \
--cache-file=$(CHECK_SPELLING_CACHE) \
"$(BLENDER_DIR)/source" \
"$(BLENDER_DIR)/intern/cycles" \
@@ -511,21 +515,21 @@ check_spelling_c: .FORCE
check_spelling_osl: .FORCE
@cd "$(BUILD_DIR)" ; \
PYTHONIOENCODING=utf_8 $(PYTHON) \
"$(BLENDER_DIR)/source/tools/check_source/check_spelling.py" \
"$(BLENDER_DIR)/tools/check_source/check_spelling.py" \
--cache-file=$(CHECK_SPELLING_CACHE) \
"$(BLENDER_DIR)/intern/cycles/kernel/shaders"
check_descriptions: .FORCE
@$(BLENDER_BIN) --background -noaudio --factory-startup --python \
"$(BLENDER_DIR)/source/tools/check_source/check_descriptions.py"
"$(BLENDER_DIR)/tools/check_source/check_descriptions.py"
check_deprecated: .FORCE
@PYTHONIOENCODING=utf_8 $(PYTHON) \
source/tools/check_source/check_deprecated.py
tools/check_source/check_deprecated.py
check_licenses: .FORCE
@PYTHONIOENCODING=utf_8 $(PYTHON) \
"$(BLENDER_DIR)/source/tools/check_source/check_licenses.py" \
"$(BLENDER_DIR)/tools/check_source/check_licenses.py" \
"--show-headers=$(SHOW_HEADERS)"
check_pep8: .FORCE
@@ -534,7 +538,7 @@ check_pep8: .FORCE
check_cmake: .FORCE
@PYTHONIOENCODING=utf_8 $(PYTHON) \
source/tools/check_source/check_cmake_consistency.py
tools/check_source/check_cmake_consistency.py
# -----------------------------------------------------------------------------
@@ -572,8 +576,8 @@ update_code: .FORCE
@$(PYTHON) ./build_files/utils/make_update.py --no-libraries
format: .FORCE
@PATH="${LIBDIR}/llvm/bin/:$(PATH)" $(PYTHON) source/tools/utils_maintenance/clang_format_paths.py $(PATHS)
@$(PYTHON) source/tools/utils_maintenance/autopep8_format_paths.py --autopep8-command="$(AUTOPEP8)" $(PATHS)
@PATH="${LIBDIR}/llvm/bin/:$(PATH)" $(PYTHON) tools/utils_maintenance/clang_format_paths.py $(PATHS)
@$(PYTHON) tools/utils_maintenance/autopep8_format_paths.py --autopep8-command="$(AUTOPEP8)" $(PATHS)
# -----------------------------------------------------------------------------

View File

@@ -24,7 +24,7 @@ Development
-----------
- [Build Instructions](https://wiki.blender.org/wiki/Building_Blender)
- [Code Review & Bug Tracker](https://developer.blender.org)
- [Code Review & Bug Tracker](https://projects.blender.org)
- [Developer Forum](https://devtalk.blender.org)
- [Developer Documentation](https://wiki.blender.org)

View File

@@ -10,7 +10,7 @@ ExternalProject_Add(external_epoxy
URL_HASH ${EPOXY_HASH_TYPE}=${EPOXY_HASH}
PREFIX ${BUILD_DIR}/epoxy
PATCH_COMMAND ${PATCH_CMD} -p 1 -N -d ${BUILD_DIR}/epoxy/src/external_epoxy/ < ${PATCH_DIR}/epoxy.diff
CONFIGURE_COMMAND ${CONFIGURE_ENV} && ${MESON} setup --prefix ${LIBDIR}/epoxy --default-library ${EPOXY_LIB_TYPE} --libdir lib ${BUILD_DIR}/epoxy/src/external_epoxy-build ${BUILD_DIR}/epoxy/src/external_epoxy -Dtests=false
CONFIGURE_COMMAND ${CONFIGURE_ENV} && ${MESON} setup --prefix ${LIBDIR}/epoxy --default-library ${EPOXY_LIB_TYPE} --libdir lib ${BUILD_DIR}/epoxy/src/external_epoxy-build ${BUILD_DIR}/epoxy/src/external_epoxy -Dtests=false ${MESON_BUILD_TYPE}
BUILD_COMMAND ninja
INSTALL_COMMAND ninja install
)

View File

@@ -9,7 +9,7 @@ ExternalProject_Add(external_fribidi
URL_HASH ${FRIBIDI_HASH_TYPE}=${FRIBIDI_HASH}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
PREFIX ${BUILD_DIR}/fribidi
CONFIGURE_COMMAND ${MESON} setup --prefix ${LIBDIR}/fribidi -Ddocs=false --default-library static --libdir lib ${BUILD_DIR}/fribidi/src/external_fribidi-build ${BUILD_DIR}/fribidi/src/external_fribidi
CONFIGURE_COMMAND ${MESON} setup --prefix ${LIBDIR}/fribidi ${MESON_BUILD_TYPE} -Ddocs=false --default-library static --libdir lib ${BUILD_DIR}/fribidi/src/external_fribidi-build ${BUILD_DIR}/fribidi/src/external_fribidi
BUILD_COMMAND ninja
INSTALL_COMMAND ninja install
INSTALL_DIR ${LIBDIR}/fribidi

View File

@@ -22,7 +22,7 @@ elseif(UNIX AND NOT APPLE)
)
endif()
# Boolean crashes with Arm assembly, see T103423.
# Boolean crashes with Arm assembly, see #103423.
if(BLENDER_PLATFORM_ARM)
set(GMP_OPTIONS
${GMP_OPTIONS}

View File

@@ -21,6 +21,7 @@ set(HARFBUZZ_EXTRA_OPTIONS
# Only used for command line utilities,
# disable as this would add an addition & unnecessary build-dependency.
-Dcairo=disabled
${MESON_BUILD_TYPE}
)
ExternalProject_Add(external_harfbuzz
@@ -59,3 +60,10 @@ if(BUILD_MODE STREQUAL Release AND WIN32)
DEPENDEES install
)
endif()
if(BUILD_MODE STREQUAL Debug AND WIN32)
ExternalProject_Add_Step(external_harfbuzz after_install
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/harfbuzz/lib/libharfbuzz.a ${HARVEST_TARGET}/harfbuzz/lib/libharfbuzz_d.lib
DEPENDEES install
)
endif()

View File

@@ -40,7 +40,8 @@ ExternalProject_Add(external_igc_llvm
${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/clang/0004-OpenCL-support-cl_ext_float_atomics.patch &&
${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/clang/0005-OpenCL-Add-cl_khr_integer_dot_product.patch &&
${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/llvm/0001-Memory-leak-fix-for-Managed-Static-Mutex.patch &&
${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/llvm/0002-Remove-repo-name-in-LLVM-IR.patch
${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/llvm/0002-Remove-repo-name-in-LLVM-IR.patch &&
${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/llvm/0003-Add-missing-include-limit-in-benchmark.patch
)
add_dependencies(
external_igc_llvm
@@ -55,9 +56,6 @@ ExternalProject_Add(external_igc_spirv_translator
CONFIGURE_COMMAND echo .
BUILD_COMMAND echo .
INSTALL_COMMAND echo .
PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${IGC_SPIRV_TRANSLATOR_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/spirv/0001-update-SPIR-V-headers-for-SPV_INTEL_split_barrier.patch &&
${PATCH_CMD} -p 1 -d ${IGC_SPIRV_TRANSLATOR_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/spirv/0002-Add-support-for-split-barriers-extension-SPV_INTEL_s.patch &&
${PATCH_CMD} -p 1 -d ${IGC_SPIRV_TRANSLATOR_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/spirv/0003-Support-cl_bf16_conversions.patch
)
add_dependencies(
external_igc_spirv_translator

View File

@@ -15,7 +15,7 @@ llvm-config = '${LIBDIR}/llvm/bin/llvm-config'"
)
set(MESA_EXTRA_FLAGS
-Dbuildtype=release
${MESON_BUILD_TYPE}
-Dc_args=${MESA_CFLAGS}
-Dcpp_args=${MESA_CXXFLAGS}
-Dc_link_args=${MESA_LDFLAGS}

View File

@@ -44,13 +44,21 @@ set(OPENVDB_EXTRA_ARGS
# -DLLVM_DIR=${LIBDIR}/llvm/lib/cmake/llvm
)
set(OPENVDB_PATCH ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/openvdb/src/openvdb < ${PATCH_DIR}/openvdb.diff)
if(APPLE)
set(OPENVDB_PATCH
${OPENVDB_PATCH} &&
${PATCH_CMD} -p 0 -d ${BUILD_DIR}/openvdb/src/openvdb < ${PATCH_DIR}/openvdb_metal.diff
)
endif()
ExternalProject_Add(openvdb
URL file://${PACKAGE_DIR}/${OPENVDB_FILE}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH ${OPENVDB_HASH_TYPE}=${OPENVDB_HASH}
CMAKE_GENERATOR ${PLATFORM_ALT_GENERATOR}
PREFIX ${BUILD_DIR}/openvdb
PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/openvdb/src/openvdb < ${PATCH_DIR}/openvdb.diff
PATCH_COMMAND ${OPENVDB_PATCH}
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openvdb ${DEFAULT_CMAKE_FLAGS} ${OPENVDB_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/openvdb
)

View File

@@ -16,8 +16,10 @@ message("BuildMode = ${BUILD_MODE}")
if(BUILD_MODE STREQUAL "Debug")
set(LIBDIR ${CMAKE_CURRENT_BINARY_DIR}/Debug)
set(MESON_BUILD_TYPE -Dbuildtype=debug)
else()
set(LIBDIR ${CMAKE_CURRENT_BINARY_DIR}/Release)
set(MESON_BUILD_TYPE -Dbuildtype=release)
endif()
set(DOWNLOAD_DIR "${CMAKE_CURRENT_BINARY_DIR}/downloads" CACHE STRING "Path for downloaded files")

View File

@@ -88,6 +88,19 @@ else()
export LDFLAGS=${PYTHON_LDFLAGS} &&
export PKG_CONFIG_PATH=${LIBDIR}/ffi/lib/pkgconfig)
# NOTE: untested on APPLE so far.
if(NOT APPLE)
set(PYTHON_CONFIGURE_EXTRA_ARGS
${PYTHON_CONFIGURE_EXTRA_ARGS}
# Used on most release Linux builds (Fedora for e.g.),
# increases build times noticeably with the benefit of a modest speedup at runtime.
--enable-optimizations
# While LTO is OK when building on the same system, it's incompatible across GCC versions,
# making it impractical for developers to build against, so keep it disabled.
# `--with-lto`
)
endif()
ExternalProject_Add(external_python
URL file://${PACKAGE_DIR}/${PYTHON_FILE}
DOWNLOAD_DIR ${DOWNLOAD_DIR}

View File

@@ -668,9 +668,9 @@ set(SPIRV_HEADERS_FILE SPIR-V-Headers-${SPIRV_HEADERS_VERSION}.tar.gz)
# compiler, the versions used are taken from the following location
# https://github.com/intel/intel-graphics-compiler/releases
set(IGC_VERSION 1.0.12149.1)
set(IGC_VERSION 1.0.13064.7)
set(IGC_URI https://github.com/intel/intel-graphics-compiler/archive/refs/tags/igc-${IGC_VERSION}.tar.gz)
set(IGC_HASH 44f67f24e3bc5130f9f062533abf8154782a9d0a992bc19b498639a8521ae836)
set(IGC_HASH a929abd4cca2b293961ec0437ee4b3b2147bd3b2c8a3c423af78c0c359b2e5ae)
set(IGC_HASH_TYPE SHA256)
set(IGC_FILE igc-${IGC_VERSION}.tar.gz)
@@ -690,15 +690,15 @@ set(IGC_LLVM_FILE ${IGC_LLVM_VERSION}.tar.gz)
#
# WARNING WARNING WARNING
set(IGC_OPENCL_CLANG_VERSION 363a5262d8c7cff3fb28f3bdb5d85c8d7e91c1bb)
set(IGC_OPENCL_CLANG_VERSION ee31812ea8b89d08c2918f045d11a19bd33525c5)
set(IGC_OPENCL_CLANG_URI https://github.com/intel/opencl-clang/archive/${IGC_OPENCL_CLANG_VERSION}.tar.gz)
set(IGC_OPENCL_CLANG_HASH aa8cf72bb239722ce8ce44f79413c6887ecc8ca18477dd520aa5c4809756da9a)
set(IGC_OPENCL_CLANG_HASH 1db6735bbcfaa31e8a9ba39f121d6bafa806ea8919e9f56782d6aaa67771ddda)
set(IGC_OPENCL_CLANG_HASH_TYPE SHA256)
set(IGC_OPENCL_CLANG_FILE opencl-clang-${IGC_OPENCL_CLANG_VERSION}.tar.gz)
set(IGC_VCINTRINSICS_VERSION v0.5.0)
set(IGC_VCINTRINSICS_VERSION v0.11.0)
set(IGC_VCINTRINSICS_URI https://github.com/intel/vc-intrinsics/archive/refs/tags/${IGC_VCINTRINSICS_VERSION}.tar.gz)
set(IGC_VCINTRINSICS_HASH 70bb47c5e32173cf61514941e83ae7c7eb4485e6d2fca60cfa1f50d4f42c41f2)
set(IGC_VCINTRINSICS_HASH e5acd5626ce7fa6d41ce154c50ac805eda734ee66af94ef28e680ac2ad81bb9f)
set(IGC_VCINTRINSICS_HASH_TYPE SHA256)
set(IGC_VCINTRINSICS_FILE vc-intrinsics-${IGC_VCINTRINSICS_VERSION}.tar.gz)
@@ -714,9 +714,9 @@ set(IGC_SPIRV_TOOLS_HASH 6e19900e948944243024aedd0a201baf3854b377b9cc7a386553bc1
set(IGC_SPIRV_TOOLS_HASH_TYPE SHA256)
set(IGC_SPIRV_TOOLS_FILE SPIR-V-Tools-${IGC_SPIRV_TOOLS_VERSION}.tar.gz)
set(IGC_SPIRV_TRANSLATOR_VERSION a31ffaeef77e23d500b3ea3d35e0c42ff5648ad9)
set(IGC_SPIRV_TRANSLATOR_VERSION d739c01d65ec00dee64dedd40deed805216a7193)
set(IGC_SPIRV_TRANSLATOR_URI https://github.com/KhronosGroup/SPIRV-LLVM-Translator/archive/${IGC_SPIRV_TRANSLATOR_VERSION}.tar.gz)
set(IGC_SPIRV_TRANSLATOR_HASH 9e26c96a45341b8f8af521bacea20e752623346340addd02af95d669f6e89252)
set(IGC_SPIRV_TRANSLATOR_HASH ddc0cc9ccbe59dadeaf291012d59de142b2e9f2b124dbb634644d39daddaa13e)
set(IGC_SPIRV_TRANSLATOR_HASH_TYPE SHA256)
set(IGC_SPIRV_TRANSLATOR_FILE SPIR-V-Translator-${IGC_SPIRV_TRANSLATOR_VERSION}.tar.gz)
@@ -724,15 +724,15 @@ set(IGC_SPIRV_TRANSLATOR_FILE SPIR-V-Translator-${IGC_SPIRV_TRANSLATOR_VERSION}.
### Intel Graphics Compiler DEPS END ###
########################################
set(GMMLIB_VERSION intel-gmmlib-22.1.8)
set(GMMLIB_VERSION intel-gmmlib-22.3.0)
set(GMMLIB_URI https://github.com/intel/gmmlib/archive/refs/tags/${GMMLIB_VERSION}.tar.gz)
set(GMMLIB_HASH bf23e9a3742b4fb98c7666c9e9b29f3219e4b2fb4d831aaf4eed71f5e2d17368)
set(GMMLIB_HASH c1f33e1519edfc527127baeb0436b783430dfd256c643130169a3a71dc86aff9)
set(GMMLIB_HASH_TYPE SHA256)
set(GMMLIB_FILE ${GMMLIB_VERSION}.tar.gz)
set(OCLOC_VERSION 22.38.24278)
set(OCLOC_VERSION 22.49.25018.21)
set(OCLOC_URI https://github.com/intel/compute-runtime/archive/refs/tags/${OCLOC_VERSION}.tar.gz)
set(OCLOC_HASH db0c542fccd651e6404b15a74d46027f1ce0eda8dc9e25a40cbb6c0faef257ee)
set(OCLOC_HASH 92362dae08b503a34e5d3820ed284198c452bcd5e7504d90eb69887b20492c06)
set(OCLOC_HASH_TYPE SHA256)
set(OCLOC_FILE ocloc-${OCLOC_VERSION}.tar.gz)

View File

@@ -13,7 +13,7 @@ ExternalProject_Add(external_wayland
# NOTE: `-lm` is needed for `libxml2` which is a static library that uses `libm.so`,
# without this, math symbols such as `floor` aren't found.
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env PKG_CONFIG_PATH=${LIBDIR}/expat/lib/pkgconfig:${LIBDIR}/xml2/lib/pkgconfig:${LIBDIR}/ffi/lib/pkgconfig:$PKG_CONFIG_PATH
${MESON} --prefix ${LIBDIR}/wayland -Ddocumentation=false -Dtests=false -D "c_link_args=-L${LIBDIR}/ffi/lib -lm" . ../external_wayland
${MESON} --prefix ${LIBDIR}/wayland ${MESON_BUILD_TYPE} -Ddocumentation=false -Dtests=false -D "c_link_args=-L${LIBDIR}/ffi/lib -lm" . ../external_wayland
BUILD_COMMAND ninja
INSTALL_COMMAND ninja install
)

View File

@@ -7,7 +7,7 @@ ExternalProject_Add(external_wayland_protocols
PREFIX ${BUILD_DIR}/wayland-protocols
# Use `-E` so the `PKG_CONFIG_PATH` can be defined to link against our own WAYLAND.
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env PKG_CONFIG_PATH=${LIBDIR}/wayland/lib64/pkgconfig:$PKG_CONFIG_PATH
${MESON} --prefix ${LIBDIR}/wayland-protocols . ../external_wayland_protocols -Dtests=false
${MESON} --prefix ${LIBDIR}/wayland-protocols ${MESON_BUILD_TYPE} . ../external_wayland_protocols -Dtests=false
BUILD_COMMAND ninja
INSTALL_COMMAND ninja install
)

View File

@@ -17,11 +17,13 @@ ExternalProject_Add(external_xvidcore
INSTALL_DIR ${LIBDIR}/xvidcore
)
ExternalProject_Add_Step(external_xvidcore after_install
COMMAND ${CMAKE_COMMAND} -E rename ${LIBDIR}/xvidcore/lib/xvidcore.a ${LIBDIR}/xvidcore/lib/libxvidcore.a || true
COMMAND ${CMAKE_COMMAND} -E remove ${LIBDIR}/xvidcore/lib/xvidcore.dll.a
DEPENDEES install
)
if(WIN32)
ExternalProject_Add_Step(external_xvidcore after_install
COMMAND ${CMAKE_COMMAND} -E rename ${LIBDIR}/xvidcore/lib/xvidcore.a ${LIBDIR}/xvidcore/lib/libxvidcore.a || true
COMMAND ${CMAKE_COMMAND} -E remove ${LIBDIR}/xvidcore/lib/xvidcore.dll.a
DEPENDEES install
)
endif()
if(MSVC)
set_target_properties(external_xvidcore PROPERTIES FOLDER Mingw)

View File

@@ -6615,11 +6615,9 @@ print_info() {
fi
if [ -d $INST/oiio ]; then
_1="-D WITH_OPENIMAGEIO=ON"
_2="-D OPENIMAGEIO_ROOT_DIR=$INST/oiio"
_1="-D OPENIMAGEIO_ROOT_DIR=$INST/oiio"
PRINT " $_1"
PRINT " $_2"
_buildargs="$_buildargs $_1 $_2"
_buildargs="$_buildargs $_1"
fi
if [ "$OSL_SKIP" = false ]; then

View File

@@ -1,8 +1,8 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-2.0-or-later
# This script is part of the official build environment, see WIKI page for details.
# https://wiki.blender.org/wiki/Building_Blender/Other/CentOS7ReleaseEnvironment
# This script is part of the official build environment, see wiki page for details.
# https://wiki.blender.org/wiki/Building_Blender/Other/Rocky8ReleaseEnvironment
set -e
@@ -59,7 +59,7 @@ PACKAGES_FOR_LIBS=(
automake
libtool
# TODO: why is this needed?
# Used to set rpath on shared libraries
patchelf
# Builds generated by meson use Ninja for the actual build.

View File

@@ -0,0 +1,74 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-2.0-or-later
# This script ensures:
# - One dependency is built at a time.
# - That dependency uses all available cores.
#
# Without this, simply calling `make -j$(nproc)` from the `${CMAKE_BUILD_DIR}/deps/`
# directory will build many projects at once.
#
# This is undesirable for the following reasons:
#
# - The output from projects is mixed together,
# making it difficult to track down the cause of a build failure.
#
# - Larger dependencies such as LLVM can bottleneck the build process,
# making it necessary to cancel the build and manually run build commands in each directory.
#
# - Building many projects at once means canceling (Control-C) can lead to the build being in an undefined state.
# It's possible canceling happens as a patch is being applied or files are being copied.
# (steps that aren't part of the compilation process where it's typically safe to cancel).
if [[ -z "$MY_MAKE_CALL_LEVEL" ]]; then
export MY_MAKE_CALL_LEVEL=0
export MY_MAKEFLAGS=$MAKEFLAGS
# Extract the jobs argument (`-jN`, `-j N`, `--jobs=N`).
add_next=0
for i in "$@"; do
case $i in
-j*)
export MY_JOBS_ARG=$i
if [ "$MY_JOBS_ARG" = "-j" ]; then
add_next=1
fi
;;
--jobs=*)
shift # past argument=value
MY_JOBS_ARG=$i
;;
*)
if (( add_next == 1 )); then
MY_JOBS_ARG="$MY_JOBS_ARG $i"
add_next=0
fi
;;
esac
done
unset i add_next
if [[ -z "$MY_JOBS_ARG" ]]; then
MY_JOBS_ARG="-j$(nproc)"
fi
export MY_JOBS_ARG
# Support user defined `MAKEFLAGS`.
export MAKEFLAGS="$MY_MAKEFLAGS -j1"
else
export MY_MAKE_CALL_LEVEL=$(( MY_MAKE_CALL_LEVEL + 1 ))
if (( MY_MAKE_CALL_LEVEL == 1 )); then
# Important to set jobs to 1, otherwise user defined jobs argument is used.
export MAKEFLAGS="$MY_MAKEFLAGS -j1"
elif (( MY_MAKE_CALL_LEVEL == 2 )); then
# This is the level used by each sub-project.
export MAKEFLAGS="$MY_MAKEFLAGS $MY_JOBS_ARG"
fi
# Else leave `MY_MAKEFLAGS` flags as-is, avoids setting a high number of jobs on recursive
# calls (which may easily run out of memory). Let the job-server handle the rest.
fi
# Useful for troubleshooting the wrapper.
# echo "Call level: $MY_MAKE_CALL_LEVEL, args=$@".
# Call actual make but ensure recursive calls run via this script.
exec make MAKE="$0" "$@"

View File

@@ -1,7 +1,7 @@
diff -Naur external_igc_opencl_clang.orig/CMakeLists.txt external_igc_opencl_clang/CMakeLists.txt
--- external_igc_opencl_clang.orig/CMakeLists.txt 2022-03-16 05:51:10 -0600
+++ external_igc_opencl_clang/CMakeLists.txt 2022-05-23 10:40:09 -0600
@@ -126,22 +126,24 @@
@@ -147,22 +147,24 @@
)
endif()

File diff suppressed because it is too large Load Diff

View File

@@ -23,19 +23,19 @@ if(EXISTS ${SOURCE_DIR}/.git)
if(MY_WC_BRANCH STREQUAL "HEAD")
# Detached HEAD, check whether commit hash is reachable
# in the master branch
# in the main branch
execute_process(COMMAND git rev-parse --short=12 HEAD
WORKING_DIRECTORY ${SOURCE_DIR}
OUTPUT_VARIABLE MY_WC_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND git branch --list master blender-v* --contains ${MY_WC_HASH}
execute_process(COMMAND git branch --list main blender-v* --contains ${MY_WC_HASH}
WORKING_DIRECTORY ${SOURCE_DIR}
OUTPUT_VARIABLE _git_contains_check
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT _git_contains_check STREQUAL "")
set(MY_WC_BRANCH "master")
set(MY_WC_BRANCH "main")
else()
execute_process(COMMAND git show-ref --tags -d
WORKING_DIRECTORY ${SOURCE_DIR}
@@ -48,7 +48,7 @@ if(EXISTS ${SOURCE_DIR}/.git)
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(_git_tag_hashes MATCHES "${_git_head_hash}")
set(MY_WC_BRANCH "master")
set(MY_WC_BRANCH "main")
else()
execute_process(COMMAND git branch --contains ${MY_WC_HASH}
WORKING_DIRECTORY ${SOURCE_DIR}

View File

@@ -36,6 +36,7 @@ set(WITH_IMAGE_WEBP OFF CACHE BOOL "" FORCE)
set(WITH_INPUT_IME OFF CACHE BOOL "" FORCE)
set(WITH_INPUT_NDOF OFF CACHE BOOL "" FORCE)
set(WITH_INTERNATIONAL OFF CACHE BOOL "" FORCE)
set(WITH_IO_PLY OFF CACHE BOOL "" FORCE)
set(WITH_IO_STL OFF CACHE BOOL "" FORCE)
set(WITH_IO_WAVEFRONT_OBJ OFF CACHE BOOL "" FORCE)
set(WITH_IO_GPENCIL OFF CACHE BOOL "" FORCE)
@@ -52,7 +53,6 @@ set(WITH_OPENAL OFF CACHE BOOL "" FORCE)
set(WITH_OPENCOLLADA OFF CACHE BOOL "" FORCE)
set(WITH_OPENCOLORIO OFF CACHE BOOL "" FORCE)
set(WITH_OPENIMAGEDENOISE OFF CACHE BOOL "" FORCE)
set(WITH_OPENIMAGEIO OFF CACHE BOOL "" FORCE)
set(WITH_OPENMP OFF CACHE BOOL "" FORCE)
set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE)
set(WITH_OPENVDB OFF CACHE BOOL "" FORCE)

View File

@@ -85,7 +85,7 @@ if(NOT APPLE)
set(WITH_CYCLES_DEVICE_OPTIX ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_CUDA_BINARIES ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_CUBIN_COMPILER OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES_HIP_BINARIES ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_HIP_BINARIES OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES_DEVICE_ONEAPI ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_ONEAPI_BINARIES ON CACHE BOOL "" FORCE)
endif()

View File

@@ -11,11 +11,11 @@
mkdir ~/blender-git
cd ~/blender-git
git clone http://git.blender.org/blender.git
git clone https://projects.blender.org/blender/blender.git
cd blender
git submodule update --init --recursive
git submodule foreach git checkout master
git submodule foreach git pull --rebase origin master
git submodule foreach git checkout main
git submodule foreach git pull --rebase origin main
# create build dir
mkdir ~/blender-git/build-cmake
@@ -35,7 +35,7 @@ ln -s ~/blender-git/build-cmake/bin/blender ~/blender-git/blender/blender.bin
echo ""
echo "* Useful Commands *"
echo " Run Blender: ~/blender-git/blender/blender.bin"
echo " Update Blender: git pull --rebase; git submodule foreach git pull --rebase origin master"
echo " Update Blender: git pull --rebase; git submodule foreach git pull --rebase origin main"
echo " Reconfigure Blender: cd ~/blender-git/build-cmake ; cmake ."
echo " Build Blender: cd ~/blender-git/build-cmake ; make"
echo ""

View File

@@ -544,7 +544,7 @@ endfunction()
function(setup_platform_linker_libs
target
)
# jemalloc must be early in the list, to be before pthread (see T57998)
# jemalloc must be early in the list, to be before pthread (see #57998).
if(WITH_MEM_JEMALLOC)
target_link_libraries(${target} ${JEMALLOC_LIBRARIES})
endif()
@@ -1090,7 +1090,7 @@ function(msgfmt_simple
add_custom_command(
OUTPUT ${_file_to}
COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path}
COMMAND "$<TARGET_FILE:msgfmt>" ${_file_from} ${_file_to}
COMMAND ${CMAKE_COMMAND} -E env ${PLATFORM_ENV_BUILD} "$<TARGET_FILE:msgfmt>" ${_file_from} ${_file_to}
DEPENDS msgfmt ${_file_from})
set_source_files_properties(${_file_to} PROPERTIES GENERATED TRUE)

View File

@@ -270,19 +270,7 @@ if(WITH_PUGIXML)
find_package(PugiXML REQUIRED)
endif()
if(WITH_OPENIMAGEIO)
find_package(OpenImageIO)
list(APPEND OPENIMAGEIO_LIBRARIES
${PNG_LIBRARIES}
${JPEG_LIBRARIES}
${TIFF_LIBRARY}
${OPENEXR_LIBRARIES}
${OPENJPEG_LIBRARIES}
${ZLIB_LIBRARIES}
)
set(OPENIMAGEIO_DEFINITIONS "-DOIIO_STATIC_BUILD")
set(OPENIMAGEIO_IDIFF "${LIBDIR}/openimageio/bin/idiff")
endif()
find_package(OpenImageIO REQUIRED)
add_bundled_libraries(openimageio/lib)
if(WITH_OPENCOLORIO)
@@ -440,7 +428,7 @@ string(APPEND PLATFORM_LINKFLAGS " -stdlib=libc++")
# Make stack size more similar to Embree, required for Embree.
string(APPEND PLATFORM_LINKFLAGS_EXECUTABLE " -Wl,-stack_size,0x100000")
# Suppress ranlib "has no symbols" warnings (workaround for T48250)
# Suppress ranlib "has no symbols" warnings (workaround for #48250).
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
# llvm-ranlib doesn't support this flag. Xcode's libtool does.

View File

@@ -438,32 +438,7 @@ if(WITH_IMAGE_WEBP)
set_and_warn_library_found("WebP" WEBP_FOUND WITH_IMAGE_WEBP)
endif()
if(WITH_OPENIMAGEIO)
find_package_wrapper(OpenImageIO)
set(OPENIMAGEIO_LIBRARIES
${OPENIMAGEIO_LIBRARIES}
${PNG_LIBRARIES}
${JPEG_LIBRARIES}
${ZLIB_LIBRARIES}
)
set(OPENIMAGEIO_DEFINITIONS "")
if(WITH_BOOST)
list(APPEND OPENIMAGEIO_LIBRARIES "${BOOST_LIBRARIES}")
endif()
if(WITH_IMAGE_TIFF)
list(APPEND OPENIMAGEIO_LIBRARIES "${TIFF_LIBRARY}")
endif()
if(WITH_IMAGE_OPENEXR)
list(APPEND OPENIMAGEIO_LIBRARIES "${OPENEXR_LIBRARIES}")
endif()
if(WITH_IMAGE_WEBP)
list(APPEND OPENIMAGEIO_LIBRARIES "${WEBP_LIBRARIES}")
endif()
set_and_warn_library_found("OPENIMAGEIO" OPENIMAGEIO_FOUND WITH_OPENIMAGEIO)
endif()
find_package_wrapper(OpenImageIO REQUIRED)
add_bundled_libraries(openimageio/lib)
if(WITH_OPENCOLORIO)

View File

@@ -121,7 +121,7 @@ if(WITH_WINDOWS_BUNDLE_CRT)
include(InstallRequiredSystemLibraries)
# ucrtbase(d).dll cannot be in the manifest, due to the way windows 10 handles
# redirects for this dll, for details see T88813.
# redirects for this dll, for details see #88813.
foreach(lib ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS})
string(FIND ${lib} "ucrtbase" pos)
if(NOT pos EQUAL -1)
@@ -295,7 +295,7 @@ unset(MATERIALX_LIB_FOLDER_EXISTS)
if(NOT MSVC_CLANG AND # Available with MSVC 15.7+ but not for CLANG.
NOT WITH_WINDOWS_SCCACHE AND # And not when sccache is enabled
NOT VS_CLANG_TIDY) # Clang-tidy does not like these options
add_compile_options(/experimental:external /external:templates- /external:I "${LIBDIR}" /external:W0)
add_compile_options(/experimental:external /external:I "${LIBDIR}" /external:W0)
endif()
# Add each of our libraries to our cmake_prefix_path so find_package() could work
@@ -522,6 +522,28 @@ if(WITH_PYTHON)
set(PYTHON_LIBRARIES debug "${PYTHON_LIBRARY_DEBUG}" optimized "${PYTHON_LIBRARY}" )
endif()
if(NOT WITH_WINDOWS_FIND_MODULES)
# even if boost is off, we still need to install the dlls when we use our lib folder since
# some of the other dependencies may need them. For this to work, BOOST_VERSION,
# BOOST_POSTFIX, and BOOST_DEBUG_POSTFIX need to be set.
set(BOOST ${LIBDIR}/boost)
set(BOOST_INCLUDE_DIR ${BOOST}/include)
set(BOOST_LIBPATH ${BOOST}/lib)
set(BOOST_VERSION_HEADER ${BOOST_INCLUDE_DIR}/boost/version.hpp)
if(EXISTS ${BOOST_VERSION_HEADER})
file(STRINGS "${BOOST_VERSION_HEADER}" BOOST_LIB_VERSION REGEX "#define BOOST_LIB_VERSION ")
if(BOOST_LIB_VERSION MATCHES "#define BOOST_LIB_VERSION \"([0-9_]+)\"")
set(BOOST_VERSION "${CMAKE_MATCH_1}")
endif()
endif()
if(NOT BOOST_VERSION)
message(FATAL_ERROR "Unable to determine Boost version")
endif()
set(BOOST_POSTFIX "vc142-mt-x64-${BOOST_VERSION}")
set(BOOST_DEBUG_POSTFIX "vc142-mt-gyd-x64-${BOOST_VERSION}")
set(BOOST_PREFIX "")
endif()
if(WITH_BOOST)
if(WITH_CYCLES AND WITH_CYCLES_OSL)
set(boost_extra_libs wave)
@@ -537,22 +559,6 @@ if(WITH_BOOST)
endif()
if(NOT Boost_FOUND)
warn_hardcoded_paths(BOOST)
set(BOOST ${LIBDIR}/boost)
set(BOOST_INCLUDE_DIR ${BOOST}/include)
set(BOOST_LIBPATH ${BOOST}/lib)
set(BOOST_VERSION_HEADER ${BOOST_INCLUDE_DIR}/boost/version.hpp)
if(EXISTS ${BOOST_VERSION_HEADER})
file(STRINGS "${BOOST_VERSION_HEADER}" BOOST_LIB_VERSION REGEX "#define BOOST_LIB_VERSION ")
if(BOOST_LIB_VERSION MATCHES "#define BOOST_LIB_VERSION \"([0-9_]+)\"")
set(BOOST_VERSION "${CMAKE_MATCH_1}")
endif()
endif()
if(NOT BOOST_VERSION)
message(FATAL_ERROR "Unable to determine Boost version")
endif()
set(BOOST_POSTFIX "vc142-mt-x64-${BOOST_VERSION}")
set(BOOST_DEBUG_POSTFIX "vc142-mt-gyd-x64-${BOOST_VERSION}")
set(BOOST_PREFIX "")
# This is file new in 3.4 if it does not exist, assume we are building against 3.3 libs
set(BOOST_34_TRIGGER_FILE ${BOOST_LIBPATH}/${BOOST_PREFIX}boost_python310-${BOOST_DEBUG_POSTFIX}.lib)
if(NOT EXISTS ${BOOST_34_TRIGGER_FILE})
@@ -602,25 +608,18 @@ if(WITH_BOOST)
set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB")
endif()
if(WITH_OPENIMAGEIO)
windows_find_package(OpenImageIO)
if(NOT OpenImageIO_FOUND)
set(OPENIMAGEIO ${LIBDIR}/OpenImageIO)
set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib)
set(OPENIMAGEIO_INCLUDE_DIR ${OPENIMAGEIO}/include)
set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO_INCLUDE_DIR})
set(OIIO_OPTIMIZED optimized ${OPENIMAGEIO_LIBPATH}/OpenImageIO.lib optimized ${OPENIMAGEIO_LIBPATH}/OpenImageIO_Util.lib)
set(OIIO_DEBUG debug ${OPENIMAGEIO_LIBPATH}/OpenImageIO_d.lib debug ${OPENIMAGEIO_LIBPATH}/OpenImageIO_Util_d.lib)
set(OPENIMAGEIO_LIBRARIES ${OIIO_OPTIMIZED} ${OIIO_DEBUG})
endif()
set(OPENIMAGEIO_DEFINITIONS "-DUSE_TBB=0")
windows_find_package(OpenImageIO)
if(NOT OpenImageIO_FOUND)
set(OPENIMAGEIO ${LIBDIR}/OpenImageIO)
set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib)
set(OPENIMAGEIO_INCLUDE_DIR ${OPENIMAGEIO}/include)
set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO_INCLUDE_DIR})
set(OIIO_OPTIMIZED optimized ${OPENIMAGEIO_LIBPATH}/OpenImageIO.lib optimized ${OPENIMAGEIO_LIBPATH}/OpenImageIO_Util.lib)
set(OIIO_DEBUG debug ${OPENIMAGEIO_LIBPATH}/OpenImageIO_d.lib debug ${OPENIMAGEIO_LIBPATH}/OpenImageIO_Util_d.lib)
set(OPENIMAGEIO_LIBRARIES ${OIIO_OPTIMIZED} ${OIIO_DEBUG})
set(OPENIMAGEIO_IDIFF "${OPENIMAGEIO}/bin/idiff.exe")
# If the .dll does not exist, assume it is a static OIIO
if(NOT EXISTS ${OPENIMAGEIO}/bin/OpenImageIO.dll)
add_definitions(-DOIIO_STATIC_DEFINE)
endif()
add_definitions(-DOIIO_NO_SSE=1)
endif()
add_definitions(-DOIIO_NO_SSE=1)
if(WITH_LLVM)
set(LLVM_ROOT_DIR ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation")
@@ -901,11 +900,11 @@ endif()
if(WINDOWS_PYTHON_DEBUG)
# Include the system scripts in the blender_python_system_scripts project.
file(GLOB_RECURSE inFiles "${CMAKE_SOURCE_DIR}/release/scripts/*.*" )
file(GLOB_RECURSE inFiles "${CMAKE_SOURCE_DIR}/scripts/*.*" )
add_custom_target(blender_python_system_scripts SOURCES ${inFiles})
foreach(_source IN ITEMS ${inFiles})
get_filename_component(_source_path "${_source}" PATH)
string(REPLACE "${CMAKE_SOURCE_DIR}/release/scripts/" "" _source_path "${_source_path}")
string(REPLACE "${CMAKE_SOURCE_DIR}/scripts/" "" _source_path "${_source_path}")
string(REPLACE "/" "\\" _group_path "${_source_path}")
source_group("${_group_path}" FILES "${_source}")
endforeach()
@@ -940,7 +939,7 @@ if(WINDOWS_PYTHON_DEBUG)
file(WRITE ${USER_PROPS_FILE} "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">
<PropertyGroup>
<LocalDebuggerCommandArguments>-con --env-system-scripts \"${CMAKE_SOURCE_DIR}/release/scripts\" </LocalDebuggerCommandArguments>
<LocalDebuggerCommandArguments>-con --env-system-scripts \"${CMAKE_SOURCE_DIR}/scripts\" </LocalDebuggerCommandArguments>
</PropertyGroup>
</Project>")
endif()
@@ -1040,7 +1039,7 @@ endif()
# Environment variables to run precompiled executables that needed libraries.
list(JOIN PLATFORM_BUNDLED_LIBRARY_DIRS ";" _library_paths)
set(PLATFORM_ENV_BUILD_DIRS "${LIBDIR}/OpenImageIO/bin\;${LIBDIR}/boost/lib\;${LIBDIR}/openexr/bin\;${LIBDIR}/imath/bin\;${PATH}")
set(PLATFORM_ENV_BUILD_DIRS "${LIBDIR}/tbb/bin\;${LIBDIR}/OpenImageIO/bin\;${LIBDIR}/boost/lib\;${LIBDIR}/openexr/bin\;${LIBDIR}/imath/bin\;${PATH}")
set(PLATFORM_ENV_BUILD "PATH=${PLATFORM_ENV_BUILD_DIRS}")
# Install needs the additional folders from PLATFORM_ENV_BUILD_DIRS as well, as tools like idiff and abcls use the release mode dlls
set(PLATFORM_ENV_INSTALL "PATH=${CMAKE_INSTALL_PREFIX_WITH_CONFIG}/blender.shared/\;${PLATFORM_ENV_BUILD_DIRS}\;$ENV{PATH}")

View File

@@ -142,7 +142,7 @@ def cmake_advanced_info() -> Union[Tuple[List[str], List[Tuple[str, str]]], Tupl
make_exe = cmake_cache_var("CMAKE_MAKE_PROGRAM")
if make_exe is None:
print("Make command not found in: %r not found" % project_path)
print("Make command not found: CMAKE_MAKE_PROGRAM")
return None, None
make_exe_basename = os.path.basename(make_exe)

View File

@@ -1,53 +1,3 @@
#
# Used by Buildbot build pipeline make_update.py script only for now
# We intended to update the make_update.py in the branches to use this file eventually
#
update-code:
git:
submodules:
- branch: master
commit_id: HEAD
path: release/scripts/addons
- branch: master
commit_id: HEAD
path: release/scripts/addons_contrib
- branch: master
commit_id: HEAD
path: release/datafiles/locale
- branch: master
commit_id: HEAD
path: source/tools
svn:
libraries:
darwin-arm64:
branch: trunk
commit_id: HEAD
path: lib/darwin_arm64
darwin-x86_64:
branch: trunk
commit_id: HEAD
path: lib/darwin
linux-x86_64:
branch: trunk
commit_id: HEAD
path: lib/linux_x86_64_glibc_228
windows-amd64:
branch: trunk
commit_id: HEAD
path: lib/win64_vc15
tests:
branch: trunk
commit_id: HEAD
path: lib/tests
benchmarks:
branch: trunk
commit_id: HEAD
path: lib/benchmarks
assets:
branch: trunk
commit_id: HEAD
path: lib/assets
#
# Buildbot only configs
#

View File

@@ -58,7 +58,7 @@ Each Blender release supports one Python version, and the package is only compat
## Source Code
* [Releases](https://download.blender.org/source/)
* Repository: [git.blender.org/blender.git](https://git.blender.org/gitweb/gitweb.cgi/blender.git)
* Repository: [projects.blender.org/blender/blender.git](https://projects.blender.org/blender/blender)
## Credits

View File

@@ -135,7 +135,7 @@ def submodules_to_manifest(
submodule = line.split()[1]
# Don't use native slashes as GIT for MS-Windows outputs forward slashes.
if skip_addon_contrib and submodule == "release/scripts/addons_contrib":
if skip_addon_contrib and submodule == "scripts/addons_contrib":
continue
for path in git_ls_files(blender_srcdir / submodule):

View File

@@ -16,14 +16,28 @@ import shutil
import sys
import make_utils
from pathlib import Path
from make_utils import call, check_output
from urllib.parse import urljoin
from typing import (
List,
Iterable,
Optional,
)
class Submodule:
path: str
branch: str
branch_fallback: str
def __init__(self, path: str, branch: str, branch_fallback: str) -> None:
self.path = path
self.branch = branch
self.branch_fallback = branch_fallback
def print_stage(text: str) -> None:
print("")
print(text)
@@ -42,6 +56,7 @@ def parse_arguments() -> argparse.Namespace:
parser.add_argument("--svn-branch", default=None)
parser.add_argument("--git-command", default="git")
parser.add_argument("--use-linux-libraries", action="store_true")
parser.add_argument("--architecture", type=str, choices=("x86_64", "amd64", "arm64",))
return parser.parse_args()
@@ -51,6 +66,19 @@ def get_blender_git_root() -> str:
# Setup for precompiled libraries and tests from svn.
def get_effective_architecture(args: argparse.Namespace) -> str:
architecture = args.architecture
if architecture:
assert isinstance(architecture, str)
return architecture
# Check platform.version to detect arm64 with x86_64 python binary.
if "ARM64" in platform.version():
return "arm64"
return platform.machine().lower()
def svn_update(args: argparse.Namespace, release_version: Optional[str]) -> None:
svn_non_interactive = [args.svn_command, '--non-interactive']
@@ -58,11 +86,11 @@ def svn_update(args: argparse.Namespace, release_version: Optional[str]) -> None
svn_url = make_utils.svn_libraries_base_url(release_version, args.svn_branch)
# Checkout precompiled libraries
architecture = get_effective_architecture(args)
if sys.platform == 'darwin':
# Check platform.version to detect arm64 with x86_64 python binary.
if platform.machine() == 'arm64' or ('ARM64' in platform.version()):
if architecture == 'arm64':
lib_platform = "darwin_arm64"
elif platform.machine() == 'x86_64':
elif architecture == 'x86_64':
lib_platform = "darwin"
else:
lib_platform = None
@@ -170,7 +198,7 @@ def git_update_skip(args: argparse.Namespace, check_remote_exists: bool = True)
return "rebase or merge in progress, complete it first"
# Abort if uncommitted changes.
changes = check_output([args.git_command, 'status', '--porcelain', '--untracked-files=no'])
changes = check_output([args.git_command, 'status', '--porcelain', '--untracked-files=no', '--ignore-submodules'])
if len(changes) != 0:
return "you have unstaged changes"
@@ -184,97 +212,291 @@ def git_update_skip(args: argparse.Namespace, check_remote_exists: bool = True)
return ""
def use_upstream_workflow(args: argparse.Namespace) -> bool:
return make_utils.git_remote_exist(args.git_command, "upstream")
def work_tree_update_upstream_workflow(args: argparse.Namespace, use_fetch: bool = True) -> str:
"""
Update the Blender repository using the Github style of fork organization
Returns true if the current local branch has been updated to the upstream state.
Otherwise false is returned.
"""
branch_name = make_utils.git_branch(args.git_command)
if use_fetch:
call((args.git_command, "fetch", "upstream"))
upstream_branch = f"upstream/{branch_name}"
if not make_utils.git_branch_exists(args.git_command, upstream_branch):
return "no_branch"
retcode = call((args.git_command, "merge", "--ff-only", upstream_branch), exit_on_error=False)
if retcode != 0:
return "Unable to fast forward\n"
return ""
def work_tree_update(args: argparse.Namespace, use_fetch: bool = True) -> str:
"""
Update the Git working tree using the best strategy
This function detects whether it is a github style of fork remote organization is used, or
is it a repository which origin is an upstream.
"""
if use_upstream_workflow(args):
message = work_tree_update_upstream_workflow(args, use_fetch)
if message != "no_branch":
return message
# If there is upstream configured but the local branch is not in the upstream, try to
# update the branch from the fork.
update_command = [args.git_command, "pull", "--rebase"]
call(update_command)
return ""
# Update blender repository.
def blender_update(args: argparse.Namespace) -> None:
def blender_update(args: argparse.Namespace) -> str:
print_stage("Updating Blender Git Repository")
call([args.git_command, "pull", "--rebase"])
return work_tree_update(args)
# Update submodules.
def submodules_update(
args: argparse.Namespace,
release_version: Optional[str],
branch: Optional[str],
) -> str:
print_stage("Updating Submodules")
if make_utils.command_missing(args.git_command):
sys.stderr.write("git not found, can't update code\n")
sys.exit(1)
def resolve_external_url(blender_url: str, repo_name: str) -> str:
return urljoin(blender_url + "/", "../" + repo_name)
# Update submodules to appropriate given branch,
# falling back to master if none is given and/or found in a sub-repository.
branch_fallback = "master"
def external_script_copy_old_submodule_over(args: argparse.Namespace, directory_name: str) -> None:
blender_git_root = Path(get_blender_git_root())
scripts_dir = blender_git_root / "scripts"
external_dir = scripts_dir / directory_name
old_submodule_relative_dir = Path("release") / "scripts" / directory_name
print(f"Moving {old_submodule_relative_dir} to scripts/{directory_name} ...")
old_submodule_dir = blender_git_root / old_submodule_relative_dir
shutil.move(old_submodule_dir, external_dir)
# Remove old ".git" which is a file with path to a submodule bare repo inside of main
# repo .git/modules directory.
(external_dir / ".git").unlink()
bare_repo_relative_dir = Path(".git") / "modules" / "release" / "scripts" / directory_name
print(f"Copying {bare_repo_relative_dir} to scripts/{directory_name}/.git ...")
bare_repo_dir = blender_git_root / bare_repo_relative_dir
shutil.copytree(bare_repo_dir, external_dir / ".git")
git_config = external_dir / ".git" / "config"
call((args.git_command, "config", "--file", str(git_config), "--unset", "core.worktree"))
def external_script_initialize_if_needed(args: argparse.Namespace,
repo_name: str,
directory_name: str) -> None:
"""Initialize checkout of an external repository scripts directory"""
blender_git_root = Path(get_blender_git_root())
blender_dot_git = blender_git_root / ".git"
scripts_dir = blender_git_root / "scripts"
external_dir = scripts_dir / directory_name
if external_dir.exists():
return
print(f"Initializing scripts/{directory_name} ...")
old_submodule_dot_git = blender_git_root / "release" / "scripts" / directory_name / ".git"
if old_submodule_dot_git.exists() and blender_dot_git.is_dir():
external_script_copy_old_submodule_over(args, directory_name)
return
origin_name = "upstream" if use_upstream_workflow(args) else "origin"
blender_url = make_utils.git_get_remote_url(args.git_command, origin_name)
external_url = resolve_external_url(blender_url, repo_name)
call((args.git_command, "clone", "--origin", origin_name, external_url, str(external_dir)))
def external_script_add_origin_if_needed(args: argparse.Namespace,
repo_name: str,
directory_name: str) -> None:
"""
Add remote called 'origin' if there is a fork of the external repository available
This is only done when using Github style upstream workflow in the main repository.
"""
if not use_upstream_workflow(args):
return
cwd = os.getcwd()
blender_git_root = Path(get_blender_git_root())
scripts_dir = blender_git_root / "scripts"
external_dir = scripts_dir / directory_name
origin_blender_url = make_utils.git_get_remote_url(args.git_command, "origin")
origin_external_url = resolve_external_url(origin_blender_url, repo_name)
try:
os.chdir(external_dir)
if (make_utils.git_remote_exist(args.git_command, "origin") or
not make_utils.git_remote_exist(args.git_command, "upstream")):
return
if not make_utils.git_is_remote_repository(args.git_command, origin_external_url):
return
print(f"Adding origin remote to {directory_name} pointing to fork ...")
# Non-obvious tricks to introduce the new remote called "origin" to the existing
# submodule configuration.
#
# This is all within the content of creating a fork of a submodule after `make update`
# has been run and possibly local branches tracking upstream were added.
#
# The idea here goes as following:
#
# - Rename remote "upstream" to "origin", which takes care of changing the names of
# remotes the local branches are tracking.
#
# - Change the URL to the "origin", which so was was still pointing to upstream.
#
# - Re-introduce the "upstream" remote, with the same URL as it had prior to rename.
upstream_url = make_utils.git_get_remote_url(args.git_command, "upstream")
call((args.git_command, "remote", "rename", "upstream", "origin"))
make_utils.git_set_config(args.git_command, f"remote.origin.url", origin_external_url)
call((args.git_command, "remote", "add", "upstream", upstream_url))
finally:
os.chdir(cwd)
return
def external_scripts_update(args: argparse.Namespace,
repo_name: str,
directory_name: str,
branch: Optional[str]) -> str:
"""Update a single external checkout with the given name in the scripts folder"""
external_script_initialize_if_needed(args, repo_name, directory_name)
external_script_add_origin_if_needed(args, repo_name, directory_name)
print(f"Updating scripts/{directory_name} ...")
cwd = os.getcwd()
blender_git_root = Path(get_blender_git_root())
scripts_dir = blender_git_root / "scripts"
external_dir = scripts_dir / directory_name
# Update externals to appropriate given branch, falling back to main if none is given and/or
# found in a sub-repository.
branch_fallback = "main"
if not branch:
branch = branch_fallback
submodules = [
("release/scripts/addons", branch, branch_fallback),
("release/scripts/addons_contrib", branch, branch_fallback),
("release/datafiles/locale", branch, branch_fallback),
("source/tools", branch, branch_fallback),
]
# Initialize submodules only if needed.
for submodule_path, submodule_branch, submodule_branch_fallback in submodules:
if not os.path.exists(os.path.join(submodule_path, ".git")):
call([args.git_command, "submodule", "update", "--init", "--recursive"])
break
# Checkout appropriate branch and pull changes.
skip_msg = ""
for submodule_path, submodule_branch, submodule_branch_fallback in submodules:
cwd = os.getcwd()
try:
os.chdir(submodule_path)
msg = git_update_skip(args, check_remote_exists=False)
if msg:
skip_msg += submodule_path + " skipped: " + msg + "\n"
else:
# Find a matching branch that exists.
call([args.git_command, "fetch", "origin"])
if make_utils.git_branch_exists(args.git_command, submodule_branch):
pass
elif make_utils.git_branch_exists(args.git_command, submodule_branch_fallback):
submodule_branch = submodule_branch_fallback
else:
# Skip.
submodule_branch = ""
# Switch to branch and pull.
if submodule_branch:
if make_utils.git_branch(args.git_command) != submodule_branch:
try:
os.chdir(external_dir)
msg = git_update_skip(args, check_remote_exists=False)
if msg:
skip_msg += directory_name + " skipped: " + msg + "\n"
else:
# Find a matching branch that exists.
for remote in ("origin", "upstream"):
if make_utils.git_remote_exist(args.git_command, remote):
call([args.git_command, "fetch", remote])
submodule_branch = branch
if make_utils.git_branch_exists(args.git_command, submodule_branch):
pass
elif make_utils.git_branch_exists(args.git_command, branch_fallback):
submodule_branch = branch_fallback
else:
# Skip.
submodule_branch = ""
# Switch to branch and pull.
if submodule_branch:
if make_utils.git_branch(args.git_command) != submodule_branch:
# If the local branch exists just check out to it.
# If there is no local branch but only remote specify an explicit remote.
# Without this explicit specification Git attempts to set-up tracking
# automatically and fails when the branch is available in multiple remotes.
if make_utils.git_local_branch_exists(args.git_command, submodule_branch):
call([args.git_command, "checkout", submodule_branch])
call([args.git_command, "pull", "--rebase", "origin", submodule_branch])
finally:
os.chdir(cwd)
elif make_utils.git_remote_exist(args.git_command, "origin"):
call([args.git_command, "checkout", "-t", f"origin/{submodule_branch}"])
elif make_utils.git_remote_exist(args.git_command, "upstream"):
call([args.git_command, "checkout", "-t", f"upstream/{submodule_branch}"])
# Don't use extra fetch since all remotes of interest have been already fetched
# some lines above.
skip_msg += work_tree_update(args, use_fetch=False)
finally:
os.chdir(cwd)
return skip_msg
def scripts_submodules_update(args: argparse.Namespace, branch: Optional[str]) -> str:
"""Update working trees of addons and addons_contrib within the scripts/ directory"""
msg = ""
msg += external_scripts_update(args, "blender-addons", "addons", branch)
msg += external_scripts_update(args, "blender-addons-contrib", "addons_contrib", branch)
return msg
def submodules_update(args: argparse.Namespace, branch: Optional[str]) -> str:
"""Update submodules or other externally tracked source trees"""
msg = ""
msg += scripts_submodules_update(args, branch)
return msg
if __name__ == "__main__":
args = parse_arguments()
blender_skip_msg = ""
submodules_skip_msg = ""
# Test if we are building a specific release version.
branch = make_utils.git_branch(args.git_command)
if branch == 'HEAD':
sys.stderr.write('Blender git repository is in detached HEAD state, must be in a branch\n')
sys.exit(1)
tag = make_utils.git_tag(args.git_command)
release_version = make_utils.git_branch_release_version(branch, tag)
blender_version = make_utils. parse_blender_version()
if blender_version.cycle != 'alpha':
major = blender_version.version // 100
minor = blender_version.version % 100
branch = f"blender-v{major}.{minor}-release"
release_version: Optional[str] = f"{major}.{minor}"
else:
branch = 'main'
release_version = None
if not args.no_libraries:
svn_update(args, release_version)
if not args.no_blender:
blender_skip_msg = git_update_skip(args)
if not blender_skip_msg:
blender_skip_msg = blender_update(args)
if blender_skip_msg:
blender_skip_msg = "Blender repository skipped: " + blender_skip_msg + "\n"
else:
blender_update(args)
if not args.no_submodules:
submodules_skip_msg = submodules_update(args, release_version, branch)
submodules_skip_msg = submodules_update(args, branch)
# Report any skipped repositories at the end, so it's not as easy to miss.
skip_msg = blender_skip_msg + submodules_skip_msg

View File

@@ -9,7 +9,9 @@ import re
import shutil
import subprocess
import sys
import os
from pathlib import Path
from urllib.parse import urljoin
from typing import (
Sequence,
@@ -19,7 +21,7 @@ from typing import (
def call(cmd: Sequence[str], exit_on_error: bool = True, silent: bool = False) -> int:
if not silent:
print(" ".join(cmd))
print(" ".join([str(x) for x in cmd]))
# Flush to ensure correct order output on Windows.
sys.stdout.flush()
@@ -52,13 +54,57 @@ def check_output(cmd: Sequence[str], exit_on_error: bool = True) -> str:
return output.strip()
def git_local_branch_exists(git_command: str, branch: str) -> bool:
return (
call([git_command, "rev-parse", "--verify", branch], exit_on_error=False, silent=True) == 0
)
def git_branch_exists(git_command: str, branch: str) -> bool:
return (
call([git_command, "rev-parse", "--verify", branch], exit_on_error=False, silent=True) == 0 or
git_local_branch_exists(git_command, branch) or
call([git_command, "rev-parse", "--verify", "remotes/upstream/" + branch], exit_on_error=False, silent=True) == 0 or
call([git_command, "rev-parse", "--verify", "remotes/origin/" + branch], exit_on_error=False, silent=True) == 0
)
def git_get_remote_url(git_command: str, remote_name: str) -> str:
return check_output((git_command, "ls-remote", "--get-url", remote_name))
def git_remote_exist(git_command: str, remote_name: str) -> bool:
"""Check whether there is a remote with the given name"""
# `git ls-remote --get-url upstream` will print an URL if there is such remote configured, and
# otherwise will print "upstream".
remote_url = check_output((git_command, "ls-remote", "--get-url", remote_name))
return remote_url != remote_name
def git_get_resolved_submodule_url(git_command: str, blender_url: str, submodule_path: str) -> str:
git_root = check_output([git_command, "rev-parse", "--show-toplevel"])
dot_gitmodules = os.path.join(git_root, ".gitmodules")
submodule_key_prefix = f"submodule.{submodule_path}"
submodule_key_url = f"{submodule_key_prefix}.url"
gitmodule_url = git_get_config(
git_command, submodule_key_url, file=dot_gitmodules)
# A bit of a trickery to construct final URL.
# Only works for the relative submodule URLs.
#
# Note that unless the LHS URL ends up with a slash urljoin treats the last component as a
# file.
assert gitmodule_url.startswith('..')
return urljoin(blender_url + "/", gitmodule_url)
def git_is_remote_repository(git_command: str, repo: str) -> bool:
"""Returns true if the given repository is a valid/clonable git repo"""
exit_code = call((git_command, "ls-remote", repo, "HEAD"), exit_on_error=False, silent=True)
return exit_code == 0
def git_branch(git_command: str) -> str:
# Get current branch name.
try:
@@ -70,6 +116,20 @@ def git_branch(git_command: str) -> str:
return branch.strip().decode('utf8')
def git_get_config(git_command: str, key: str, file: Optional[str] = None) -> str:
if file:
return check_output([git_command, "config", "--file", file, "--get", key])
return check_output([git_command, "config", "--get", key])
def git_set_config(git_command: str, key: str, value: str, file: Optional[str] = None) -> str:
if file:
return check_output([git_command, "config", "--file", file, key, value])
return check_output([git_command, "config", key, value])
def git_tag(git_command: str) -> Optional[str]:
# Get current tag name.
try:

View File

@@ -3,9 +3,9 @@ if NOT exist "%BLENDER_DIR%\source\tools\.git" (
if not "%GIT%" == "" (
"%GIT%" submodule update --init --recursive --progress
if errorlevel 1 goto FAIL
"%GIT%" submodule foreach git checkout master
"%GIT%" submodule foreach git checkout main
if errorlevel 1 goto FAIL
"%GIT%" submodule foreach git pull --rebase origin master
"%GIT%" submodule foreach git pull --rebase origin main
if errorlevel 1 goto FAIL
goto EOF
) else (

View File

@@ -4,9 +4,9 @@ if "%GIT%" == "" (
)
cd "%BLENDER_DIR%"
for /f "delims=" %%i in ('"%GIT%" rev-parse HEAD') do echo Branch_hash=%%i
cd "%BLENDER_DIR%/release/datafiles/locale"
cd "%BLENDER_DIR%/locale"
for /f "delims=" %%i in ('"%GIT%" rev-parse HEAD') do echo Locale_hash=%%i
cd "%BLENDER_DIR%/release/scripts/addons"
cd "%BLENDER_DIR%/scripts/addons"
for /f "delims=" %%i in ('"%GIT%" rev-parse HEAD') do echo Addons_Hash=%%i
cd "%BLENDER_DIR%"
:EOF

View File

@@ -231,7 +231,7 @@ class FileBlockHeader:
self.SDNAIndex = 0
self.Count = 0
self.FileOffset = handle.tell()
#self.Code += ' ' * (4 - len(self.Code))
# self.Code += ' ' * (4 - len(self.Code))
log.debug("found blend-file-block-fileheader {0} {1}".format(self.Code, self.FileOffset))
def skip(self, handle):

View File

@@ -38,7 +38,7 @@ PROJECT_NAME = Blender
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = V3.5
PROJECT_NUMBER = V3.6
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

View File

@@ -37,7 +37,7 @@ def draw_callback_px(self, context):
# BLF drawing routine
font_id = font_info["font_id"]
blf.position(font_id, 2, 80, 0)
blf.size(font_id, 50, 72)
blf.size(font_id, 50)
blf.draw(font_id, "Hello World")

View File

@@ -31,7 +31,7 @@ For an overview of BMesh data types and how they reference each other see:
Example Script
--------------
.. literalinclude:: __/__/__/release/scripts/templates_py/bmesh_simple.py
.. literalinclude:: __/__/__/scripts/templates_py/bmesh_simple.py
Standalone Module

View File

@@ -288,7 +288,7 @@ In Python, this is done by defining a class, which is a subclass of an existing
Example Operator
----------------
.. literalinclude:: __/__/__/release/scripts/templates_py/operator_simple.py
.. literalinclude:: __/__/__/scripts/templates_py/operator_simple.py
Once this script runs, ``SimpleOperator`` is registered with Blender
and can be called from Operator Search or added to the toolbar.
@@ -320,7 +320,7 @@ Example Panel
Panels are registered as a class, like an operator.
Notice the extra ``bl_`` variables used to set the context they display in.
.. literalinclude:: __/__/__/release/scripts/templates_py/ui_panel_simple.py
.. literalinclude:: __/__/__/scripts/templates_py/ui_panel_simple.py
To run the script:

View File

@@ -367,13 +367,13 @@ except ImportError:
# Note that ".." is replaced by "__" in the RST files,
# to avoid having to match Blender's source tree.
EXTRA_SOURCE_FILES = (
"../../../release/scripts/templates_py/bmesh_simple.py",
"../../../release/scripts/templates_py/gizmo_operator.py",
"../../../release/scripts/templates_py/gizmo_operator_target.py",
"../../../release/scripts/templates_py/gizmo_simple.py",
"../../../release/scripts/templates_py/operator_simple.py",
"../../../release/scripts/templates_py/ui_panel_simple.py",
"../../../release/scripts/templates_py/ui_previews_custom_icon.py",
"../../../scripts/templates_py/bmesh_simple.py",
"../../../scripts/templates_py/gizmo_operator.py",
"../../../scripts/templates_py/gizmo_operator_target.py",
"../../../scripts/templates_py/gizmo_simple.py",
"../../../scripts/templates_py/operator_simple.py",
"../../../scripts/templates_py/ui_panel_simple.py",
"../../../scripts/templates_py/ui_previews_custom_icon.py",
"../examples/bmesh.ops.1.py",
"../examples/bpy.app.translations.py",
)
@@ -476,7 +476,7 @@ MODULE_GROUPING = {
# -------------------------------BLENDER----------------------------------------
# converting bytes to strings, due to T30154
# Converting bytes to strings, due to #30154.
BLENDER_REVISION = str(bpy.app.build_hash, 'utf_8')
BLENDER_REVISION_TIMESTAMP = bpy.app.build_commit_timestamp
@@ -487,7 +487,7 @@ BLENDER_VERSION_DOTS = "%d.%d" % (bpy.app.version[0], bpy.app.version[1])
if BLENDER_REVISION != "Unknown":
# SHA1 Git hash
BLENDER_VERSION_HASH = BLENDER_REVISION
BLENDER_VERSION_HASH_HTML_LINK = "<a href=https://developer.blender.org/rB%s>%s</a>" % (
BLENDER_VERSION_HASH_HTML_LINK = "<a href=https://projects.blender.org/blender/blender/commit/%s>%s</a>" % (
BLENDER_VERSION_HASH, BLENDER_VERSION_HASH,
)
BLENDER_VERSION_DATE = time.strftime("%d/%m/%Y", time.localtime(BLENDER_REVISION_TIMESTAMP))
@@ -647,7 +647,7 @@ def undocumented_message(module_name, type_name, identifier):
module_name, type_name, identifier,
)
return "Undocumented, consider `contributing <https://developer.blender.org/T51061>`__."
return "Undocumented, consider `contributing <https://developer.blender.org/>`__."
def range_str(val):
@@ -1816,9 +1816,9 @@ def pyrna2sphinx(basepath):
# operators
def write_ops():
API_BASEURL = "https://developer.blender.org/diffusion/B/browse/master/release/scripts"
API_BASEURL_ADDON = "https://developer.blender.org/diffusion/BA"
API_BASEURL_ADDON_CONTRIB = "https://developer.blender.org/diffusion/BAC"
API_BASEURL = "https://projects.blender.org/blender/blender/src/branch/main/scripts"
API_BASEURL_ADDON = "https://projects.blender.org/blender/blender-addons"
API_BASEURL_ADDON_CONTRIB = "https://projects.blender.org/blender/blender-addons-contrib"
op_modules = {}
op = None
@@ -2200,7 +2200,7 @@ def write_rst_enum_items(basepath, key, key_no_prefix, enum_items):
Write a single page for a static enum in RST.
This helps avoiding very large lists being in-lined in many places which is an issue
especially with icons in ``bpy.types.UILayout``. See T87008.
especially with icons in ``bpy.types.UILayout``. See #87008.
"""
filepath = os.path.join(basepath, "%s.rst" % key_no_prefix)
with open(filepath, "w", encoding="utf-8") as fh:

View File

@@ -156,7 +156,7 @@ var Popover = function() {
},
getNamed : function(v) {
$.each(all_versions, function(ix, title) {
if (ix === "master" || ix === "latest") {
if (ix === "master" || ix === "main" || ix === "latest") {
var m = title.match(/\d\.\d[\w\d\.]*/)[0];
if (parseFloat(m) == v) {
v = ix;

View File

@@ -1,5 +1,5 @@
Project: Blender
URL: https://git.blender.org/blender.git
URL: https://projects.blender.org/blender/blender.git
License: Apache 2.0
Upstream version: N/A
Local modifications: None

View File

@@ -12,6 +12,7 @@ from bpy.props import (
PointerProperty,
StringProperty,
)
from bpy.app.translations import pgettext_iface as iface_
from math import pi
@@ -1664,30 +1665,51 @@ class CyclesPreferences(bpy.types.AddonPreferences):
col.label(text="No compatible GPUs found for Cycles", icon='INFO')
if device_type == 'CUDA':
col.label(text="Requires NVIDIA GPU with compute capability 3.0", icon='BLANK1')
compute_capability = "3.0"
col.label(text=iface_("Requires NVIDIA GPU with compute capability %s") % compute_capability,
icon='BLANK1', translate=False)
elif device_type == 'OPTIX':
col.label(text="Requires NVIDIA GPU with compute capability 5.0", icon='BLANK1')
col.label(text="and NVIDIA driver version 470 or newer", icon='BLANK1')
compute_capability = "5.0"
driver_version = "470"
col.label(text=iface_("Requires NVIDIA GPU with compute capability %s") % compute_capability,
icon='BLANK1', translate=False)
col.label(text=iface_("and NVIDIA driver version %s or newer") % driver_version,
icon='BLANK1', translate=False)
elif device_type == 'HIP':
import sys
if sys.platform[:3] == "win":
col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1')
col.label(text="and AMD Radeon Pro 21.Q4 driver or newer", icon='BLANK1')
elif sys.platform.startswith("linux"):
col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1')
col.label(text="and AMD driver version 22.10 or newer", icon='BLANK1')
if True:
col.label(text="HIP temporarily disabled due to compiler bugs", icon='BLANK1')
else:
import sys
if sys.platform[:3] == "win":
driver_version = "21.Q4"
col.label(text="Requires AMD GPU with Vega or RDNA architecture", icon='BLANK1')
col.label(text=iface_("and AMD Radeon Pro %s driver or newer") % driver_version,
icon='BLANK1', translate=False)
elif sys.platform.startswith("linux"):
driver_version = "22.10"
col.label(text="Requires AMD GPU with Vega or RDNA architecture", icon='BLANK1')
col.label(text=iface_("and AMD driver version %s or newer") % driver_version, icon='BLANK1',
translate=False)
elif device_type == 'ONEAPI':
import sys
if sys.platform.startswith("win"):
driver_version = "101.4032"
col.label(text="Requires Intel GPU with Xe-HPG architecture", icon='BLANK1')
col.label(text="and Windows driver version 101.4032 or newer", icon='BLANK1')
col.label(text=iface_("and Windows driver version %s or newer") % driver_version,
icon='BLANK1', translate=False)
elif sys.platform.startswith("linux"):
driver_version = "1.3.24931"
col.label(text="Requires Intel GPU with Xe-HPG architecture and", icon='BLANK1')
col.label(text=" - intel-level-zero-gpu version 1.3.24931 or newer", icon='BLANK1')
col.label(text=iface_(" - intel-level-zero-gpu version %s or newer") % driver_version,
icon='BLANK1', translate=False)
col.label(text=" - oneAPI Level-Zero Loader", icon='BLANK1')
elif device_type == 'METAL':
col.label(text="Requires Apple Silicon with macOS 12.2 or newer", icon='BLANK1')
col.label(text="or AMD with macOS 12.3 or newer", icon='BLANK1')
silicon_mac_version = "12.2"
amd_mac_version = "12.3"
col.label(text=iface_("Requires Apple Silicon with macOS %s or newer") % silicon_mac_version,
icon='BLANK1', translate=False)
col.label(text=iface_("or AMD with macOS %s or newer") % amd_mac_version, icon='BLANK1',
translate=False)
return
for device in devices:
@@ -1697,7 +1719,8 @@ class CyclesPreferences(bpy.types.AddonPreferences):
.replace('(TM)', unicodedata.lookup('TRADE MARK SIGN'))
.replace('(tm)', unicodedata.lookup('TRADE MARK SIGN'))
.replace('(R)', unicodedata.lookup('REGISTERED SIGN'))
.replace('(C)', unicodedata.lookup('COPYRIGHT SIGN'))
.replace('(C)', unicodedata.lookup('COPYRIGHT SIGN')),
translate=False
)
def draw_impl(self, layout, context):
@@ -1722,19 +1745,21 @@ class CyclesPreferences(bpy.types.AddonPreferences):
row.prop(self, "peer_memory")
if compute_device_type == 'METAL':
import platform, re
isNavi2 = False
import platform
import re
is_navi_2 = False
for device in devices:
obj = re.search("((RX)|(Pro)|(PRO))\s+W?6\d00X",device.name)
if obj:
isNavi2 = True
if re.search(r"((RX)|(Pro)|(PRO))\s+W?6\d00X", device.name):
is_navi_2 = True
break
# MetalRT only works on Apple Silicon and Navi2
if platform.machine() == 'arm64' or isNavi2:
# MetalRT only works on Apple Silicon and Navi2.
is_arm64 = platform.machine() == 'arm64'
if is_arm64 or is_navi_2:
col = layout.column()
col.use_property_split = True
# Kernel specialization is only supported on Apple Silicon
if platform.machine() == 'arm64':
if is_arm64:
col.prop(self, "kernel_optimization_level")
col.prop(self, "use_metalrt")

View File

@@ -20,7 +20,7 @@ class CyclesPresetPanel(PresetPanel, Panel):
@staticmethod
def post_cb(context):
# Modify an arbitrary built-in scene property to force a depsgraph
# update, because add-on properties don't. (see T62325)
# update, because add-on properties don't. (see #62325)
render = context.scene.render
render.filter_size = render.filter_size

View File

@@ -3,6 +3,7 @@
#include <optional>
#include "BKE_curves.hh"
#include "blender/sync.h"
#include "blender/util.h"
@@ -272,10 +273,13 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
if (hair->num_curves())
return;
Attribute *attr_normal = NULL;
Attribute *attr_intercept = NULL;
Attribute *attr_length = NULL;
Attribute *attr_random = NULL;
if (hair->need_attribute(scene, ATTR_STD_VERTEX_NORMAL))
attr_normal = hair->attributes.add(ATTR_STD_VERTEX_NORMAL);
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT))
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT);
if (hair->need_attribute(scene, ATTR_STD_CURVE_LENGTH))
@@ -322,6 +326,11 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
if (attr_intercept)
attr_intercept->add(time);
if (attr_normal) {
/* TODO: compute geometry normals. */
attr_normal->add(make_float3(1.0f, 0.0f, 0.0f));
}
num_curve_keys++;
}
@@ -885,6 +894,14 @@ static void export_hair_curves(Scene *scene,
float *attr_length = NULL;
float *attr_random = NULL;
if (hair->need_attribute(scene, ATTR_STD_VERTEX_NORMAL)) {
/* Compute geometry normals. */
float3 *attr_normal = hair->attributes.add(ATTR_STD_VERTEX_NORMAL)->data_float3();
int i = 0;
for (BL::FloatVectorValueReadOnly &normal : b_curves.normals) {
attr_normal[i++] = get_float3(normal.vector());
}
}
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) {
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT)->data_float();
}

View File

@@ -54,44 +54,10 @@ int BlenderDisplayShader::get_tex_coord_attrib_location()
/* --------------------------------------------------------------------
* BlenderFallbackDisplayShader.
*/
/* TODO move shaders to standalone .glsl file. */
static const char *FALLBACK_VERTEX_SHADER =
"uniform vec2 fullscreen;\n"
"in vec2 texCoord;\n"
"in vec2 pos;\n"
"out vec2 texCoord_interp;\n"
"\n"
"vec2 normalize_coordinates()\n"
"{\n"
" return (vec2(2.0) * (pos / fullscreen)) - vec2(1.0);\n"
"}\n"
"\n"
"void main()\n"
"{\n"
" gl_Position = vec4(normalize_coordinates(), 0.0, 1.0);\n"
" texCoord_interp = texCoord;\n"
"}\n\0";
static const char *FALLBACK_FRAGMENT_SHADER =
"uniform sampler2D image_texture;\n"
"in vec2 texCoord_interp;\n"
"out vec4 fragColor;\n"
"\n"
"void main()\n"
"{\n"
" fragColor = texture(image_texture, texCoord_interp);\n"
"}\n\0";
static GPUShader *compile_fallback_shader(void)
{
/* NOTE: Compilation errors are logged to console. */
GPUShader *shader = GPU_shader_create(FALLBACK_VERTEX_SHADER,
FALLBACK_FRAGMENT_SHADER,
nullptr,
nullptr,
nullptr,
"FallbackCyclesBlitShader");
GPUShader *shader = GPU_shader_create_from_info_name("gpu_shader_cycles_display_fallback");
return shader;
}
@@ -105,11 +71,12 @@ GPUShader *BlenderFallbackDisplayShader::bind(int width, int height)
/* Bind shader now to enable uniform assignment. */
GPU_shader_bind(shader_program_);
GPU_shader_uniform_int(shader_program_, image_texture_location_, 0);
int slot = 0;
GPU_shader_uniform_int_ex(shader_program_, image_texture_location_, 1, 1, &slot);
float size[2];
size[0] = width;
size[1] = height;
GPU_shader_uniform_vector(shader_program_, fullscreen_location_, 2, 1, size);
GPU_shader_uniform_float_ex(shader_program_, fullscreen_location_, 2, 1, size);
return shader_program_;
}
@@ -249,8 +216,13 @@ class DisplayGPUTexture {
height = texture_height;
/* Texture must have a minimum size of 1x1. */
gpu_texture = GPU_texture_create_2d(
"CyclesBlitTexture", max(width, 1), max(height, 1), 1, GPU_RGBA16F, nullptr);
gpu_texture = GPU_texture_create_2d("CyclesBlitTexture",
max(width, 1),
max(height, 1),
1,
GPU_RGBA16F,
GPU_TEXTURE_USAGE_GENERAL,
nullptr);
if (!gpu_texture) {
LOG(ERROR) << "Error creating texture.";
@@ -733,14 +705,14 @@ static void draw_tile(const float2 &zoom,
const float zoomed_height = draw_tile.params.size.y * zoom.y;
if (texture.width != draw_tile.params.size.x || texture.height != draw_tile.params.size.y) {
/* Resolution divider is different from 1, force nearest interpolation. */
GPU_texture_bind_ex(texture.gpu_texture, GPU_SAMPLER_DEFAULT, 0, false);
GPU_texture_bind_ex(texture.gpu_texture, GPU_SAMPLER_DEFAULT, 0);
}
else if (zoomed_width - draw_tile.params.size.x > 0.5f ||
zoomed_height - draw_tile.params.size.y > 0.5f) {
GPU_texture_bind_ex(texture.gpu_texture, GPU_SAMPLER_DEFAULT, 0, false);
GPU_texture_bind_ex(texture.gpu_texture, GPU_SAMPLER_DEFAULT, 0);
}
else {
GPU_texture_bind_ex(texture.gpu_texture, GPU_SAMPLER_FILTER, 0, false);
GPU_texture_bind_ex(texture.gpu_texture, GPU_SAMPLER_FILTER, 0);
}
/* Draw at the parameters for which the texture has been updated for. This allows to always draw

View File

@@ -20,7 +20,7 @@ BlenderImageLoader::BlenderImageLoader(BL::Image b_image,
: b_image(b_image),
frame(frame),
tile_number(tile_number),
/* Don't free cache for preview render to avoid race condition from T93560, to be fixed
/* Don't free cache for preview render to avoid race condition from #93560, to be fixed
* properly later as we are close to release. */
free_cache(!is_preview_render && !b_image.has_data())
{
@@ -72,7 +72,7 @@ bool BlenderImageLoader::load_metadata(const ImageDeviceFeatures &, ImageMetaDat
metadata.colorspace = u_colorspace_raw;
}
else {
/* In some cases (e.g. T94135), the colorspace setting in Blender gets updated as part of the
/* In some cases (e.g. #94135), the colorspace setting in Blender gets updated as part of the
* metadata queries in this function, so update the colorspace setting here. */
PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr;
metadata.colorspace = get_enum_identifier(colorspace_ptr, "name");

View File

@@ -24,7 +24,7 @@ void BlenderSync::sync_light(BL::Object &b_parent,
Light *light = light_map.find(key);
/* Check if the transform was modified, in case a linked collection is moved we do not get a
* specific depsgraph update (T88515). This also mimics the behavior for Objects. */
* specific depsgraph update (#88515). This also mimics the behavior for Objects. */
const bool tfm_updated = (light && light->get_tfm() != tfm);
/* Update if either object or light data changed. */

View File

@@ -222,7 +222,10 @@ static void export_pointcloud_motion(PointCloud *pointcloud,
/* Export motion points. */
const int num_points = pointcloud->num_points();
float3 *mP = attr_mP->data_float3() + motion_step * num_points;
// Point cloud attributes are stored as float4 with the radius
// in the w element. This is explict now as float3 is no longer
// interchangeable with float4 as it is packed now.
float4 *mP = attr_mP->data_float4() + motion_step * num_points;
bool have_motion = false;
const array<float3> &pointcloud_points = pointcloud->get_points();
@@ -231,11 +234,9 @@ static void export_pointcloud_motion(PointCloud *pointcloud,
std::optional<BL::FloatAttribute> b_attr_radius = find_radius_attribute(b_pointcloud);
for (int i = 0; i < std::min(num_points, b_points_num); i++) {
const float3 co = get_float3(b_attr_position.data[i].vector());
const float3 P = get_float3(b_attr_position.data[i].vector());
const float radius = b_attr_radius ? b_attr_radius->data[i].value() : 0.01f;
float3 P = co;
P.w = radius;
mP[i] = P;
mP[i] = make_float4(P.x, P.y, P.z, radius);
have_motion = have_motion || (P != pointcloud_points[i]);
}

View File

@@ -94,7 +94,7 @@ void python_thread_state_restore(void **python_thread_state)
*python_thread_state = NULL;
}
static const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
static const char *PyC_UnicodeAsBytes(PyObject *py_str, PyObject **coerce)
{
const char *result = PyUnicode_AsUTF8(py_str);
if (result) {
@@ -131,8 +131,8 @@ static PyObject *init_func(PyObject * /*self*/, PyObject *args)
}
PyObject *path_coerce = nullptr, *user_path_coerce = nullptr;
path_init(PyC_UnicodeAsByte(path, &path_coerce),
PyC_UnicodeAsByte(user_path, &user_path_coerce));
path_init(PyC_UnicodeAsBytes(path, &path_coerce),
PyC_UnicodeAsBytes(user_path, &user_path_coerce));
Py_XDECREF(path_coerce);
Py_XDECREF(user_path_coerce);

View File

@@ -404,7 +404,7 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
* point we know that we've got everything to render current view layer.
*/
/* At the moment we only free if we are not doing multi-view
* (or if we are rendering the last view). See T58142/D4239 for discussion.
* (or if we are rendering the last view). See #58142/D4239 for discussion.
*/
if (view_index == num_views - 1) {
free_blender_memory_if_possible();

View File

@@ -660,6 +660,22 @@ static ShaderNode *add_node(Scene *scene,
NODE_PRINCIPLED_HAIR_REFLECTANCE));
node = principled_hair;
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfHairMicrofacet)) {
BL::ShaderNodeBsdfHairMicrofacet b_microfacet_hair_node(b_node);
MicrofacetHairBsdfNode *microfacet_hair = graph->create_node<MicrofacetHairBsdfNode>();
microfacet_hair->set_parametrization(
(NodeMicrofacetHairParametrization)get_enum(b_microfacet_hair_node.ptr,
"parametrization",
NODE_MICROFACET_HAIR_NUM,
NODE_MICROFACET_HAIR_REFLECTANCE));
microfacet_hair->set_distribution_type(
(NodeMicrofacetHairDistributionType)get_enum(b_microfacet_hair_node.ptr,
"distribution_type",
NODE_MICROFACET_HAIR_DISTRIBUTION_TYPE_NUM,
NODE_MICROFACET_HAIR_GGX));
node = microfacet_hair;
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfPrincipled)) {
BL::ShaderNodeBsdfPrincipled b_principled_node(b_node);
PrincipledBsdfNode *principled = graph->create_node<PrincipledBsdfNode>();

View File

@@ -349,8 +349,7 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
bool use_light_tree = get_boolean(cscene, "use_light_tree");
integrator->set_use_light_tree(use_light_tree);
integrator->set_light_sampling_threshold(
(use_light_tree) ? 0.0f : get_float(cscene, "light_sampling_threshold"));
integrator->set_light_sampling_threshold(get_float(cscene, "light_sampling_threshold"));
if (integrator->use_light_tree_is_modified()) {
scene->light_manager->tag_update(scene, LightManager::UPDATE_ALL);
@@ -766,7 +765,7 @@ void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph)
(BlenderSession::headless || is_interface_locked) &&
/* Baking re-uses the depsgraph multiple times, clearing crashes
* reading un-evaluated mesh data which isn't aligned with the
* geometry we're baking, see T71012. */
* geometry we're baking, see #71012. */
!scene->bake_manager->get_baking() &&
/* Persistent data must main caches for performance and correctness. */
!is_persistent_data;

View File

@@ -180,9 +180,9 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox &center, Hair *hair
curve.bounds_grow(k, &hair->get_curve_keys()[0], curve_radius, bounds);
const size_t num_keys = hair->get_curve_keys().size();
const size_t num_steps = hair->get_motion_steps();
const float3 *key_steps = curve_attr_mP->data_float3();
const float4 *key_steps = curve_attr_mP->data_float4();
for (size_t step = 0; step < num_steps - 1; step++) {
curve.bounds_grow(k, key_steps + step * num_keys, curve_radius, bounds);
curve.bounds_grow(k, key_steps + step * num_keys, bounds);
}
if (bounds.valid()) {
int packed_type = PRIMITIVE_PACK_SEGMENT(primitive_type, k);
@@ -200,7 +200,7 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox &center, Hair *hair
const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
const size_t num_steps = hair->get_motion_steps();
const float3 *curve_keys = &hair->get_curve_keys()[0];
const float3 *key_steps = curve_attr_mP->data_float3();
const float4 *key_steps = curve_attr_mP->data_float4();
const size_t num_keys = hair->get_curve_keys().size();
/* Calculate bounding box of the previous time step.
* Will be reused later to avoid duplicated work on

View File

@@ -254,20 +254,15 @@ void BVHEmbree::add_triangles(const Object *ob, const Mesh *mesh, int i)
rtcSetGeometryBuildQuality(geom_id, build_quality);
rtcSetGeometryTimeStepCount(geom_id, num_motion_steps);
unsigned *rtc_indices = (unsigned *)rtcSetNewGeometryBuffer(
geom_id, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, sizeof(int) * 3, num_triangles);
assert(rtc_indices);
if (!rtc_indices) {
VLOG_WARNING << "Embree could not create new geometry buffer for mesh " << mesh->name.c_str()
<< ".\n";
return;
}
for (size_t j = 0; j < num_triangles; ++j) {
Mesh::Triangle t = mesh->get_triangle(j);
rtc_indices[j * 3] = t.v[0];
rtc_indices[j * 3 + 1] = t.v[1];
rtc_indices[j * 3 + 2] = t.v[2];
}
const int *triangles = mesh->get_triangles().data();
rtcSetSharedGeometryBuffer(geom_id,
RTC_BUFFER_TYPE_INDEX,
0,
RTC_FORMAT_UINT3,
triangles,
0,
sizeof(int) * 3,
num_triangles);
set_tri_vertex_buffer(geom_id, mesh, false);
@@ -309,28 +304,46 @@ void BVHEmbree::set_tri_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh, con
verts = &attr_mP->data_float3()[t_ * num_verts];
}
float *rtc_verts = (update) ?
(float *)rtcGetGeometryBufferData(geom_id, RTC_BUFFER_TYPE_VERTEX, t) :
(float *)rtcSetNewGeometryBuffer(geom_id,
RTC_BUFFER_TYPE_VERTEX,
t,
RTC_FORMAT_FLOAT3,
sizeof(float) * 3,
num_verts + 1);
assert(rtc_verts);
if (rtc_verts) {
for (size_t j = 0; j < num_verts; ++j) {
rtc_verts[0] = verts[j].x;
rtc_verts[1] = verts[j].y;
rtc_verts[2] = verts[j].z;
rtc_verts += 3;
}
}
if (update) {
rtcUpdateGeometryBuffer(geom_id, RTC_BUFFER_TYPE_VERTEX, t);
}
else {
rtcSetSharedGeometryBuffer(geom_id,
RTC_BUFFER_TYPE_VERTEX,
t,
RTC_FORMAT_FLOAT3,
verts,
0,
sizeof(float3),
num_verts + 1);
}
}
}
/**
* Packs the hair motion curve data control variables (CVs) into float4s as [x y z radius]
*/
template<typename T>
void pack_motion_verts(size_t num_curves,
const Hair *hair,
const T *verts,
const float *curve_radius,
float4 *rtc_verts)
{
for (size_t j = 0; j < num_curves; ++j) {
Hair::Curve c = hair->get_curve(j);
int fk = c.first_key;
int k = 1;
for (; k < c.num_keys + 1; ++k, ++fk) {
rtc_verts[k].x = verts[fk].x;
rtc_verts[k].y = verts[fk].y;
rtc_verts[k].z = verts[fk].z;
rtc_verts[k].w = curve_radius[fk];
}
/* Duplicate Embree's Catmull-Rom spline CVs at the start and end of each curve. */
rtc_verts[0] = rtc_verts[1];
rtc_verts[k] = rtc_verts[k - 1];
rtc_verts += c.num_keys + 2;
}
}
@@ -360,15 +373,10 @@ void BVHEmbree::set_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair, c
const int t_mid = (num_motion_steps - 1) / 2;
const float *curve_radius = &hair->get_curve_radius()[0];
for (int t = 0; t < num_motion_steps; ++t) {
const float3 *verts;
if (t == t_mid || attr_mP == NULL) {
verts = &hair->get_curve_keys()[0];
}
else {
int t_ = (t > t_mid) ? (t - 1) : t;
verts = &attr_mP->data_float3()[t_ * num_keys];
}
// As float4 and float3 are no longer interchangeable the 2 types need to be
// handled separately. Attributes are float4s where the radius is stored in w and
// the middle motion vector is from the mesh points which are stored float3s with
// the radius stored in another array.
float4 *rtc_verts = (update) ? (float4 *)rtcGetGeometryBufferData(
geom_id, RTC_BUFFER_TYPE_VERTEX, t) :
(float4 *)rtcSetNewGeometryBuffer(geom_id,
@@ -381,18 +389,14 @@ void BVHEmbree::set_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair, c
assert(rtc_verts);
if (rtc_verts) {
const size_t num_curves = hair->num_curves();
for (size_t j = 0; j < num_curves; ++j) {
Hair::Curve c = hair->get_curve(j);
int fk = c.first_key;
int k = 1;
for (; k < c.num_keys + 1; ++k, ++fk) {
rtc_verts[k] = float3_to_float4(verts[fk]);
rtc_verts[k].w = curve_radius[fk];
}
/* Duplicate Embree's Catmull-Rom spline CVs at the start and end of each curve. */
rtc_verts[0] = rtc_verts[1];
rtc_verts[k] = rtc_verts[k - 1];
rtc_verts += c.num_keys + 2;
if (t == t_mid || attr_mP == NULL) {
const float3 *verts = &hair->get_curve_keys()[0];
pack_motion_verts<float3>(num_curves, hair, verts, curve_radius, rtc_verts);
}
else {
int t_ = (t > t_mid) ? (t - 1) : t;
const float4 *verts = &attr_mP->data_float4()[t_ * num_keys];
pack_motion_verts<float4>(num_curves, hair, verts, curve_radius, rtc_verts);
}
}
@@ -402,6 +406,20 @@ void BVHEmbree::set_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair, c
}
}
/**
* Pack the motion points into a float4 as [x y z radius]
*/
template<typename T>
void pack_motion_points(size_t num_points, const T *verts, const float *radius, float4 *rtc_verts)
{
for (size_t j = 0; j < num_points; ++j) {
rtc_verts[j].x = verts[j].x;
rtc_verts[j].y = verts[j].y;
rtc_verts[j].z = verts[j].z;
rtc_verts[j].w = radius[j];
}
}
void BVHEmbree::set_point_vertex_buffer(RTCGeometry geom_id,
const PointCloud *pointcloud,
const bool update)
@@ -421,15 +439,10 @@ void BVHEmbree::set_point_vertex_buffer(RTCGeometry geom_id,
const int t_mid = (num_motion_steps - 1) / 2;
const float *radius = pointcloud->get_radius().data();
for (int t = 0; t < num_motion_steps; ++t) {
const float3 *verts;
if (t == t_mid || attr_mP == NULL) {
verts = pointcloud->get_points().data();
}
else {
int t_ = (t > t_mid) ? (t - 1) : t;
verts = &attr_mP->data_float3()[t_ * num_points];
}
// As float4 and float3 are no longer interchangeable the 2 types need to be
// handled separately. Attributes are float4s where the radius is stored in w and
// the middle motion vector is from the mesh points which are stored float3s with
// the radius stored in another array.
float4 *rtc_verts = (update) ? (float4 *)rtcGetGeometryBufferData(
geom_id, RTC_BUFFER_TYPE_VERTEX, t) :
(float4 *)rtcSetNewGeometryBuffer(geom_id,
@@ -441,9 +454,14 @@ void BVHEmbree::set_point_vertex_buffer(RTCGeometry geom_id,
assert(rtc_verts);
if (rtc_verts) {
for (size_t j = 0; j < num_points; ++j) {
rtc_verts[j] = float3_to_float4(verts[j]);
rtc_verts[j].w = radius[j];
if (t == t_mid || attr_mP == NULL) {
const float3 *verts = pointcloud->get_points().data();
pack_motion_points<float3>(num_points, verts, radius, rtc_verts);
}
else {
int t_ = (t > t_mid) ? (t - 1) : t;
const float4 *verts = &attr_mP->data_float4()[t_ * num_points];
pack_motion_points<float4>(num_points, verts, radius, rtc_verts);
}
}

View File

@@ -35,7 +35,7 @@ struct BVHReferenceCompare {
/* Compare two references.
*
* Returns value is similar to return value of strcmp().
* Returns value is similar to return value of `strcmp()`.
*/
__forceinline int compare(const BVHReference &ra, const BVHReference &rb) const
{

View File

@@ -42,12 +42,15 @@ endif()
###########################################################################
if(WITH_CYCLES_HIP_BINARIES AND WITH_CYCLES_DEVICE_HIP)
find_package(HIP)
set_and_warn_library_found("HIP compiler" HIP_FOUND WITH_CYCLES_HIP_BINARIES)
set(WITH_CYCLES_HIP_BINARIES OFF)
message(STATUS "HIP temporarily disabled due to compiler bugs")
if(HIP_FOUND)
message(STATUS "Found HIP ${HIP_HIPCC_EXECUTABLE} (${HIP_VERSION})")
endif()
# find_package(HIP)
# set_and_warn_library_found("HIP compiler" HIP_FOUND WITH_CYCLES_HIP_BINARIES)
# if(HIP_FOUND)
# message(STATUS "Found HIP ${HIP_HIPCC_EXECUTABLE} (${HIP_VERSION})")
# endif()
endif()
if(NOT WITH_HIP_DYNLOAD)

View File

@@ -53,8 +53,12 @@ void CUDADevice::set_error(const string &error)
}
CUDADevice::CUDADevice(const DeviceInfo &info, Stats &stats, Profiler &profiler)
: Device(info, stats, profiler), texture_info(this, "texture_info", MEM_GLOBAL)
: GPUDevice(info, stats, profiler)
{
/* Verify that base class types can be used with specific backend types */
static_assert(sizeof(texMemObject) == sizeof(CUtexObject));
static_assert(sizeof(arrayMemObject) == sizeof(CUarray));
first_error = true;
cuDevId = info.num;
@@ -65,12 +69,6 @@ CUDADevice::CUDADevice(const DeviceInfo &info, Stats &stats, Profiler &profiler)
need_texture_info = false;
device_texture_headroom = 0;
device_working_headroom = 0;
move_texture_to_host = false;
map_host_limit = 0;
map_host_used = 0;
can_map_host = 0;
pitch_alignment = 0;
/* Initialize CUDA. */
@@ -91,8 +89,9 @@ CUDADevice::CUDADevice(const DeviceInfo &info, Stats &stats, Profiler &profiler)
/* CU_CTX_MAP_HOST for mapping host memory when out of device memory.
* CU_CTX_LMEM_RESIZE_TO_MAX for reserving local memory ahead of render,
* so we can predict which memory to map to host. */
cuda_assert(
cuDeviceGetAttribute(&can_map_host, CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY, cuDevice));
int value;
cuda_assert(cuDeviceGetAttribute(&value, CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY, cuDevice));
can_map_host = value != 0;
cuda_assert(cuDeviceGetAttribute(
&pitch_alignment, CU_DEVICE_ATTRIBUTE_TEXTURE_PITCH_ALIGNMENT, cuDevice));
@@ -499,311 +498,57 @@ void CUDADevice::reserve_local_memory(const uint kernel_features)
# endif
}
void CUDADevice::init_host_memory()
{
/* Limit amount of host mapped memory, because allocating too much can
* cause system instability. Leave at least half or 4 GB of system
* memory free, whichever is smaller. */
size_t default_limit = 4 * 1024 * 1024 * 1024LL;
size_t system_ram = system_physical_ram();
if (system_ram > 0) {
if (system_ram / 2 > default_limit) {
map_host_limit = system_ram - default_limit;
}
else {
map_host_limit = system_ram / 2;
}
}
else {
VLOG_WARNING << "Mapped host memory disabled, failed to get system RAM";
map_host_limit = 0;
}
/* Amount of device memory to keep is free after texture memory
* and working memory allocations respectively. We set the working
* memory limit headroom lower so that some space is left after all
* texture memory allocations. */
device_working_headroom = 32 * 1024 * 1024LL; // 32MB
device_texture_headroom = 128 * 1024 * 1024LL; // 128MB
VLOG_INFO << "Mapped host memory limit set to " << string_human_readable_number(map_host_limit)
<< " bytes. (" << string_human_readable_size(map_host_limit) << ")";
}
void CUDADevice::load_texture_info()
{
if (need_texture_info) {
/* Unset flag before copying, so this does not loop indefinitely if the copy below calls
* into 'move_textures_to_host' (which calls 'load_texture_info' again). */
need_texture_info = false;
texture_info.copy_to_device();
}
}
void CUDADevice::move_textures_to_host(size_t size, bool for_texture)
{
/* Break out of recursive call, which can happen when moving memory on a multi device. */
static bool any_device_moving_textures_to_host = false;
if (any_device_moving_textures_to_host) {
return;
}
/* Signal to reallocate textures in host memory only. */
move_texture_to_host = true;
while (size > 0) {
/* Find suitable memory allocation to move. */
device_memory *max_mem = NULL;
size_t max_size = 0;
bool max_is_image = false;
thread_scoped_lock lock(cuda_mem_map_mutex);
foreach (CUDAMemMap::value_type &pair, cuda_mem_map) {
device_memory &mem = *pair.first;
CUDAMem *cmem = &pair.second;
/* Can only move textures allocated on this device (and not those from peer devices).
* And need to ignore memory that is already on the host. */
if (!mem.is_resident(this) || cmem->use_mapped_host) {
continue;
}
bool is_texture = (mem.type == MEM_TEXTURE || mem.type == MEM_GLOBAL) &&
(&mem != &texture_info);
bool is_image = is_texture && (mem.data_height > 1);
/* Can't move this type of memory. */
if (!is_texture || cmem->array) {
continue;
}
/* For other textures, only move image textures. */
if (for_texture && !is_image) {
continue;
}
/* Try to move largest allocation, prefer moving images. */
if (is_image > max_is_image || (is_image == max_is_image && mem.device_size > max_size)) {
max_is_image = is_image;
max_size = mem.device_size;
max_mem = &mem;
}
}
lock.unlock();
/* Move to host memory. This part is mutex protected since
* multiple CUDA devices could be moving the memory. The
* first one will do it, and the rest will adopt the pointer. */
if (max_mem) {
VLOG_WORK << "Move memory from device to host: " << max_mem->name;
static thread_mutex move_mutex;
thread_scoped_lock lock(move_mutex);
any_device_moving_textures_to_host = true;
/* Potentially need to call back into multi device, so pointer mapping
* and peer devices are updated. This is also necessary since the device
* pointer may just be a key here, so cannot be accessed and freed directly.
* Unfortunately it does mean that memory is reallocated on all other
* devices as well, which is potentially dangerous when still in use (since
* a thread rendering on another devices would only be caught in this mutex
* if it so happens to do an allocation at the same time as well. */
max_mem->device_copy_to();
size = (max_size >= size) ? 0 : size - max_size;
any_device_moving_textures_to_host = false;
}
else {
break;
}
}
/* Unset flag before texture info is reloaded, since it should stay in device memory. */
move_texture_to_host = false;
/* Update texture info array with new pointers. */
load_texture_info();
}
CUDADevice::CUDAMem *CUDADevice::generic_alloc(device_memory &mem, size_t pitch_padding)
void CUDADevice::get_device_memory_info(size_t &total, size_t &free)
{
CUDAContextScope scope(this);
CUdeviceptr device_pointer = 0;
size_t size = mem.memory_size() + pitch_padding;
CUresult mem_alloc_result = CUDA_ERROR_OUT_OF_MEMORY;
const char *status = "";
/* First try allocating in device memory, respecting headroom. We make
* an exception for texture info. It is small and frequently accessed,
* so treat it as working memory.
*
* If there is not enough room for working memory, we will try to move
* textures to host memory, assuming the performance impact would have
* been worse for working memory. */
bool is_texture = (mem.type == MEM_TEXTURE || mem.type == MEM_GLOBAL) && (&mem != &texture_info);
bool is_image = is_texture && (mem.data_height > 1);
size_t headroom = (is_texture) ? device_texture_headroom : device_working_headroom;
size_t total = 0, free = 0;
cuMemGetInfo(&free, &total);
/* Move textures to host memory if needed. */
if (!move_texture_to_host && !is_image && (size + headroom) >= free && can_map_host) {
move_textures_to_host(size + headroom - free, is_texture);
cuMemGetInfo(&free, &total);
}
/* Allocate in device memory. */
if (!move_texture_to_host && (size + headroom) < free) {
mem_alloc_result = cuMemAlloc(&device_pointer, size);
if (mem_alloc_result == CUDA_SUCCESS) {
status = " in device memory";
}
}
/* Fall back to mapped host memory if needed and possible. */
void *shared_pointer = 0;
if (mem_alloc_result != CUDA_SUCCESS && can_map_host && mem.type != MEM_DEVICE_ONLY) {
if (mem.shared_pointer) {
/* Another device already allocated host memory. */
mem_alloc_result = CUDA_SUCCESS;
shared_pointer = mem.shared_pointer;
}
else if (map_host_used + size < map_host_limit) {
/* Allocate host memory ourselves. */
mem_alloc_result = cuMemHostAlloc(
&shared_pointer, size, CU_MEMHOSTALLOC_DEVICEMAP | CU_MEMHOSTALLOC_WRITECOMBINED);
assert((mem_alloc_result == CUDA_SUCCESS && shared_pointer != 0) ||
(mem_alloc_result != CUDA_SUCCESS && shared_pointer == 0));
}
if (mem_alloc_result == CUDA_SUCCESS) {
cuda_assert(cuMemHostGetDevicePointer_v2(&device_pointer, shared_pointer, 0));
map_host_used += size;
status = " in host memory";
}
}
if (mem_alloc_result != CUDA_SUCCESS) {
if (mem.type == MEM_DEVICE_ONLY) {
status = " failed, out of device memory";
set_error("System is out of GPU memory");
}
else {
status = " failed, out of device and host memory";
set_error("System is out of GPU and shared host memory");
}
}
if (mem.name) {
VLOG_WORK << "Buffer allocate: " << mem.name << ", "
<< string_human_readable_number(mem.memory_size()) << " bytes. ("
<< string_human_readable_size(mem.memory_size()) << ")" << status;
}
mem.device_pointer = (device_ptr)device_pointer;
mem.device_size = size;
stats.mem_alloc(size);
if (!mem.device_pointer) {
return NULL;
}
/* Insert into map of allocations. */
thread_scoped_lock lock(cuda_mem_map_mutex);
CUDAMem *cmem = &cuda_mem_map[&mem];
if (shared_pointer != 0) {
/* Replace host pointer with our host allocation. Only works if
* CUDA memory layout is the same and has no pitch padding. Also
* does not work if we move textures to host during a render,
* since other devices might be using the memory. */
if (!move_texture_to_host && pitch_padding == 0 && mem.host_pointer &&
mem.host_pointer != shared_pointer) {
memcpy(shared_pointer, mem.host_pointer, size);
/* A Call to device_memory::host_free() should be preceded by
* a call to device_memory::device_free() for host memory
* allocated by a device to be handled properly. Two exceptions
* are here and a call in OptiXDevice::generic_alloc(), where
* the current host memory can be assumed to be allocated by
* device_memory::host_alloc(), not by a device */
mem.host_free();
mem.host_pointer = shared_pointer;
}
mem.shared_pointer = shared_pointer;
mem.shared_counter++;
cmem->use_mapped_host = true;
}
else {
cmem->use_mapped_host = false;
}
return cmem;
}
void CUDADevice::generic_copy_to(device_memory &mem)
bool CUDADevice::alloc_device(void *&device_pointer, size_t size)
{
if (!mem.host_pointer || !mem.device_pointer) {
return;
}
CUDAContextScope scope(this);
/* If use_mapped_host of mem is false, the current device only uses device memory allocated by
* cuMemAlloc regardless of mem.host_pointer and mem.shared_pointer, and should copy data from
* mem.host_pointer. */
thread_scoped_lock lock(cuda_mem_map_mutex);
if (!cuda_mem_map[&mem].use_mapped_host || mem.host_pointer != mem.shared_pointer) {
const CUDAContextScope scope(this);
cuda_assert(
cuMemcpyHtoD((CUdeviceptr)mem.device_pointer, mem.host_pointer, mem.memory_size()));
}
CUresult mem_alloc_result = cuMemAlloc((CUdeviceptr *)&device_pointer, size);
return mem_alloc_result == CUDA_SUCCESS;
}
void CUDADevice::generic_free(device_memory &mem)
void CUDADevice::free_device(void *device_pointer)
{
if (mem.device_pointer) {
CUDAContextScope scope(this);
thread_scoped_lock lock(cuda_mem_map_mutex);
DCHECK(cuda_mem_map.find(&mem) != cuda_mem_map.end());
const CUDAMem &cmem = cuda_mem_map[&mem];
CUDAContextScope scope(this);
/* If cmem.use_mapped_host is true, reference counting is used
* to safely free a mapped host memory. */
cuda_assert(cuMemFree((CUdeviceptr)device_pointer));
}
if (cmem.use_mapped_host) {
assert(mem.shared_pointer);
if (mem.shared_pointer) {
assert(mem.shared_counter > 0);
if (--mem.shared_counter == 0) {
if (mem.host_pointer == mem.shared_pointer) {
mem.host_pointer = 0;
}
cuMemFreeHost(mem.shared_pointer);
mem.shared_pointer = 0;
}
}
map_host_used -= mem.device_size;
}
else {
/* Free device memory. */
cuda_assert(cuMemFree(mem.device_pointer));
}
bool CUDADevice::alloc_host(void *&shared_pointer, size_t size)
{
CUDAContextScope scope(this);
stats.mem_free(mem.device_size);
mem.device_pointer = 0;
mem.device_size = 0;
CUresult mem_alloc_result = cuMemHostAlloc(
&shared_pointer, size, CU_MEMHOSTALLOC_DEVICEMAP | CU_MEMHOSTALLOC_WRITECOMBINED);
return mem_alloc_result == CUDA_SUCCESS;
}
cuda_mem_map.erase(cuda_mem_map.find(&mem));
}
void CUDADevice::free_host(void *shared_pointer)
{
CUDAContextScope scope(this);
cuMemFreeHost(shared_pointer);
}
bool CUDADevice::transform_host_pointer(void *&device_pointer, void *&shared_pointer)
{
CUDAContextScope scope(this);
cuda_assert(cuMemHostGetDevicePointer_v2((CUdeviceptr *)&device_pointer, shared_pointer, 0));
return true;
}
void CUDADevice::copy_host_to_device(void *device_pointer, void *host_pointer, size_t size)
{
const CUDAContextScope scope(this);
cuda_assert(cuMemcpyHtoD((CUdeviceptr)device_pointer, host_pointer, size));
}
void CUDADevice::mem_alloc(device_memory &mem)
@@ -868,8 +613,8 @@ void CUDADevice::mem_zero(device_memory &mem)
/* If use_mapped_host of mem is false, mem.device_pointer currently refers to device memory
* regardless of mem.host_pointer and mem.shared_pointer. */
thread_scoped_lock lock(cuda_mem_map_mutex);
if (!cuda_mem_map[&mem].use_mapped_host || mem.host_pointer != mem.shared_pointer) {
thread_scoped_lock lock(device_mem_map_mutex);
if (!device_mem_map[&mem].use_mapped_host || mem.host_pointer != mem.shared_pointer) {
const CUDAContextScope scope(this);
cuda_assert(cuMemsetD8((CUdeviceptr)mem.device_pointer, 0, mem.memory_size()));
}
@@ -994,19 +739,19 @@ void CUDADevice::tex_alloc(device_texture &mem)
return;
}
CUDAMem *cmem = NULL;
Mem *cmem = NULL;
CUarray array_3d = NULL;
size_t src_pitch = mem.data_width * dsize * mem.data_elements;
size_t dst_pitch = src_pitch;
if (!mem.is_resident(this)) {
thread_scoped_lock lock(cuda_mem_map_mutex);
cmem = &cuda_mem_map[&mem];
thread_scoped_lock lock(device_mem_map_mutex);
cmem = &device_mem_map[&mem];
cmem->texobject = 0;
if (mem.data_depth > 1) {
array_3d = (CUarray)mem.device_pointer;
cmem->array = array_3d;
cmem->array = reinterpret_cast<arrayMemObject>(array_3d);
}
else if (mem.data_height > 0) {
dst_pitch = align_up(src_pitch, pitch_alignment);
@@ -1050,10 +795,10 @@ void CUDADevice::tex_alloc(device_texture &mem)
mem.device_size = size;
stats.mem_alloc(size);
thread_scoped_lock lock(cuda_mem_map_mutex);
cmem = &cuda_mem_map[&mem];
thread_scoped_lock lock(device_mem_map_mutex);
cmem = &device_mem_map[&mem];
cmem->texobject = 0;
cmem->array = array_3d;
cmem->array = reinterpret_cast<arrayMemObject>(array_3d);
}
else if (mem.data_height > 0) {
/* 2D texture, using pitch aligned linear memory. */
@@ -1137,8 +882,8 @@ void CUDADevice::tex_alloc(device_texture &mem)
texDesc.filterMode = filter_mode;
texDesc.flags = CU_TRSF_NORMALIZED_COORDINATES;
thread_scoped_lock lock(cuda_mem_map_mutex);
cmem = &cuda_mem_map[&mem];
thread_scoped_lock lock(device_mem_map_mutex);
cmem = &device_mem_map[&mem];
cuda_assert(cuTexObjectCreate(&cmem->texobject, &resDesc, &texDesc, NULL));
@@ -1153,9 +898,9 @@ void CUDADevice::tex_free(device_texture &mem)
{
if (mem.device_pointer) {
CUDAContextScope scope(this);
thread_scoped_lock lock(cuda_mem_map_mutex);
DCHECK(cuda_mem_map.find(&mem) != cuda_mem_map.end());
const CUDAMem &cmem = cuda_mem_map[&mem];
thread_scoped_lock lock(device_mem_map_mutex);
DCHECK(device_mem_map.find(&mem) != device_mem_map.end());
const Mem &cmem = device_mem_map[&mem];
if (cmem.texobject) {
/* Free bindless texture. */
@@ -1164,16 +909,16 @@ void CUDADevice::tex_free(device_texture &mem)
if (!mem.is_resident(this)) {
/* Do not free memory here, since it was allocated on a different device. */
cuda_mem_map.erase(cuda_mem_map.find(&mem));
device_mem_map.erase(device_mem_map.find(&mem));
}
else if (cmem.array) {
/* Free array. */
cuArrayDestroy(cmem.array);
cuArrayDestroy(reinterpret_cast<CUarray>(cmem.array));
stats.mem_free(mem.device_size);
mem.device_pointer = 0;
mem.device_size = 0;
cuda_mem_map.erase(cuda_mem_map.find(&mem));
device_mem_map.erase(device_mem_map.find(&mem));
}
else {
lock.unlock();

View File

@@ -21,7 +21,7 @@ CCL_NAMESPACE_BEGIN
class DeviceQueue;
class CUDADevice : public Device {
class CUDADevice : public GPUDevice {
friend class CUDAContextScope;
@@ -29,36 +29,11 @@ class CUDADevice : public Device {
CUdevice cuDevice;
CUcontext cuContext;
CUmodule cuModule;
size_t device_texture_headroom;
size_t device_working_headroom;
bool move_texture_to_host;
size_t map_host_used;
size_t map_host_limit;
int can_map_host;
int pitch_alignment;
int cuDevId;
int cuDevArchitecture;
bool first_error;
struct CUDAMem {
CUDAMem() : texobject(0), array(0), use_mapped_host(false)
{
}
CUtexObject texobject;
CUarray array;
/* If true, a mapped host memory in shared_pointer is being used. */
bool use_mapped_host;
};
typedef map<device_memory *, CUDAMem> CUDAMemMap;
CUDAMemMap cuda_mem_map;
thread_mutex cuda_mem_map_mutex;
/* Bindless Textures */
device_vector<TextureInfo> texture_info;
bool need_texture_info;
CUDADeviceKernels kernels;
static bool have_precompiled_kernels();
@@ -88,17 +63,13 @@ class CUDADevice : public Device {
void reserve_local_memory(const uint kernel_features);
void init_host_memory();
void load_texture_info();
void move_textures_to_host(size_t size, bool for_texture);
CUDAMem *generic_alloc(device_memory &mem, size_t pitch_padding = 0);
void generic_copy_to(device_memory &mem);
void generic_free(device_memory &mem);
virtual void get_device_memory_info(size_t &total, size_t &free) override;
virtual bool alloc_device(void *&device_pointer, size_t size) override;
virtual void free_device(void *device_pointer) override;
virtual bool alloc_host(void *&shared_pointer, size_t size) override;
virtual void free_host(void *shared_pointer) override;
virtual bool transform_host_pointer(void *&device_pointer, void *&shared_pointer) override;
virtual void copy_host_to_device(void *device_pointer, void *host_pointer, size_t size) override;
void mem_alloc(device_memory &mem) override;

View File

@@ -452,6 +452,320 @@ void *Device::get_cpu_osl_memory()
return nullptr;
}
GPUDevice::~GPUDevice() noexcept(false)
{
}
bool GPUDevice::load_texture_info()
{
if (need_texture_info) {
/* Unset flag before copying, so this does not loop indefinitely if the copy below calls
* into 'move_textures_to_host' (which calls 'load_texture_info' again). */
need_texture_info = false;
texture_info.copy_to_device();
return true;
}
else {
return false;
}
}
void GPUDevice::init_host_memory(size_t preferred_texture_headroom,
size_t preferred_working_headroom)
{
/* Limit amount of host mapped memory, because allocating too much can
* cause system instability. Leave at least half or 4 GB of system
* memory free, whichever is smaller. */
size_t default_limit = 4 * 1024 * 1024 * 1024LL;
size_t system_ram = system_physical_ram();
if (system_ram > 0) {
if (system_ram / 2 > default_limit) {
map_host_limit = system_ram - default_limit;
}
else {
map_host_limit = system_ram / 2;
}
}
else {
VLOG_WARNING << "Mapped host memory disabled, failed to get system RAM";
map_host_limit = 0;
}
/* Amount of device memory to keep free after texture memory
* and working memory allocations respectively. We set the working
* memory limit headroom lower than the working one so there
* is space left for it. */
device_working_headroom = preferred_working_headroom > 0 ? preferred_working_headroom :
32 * 1024 * 1024LL; // 32MB
device_texture_headroom = preferred_texture_headroom > 0 ? preferred_texture_headroom :
128 * 1024 * 1024LL; // 128MB
VLOG_INFO << "Mapped host memory limit set to " << string_human_readable_number(map_host_limit)
<< " bytes. (" << string_human_readable_size(map_host_limit) << ")";
}
void GPUDevice::move_textures_to_host(size_t size, bool for_texture)
{
/* Break out of recursive call, which can happen when moving memory on a multi device. */
static bool any_device_moving_textures_to_host = false;
if (any_device_moving_textures_to_host) {
return;
}
/* Signal to reallocate textures in host memory only. */
move_texture_to_host = true;
while (size > 0) {
/* Find suitable memory allocation to move. */
device_memory *max_mem = NULL;
size_t max_size = 0;
bool max_is_image = false;
thread_scoped_lock lock(device_mem_map_mutex);
foreach (MemMap::value_type &pair, device_mem_map) {
device_memory &mem = *pair.first;
Mem *cmem = &pair.second;
/* Can only move textures allocated on this device (and not those from peer devices).
* And need to ignore memory that is already on the host. */
if (!mem.is_resident(this) || cmem->use_mapped_host) {
continue;
}
bool is_texture = (mem.type == MEM_TEXTURE || mem.type == MEM_GLOBAL) &&
(&mem != &texture_info);
bool is_image = is_texture && (mem.data_height > 1);
/* Can't move this type of memory. */
if (!is_texture || cmem->array) {
continue;
}
/* For other textures, only move image textures. */
if (for_texture && !is_image) {
continue;
}
/* Try to move largest allocation, prefer moving images. */
if (is_image > max_is_image || (is_image == max_is_image && mem.device_size > max_size)) {
max_is_image = is_image;
max_size = mem.device_size;
max_mem = &mem;
}
}
lock.unlock();
/* Move to host memory. This part is mutex protected since
* multiple backend devices could be moving the memory. The
* first one will do it, and the rest will adopt the pointer. */
if (max_mem) {
VLOG_WORK << "Move memory from device to host: " << max_mem->name;
static thread_mutex move_mutex;
thread_scoped_lock lock(move_mutex);
any_device_moving_textures_to_host = true;
/* Potentially need to call back into multi device, so pointer mapping
* and peer devices are updated. This is also necessary since the device
* pointer may just be a key here, so cannot be accessed and freed directly.
* Unfortunately it does mean that memory is reallocated on all other
* devices as well, which is potentially dangerous when still in use (since
* a thread rendering on another devices would only be caught in this mutex
* if it so happens to do an allocation at the same time as well. */
max_mem->device_copy_to();
size = (max_size >= size) ? 0 : size - max_size;
any_device_moving_textures_to_host = false;
}
else {
break;
}
}
/* Unset flag before texture info is reloaded, since it should stay in device memory. */
move_texture_to_host = false;
/* Update texture info array with new pointers. */
load_texture_info();
}
GPUDevice::Mem *GPUDevice::generic_alloc(device_memory &mem, size_t pitch_padding)
{
void *device_pointer = 0;
size_t size = mem.memory_size() + pitch_padding;
bool mem_alloc_result = false;
const char *status = "";
/* First try allocating in device memory, respecting headroom. We make
* an exception for texture info. It is small and frequently accessed,
* so treat it as working memory.
*
* If there is not enough room for working memory, we will try to move
* textures to host memory, assuming the performance impact would have
* been worse for working memory. */
bool is_texture = (mem.type == MEM_TEXTURE || mem.type == MEM_GLOBAL) && (&mem != &texture_info);
bool is_image = is_texture && (mem.data_height > 1);
size_t headroom = (is_texture) ? device_texture_headroom : device_working_headroom;
size_t total = 0, free = 0;
get_device_memory_info(total, free);
/* Move textures to host memory if needed. */
if (!move_texture_to_host && !is_image && (size + headroom) >= free && can_map_host) {
move_textures_to_host(size + headroom - free, is_texture);
get_device_memory_info(total, free);
}
/* Allocate in device memory. */
if (!move_texture_to_host && (size + headroom) < free) {
mem_alloc_result = alloc_device(device_pointer, size);
if (mem_alloc_result) {
device_mem_in_use += size;
status = " in device memory";
}
}
/* Fall back to mapped host memory if needed and possible. */
void *shared_pointer = 0;
if (!mem_alloc_result && can_map_host && mem.type != MEM_DEVICE_ONLY) {
if (mem.shared_pointer) {
/* Another device already allocated host memory. */
mem_alloc_result = true;
shared_pointer = mem.shared_pointer;
}
else if (map_host_used + size < map_host_limit) {
/* Allocate host memory ourselves. */
mem_alloc_result = alloc_host(shared_pointer, size);
assert((mem_alloc_result && shared_pointer != 0) ||
(!mem_alloc_result && shared_pointer == 0));
}
if (mem_alloc_result) {
assert(transform_host_pointer(device_pointer, shared_pointer));
map_host_used += size;
status = " in host memory";
}
}
if (!mem_alloc_result) {
if (mem.type == MEM_DEVICE_ONLY) {
status = " failed, out of device memory";
set_error("System is out of GPU memory");
}
else {
status = " failed, out of device and host memory";
set_error("System is out of GPU and shared host memory");
}
}
if (mem.name) {
VLOG_WORK << "Buffer allocate: " << mem.name << ", "
<< string_human_readable_number(mem.memory_size()) << " bytes. ("
<< string_human_readable_size(mem.memory_size()) << ")" << status;
}
mem.device_pointer = (device_ptr)device_pointer;
mem.device_size = size;
stats.mem_alloc(size);
if (!mem.device_pointer) {
return NULL;
}
/* Insert into map of allocations. */
thread_scoped_lock lock(device_mem_map_mutex);
Mem *cmem = &device_mem_map[&mem];
if (shared_pointer != 0) {
/* Replace host pointer with our host allocation. Only works if
* memory layout is the same and has no pitch padding. Also
* does not work if we move textures to host during a render,
* since other devices might be using the memory. */
if (!move_texture_to_host && pitch_padding == 0 && mem.host_pointer &&
mem.host_pointer != shared_pointer) {
memcpy(shared_pointer, mem.host_pointer, size);
/* A Call to device_memory::host_free() should be preceded by
* a call to device_memory::device_free() for host memory
* allocated by a device to be handled properly. Two exceptions
* are here and a call in OptiXDevice::generic_alloc(), where
* the current host memory can be assumed to be allocated by
* device_memory::host_alloc(), not by a device */
mem.host_free();
mem.host_pointer = shared_pointer;
}
mem.shared_pointer = shared_pointer;
mem.shared_counter++;
cmem->use_mapped_host = true;
}
else {
cmem->use_mapped_host = false;
}
return cmem;
}
void GPUDevice::generic_free(device_memory &mem)
{
if (mem.device_pointer) {
thread_scoped_lock lock(device_mem_map_mutex);
DCHECK(device_mem_map.find(&mem) != device_mem_map.end());
const Mem &cmem = device_mem_map[&mem];
/* If cmem.use_mapped_host is true, reference counting is used
* to safely free a mapped host memory. */
if (cmem.use_mapped_host) {
assert(mem.shared_pointer);
if (mem.shared_pointer) {
assert(mem.shared_counter > 0);
if (--mem.shared_counter == 0) {
if (mem.host_pointer == mem.shared_pointer) {
mem.host_pointer = 0;
}
free_host(mem.shared_pointer);
mem.shared_pointer = 0;
}
}
map_host_used -= mem.device_size;
}
else {
/* Free device memory. */
free_device((void *)mem.device_pointer);
device_mem_in_use -= mem.device_size;
}
stats.mem_free(mem.device_size);
mem.device_pointer = 0;
mem.device_size = 0;
device_mem_map.erase(device_mem_map.find(&mem));
}
}
void GPUDevice::generic_copy_to(device_memory &mem)
{
if (!mem.host_pointer || !mem.device_pointer) {
return;
}
/* If use_mapped_host of mem is false, the current device only uses device memory allocated by
* backend device allocation regardless of mem.host_pointer and mem.shared_pointer, and should
* copy data from mem.host_pointer. */
thread_scoped_lock lock(device_mem_map_mutex);
if (!device_mem_map[&mem].use_mapped_host || mem.host_pointer != mem.shared_pointer) {
copy_host_to_device((void *)mem.device_pointer, mem.host_pointer, mem.memory_size());
}
}
/* DeviceInfo */
CCL_NAMESPACE_END

View File

@@ -182,7 +182,7 @@ class Device {
{
}
/* Return true if device is ready for rendering, or report status if not. */
/* Report status and return true if device is ready for rendering. */
virtual bool is_ready(string & /*status*/) const
{
return true;
@@ -309,6 +309,93 @@ class Device {
static uint devices_initialized_mask;
};
/* Device, which is GPU, with some common functionality for GPU backends */
class GPUDevice : public Device {
protected:
GPUDevice(const DeviceInfo &info_, Stats &stats_, Profiler &profiler_)
: Device(info_, stats_, profiler_),
texture_info(this, "texture_info", MEM_GLOBAL),
need_texture_info(false),
can_map_host(false),
map_host_used(0),
map_host_limit(0),
device_texture_headroom(0),
device_working_headroom(0),
device_mem_map(),
device_mem_map_mutex(),
move_texture_to_host(false),
device_mem_in_use(0)
{
}
public:
virtual ~GPUDevice() noexcept(false);
/* For GPUs that can use bindless textures in some way or another. */
device_vector<TextureInfo> texture_info;
bool need_texture_info;
/* Returns true if the texture info was copied to the device (meaning, some more
* re-initialization might be needed). */
virtual bool load_texture_info();
protected:
/* Memory allocation, only accessed through device_memory. */
friend class device_memory;
bool can_map_host;
size_t map_host_used;
size_t map_host_limit;
size_t device_texture_headroom;
size_t device_working_headroom;
typedef unsigned long long texMemObject;
typedef unsigned long long arrayMemObject;
struct Mem {
Mem() : texobject(0), array(0), use_mapped_host(false)
{
}
texMemObject texobject;
arrayMemObject array;
/* If true, a mapped host memory in shared_pointer is being used. */
bool use_mapped_host;
};
typedef map<device_memory *, Mem> MemMap;
MemMap device_mem_map;
thread_mutex device_mem_map_mutex;
bool move_texture_to_host;
/* Simple counter which will try to track amount of used device memory */
size_t device_mem_in_use;
virtual void init_host_memory(size_t preferred_texture_headroom = 0,
size_t preferred_working_headroom = 0);
virtual void move_textures_to_host(size_t size, bool for_texture);
/* Allocation, deallocation and copy functions, with corresponding
* support of device/host allocations. */
virtual GPUDevice::Mem *generic_alloc(device_memory &mem, size_t pitch_padding = 0);
virtual void generic_free(device_memory &mem);
virtual void generic_copy_to(device_memory &mem);
/* total - amount of device memory, free - amount of available device memory */
virtual void get_device_memory_info(size_t &total, size_t &free) = 0;
virtual bool alloc_device(void *&device_pointer, size_t size) = 0;
virtual void free_device(void *device_pointer) = 0;
virtual bool alloc_host(void *&shared_pointer, size_t size) = 0;
virtual void free_host(void *shared_pointer) = 0;
/* This function should return device pointer corresponding to shared pointer, which
* is host buffer, allocated in `alloc_host`. The function should `true`, if such
* address transformation is possible and `false` otherwise. */
virtual bool transform_host_pointer(void *&device_pointer, void *&shared_pointer) = 0;
virtual void copy_host_to_device(void *device_pointer, void *host_pointer, size_t size) = 0;
};
CCL_NAMESPACE_END
#endif /* __DEVICE_H__ */

View File

@@ -53,8 +53,12 @@ void HIPDevice::set_error(const string &error)
}
HIPDevice::HIPDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler)
: Device(info, stats, profiler), texture_info(this, "texture_info", MEM_GLOBAL)
: GPUDevice(info, stats, profiler)
{
/* Verify that base class types can be used with specific backend types */
static_assert(sizeof(texMemObject) == sizeof(hipTextureObject_t));
static_assert(sizeof(arrayMemObject) == sizeof(hArray));
first_error = true;
hipDevId = info.num;
@@ -65,12 +69,6 @@ HIPDevice::HIPDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler)
need_texture_info = false;
device_texture_headroom = 0;
device_working_headroom = 0;
move_texture_to_host = false;
map_host_limit = 0;
map_host_used = 0;
can_map_host = 0;
pitch_alignment = 0;
/* Initialize HIP. */
@@ -91,7 +89,9 @@ HIPDevice::HIPDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler)
/* hipDeviceMapHost for mapping host memory when out of device memory.
* hipDeviceLmemResizeToMax for reserving local memory ahead of render,
* so we can predict which memory to map to host. */
hip_assert(hipDeviceGetAttribute(&can_map_host, hipDeviceAttributeCanMapHostMemory, hipDevice));
int value;
hip_assert(hipDeviceGetAttribute(&value, hipDeviceAttributeCanMapHostMemory, hipDevice));
can_map_host = value != 0;
hip_assert(
hipDeviceGetAttribute(&pitch_alignment, hipDeviceAttributeTexturePitchAlignment, hipDevice));
@@ -460,305 +460,58 @@ void HIPDevice::reserve_local_memory(const uint kernel_features)
# endif
}
void HIPDevice::init_host_memory()
{
/* Limit amount of host mapped memory, because allocating too much can
* cause system instability. Leave at least half or 4 GB of system
* memory free, whichever is smaller. */
size_t default_limit = 4 * 1024 * 1024 * 1024LL;
size_t system_ram = system_physical_ram();
if (system_ram > 0) {
if (system_ram / 2 > default_limit) {
map_host_limit = system_ram - default_limit;
}
else {
map_host_limit = system_ram / 2;
}
}
else {
VLOG_WARNING << "Mapped host memory disabled, failed to get system RAM";
map_host_limit = 0;
}
/* Amount of device memory to keep is free after texture memory
* and working memory allocations respectively. We set the working
* memory limit headroom lower so that some space is left after all
* texture memory allocations. */
device_working_headroom = 32 * 1024 * 1024LL; // 32MB
device_texture_headroom = 128 * 1024 * 1024LL; // 128MB
VLOG_INFO << "Mapped host memory limit set to " << string_human_readable_number(map_host_limit)
<< " bytes. (" << string_human_readable_size(map_host_limit) << ")";
}
void HIPDevice::load_texture_info()
{
if (need_texture_info) {
/* Unset flag before copying, so this does not loop indefinitely if the copy below calls
* into 'move_textures_to_host' (which calls 'load_texture_info' again). */
need_texture_info = false;
texture_info.copy_to_device();
}
}
void HIPDevice::move_textures_to_host(size_t size, bool for_texture)
{
/* Break out of recursive call, which can happen when moving memory on a multi device. */
static bool any_device_moving_textures_to_host = false;
if (any_device_moving_textures_to_host) {
return;
}
/* Signal to reallocate textures in host memory only. */
move_texture_to_host = true;
while (size > 0) {
/* Find suitable memory allocation to move. */
device_memory *max_mem = NULL;
size_t max_size = 0;
bool max_is_image = false;
thread_scoped_lock lock(hip_mem_map_mutex);
foreach (HIPMemMap::value_type &pair, hip_mem_map) {
device_memory &mem = *pair.first;
HIPMem *cmem = &pair.second;
/* Can only move textures allocated on this device (and not those from peer devices).
* And need to ignore memory that is already on the host. */
if (!mem.is_resident(this) || cmem->use_mapped_host) {
continue;
}
bool is_texture = (mem.type == MEM_TEXTURE || mem.type == MEM_GLOBAL) &&
(&mem != &texture_info);
bool is_image = is_texture && (mem.data_height > 1);
/* Can't move this type of memory. */
if (!is_texture || cmem->array) {
continue;
}
/* For other textures, only move image textures. */
if (for_texture && !is_image) {
continue;
}
/* Try to move largest allocation, prefer moving images. */
if (is_image > max_is_image || (is_image == max_is_image && mem.device_size > max_size)) {
max_is_image = is_image;
max_size = mem.device_size;
max_mem = &mem;
}
}
lock.unlock();
/* Move to host memory. This part is mutex protected since
* multiple HIP devices could be moving the memory. The
* first one will do it, and the rest will adopt the pointer. */
if (max_mem) {
VLOG_WORK << "Move memory from device to host: " << max_mem->name;
static thread_mutex move_mutex;
thread_scoped_lock lock(move_mutex);
any_device_moving_textures_to_host = true;
/* Potentially need to call back into multi device, so pointer mapping
* and peer devices are updated. This is also necessary since the device
* pointer may just be a key here, so cannot be accessed and freed directly.
* Unfortunately it does mean that memory is reallocated on all other
* devices as well, which is potentially dangerous when still in use (since
* a thread rendering on another devices would only be caught in this mutex
* if it so happens to do an allocation at the same time as well. */
max_mem->device_copy_to();
size = (max_size >= size) ? 0 : size - max_size;
any_device_moving_textures_to_host = false;
}
else {
break;
}
}
/* Unset flag before texture info is reloaded, since it should stay in device memory. */
move_texture_to_host = false;
/* Update texture info array with new pointers. */
load_texture_info();
}
HIPDevice::HIPMem *HIPDevice::generic_alloc(device_memory &mem, size_t pitch_padding)
void HIPDevice::get_device_memory_info(size_t &total, size_t &free)
{
HIPContextScope scope(this);
hipDeviceptr_t device_pointer = 0;
size_t size = mem.memory_size() + pitch_padding;
hipError_t mem_alloc_result = hipErrorOutOfMemory;
const char *status = "";
/* First try allocating in device memory, respecting headroom. We make
* an exception for texture info. It is small and frequently accessed,
* so treat it as working memory.
*
* If there is not enough room for working memory, we will try to move
* textures to host memory, assuming the performance impact would have
* been worse for working memory. */
bool is_texture = (mem.type == MEM_TEXTURE || mem.type == MEM_GLOBAL) && (&mem != &texture_info);
bool is_image = is_texture && (mem.data_height > 1);
size_t headroom = (is_texture) ? device_texture_headroom : device_working_headroom;
size_t total = 0, free = 0;
hipMemGetInfo(&free, &total);
/* Move textures to host memory if needed. */
if (!move_texture_to_host && !is_image && (size + headroom) >= free && can_map_host) {
move_textures_to_host(size + headroom - free, is_texture);
hipMemGetInfo(&free, &total);
}
/* Allocate in device memory. */
if (!move_texture_to_host && (size + headroom) < free) {
mem_alloc_result = hipMalloc(&device_pointer, size);
if (mem_alloc_result == hipSuccess) {
status = " in device memory";
}
}
/* Fall back to mapped host memory if needed and possible. */
void *shared_pointer = 0;
if (mem_alloc_result != hipSuccess && can_map_host) {
if (mem.shared_pointer) {
/* Another device already allocated host memory. */
mem_alloc_result = hipSuccess;
shared_pointer = mem.shared_pointer;
}
else if (map_host_used + size < map_host_limit) {
/* Allocate host memory ourselves. */
mem_alloc_result = hipHostMalloc(
&shared_pointer, size, hipHostMallocMapped | hipHostMallocWriteCombined);
assert((mem_alloc_result == hipSuccess && shared_pointer != 0) ||
(mem_alloc_result != hipSuccess && shared_pointer == 0));
}
if (mem_alloc_result == hipSuccess) {
hip_assert(hipHostGetDevicePointer(&device_pointer, shared_pointer, 0));
map_host_used += size;
status = " in host memory";
}
}
if (mem_alloc_result != hipSuccess) {
status = " failed, out of device and host memory";
set_error("System is out of GPU and shared host memory");
}
if (mem.name) {
VLOG_WORK << "Buffer allocate: " << mem.name << ", "
<< string_human_readable_number(mem.memory_size()) << " bytes. ("
<< string_human_readable_size(mem.memory_size()) << ")" << status;
}
mem.device_pointer = (device_ptr)device_pointer;
mem.device_size = size;
stats.mem_alloc(size);
if (!mem.device_pointer) {
return NULL;
}
/* Insert into map of allocations. */
thread_scoped_lock lock(hip_mem_map_mutex);
HIPMem *cmem = &hip_mem_map[&mem];
if (shared_pointer != 0) {
/* Replace host pointer with our host allocation. Only works if
* HIP memory layout is the same and has no pitch padding. Also
* does not work if we move textures to host during a render,
* since other devices might be using the memory. */
if (!move_texture_to_host && pitch_padding == 0 && mem.host_pointer &&
mem.host_pointer != shared_pointer) {
memcpy(shared_pointer, mem.host_pointer, size);
/* A Call to device_memory::host_free() should be preceded by
* a call to device_memory::device_free() for host memory
* allocated by a device to be handled properly. Two exceptions
* are here and a call in OptiXDevice::generic_alloc(), where
* the current host memory can be assumed to be allocated by
* device_memory::host_alloc(), not by a device */
mem.host_free();
mem.host_pointer = shared_pointer;
}
mem.shared_pointer = shared_pointer;
mem.shared_counter++;
cmem->use_mapped_host = true;
}
else {
cmem->use_mapped_host = false;
}
return cmem;
}
void HIPDevice::generic_copy_to(device_memory &mem)
bool HIPDevice::alloc_device(void *&device_pointer, size_t size)
{
if (!mem.host_pointer || !mem.device_pointer) {
return;
}
HIPContextScope scope(this);
/* If use_mapped_host of mem is false, the current device only uses device memory allocated by
* hipMalloc regardless of mem.host_pointer and mem.shared_pointer, and should copy data from
* mem.host_pointer. */
thread_scoped_lock lock(hip_mem_map_mutex);
if (!hip_mem_map[&mem].use_mapped_host || mem.host_pointer != mem.shared_pointer) {
const HIPContextScope scope(this);
hip_assert(
hipMemcpyHtoD((hipDeviceptr_t)mem.device_pointer, mem.host_pointer, mem.memory_size()));
}
hipError_t mem_alloc_result = hipMalloc((hipDeviceptr_t *)&device_pointer, size);
return mem_alloc_result == hipSuccess;
}
void HIPDevice::generic_free(device_memory &mem)
void HIPDevice::free_device(void *device_pointer)
{
if (mem.device_pointer) {
HIPContextScope scope(this);
thread_scoped_lock lock(hip_mem_map_mutex);
DCHECK(hip_mem_map.find(&mem) != hip_mem_map.end());
const HIPMem &cmem = hip_mem_map[&mem];
HIPContextScope scope(this);
/* If cmem.use_mapped_host is true, reference counting is used
* to safely free a mapped host memory. */
hip_assert(hipFree((hipDeviceptr_t)device_pointer));
}
if (cmem.use_mapped_host) {
assert(mem.shared_pointer);
if (mem.shared_pointer) {
assert(mem.shared_counter > 0);
if (--mem.shared_counter == 0) {
if (mem.host_pointer == mem.shared_pointer) {
mem.host_pointer = 0;
}
hipHostFree(mem.shared_pointer);
mem.shared_pointer = 0;
}
}
map_host_used -= mem.device_size;
}
else {
/* Free device memory. */
hip_assert(hipFree(mem.device_pointer));
}
bool HIPDevice::alloc_host(void *&shared_pointer, size_t size)
{
HIPContextScope scope(this);
stats.mem_free(mem.device_size);
mem.device_pointer = 0;
mem.device_size = 0;
hipError_t mem_alloc_result = hipHostMalloc(
&shared_pointer, size, hipHostMallocMapped | hipHostMallocWriteCombined);
hip_mem_map.erase(hip_mem_map.find(&mem));
}
return mem_alloc_result == hipSuccess;
}
void HIPDevice::free_host(void *shared_pointer)
{
HIPContextScope scope(this);
hipHostFree(shared_pointer);
}
bool HIPDevice::transform_host_pointer(void *&device_pointer, void *&shared_pointer)
{
HIPContextScope scope(this);
hip_assert(hipHostGetDevicePointer((hipDeviceptr_t *)&device_pointer, shared_pointer, 0));
return true;
}
void HIPDevice::copy_host_to_device(void *device_pointer, void *host_pointer, size_t size)
{
const HIPContextScope scope(this);
hip_assert(hipMemcpyHtoD((hipDeviceptr_t)device_pointer, host_pointer, size));
}
void HIPDevice::mem_alloc(device_memory &mem)
@@ -823,8 +576,8 @@ void HIPDevice::mem_zero(device_memory &mem)
/* If use_mapped_host of mem is false, mem.device_pointer currently refers to device memory
* regardless of mem.host_pointer and mem.shared_pointer. */
thread_scoped_lock lock(hip_mem_map_mutex);
if (!hip_mem_map[&mem].use_mapped_host || mem.host_pointer != mem.shared_pointer) {
thread_scoped_lock lock(device_mem_map_mutex);
if (!device_mem_map[&mem].use_mapped_host || mem.host_pointer != mem.shared_pointer) {
const HIPContextScope scope(this);
hip_assert(hipMemsetD8((hipDeviceptr_t)mem.device_pointer, 0, mem.memory_size()));
}
@@ -951,19 +704,19 @@ void HIPDevice::tex_alloc(device_texture &mem)
return;
}
HIPMem *cmem = NULL;
Mem *cmem = NULL;
hArray array_3d = NULL;
size_t src_pitch = mem.data_width * dsize * mem.data_elements;
size_t dst_pitch = src_pitch;
if (!mem.is_resident(this)) {
thread_scoped_lock lock(hip_mem_map_mutex);
cmem = &hip_mem_map[&mem];
thread_scoped_lock lock(device_mem_map_mutex);
cmem = &device_mem_map[&mem];
cmem->texobject = 0;
if (mem.data_depth > 1) {
array_3d = (hArray)mem.device_pointer;
cmem->array = array_3d;
cmem->array = reinterpret_cast<arrayMemObject>(array_3d);
}
else if (mem.data_height > 0) {
dst_pitch = align_up(src_pitch, pitch_alignment);
@@ -1007,10 +760,10 @@ void HIPDevice::tex_alloc(device_texture &mem)
mem.device_size = size;
stats.mem_alloc(size);
thread_scoped_lock lock(hip_mem_map_mutex);
cmem = &hip_mem_map[&mem];
thread_scoped_lock lock(device_mem_map_mutex);
cmem = &device_mem_map[&mem];
cmem->texobject = 0;
cmem->array = array_3d;
cmem->array = reinterpret_cast<arrayMemObject>(array_3d);
}
else if (mem.data_height > 0) {
/* 2D texture, using pitch aligned linear memory. */
@@ -1095,8 +848,8 @@ void HIPDevice::tex_alloc(device_texture &mem)
texDesc.filterMode = filter_mode;
texDesc.flags = HIP_TRSF_NORMALIZED_COORDINATES;
thread_scoped_lock lock(hip_mem_map_mutex);
cmem = &hip_mem_map[&mem];
thread_scoped_lock lock(device_mem_map_mutex);
cmem = &device_mem_map[&mem];
hip_assert(hipTexObjectCreate(&cmem->texobject, &resDesc, &texDesc, NULL));
@@ -1111,9 +864,9 @@ void HIPDevice::tex_free(device_texture &mem)
{
if (mem.device_pointer) {
HIPContextScope scope(this);
thread_scoped_lock lock(hip_mem_map_mutex);
DCHECK(hip_mem_map.find(&mem) != hip_mem_map.end());
const HIPMem &cmem = hip_mem_map[&mem];
thread_scoped_lock lock(device_mem_map_mutex);
DCHECK(device_mem_map.find(&mem) != device_mem_map.end());
const Mem &cmem = device_mem_map[&mem];
if (cmem.texobject) {
/* Free bindless texture. */
@@ -1122,16 +875,16 @@ void HIPDevice::tex_free(device_texture &mem)
if (!mem.is_resident(this)) {
/* Do not free memory here, since it was allocated on a different device. */
hip_mem_map.erase(hip_mem_map.find(&mem));
device_mem_map.erase(device_mem_map.find(&mem));
}
else if (cmem.array) {
/* Free array. */
hipArrayDestroy(cmem.array);
hipArrayDestroy(reinterpret_cast<hArray>(cmem.array));
stats.mem_free(mem.device_size);
mem.device_pointer = 0;
mem.device_size = 0;
hip_mem_map.erase(hip_mem_map.find(&mem));
device_mem_map.erase(device_mem_map.find(&mem));
}
else {
lock.unlock();
@@ -1153,7 +906,7 @@ bool HIPDevice::should_use_graphics_interop()
* possible, but from the empiric measurements it can be considerably slower than using naive
* pixels copy. */
/* Disable graphics interop for now, because of driver bug in 21.40. See T92972 */
/* Disable graphics interop for now, because of driver bug in 21.40. See #92972 */
# if 0
HIPContextScope scope(this);

View File

@@ -18,7 +18,7 @@ CCL_NAMESPACE_BEGIN
class DeviceQueue;
class HIPDevice : public Device {
class HIPDevice : public GPUDevice {
friend class HIPContextScope;
@@ -26,36 +26,11 @@ class HIPDevice : public Device {
hipDevice_t hipDevice;
hipCtx_t hipContext;
hipModule_t hipModule;
size_t device_texture_headroom;
size_t device_working_headroom;
bool move_texture_to_host;
size_t map_host_used;
size_t map_host_limit;
int can_map_host;
int pitch_alignment;
int hipDevId;
int hipDevArchitecture;
bool first_error;
struct HIPMem {
HIPMem() : texobject(0), array(0), use_mapped_host(false)
{
}
hipTextureObject_t texobject;
hArray array;
/* If true, a mapped host memory in shared_pointer is being used. */
bool use_mapped_host;
};
typedef map<device_memory *, HIPMem> HIPMemMap;
HIPMemMap hip_mem_map;
thread_mutex hip_mem_map_mutex;
/* Bindless Textures */
device_vector<TextureInfo> texture_info;
bool need_texture_info;
HIPDeviceKernels kernels;
static bool have_precompiled_kernels();
@@ -81,17 +56,13 @@ class HIPDevice : public Device {
virtual bool load_kernels(const uint kernel_features) override;
void reserve_local_memory(const uint kernel_features);
void init_host_memory();
void load_texture_info();
void move_textures_to_host(size_t size, bool for_texture);
HIPMem *generic_alloc(device_memory &mem, size_t pitch_padding = 0);
void generic_copy_to(device_memory &mem);
void generic_free(device_memory &mem);
virtual void get_device_memory_info(size_t &total, size_t &free) override;
virtual bool alloc_device(void *&device_pointer, size_t size) override;
virtual void free_device(void *device_pointer) override;
virtual bool alloc_host(void *&shared_pointer, size_t size) override;
virtual void free_host(void *shared_pointer) override;
virtual bool transform_host_pointer(void *&device_pointer, void *&shared_pointer) override;
virtual void copy_host_to_device(void *device_pointer, void *host_pointer, size_t size) override;
void mem_alloc(device_memory &mem) override;

View File

@@ -51,7 +51,7 @@ static inline bool hipSupportsDevice(const int hipDevId)
hipDeviceGetAttribute(&major, hipDeviceAttributeComputeCapabilityMajor, hipDevId);
hipDeviceGetAttribute(&minor, hipDeviceAttributeComputeCapabilityMinor, hipDevId);
return (major >= 10);
return (major >= 9);
}
CCL_NAMESPACE_END

View File

@@ -108,9 +108,10 @@ template<> struct device_type_traits<uint2> {
};
template<> struct device_type_traits<uint3> {
static const DataType data_type = TYPE_UINT;
static const size_t num_elements = 3;
static_assert(sizeof(uint3) == num_elements * datatype_size(data_type));
/* uint3 has different size depending on the device, can't use it for interchanging
* memory between CPU and GPU.
*
* Leave body empty to trigger a compile error if used. */
};
template<> struct device_type_traits<uint4> {
@@ -132,9 +133,10 @@ template<> struct device_type_traits<int2> {
};
template<> struct device_type_traits<int3> {
static const DataType data_type = TYPE_INT;
static const size_t num_elements = 4;
static_assert(sizeof(int3) == num_elements * datatype_size(data_type));
/* int3 has different size depending on the device, can't use it for interchanging
* memory between CPU and GPU.
*
* Leave body empty to trigger a compile error if used. */
};
template<> struct device_type_traits<int4> {
@@ -247,6 +249,8 @@ class device_memory {
bool is_resident(Device *sub_device) const;
protected:
friend class Device;
friend class GPUDevice;
friend class CUDADevice;
friend class OptiXDevice;
friend class HIPDevice;

View File

@@ -55,9 +55,8 @@ void device_metal_info(vector<DeviceInfo> &devices)
info.denoisers = DENOISER_NONE;
info.id = id;
if (MetalInfo::get_device_vendor(device) == METAL_GPU_AMD) {
info.has_light_tree = false;
}
info.has_nanovdb = MetalInfo::get_device_vendor(device) == METAL_GPU_APPLE;
info.has_light_tree = MetalInfo::get_device_vendor(device) != METAL_GPU_AMD;
devices.push_back(info);
device_index++;

View File

@@ -29,7 +29,8 @@ class MetalDevice : public Device {
id<MTLArgumentEncoder> mtlAncillaryArgEncoder =
nil; /* encoder used for fetching device pointers from MTLBuffers */
string source[PSO_NUM];
string source_md5[PSO_NUM];
string kernels_md5[PSO_NUM];
string global_defines_md5[PSO_NUM];
bool capture_enabled = false;
@@ -67,9 +68,12 @@ class MetalDevice : public Device {
std::recursive_mutex metal_mem_map_mutex;
/* Bindless Textures */
bool is_texture(const TextureInfo &tex);
device_vector<TextureInfo> texture_info;
bool need_texture_info;
id<MTLArgumentEncoder> mtlTextureArgEncoder = nil;
id<MTLArgumentEncoder> mtlBufferArgEncoder = nil;
id<MTLBuffer> buffer_bindings_1d = nil;
id<MTLBuffer> texture_bindings_2d = nil;
id<MTLBuffer> texture_bindings_3d = nil;
std::vector<id<MTLTexture>> texture_slot_map;
@@ -112,6 +116,10 @@ class MetalDevice : public Device {
bool use_local_atomic_sort() const;
string preprocess_source(MetalPipelineType pso_type,
const uint kernel_features,
string *source = nullptr);
bool make_source_and_check_if_compile_needed(MetalPipelineType pso_type);
void make_source(MetalPipelineType pso_type, const uint kernel_features);

View File

@@ -91,11 +91,6 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile
}
}
texture_bindings_2d = [mtlDevice newBufferWithLength:4096 options:default_storage_mode];
texture_bindings_3d = [mtlDevice newBufferWithLength:4096 options:default_storage_mode];
stats.mem_alloc(texture_bindings_2d.allocatedSize + texture_bindings_3d.allocatedSize);
switch (device_vendor) {
default:
break;
@@ -105,6 +100,7 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile
}
case METAL_GPU_AMD: {
max_threads_per_threadgroup = 128;
use_metalrt = info.use_metalrt;
break;
}
case METAL_GPU_APPLE: {
@@ -155,6 +151,16 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile
arg_desc_texture.dataType = MTLDataTypeTexture;
arg_desc_texture.access = MTLArgumentAccessReadOnly;
mtlTextureArgEncoder = [mtlDevice newArgumentEncoderWithArguments:@[ arg_desc_texture ]];
MTLArgumentDescriptor *arg_desc_buffer = [[MTLArgumentDescriptor alloc] init];
arg_desc_buffer.dataType = MTLDataTypePointer;
arg_desc_buffer.access = MTLArgumentAccessReadOnly;
mtlBufferArgEncoder = [mtlDevice newArgumentEncoderWithArguments:@[ arg_desc_buffer ]];
buffer_bindings_1d = [mtlDevice newBufferWithLength:8192 options:default_storage_mode];
texture_bindings_2d = [mtlDevice newBufferWithLength:8192 options:default_storage_mode];
texture_bindings_3d = [mtlDevice newBufferWithLength:8192 options:default_storage_mode];
stats.mem_alloc(buffer_bindings_1d.allocatedSize + texture_bindings_2d.allocatedSize +
texture_bindings_3d.allocatedSize);
/* command queue for non-tracing work on the GPU */
mtlGeneralCommandQueue = [mtlDevice newCommandQueue];
@@ -179,6 +185,8 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile
arg_desc_tex.dataType = MTLDataTypePointer;
arg_desc_tex.access = MTLArgumentAccessReadOnly;
arg_desc_tex.index = index++;
[ancillary_desc addObject:[arg_desc_tex copy]]; /* metal_buf_1d */
arg_desc_tex.index = index++;
[ancillary_desc addObject:[arg_desc_tex copy]]; /* metal_tex_2d */
arg_desc_tex.index = index++;
@@ -224,11 +232,15 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile
mtlAncillaryArgEncoder = [mtlDevice newArgumentEncoderWithArguments:ancillary_desc];
// preparing the blas arg encoder
MTLArgumentDescriptor *arg_desc_blas = [[MTLArgumentDescriptor alloc] init];
arg_desc_blas.dataType = MTLDataTypeInstanceAccelerationStructure;
arg_desc_blas.access = MTLArgumentAccessReadOnly;
mtlBlasArgEncoder = [mtlDevice newArgumentEncoderWithArguments:@[ arg_desc_blas ]];
[arg_desc_blas release];
if (@available(macos 11.0, *)) {
if (use_metalrt) {
MTLArgumentDescriptor *arg_desc_blas = [[MTLArgumentDescriptor alloc] init];
arg_desc_blas.dataType = MTLDataTypeInstanceAccelerationStructure;
arg_desc_blas.access = MTLArgumentAccessReadOnly;
mtlBlasArgEncoder = [mtlDevice newArgumentEncoderWithArguments:@[ arg_desc_blas ]];
[arg_desc_blas release];
}
}
for (int i = 0; i < ancillary_desc.count; i++) {
[ancillary_desc[i] release];
@@ -248,22 +260,26 @@ MetalDevice::~MetalDevice()
* existing_devices_mutex). */
thread_scoped_lock lock(existing_devices_mutex);
for (auto &tex : texture_slot_map) {
if (tex) {
[tex release];
tex = nil;
int num_resources = texture_info.size();
for (int res = 0; res < num_resources; res++) {
if (is_texture(texture_info[res])) {
[texture_slot_map[res] release];
texture_slot_map[res] = nil;
}
}
flush_delayed_free_list();
if (texture_bindings_2d) {
stats.mem_free(texture_bindings_2d.allocatedSize + texture_bindings_3d.allocatedSize);
stats.mem_free(buffer_bindings_1d.allocatedSize + texture_bindings_2d.allocatedSize +
texture_bindings_3d.allocatedSize);
[buffer_bindings_1d release];
[texture_bindings_2d release];
[texture_bindings_3d release];
}
[mtlTextureArgEncoder release];
[mtlBufferKernelParamsEncoder release];
[mtlBufferArgEncoder release];
[mtlASArgEncoder release];
[mtlAncillaryArgEncoder release];
[mtlGeneralCommandQueue release];
@@ -294,7 +310,9 @@ bool MetalDevice::use_local_atomic_sort() const
return DebugFlags().metal.use_local_atomic_sort;
}
void MetalDevice::make_source(MetalPipelineType pso_type, const uint kernel_features)
string MetalDevice::preprocess_source(MetalPipelineType pso_type,
const uint kernel_features,
string *source)
{
string global_defines;
if (use_adaptive_compilation()) {
@@ -327,6 +345,9 @@ void MetalDevice::make_source(MetalPipelineType pso_type, const uint kernel_feat
break;
case METAL_GPU_APPLE:
global_defines += "#define __KERNEL_METAL_APPLE__\n";
# ifdef WITH_NANOVDB
global_defines += "#define WITH_NANOVDB\n";
# endif
break;
}
@@ -334,6 +355,61 @@ void MetalDevice::make_source(MetalPipelineType pso_type, const uint kernel_feat
NSOperatingSystemVersion macos_ver = [processInfo operatingSystemVersion];
global_defines += "#define __KERNEL_METAL_MACOS__ " + to_string(macos_ver.majorVersion) + "\n";
/* Replace specific KernelData "dot" dereferences with a Metal function_constant identifier of
* the same character length. Build a string of all active constant values which is then hashed
* in order to identify the PSO.
*/
if (pso_type != PSO_GENERIC) {
if (source) {
const double starttime = time_dt();
# define KERNEL_STRUCT_BEGIN(name, parent) \
string_replace_same_length(*source, "kernel_data." #parent ".", "kernel_data_" #parent "_");
bool next_member_is_specialized = true;
# define KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE next_member_is_specialized = false;
# define KERNEL_STRUCT_MEMBER(parent, _type, name) \
if (!next_member_is_specialized) { \
string_replace( \
*source, "kernel_data_" #parent "_" #name, "kernel_data." #parent ".__unused_" #name); \
next_member_is_specialized = true; \
}
# include "kernel/data_template.h"
# undef KERNEL_STRUCT_MEMBER
# undef KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE
# undef KERNEL_STRUCT_BEGIN
metal_printf("KernelData patching took %.1f ms\n", (time_dt() - starttime) * 1000.0);
}
/* Opt in to all of available specializations. This can be made more granular for the
* PSO_SPECIALIZED_INTERSECT case in order to minimize the number of specialization requests,
* but the overhead should be negligible as these are very quick to (re)build and aren't
* serialized to disk via MTLBinaryArchives.
*/
global_defines += "#define __KERNEL_USE_DATA_CONSTANTS__\n";
}
# if 0
metal_printf("================\n%s================\n",
global_defines.c_str());
# endif
if (source) {
*source = global_defines + *source;
}
MD5Hash md5;
md5.append(global_defines);
return md5.get_hex();
}
void MetalDevice::make_source(MetalPipelineType pso_type, const uint kernel_features)
{
string &source = this->source[pso_type];
source = "\n#include \"kernel/device/metal/kernel.metal\"\n";
source = path_source_replace_includes(source, path_get("source"));
@@ -342,62 +418,7 @@ void MetalDevice::make_source(MetalPipelineType pso_type, const uint kernel_feat
* With Metal function constants we can generate a single variant of the kernel source which can
* be repeatedly respecialized.
*/
string baked_constants;
/* Replace specific KernelData "dot" dereferences with a Metal function_constant identifier of
* the same character length. Build a string of all active constant values which is then hashed
* in order to identify the PSO.
*/
if (pso_type != PSO_GENERIC) {
const double starttime = time_dt();
# define KERNEL_STRUCT_BEGIN(name, parent) \
string_replace_same_length(source, "kernel_data." #parent ".", "kernel_data_" #parent "_");
bool next_member_is_specialized = true;
# define KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE next_member_is_specialized = false;
/* Add constants to md5 so that 'get_best_pipeline' is able to return a suitable match. */
# define KERNEL_STRUCT_MEMBER(parent, _type, name) \
if (next_member_is_specialized) { \
baked_constants += string(#parent "." #name "=") + \
to_string(_type(launch_params.data.parent.name)) + "\n"; \
} \
else { \
string_replace( \
source, "kernel_data_" #parent "_" #name, "kernel_data." #parent ".__unused_" #name); \
next_member_is_specialized = true; \
}
# include "kernel/data_template.h"
/* Opt in to all of available specializations. This can be made more granular for the
* PSO_SPECIALIZED_INTERSECT case in order to minimize the number of specialization requests,
* but the overhead should be negligible as these are very quick to (re)build and aren't
* serialized to disk via MTLBinaryArchives.
*/
global_defines += "#define __KERNEL_USE_DATA_CONSTANTS__\n";
metal_printf("KernelData patching took %.1f ms\n", (time_dt() - starttime) * 1000.0);
}
source = global_defines + source;
# if 0
metal_printf("================\n%s================\n\%s================\n",
global_defines.c_str(),
baked_constants.c_str());
# endif
/* Generate an MD5 from the source and include any baked constants. This is used when caching
* PSOs. */
MD5Hash md5;
md5.append(baked_constants);
md5.append(source);
if (use_metalrt) {
md5.append(std::to_string(kernel_features & METALRT_FEATURE_MASK));
}
source_md5[pso_type] = md5.get_hex();
global_defines_md5[pso_type] = preprocess_source(pso_type, kernel_features, &source);
}
bool MetalDevice::load_kernels(const uint _kernel_features)
@@ -431,9 +452,49 @@ bool MetalDevice::load_kernels(const uint _kernel_features)
bool MetalDevice::make_source_and_check_if_compile_needed(MetalPipelineType pso_type)
{
if (this->source[pso_type].empty()) {
string defines_md5 = preprocess_source(pso_type, kernel_features);
/* Rebuild the source string if the injected block of #defines has changed. */
if (global_defines_md5[pso_type] != defines_md5) {
make_source(pso_type, kernel_features);
}
string constant_values;
if (pso_type != PSO_GENERIC) {
bool next_member_is_specialized = true;
# define KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE next_member_is_specialized = false;
/* Add specialization constants to md5 so that 'get_best_pipeline' is able to return a suitable
* match. */
# define KERNEL_STRUCT_MEMBER(parent, _type, name) \
if (next_member_is_specialized) { \
constant_values += string(#parent "." #name "=") + \
to_string(_type(launch_params.data.parent.name)) + "\n"; \
} \
else { \
next_member_is_specialized = true; \
}
# include "kernel/data_template.h"
# undef KERNEL_STRUCT_MEMBER
# undef KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE
# if 0
metal_printf("================\n%s================\n",
constant_values.c_str());
# endif
}
MD5Hash md5;
md5.append(constant_values);
md5.append(source[pso_type]);
if (use_metalrt) {
md5.append(string_printf("metalrt_features=%d", kernel_features & METALRT_FEATURE_MASK));
}
kernels_md5[pso_type] = md5.get_hex();
return MetalDeviceKernels::should_load_kernels(this, pso_type);
}
@@ -541,6 +602,11 @@ void MetalDevice::compile_and_load(int device_id, MetalPipelineType pso_type)
}
}
bool MetalDevice::is_texture(const TextureInfo &tex)
{
return (tex.depth > 0 || tex.height > 0);
}
void MetalDevice::load_texture_info()
{
if (need_texture_info) {
@@ -552,21 +618,20 @@ void MetalDevice::load_texture_info()
for (int tex = 0; tex < num_textures; tex++) {
uint64_t offset = tex * sizeof(void *);
id<MTLTexture> metal_texture = texture_slot_map[tex];
if (!metal_texture) {
[mtlTextureArgEncoder setArgumentBuffer:texture_bindings_2d offset:offset];
[mtlTextureArgEncoder setTexture:nil atIndex:0];
[mtlTextureArgEncoder setArgumentBuffer:texture_bindings_3d offset:offset];
[mtlTextureArgEncoder setTexture:nil atIndex:0];
}
else {
if (is_texture(texture_info[tex]) && texture_slot_map[tex]) {
id<MTLTexture> metal_texture = texture_slot_map[tex];
MTLTextureType type = metal_texture.textureType;
[mtlTextureArgEncoder setArgumentBuffer:texture_bindings_2d offset:offset];
[mtlTextureArgEncoder setTexture:type == MTLTextureType2D ? metal_texture : nil atIndex:0];
[mtlTextureArgEncoder setArgumentBuffer:texture_bindings_3d offset:offset];
[mtlTextureArgEncoder setTexture:type == MTLTextureType3D ? metal_texture : nil atIndex:0];
}
else {
[mtlTextureArgEncoder setArgumentBuffer:texture_bindings_2d offset:offset];
[mtlTextureArgEncoder setTexture:nil atIndex:0];
[mtlTextureArgEncoder setArgumentBuffer:texture_bindings_3d offset:offset];
[mtlTextureArgEncoder setTexture:nil atIndex:0];
}
}
if (default_storage_mode == MTLResourceStorageModeManaged) {
[texture_bindings_2d didModifyRange:NSMakeRange(0, num_textures * sizeof(void *))];
@@ -585,7 +650,7 @@ void MetalDevice::erase_allocation(device_memory &mem)
if (it != metal_mem_map.end()) {
MetalMem *mmem = it->second.get();
/* blank out reference to MetalMem* in the launch params (fixes crash T94736) */
/* blank out reference to MetalMem* in the launch params (fixes crash #94736) */
if (mmem->pointer_index >= 0) {
device_ptr *pointers = (device_ptr *)&launch_params;
pointers[mmem->pointer_index] = 0;
@@ -739,7 +804,6 @@ void MetalDevice::generic_free(device_memory &mem)
mem.shared_pointer = 0;
/* Free device memory. */
delayed_free_list.push_back(mmem.mtlBuffer);
mmem.mtlBuffer = nil;
}
@@ -861,6 +925,11 @@ void MetalDevice::cancel()
bool MetalDevice::is_ready(string &status) const
{
if (!error_msg.empty()) {
/* Avoid hanging if we had an error. */
return true;
}
int num_loaded = MetalDeviceKernels::get_loaded_kernel_count(this, PSO_GENERIC);
if (num_loaded < DEVICE_KERNEL_NUM) {
status = string_printf("%d / %d render kernels loaded (may take a few minutes the first time)",
@@ -868,6 +937,17 @@ bool MetalDevice::is_ready(string &status) const
DEVICE_KERNEL_NUM);
return false;
}
if (int num_requests = MetalDeviceKernels::num_incomplete_specialization_requests()) {
status = string_printf("%d kernels to optimize", num_requests);
}
else if (kernel_specialization_level == PSO_SPECIALIZED_INTERSECT) {
status = "Using optimized intersection kernels";
}
else if (kernel_specialization_level == PSO_SPECIALIZED_SHADE) {
status = "Using optimized kernels";
}
metal_printf("MetalDevice::is_ready(...) --> true\n");
return true;
}
@@ -904,7 +984,7 @@ void MetalDevice::optimize_for_scene(Scene *scene)
}
if (specialize_in_background) {
if (!MetalDeviceKernels::any_specialization_happening_now()) {
if (MetalDeviceKernels::num_incomplete_specialization_requests() == 0) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
specialize_kernels_fn);
}
@@ -974,7 +1054,7 @@ void MetalDevice::global_free(device_memory &mem)
void MetalDevice::tex_alloc_as_buffer(device_texture &mem)
{
generic_alloc(mem);
MetalDevice::MetalMem *mmem = generic_alloc(mem);
generic_copy_to(mem);
/* Resize once */
@@ -983,27 +1063,32 @@ void MetalDevice::tex_alloc_as_buffer(device_texture &mem)
/* Allocate some slots in advance, to reduce amount
* of re-allocations. */
texture_info.resize(round_up(slot + 1, 128));
texture_slot_map.resize(round_up(slot + 1, 128));
}
mem.info.data = (uint64_t)mem.device_pointer;
/* Set Mapping and tag that we need to (re-)upload to device */
texture_info[slot] = mem.info;
uint64_t offset = slot * sizeof(void *);
[mtlBufferArgEncoder setArgumentBuffer:buffer_bindings_1d offset:offset];
[mtlBufferArgEncoder setBuffer:mmem->mtlBuffer offset:0 atIndex:0];
texture_info[slot].data = *(uint64_t *)((uint64_t)buffer_bindings_1d.contents + offset);
texture_slot_map[slot] = nil;
need_texture_info = true;
}
void MetalDevice::tex_alloc(device_texture &mem)
{
/* Check that dimensions fit within maximum allowable size.
* If 1D texture is allocated, use 1D buffer.
* See: https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf */
if (mem.data_width > 16384 || mem.data_height > 16384) {
set_error(string_printf(
"Texture exceeds maximum allowed size of 16384 x 16384 (requested: %zu x %zu)",
mem.data_width,
mem.data_height));
return;
if (mem.data_height > 0) {
if (mem.data_width > 16384 || mem.data_height > 16384) {
set_error(string_printf(
"Texture exceeds maximum allowed size of 16384 x 16384 (requested: %zu x %zu)",
mem.data_width,
mem.data_height));
return;
}
}
MTLStorageMode storage_mode = MTLStorageModeManaged;
if (@available(macos 10.15, *)) {
if ([mtlDevice hasUnifiedMemory] &&
@@ -1143,8 +1228,9 @@ void MetalDevice::tex_alloc(device_texture &mem)
bytesPerRow:src_pitch];
}
else {
assert(0);
/* 1D texture, using linear memory. */
tex_alloc_as_buffer(mem);
return;
}
mem.device_pointer = (device_ptr)mtlTexture;
@@ -1168,17 +1254,22 @@ void MetalDevice::tex_alloc(device_texture &mem)
ssize_t min_buffer_length = sizeof(void *) * texture_info.size();
if (!texture_bindings_2d || (texture_bindings_2d.length < min_buffer_length)) {
if (texture_bindings_2d) {
delayed_free_list.push_back(buffer_bindings_1d);
delayed_free_list.push_back(texture_bindings_2d);
delayed_free_list.push_back(texture_bindings_3d);
stats.mem_free(texture_bindings_2d.allocatedSize + texture_bindings_3d.allocatedSize);
stats.mem_free(buffer_bindings_1d.allocatedSize + texture_bindings_2d.allocatedSize +
texture_bindings_3d.allocatedSize);
}
buffer_bindings_1d = [mtlDevice newBufferWithLength:min_buffer_length
options:default_storage_mode];
texture_bindings_2d = [mtlDevice newBufferWithLength:min_buffer_length
options:default_storage_mode];
texture_bindings_3d = [mtlDevice newBufferWithLength:min_buffer_length
options:default_storage_mode];
stats.mem_alloc(texture_bindings_2d.allocatedSize + texture_bindings_3d.allocatedSize);
stats.mem_alloc(buffer_bindings_1d.allocatedSize + texture_bindings_2d.allocatedSize +
texture_bindings_3d.allocatedSize);
}
}
@@ -1205,12 +1296,18 @@ void MetalDevice::tex_alloc(device_texture &mem)
void MetalDevice::tex_free(device_texture &mem)
{
if (mem.data_depth == 0 && mem.data_height == 0) {
generic_free(mem);
return;
}
if (metal_mem_map.count(&mem)) {
std::lock_guard<std::recursive_mutex> lock(metal_mem_map_mutex);
MetalMem &mmem = *metal_mem_map.at(&mem);
assert(texture_slot_map[mem.slot] == mmem.mtlTexture);
texture_slot_map[mem.slot] = nil;
if (texture_slot_map[mem.slot] == mmem.mtlTexture)
texture_slot_map[mem.slot] = nil;
if (mmem.mtlTexture) {
/* Free bindless texture. */

View File

@@ -63,8 +63,7 @@ enum MetalPipelineType {
};
# define METALRT_FEATURE_MASK \
(KERNEL_FEATURE_HAIR | KERNEL_FEATURE_HAIR_THICK | KERNEL_FEATURE_POINTCLOUD | \
KERNEL_FEATURE_OBJECT_MOTION)
(KERNEL_FEATURE_HAIR | KERNEL_FEATURE_HAIR_THICK | KERNEL_FEATURE_POINTCLOUD)
const char *kernel_type_as_string(MetalPipelineType pso_type);
@@ -76,12 +75,12 @@ struct MetalKernelPipeline {
id<MTLLibrary> mtlLibrary = nil;
MetalPipelineType pso_type;
string source_md5;
string kernels_md5;
size_t usage_count = 0;
KernelData kernel_data_;
bool use_metalrt;
uint32_t metalrt_features = 0;
uint32_t kernel_features = 0;
int threads_per_threadgroup;
@@ -104,7 +103,7 @@ struct MetalKernelPipeline {
/* Cache of Metal kernels for each DeviceKernel. */
namespace MetalDeviceKernels {
bool any_specialization_happening_now();
int num_incomplete_specialization_requests();
int get_loaded_kernel_count(MetalDevice const *device, MetalPipelineType pso_type);
bool should_load_kernels(MetalDevice const *device, MetalPipelineType pso_type);
bool load(MetalDevice *device, MetalPipelineType pso_type);

View File

@@ -292,7 +292,7 @@ bool ShaderCache::should_load_kernel(DeviceKernel device_kernel,
/* check whether the kernel has already been requested / cached */
thread_scoped_lock lock(cache_mutex);
for (auto &pipeline : pipelines[device_kernel]) {
if (pipeline->source_md5 == device->source_md5[pso_type]) {
if (pipeline->kernels_md5 == device->kernels_md5[pso_type]) {
return false;
}
}
@@ -332,7 +332,7 @@ void ShaderCache::load_kernel(DeviceKernel device_kernel,
memcpy(&pipeline->kernel_data_, &device->launch_params.data, sizeof(pipeline->kernel_data_));
pipeline->pso_type = pso_type;
pipeline->mtlDevice = mtlDevice;
pipeline->source_md5 = device->source_md5[pso_type];
pipeline->kernels_md5 = device->kernels_md5[pso_type];
pipeline->mtlLibrary = device->mtlLibrary[pso_type];
pipeline->device_kernel = device_kernel;
pipeline->threads_per_threadgroup = device->max_threads_per_threadgroup;
@@ -344,9 +344,7 @@ void ShaderCache::load_kernel(DeviceKernel device_kernel,
/* metalrt options */
pipeline->use_metalrt = device->use_metalrt;
pipeline->metalrt_features = device->use_metalrt ?
(device->kernel_features & METALRT_FEATURE_MASK) :
0;
pipeline->kernel_features = device->kernel_features;
{
thread_scoped_lock lock(cache_mutex);
@@ -357,65 +355,36 @@ void ShaderCache::load_kernel(DeviceKernel device_kernel,
MetalKernelPipeline *ShaderCache::get_best_pipeline(DeviceKernel kernel, const MetalDevice *device)
{
/* metalrt options */
bool use_metalrt = device->use_metalrt;
bool device_metalrt_hair = use_metalrt && device->kernel_features & KERNEL_FEATURE_HAIR;
bool device_metalrt_hair_thick = use_metalrt &&
device->kernel_features & KERNEL_FEATURE_HAIR_THICK;
bool device_metalrt_pointcloud = use_metalrt &&
device->kernel_features & KERNEL_FEATURE_POINTCLOUD;
bool device_metalrt_motion = use_metalrt &&
device->kernel_features & KERNEL_FEATURE_OBJECT_MOTION;
MetalKernelPipeline *best_pipeline = nullptr;
while (!best_pipeline) {
while (running) {
/* Search all loaded pipelines with matching kernels_md5 checksums. */
MetalKernelPipeline *best_match = nullptr;
{
thread_scoped_lock lock(cache_mutex);
for (auto &pipeline : pipelines[kernel]) {
if (!pipeline->loaded) {
/* still loading - ignore */
continue;
}
bool pipeline_metalrt_hair = pipeline->metalrt_features & KERNEL_FEATURE_HAIR;
bool pipeline_metalrt_hair_thick = pipeline->metalrt_features & KERNEL_FEATURE_HAIR_THICK;
bool pipeline_metalrt_pointcloud = pipeline->metalrt_features & KERNEL_FEATURE_POINTCLOUD;
bool pipeline_metalrt_motion = use_metalrt &&
pipeline->metalrt_features & KERNEL_FEATURE_OBJECT_MOTION;
if (pipeline->use_metalrt != use_metalrt || pipeline_metalrt_hair != device_metalrt_hair ||
pipeline_metalrt_hair_thick != device_metalrt_hair_thick ||
pipeline_metalrt_pointcloud != device_metalrt_pointcloud ||
pipeline_metalrt_motion != device_metalrt_motion) {
/* wrong combination of metalrt options */
continue;
}
if (pipeline->pso_type != PSO_GENERIC) {
if (pipeline->source_md5 == device->source_md5[PSO_SPECIALIZED_INTERSECT] ||
pipeline->source_md5 == device->source_md5[PSO_SPECIALIZED_SHADE]) {
best_pipeline = pipeline.get();
for (auto &candidate : pipelines[kernel]) {
if (candidate->loaded &&
candidate->kernels_md5 == device->kernels_md5[candidate->pso_type]) {
/* Replace existing match if candidate is more specialized. */
if (!best_match || candidate->pso_type > best_match->pso_type) {
best_match = candidate.get();
}
}
else if (!best_pipeline) {
best_pipeline = pipeline.get();
}
}
}
if (!best_pipeline) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (best_match) {
if (best_match->usage_count == 0 && best_match->pso_type != PSO_GENERIC) {
metal_printf("Swapping in %s version of %s\n",
kernel_type_as_string(best_match->pso_type),
device_kernel_as_string(kernel));
}
best_match->usage_count += 1;
return best_match;
}
}
if (best_pipeline->usage_count == 0 && best_pipeline->pso_type != PSO_GENERIC) {
metal_printf("Swapping in %s version of %s\n",
kernel_type_as_string(best_pipeline->pso_type),
device_kernel_as_string(kernel));
/* Spin until a matching kernel is loaded, or we're shutting down. */
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
best_pipeline->usage_count += 1;
return best_pipeline;
return nullptr;
}
bool MetalKernelPipeline::should_use_binary_archive() const
@@ -428,11 +397,12 @@ bool MetalKernelPipeline::should_use_binary_archive() const
return false;
}
}
/* Workaround for Intel GPU having issue using Binary Archives */
MetalGPUVendor gpu_vendor = MetalInfo::get_device_vendor(mtlDevice);
if (gpu_vendor == METAL_GPU_INTEL) {
return false;
else {
/* Workaround for issues using Binary Archives on non-Apple Silicon systems. */
MetalGPUVendor gpu_vendor = MetalInfo::get_device_vendor(mtlDevice);
if (gpu_vendor != METAL_GPU_APPLE) {
return false;
}
}
if (pso_type == PSO_GENERIC) {
@@ -440,8 +410,10 @@ bool MetalKernelPipeline::should_use_binary_archive() const
return true;
}
if (device_kernel >= DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND &&
device_kernel <= DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW) {
if ((device_kernel >= DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND &&
device_kernel <= DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW) ||
(device_kernel >= DEVICE_KERNEL_SHADER_EVAL_DISPLACE &&
device_kernel <= DEVICE_KERNEL_SHADER_EVAL_CURVE_SHADOW_TRANSPARENCY)) {
/* Archive all shade kernels - they take a long time to compile. */
return true;
}
@@ -567,18 +539,14 @@ void MetalKernelPipeline::compile()
NSArray *table_functions[METALRT_TABLE_NUM] = {nil};
NSArray *linked_functions = nil;
bool metalrt_hair = use_metalrt && (metalrt_features & KERNEL_FEATURE_HAIR);
bool metalrt_hair_thick = use_metalrt && (metalrt_features & KERNEL_FEATURE_HAIR_THICK);
bool metalrt_pointcloud = use_metalrt && (metalrt_features & KERNEL_FEATURE_POINTCLOUD);
if (use_metalrt) {
id<MTLFunction> curve_intersect_default = nil;
id<MTLFunction> curve_intersect_shadow = nil;
id<MTLFunction> point_intersect_default = nil;
id<MTLFunction> point_intersect_shadow = nil;
if (metalrt_hair) {
if (kernel_features & KERNEL_FEATURE_HAIR) {
/* Add curve intersection programs. */
if (metalrt_hair_thick) {
if (kernel_features & KERNEL_FEATURE_HAIR_THICK) {
/* Slower programs for thick hair since that also slows down ribbons.
* Ideally this should not be needed. */
curve_intersect_default = rt_intersection_function[METALRT_FUNC_CURVE_ALL];
@@ -589,7 +557,7 @@ void MetalKernelPipeline::compile()
curve_intersect_shadow = rt_intersection_function[METALRT_FUNC_CURVE_RIBBON_SHADOW];
}
}
if (metalrt_pointcloud) {
if (kernel_features & KERNEL_FEATURE_POINTCLOUD) {
point_intersect_default = rt_intersection_function[METALRT_FUNC_POINT];
point_intersect_shadow = rt_intersection_function[METALRT_FUNC_POINT_SHADOW];
}
@@ -674,20 +642,11 @@ void MetalKernelPipeline::compile()
NSProcessInfo *processInfo = [NSProcessInfo processInfo];
string osVersion = [[processInfo operatingSystemVersionString] UTF8String];
MD5Hash local_md5;
local_md5.append(source_md5);
local_md5.append(kernels_md5);
local_md5.append(osVersion);
local_md5.append((uint8_t *)&this->threads_per_threadgroup,
sizeof(this->threads_per_threadgroup));
string options;
if (use_metalrt && kernel_has_intersection(device_kernel)) {
/* incorporate any MetalRT specializations into the archive name */
options += string_printf(".hair_%d.hair_thick_%d.pointcloud_%d",
metalrt_hair ? 1 : 0,
metalrt_hair_thick ? 1 : 0,
metalrt_pointcloud ? 1 : 0);
}
/* Replace non-alphanumerical characters with underscores. */
string device_name = [mtlDevice.name UTF8String];
for (char &c : device_name) {
@@ -699,7 +658,7 @@ void MetalKernelPipeline::compile()
metalbin_name = device_name;
metalbin_name = path_join(metalbin_name, device_kernel_as_string(device_kernel));
metalbin_name = path_join(metalbin_name, kernel_type_as_string(pso_type));
metalbin_name = path_join(metalbin_name, local_md5.get_hex() + options + ".bin");
metalbin_name = path_join(metalbin_name, local_md5.get_hex() + ".bin");
metalbin_path = path_cache_get(path_join("kernels", metalbin_name));
path_create_directories(metalbin_path);
@@ -857,16 +816,15 @@ void MetalDeviceKernels::wait_for_all()
}
}
bool MetalDeviceKernels::any_specialization_happening_now()
int MetalDeviceKernels::num_incomplete_specialization_requests()
{
/* Return true if any ShaderCaches have ongoing specialization requests (typically there will be
* only 1). */
int total = 0;
for (int i = 0; i < g_shaderCacheCount; i++) {
if (g_shaderCache[i].second->incomplete_specialization_requests > 0) {
return true;
}
total += g_shaderCache[i].second->incomplete_specialization_requests;
}
return false;
return total;
}
int MetalDeviceKernels::get_loaded_kernel_count(MetalDevice const *device,

View File

@@ -477,17 +477,21 @@ bool MetalDeviceQueue::enqueue(DeviceKernel kernel,
[metal_device_->mtlAncillaryArgEncoder setBuffer:metal_device_->texture_bindings_3d
offset:0
atIndex:1];
[metal_device_->mtlAncillaryArgEncoder setBuffer:metal_device_->buffer_bindings_1d
offset:0
atIndex:2];
if (@available(macos 12.0, *)) {
if (metal_device_->use_metalrt) {
if (metal_device_->bvhMetalRT) {
id<MTLAccelerationStructure> accel_struct = metal_device_->bvhMetalRT->accel_struct;
[metal_device_->mtlAncillaryArgEncoder setAccelerationStructure:accel_struct atIndex:2];
[metal_device_->mtlAncillaryArgEncoder setAccelerationStructure:accel_struct atIndex:3];
[metal_device_->mtlAncillaryArgEncoder setBuffer:metal_device_->blas_buffer
offset:0
atIndex:7];
atIndex:8];
[metal_device_->mtlAncillaryArgEncoder setBuffer:metal_device_->blas_lookup_buffer
offset:0
atIndex:8];
atIndex:9];
}
for (int table = 0; table < METALRT_TABLE_NUM; table++) {
@@ -497,13 +501,13 @@ bool MetalDeviceQueue::enqueue(DeviceKernel kernel,
atIndex:1];
[metal_device_->mtlAncillaryArgEncoder
setIntersectionFunctionTable:metal_kernel_pso->intersection_func_table[table]
atIndex:3 + table];
atIndex:4 + table];
[mtlComputeCommandEncoder useResource:metal_kernel_pso->intersection_func_table[table]
usage:MTLResourceUsageRead];
}
else {
[metal_device_->mtlAncillaryArgEncoder setIntersectionFunctionTable:nil
atIndex:3 + table];
atIndex:4 + table];
}
}
}
@@ -874,6 +878,7 @@ void MetalDeviceQueue::prepare_resources(DeviceKernel kernel)
/* ancillaries */
[mtlComputeEncoder_ useResource:metal_device_->texture_bindings_2d usage:MTLResourceUsageRead];
[mtlComputeEncoder_ useResource:metal_device_->texture_bindings_3d usage:MTLResourceUsageRead];
[mtlComputeEncoder_ useResource:metal_device_->buffer_bindings_1d usage:MTLResourceUsageRead];
}
id<MTLComputeCommandEncoder> MetalDeviceQueue::get_compute_encoder(DeviceKernel kernel)

View File

@@ -103,7 +103,7 @@ vector<id<MTLDevice>> const &MetalInfo::get_usable_devices()
}
/* If the system has both an AMD GPU (discrete) and an Intel one (integrated), prefer the AMD
* one. This can be overriden with CYCLES_METAL_FORCE_INTEL. */
* one. This can be overridden with CYCLES_METAL_FORCE_INTEL. */
bool has_usable_amd_gpu = false;
if (@available(macos 12.3, *)) {
for (id<MTLDevice> device in MTLCopyAllDevices()) {

View File

@@ -886,7 +886,7 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c
{
/* Special trick for fast navigation: schedule multiple samples during fast navigation
* (which will prefer to use lower resolution to keep up with refresh rate). This gives more
* usable visual feedback for artists. There are a couple of tricks though. */
* usable visual feedback for artists. */
if (is_denoise_active_during_update()) {
/* When denoising is used during navigation prefer using a higher resolution with less samples
@@ -896,25 +896,12 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c
return 1;
}
if (resolution_divider <= pixel_size_) {
/* When resolution divider is at or below pixel size, schedule one sample. This doesn't effect
* the sample count at this resolution division, but instead assists in the calculation of
* the resolution divider. */
return 1;
}
if (resolution_divider == pixel_size_ * 2) {
/* When resolution divider is the previous step to the final resolution, schedule two samples.
* This is so that rendering on lower resolution does not exceed time that it takes to render
* first sample at the full resolution. */
return 2;
}
/* Always render 4 samples, even if scene is configured for less.
* The idea here is to have enough information on the screen. Resolution divider of 2 allows us
* to have 4 time extra samples, so overall worst case timing is the same as the final resolution
* at one sample. */
return 4;
/* Schedule samples equal to the resolution divider up to a maximum of 4.
* The idea is to have enough information on the screen by increasing the sample count as the
* resolution is decreased. */
/* NOTE: Changing this formula will change the formula in
* `RenderScheduler::calculate_resolution_divider_for_time()`. */
return min(max(1, resolution_divider / pixel_size_), 4);
}
bool RenderScheduler::work_need_adaptive_filter() const
@@ -1100,9 +1087,10 @@ void RenderScheduler::update_start_resolution_divider()
/* TODO(sergey): Need to add hysteresis to avoid resolution divider bouncing around when actual
* render time is somewhere on a boundary between two resolutions. */
/* Never increase resolution to higher than the pixel size (which is possible if the scene is
* simple and compute device is fast). */
start_resolution_divider_ = max(resolution_divider_for_update, pixel_size_);
/* Don't let resolution drop below the desired one. It's better to be slow than provide an
* unreadable viewport render. */
start_resolution_divider_ = min(resolution_divider_for_update,
default_start_resolution_divider_);
VLOG_WORK << "Calculated resolution divider is " << start_resolution_divider_;
}
@@ -1187,24 +1175,24 @@ void RenderScheduler::check_time_limit_reached()
int RenderScheduler::calculate_resolution_divider_for_time(double desired_time, double actual_time)
{
/* TODO(sergey): There should a non-iterative analytical formula here. */
const double ratio_between_times = actual_time / desired_time;
int resolution_divider = 1;
/* We can pass `ratio_between_times` to `get_num_samples_during_navigation()` to get our
* navigation samples because the equation for calculating the resolution divider is as follows:
* `actual_time / desired_time = sqr(resolution_divider) / sample_count`.
* While `resolution_divider` is less than or equal to 4, `resolution_divider = sample_count`
* (This relationship is determined in `get_num_samples_during_navigation()`). With some
* substitution we end up with `actual_time / desired_time = resolution_divider` while the
* resolution divider is less than or equal to 4. Once the resolution divider increases above 4,
* the relationship of `actual_time / desired_time = resolution_divider` is no longer true,
* however the sample count retrieved from `get_num_samples_during_navigation()` is still
* accurate if we continue using this assumption. It should be noted that the interaction between
* `pixel_size`, sample count, and resolution divider are automatically accounted for and that's
* why `pixel_size` isn't included in any of the equations. */
const int navigation_samples = get_num_samples_during_navigation(
ceil_to_int(ratio_between_times));
/* This algorithm iterates through resolution dividers until a divider is found that achieves
* the desired render time. A limit of default_start_resolution_divider_ is put in place as the
* maximum resolution divider to avoid an unreadable viewport due to a low resolution.
* pre_resolution_division_samples and post_resolution_division_samples are used in this
* calculation to better predict the performance impact of changing resolution divisions as
* the sample count can also change between resolution divisions. */
while (actual_time > desired_time && resolution_divider < default_start_resolution_divider_) {
int pre_resolution_division_samples = get_num_samples_during_navigation(resolution_divider);
resolution_divider = resolution_divider * 2;
int post_resolution_division_samples = get_num_samples_during_navigation(resolution_divider);
actual_time /= 4.0 * pre_resolution_division_samples / post_resolution_division_samples;
}
return resolution_divider;
return ceil_to_int(sqrt(navigation_samples * ratio_between_times));
}
int calculate_resolution_divider_for_resolution(int width, int height, int resolution)

View File

@@ -113,8 +113,6 @@ set(SRC_KERNEL_CLOSURE_HEADERS
closure/bsdf_microfacet_multi_impl.h
closure/bsdf_oren_nayar.h
closure/bsdf_phong_ramp.h
closure/bsdf_reflection.h
closure/bsdf_refraction.h
closure/bsdf_toon.h
closure/bsdf_transparent.h
closure/bsdf_util.h
@@ -126,6 +124,7 @@ set(SRC_KERNEL_CLOSURE_HEADERS
closure/bsdf_principled_diffuse.h
closure/bsdf_principled_sheen.h
closure/bsdf_hair_principled.h
closure/bsdf_hair_microfacet.h
)
set(SRC_KERNEL_SVM_HEADERS
@@ -412,11 +411,12 @@ if(WITH_CYCLES_CUDA_BINARIES)
# warn for other versions
if((CUDA_VERSION STREQUAL "101") OR
(CUDA_VERSION STREQUAL "102") OR
(CUDA_VERSION_MAJOR STREQUAL "11"))
(CUDA_VERSION_MAJOR STREQUAL "11") OR
(CUDA_VERSION_MAJOR STREQUAL "12"))
else()
message(WARNING
"CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, "
"build may succeed but only CUDA 11, 10.2 and 10.1 have been tested")
"build may succeed but only CUDA 12, 11, 10.2 and 10.1 have been tested")
endif()
# build for each arch
@@ -514,6 +514,16 @@ if(WITH_CYCLES_CUDA_BINARIES)
else()
message(STATUS "CUDA binaries for ${arch} require CUDA 10 or earlier, skipped.")
endif()
elseif(${arch} MATCHES ".*_3.")
if(DEFINED CUDA11_NVCC_EXECUTABLE)
set(cuda_nvcc_executable ${CUDA11_NVCC_EXECUTABLE})
set(cuda_toolkit_root_dir ${CUDA11_TOOLKIT_ROOT_DIR})
elseif("${CUDA_VERSION}" LESS 120) # Support for sm_35, sm_37 was removed in CUDA 12
set(cuda_nvcc_executable ${CUDA_NVCC_EXECUTABLE})
set(cuda_toolkit_root_dir ${CUDA_TOOLKIT_ROOT_DIR})
else()
message(STATUS "CUDA binaries for ${arch} require CUDA 11 or earlier, skipped.")
endif()
elseif(${arch} MATCHES ".*_7." AND "${CUDA_VERSION}" LESS 100)
message(STATUS "CUDA binaries for ${arch} require CUDA 10.0+, skipped.")
elseif(${arch} MATCHES ".*_8.")

View File

@@ -11,13 +11,12 @@
#include "kernel/closure/bsdf_diffuse_ramp.h"
#include "kernel/closure/bsdf_microfacet.h"
#include "kernel/closure/bsdf_microfacet_multi.h"
#include "kernel/closure/bsdf_reflection.h"
#include "kernel/closure/bsdf_refraction.h"
#include "kernel/closure/bsdf_transparent.h"
#include "kernel/closure/bsdf_ashikhmin_shirley.h"
#include "kernel/closure/bsdf_toon.h"
#include "kernel/closure/bsdf_hair.h"
#include "kernel/closure/bsdf_hair_principled.h"
#include "kernel/closure/bsdf_hair_microfacet.h"
#include "kernel/closure/bsdf_principled_diffuse.h"
#include "kernel/closure/bsdf_principled_sheen.h"
#include "kernel/closure/bssrdf.h"
@@ -110,8 +109,8 @@ ccl_device_inline bool bsdf_is_transmission(ccl_private const ShaderClosure *sc,
ccl_device_inline int bsdf_sample(KernelGlobals kg,
ccl_private ShaderData *sd,
ccl_private const ShaderClosure *sc,
float randu,
float randv,
const int path_flag,
const float3 rand,
ccl_private Spectrum *eval,
ccl_private float3 *wo,
ccl_private float *pdf,
@@ -125,110 +124,160 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
switch (sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
label = bsdf_diffuse_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
label = bsdf_diffuse_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
#if defined(__SVM__) || defined(__OSL__)
case CLOSURE_BSDF_OREN_NAYAR_ID:
label = bsdf_oren_nayar_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
label = bsdf_oren_nayar_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
# ifdef __OSL__
case CLOSURE_BSDF_PHONG_RAMP_ID:
label = bsdf_phong_ramp_sample(
sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness);
sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf, sampled_roughness);
*eta = 1.0f;
break;
case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
label = bsdf_diffuse_ramp_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
label = bsdf_diffuse_ramp_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
# endif
case CLOSURE_BSDF_TRANSLUCENT_ID:
label = bsdf_translucent_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
label = bsdf_translucent_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_REFLECTION_ID:
label = bsdf_reflection_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf, eta);
*sampled_roughness = zero_float2();
break;
case CLOSURE_BSDF_REFRACTION_ID:
label = bsdf_refraction_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf, eta);
*sampled_roughness = zero_float2();
break;
case CLOSURE_BSDF_TRANSPARENT_ID:
label = bsdf_transparent_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
label = bsdf_transparent_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf);
*sampled_roughness = zero_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_REFLECTION_ID:
case CLOSURE_BSDF_REFRACTION_ID:
case CLOSURE_BSDF_SHARP_GLASS_ID:
label = bsdf_microfacet_sharp_sample(sc,
path_flag,
Ng,
sd->wi,
rand.x,
rand.y,
rand.z,
eval,
wo,
pdf,
sampled_roughness,
eta);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
label = bsdf_microfacet_ggx_sample(
sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness, eta);
case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
label = bsdf_microfacet_ggx_sample(sc,
path_flag,
Ng,
sd->wi,
rand.x,
rand.y,
rand.z,
eval,
wo,
pdf,
sampled_roughness,
eta);
break;
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
label = bsdf_microfacet_multi_ggx_sample(
kg, sc, Ng, sd->wi, randu, randv, eval, wo, pdf, &sd->lcg_state, sampled_roughness, eta);
label = bsdf_microfacet_multi_ggx_sample(kg,
sc,
Ng,
sd->wi,
rand.x,
rand.y,
eval,
wo,
pdf,
&sd->lcg_state,
sampled_roughness,
eta);
break;
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
label = bsdf_microfacet_multi_ggx_glass_sample(
kg, sc, Ng, sd->wi, randu, randv, eval, wo, pdf, &sd->lcg_state, sampled_roughness, eta);
label = bsdf_microfacet_multi_ggx_glass_sample(kg,
sc,
Ng,
sd->wi,
rand.x,
rand.y,
eval,
wo,
pdf,
&sd->lcg_state,
sampled_roughness,
eta);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
label = bsdf_microfacet_beckmann_sample(
sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness, eta);
case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID:
label = bsdf_microfacet_beckmann_sample(sc,
path_flag,
Ng,
sd->wi,
rand.x,
rand.y,
rand.z,
eval,
wo,
pdf,
sampled_roughness,
eta);
break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
label = bsdf_ashikhmin_shirley_sample(
sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness);
sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf, sampled_roughness);
*eta = 1.0f;
break;
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
label = bsdf_ashikhmin_velvet_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
label = bsdf_ashikhmin_velvet_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_DIFFUSE_TOON_ID:
label = bsdf_diffuse_toon_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
label = bsdf_diffuse_toon_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_GLOSSY_TOON_ID:
label = bsdf_glossy_toon_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
label = bsdf_glossy_toon_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf);
// double check if this is valid
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
label = bsdf_hair_reflection_sample(
sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness);
sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf, sampled_roughness);
*eta = 1.0f;
break;
case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
label = bsdf_hair_transmission_sample(
sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness);
sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf, sampled_roughness);
*eta = 1.0f;
break;
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
label = bsdf_principled_hair_sample(
kg, sc, sd, randu, randv, eval, wo, pdf, sampled_roughness, eta);
kg, sc, sd, rand.x, rand.y, rand.z, eval, wo, pdf, sampled_roughness, eta);
break;
case CLOSURE_BSDF_HAIR_MICROFACET_ID:
label = bsdf_microfacet_hair_sample(kg, sc, sd, rand, eval, wo, pdf, sampled_roughness, eta);
break;
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
label = bsdf_principled_diffuse_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
label = bsdf_principled_diffuse_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
label = bsdf_principled_sheen_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf);
label = bsdf_principled_sheen_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
@@ -277,7 +326,6 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
ccl_private float *eta)
{
#ifdef __SVM__
bool refractive = false;
float alpha = 1.0f;
#endif
switch (sc->type) {
@@ -305,54 +353,32 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
*roughness = one_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_REFLECTION_ID: {
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
*roughness = zero_float2();
*eta = bsdf->ior;
break;
}
case CLOSURE_BSDF_REFRACTION_ID: {
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
*roughness = zero_float2();
// do we need to inverse eta??
*eta = bsdf->ior;
break;
}
case CLOSURE_BSDF_TRANSPARENT_ID:
*roughness = zero_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_REFLECTION_ID:
case CLOSURE_BSDF_REFRACTION_ID:
case CLOSURE_BSDF_SHARP_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: {
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: {
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
*roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
*eta = refractive ? 1.0f / bsdf->ior : bsdf->ior;
*eta = CLOSURE_IS_REFRACTIVE(bsdf->type) ? 1.0f / bsdf->ior : bsdf->ior;
break;
}
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID: {
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: {
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
*roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
*eta = bsdf->ior;
break;
}
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID: {
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
*roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
*eta = bsdf->ior;
break;
}
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
*roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
*eta = refractive ? 1.0f / bsdf->ior : bsdf->ior;
} break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: {
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
*roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
@@ -387,6 +413,11 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
*roughness = make_float2(alpha, alpha);
*eta = ((ccl_private PrincipledHairBSDF *)sc)->eta;
break;
case CLOSURE_BSDF_HAIR_MICROFACET_ID:
alpha = ((ccl_private MicrofacetHairBSDF *)sc)->roughness;
*roughness = make_float2(alpha, alpha);
*eta = ((ccl_private MicrofacetHairBSDF *)sc)->eta;
break;
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
*roughness = one_float2();
*eta = 1.0f;
@@ -432,38 +463,26 @@ ccl_device_inline int bsdf_label(const KernelGlobals kg,
case CLOSURE_BSDF_TRANSLUCENT_ID:
label = LABEL_TRANSMIT | LABEL_DIFFUSE;
break;
case CLOSURE_BSDF_REFLECTION_ID:
label = LABEL_REFLECT | LABEL_SINGULAR;
break;
case CLOSURE_BSDF_REFRACTION_ID:
label = LABEL_TRANSMIT | LABEL_SINGULAR;
break;
case CLOSURE_BSDF_TRANSPARENT_ID:
label = LABEL_TRANSMIT | LABEL_TRANSPARENT;
break;
case CLOSURE_BSDF_REFLECTION_ID:
case CLOSURE_BSDF_REFRACTION_ID:
case CLOSURE_BSDF_SHARP_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: {
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
label = (bsdf->alpha_x * bsdf->alpha_y <= 1e-7f) ? LABEL_REFLECT | LABEL_SINGULAR :
LABEL_REFLECT | LABEL_GLOSSY;
break;
}
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: {
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
label = (bsdf->alpha_x * bsdf->alpha_y <= 1e-7f) ? LABEL_TRANSMIT | LABEL_SINGULAR :
LABEL_TRANSMIT | LABEL_GLOSSY;
label = ((bsdf_is_transmission(sc, wo)) ? LABEL_TRANSMIT : LABEL_REFLECT) |
((bsdf->alpha_x * bsdf->alpha_y <= 1e-7f) ? LABEL_SINGULAR : LABEL_GLOSSY);
break;
}
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
label = (bsdf_is_transmission(sc, wo)) ? LABEL_TRANSMIT | LABEL_GLOSSY :
LABEL_REFLECT | LABEL_GLOSSY;
break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
label = LABEL_REFLECT | LABEL_GLOSSY;
break;
@@ -483,6 +502,7 @@ ccl_device_inline int bsdf_label(const KernelGlobals kg,
label = LABEL_TRANSMIT | LABEL_GLOSSY;
break;
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
case CLOSURE_BSDF_HAIR_MICROFACET_ID:
if (bsdf_is_transmission(sc, wo))
label = LABEL_TRANSMIT | LABEL_GLOSSY;
else
@@ -546,31 +566,29 @@ ccl_device_inline
case CLOSURE_BSDF_TRANSLUCENT_ID:
eval = bsdf_translucent_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_REFLECTION_ID:
eval = bsdf_reflection_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_REFRACTION_ID:
eval = bsdf_refraction_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_TRANSPARENT_ID:
eval = bsdf_transparent_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_REFLECTION_ID:
case CLOSURE_BSDF_REFRACTION_ID:
case CLOSURE_BSDF_SHARP_GLASS_ID:
eval = bsdf_microfacet_sharp_eval(sc, sd->N, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
eval = bsdf_microfacet_ggx_eval(sc, sd->N, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
eval = bsdf_microfacet_multi_ggx_eval(sc, sd->N, sd->wi, wo, pdf, &sd->lcg_state);
break;
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
eval = bsdf_microfacet_multi_ggx_glass_eval(sc, sd->wi, wo, pdf, &sd->lcg_state);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID:
eval = bsdf_microfacet_beckmann_eval(sc, sd->N, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
@@ -588,6 +606,9 @@ ccl_device_inline
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
eval = bsdf_principled_hair_eval(kg, sd, sc, wo, pdf);
break;
case CLOSURE_BSDF_HAIR_MICROFACET_ID:
eval = bsdf_microfacet_hair_eval(kg, sd, sc, wo, pdf);
break;
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
eval = bsdf_hair_reflection_eval(sc, sd->wi, wo, pdf);
break;
@@ -634,19 +655,18 @@ ccl_device void bsdf_blur(KernelGlobals kg, ccl_private ShaderClosure *sc, float
#if defined(__SVM__) || defined(__OSL__)
switch (sc->type) {
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
bsdf_microfacet_multi_ggx_blur(sc, roughness);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
bsdf_microfacet_ggx_blur(sc, roughness);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID:
bsdf_microfacet_beckmann_blur(sc, roughness);
break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
@@ -655,6 +675,9 @@ ccl_device void bsdf_blur(KernelGlobals kg, ccl_private ShaderClosure *sc, float
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
bsdf_principled_hair_blur(sc, roughness);
break;
case CLOSURE_BSDF_HAIR_MICROFACET_ID:
bsdf_microfacet_hair_blur(sc, roughness);
break;
default:
break;
}
@@ -675,21 +698,15 @@ ccl_device_inline Spectrum bsdf_albedo(ccl_private const ShaderData *sd,
* TODO(lukas): Consider calling this function to determine the sample_weight? Would be a bit of
* extra overhead though. */
#if defined(__SVM__) || defined(__OSL__)
switch (sc->type) {
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
albedo *= microfacet_fresnel((ccl_private const MicrofacetBsdf *)sc, sd->wi, sc->N);
break;
case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
albedo *= ((ccl_private const PrincipledSheenBsdf *)sc)->avg_value;
break;
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
albedo *= bsdf_principled_hair_albedo(sc);
break;
default:
break;
if (CLOSURE_IS_BSDF_MICROFACET(sc->type)) {
albedo *= microfacet_fresnel((ccl_private const MicrofacetBsdf *)sc, sd->wi, sc->N, false);
}
else if (sc->type == CLOSURE_BSDF_PRINCIPLED_SHEEN_ID) {
albedo *= ((ccl_private const PrincipledSheenBsdf *)sc)->avg_value;
}
else if (sc->type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID ||
sc->type == CLOSURE_BSDF_HAIR_MICROFACET_ID) {
albedo *= bsdf_hair_albedo(sd, sc);
}
#endif
return albedo;

View File

@@ -0,0 +1,887 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2018-2022 Blender Foundation */
/* This code implements the paper [A Microfacet-based Hair Scattering
* Model](https://onlinelibrary.wiley.com/doi/full/10.1111/cgf.14588) by Weizhen Huang, Matthias B.
* Hullin and Johannes Hanika. */
#pragma once
#ifndef __KERNEL_GPU__
# include <fenv.h>
#endif
#include "kernel/util/color.h"
CCL_NAMESPACE_BEGIN
typedef struct MicrofacetHairExtra {
/* TODO: is this necessary? */
float R;
float TT;
float TRT;
/* Geometry data. */
float4 geom;
} MicrofacetHairExtra;
typedef struct MicrofacetHairBSDF {
SHADER_CLOSURE_BASE;
/* Absorption coefficient. */
Spectrum sigma;
/* Microfacet distribution roughness. */
float roughness;
/* Cuticle tilt angle. */
float tilt;
/* IOR. */
float eta;
/* GGX/Beckmann. */
int distribution_type;
/* The ratio of the minor axis to the major axis. */
float aspect_ratio;
/* Extra closure. */
ccl_private MicrofacetHairExtra *extra;
} MicrofacetHairBSDF;
static_assert(sizeof(ShaderClosure) >= sizeof(MicrofacetHairBSDF),
"MicrofacetHairBSDF is too large!");
static_assert(sizeof(ShaderClosure) >= sizeof(MicrofacetHairExtra),
"MicrofacetHairExtra is too large!");
#ifdef __HAIR__
/* Set up the hair closure. */
ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd,
ccl_private MicrofacetHairBSDF *bsdf)
{
bsdf->type = CLOSURE_BSDF_HAIR_MICROFACET_ID;
bsdf->roughness = clamp(bsdf->roughness, 0.001f, 1.0f);
/* Compute local frame. The Y axis is aligned with the curve tangent; the X axis is perpendicular
to the ray direction for circular cross-sections, or aligned with the major axis for elliptical
cross-sections. */
const float3 Y = safe_normalize(sd->dPdu);
const float3 X = safe_normalize(cross(Y, sd->wi));
/* h -1..0..1 means the rays goes from grazing the hair, to hitting it at the center, to grazing
* the other edge. This is the cosine of the angle between sd->N and X. */
const float h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : -dot(X, sd->N);
kernel_assert(fabsf(h) < 1.0f + 1e-4f);
kernel_assert(isfinite_safe(X));
kernel_assert(isfinite_safe(h));
if (bsdf->aspect_ratio != 1.0f) {
if (bsdf->aspect_ratio > 1.0f) {
bsdf->aspect_ratio = 1.0f / bsdf->aspect_ratio;
/* Switch major and minor axis. */
const float3 minor_axis = safe_normalize(cross(
sd->dPdu, make_float3(bsdf->extra->geom.x, bsdf->extra->geom.y, bsdf->extra->geom.z)));
const float3 major_axis = safe_normalize(cross(minor_axis, sd->dPdu));
bsdf->extra->geom = make_float4(major_axis.x, major_axis.y, major_axis.z, h);
}
else {
bsdf->extra->geom.w = h;
}
}
else {
/* Align local frame with the ray direction so that `phi_i == 0`. */
bsdf->extra->geom = make_float4(X.x, X.y, X.z, h);
}
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG | SD_BSDF_HAS_TRANSMISSION;
}
#endif /* __HAIR__ */
/* -------------------------------------------------------------------- */
/** \name Hair coordinate system utils.
* \{ */
/* Returns sin(theta) of the given direction. */
ccl_device_inline float sin_theta(const float3 w)
{
return w.y;
}
/* Returns cos(theta) of the given direction. */
ccl_device_inline float cos_theta(const float3 w)
{
return safe_sqrtf(sqr(w.x) + sqr(w.z));
}
/* Returns tan(theta) of the given direction. */
ccl_device_inline float tan_theta(const float3 w)
{
return sin_theta(w) / cos_theta(w);
}
/* Returns sin(phi) and cos(phi) of the given direction. */
ccl_device float sin_phi(const float3 w)
{
return w.x / cos_theta(w);
}
ccl_device float2 sincos_phi(const float3 w)
{
float c = cos_theta(w);
return make_float2(w.x / c, w.z / c);
}
/* Extract the theta coordinate from the given direction.
* -pi < theta < pi */
ccl_device_inline float dir_theta(const float3 w)
{
return atan2f(sin_theta(w), cos_theta(w));
}
/* Extract the phi coordinate from the given direction, assuming phi(wi) = 0.
* -pi < phi < pi */
ccl_device_inline float dir_phi(const float3 w)
{
return atan2f(w.x, w.z);
}
/* Extract theta and phi coordinates from the given direction, assuming phi(wi) = 0.
* -pi/2 < theta < pi/2, -pi < phi < pi */
ccl_device_inline float2 dir_sph(const float3 w)
{
return make_float2(dir_theta(w), dir_phi(w));
}
/* Conversion between gamma and phi. Notations see Figure 5 in the paper. */
ccl_device_inline float to_phi(float gamma, float b)
{
if (b == 1.0f) {
return gamma;
}
float sin_gamma, cos_gamma;
fast_sincosf(gamma, &sin_gamma, &cos_gamma);
return atan2f(b * sin_gamma, cos_gamma);
}
ccl_device_inline float to_gamma(float phi, float b)
{
if (b == 1.0f) {
return phi;
}
float sin_phi, cos_phi;
fast_sincosf(phi, &sin_phi, &cos_phi);
return atan2f(sin_phi, b * cos_phi);
}
/* Compute the coordinate on the ellipse, given gamma and the aspect ratio between the minor axis
* and the major axis. */
ccl_device_inline float2 to_point(float gamma, float b)
{
float sin_gamma, cos_gamma;
fast_sincosf(gamma, &sin_gamma, &cos_gamma);
return make_float2(sin_gamma, b * cos_gamma);
}
/* Compute the vector direction given by theta and gamma. */
ccl_device_inline float3 sphg_dir(float theta, float gamma, float b)
{
float sin_theta, cos_theta, sin_gamma, cos_gamma, sin_phi, cos_phi;
fast_sincosf(theta, &sin_theta, &cos_theta);
fast_sincosf(gamma, &sin_gamma, &cos_gamma);
if (b == 1.0f) {
sin_phi = sin_gamma;
cos_phi = cos_gamma;
}
else {
float tan_gamma = sin_gamma / cos_gamma;
float tan_phi = b * tan_gamma;
cos_phi = signf(cos_gamma) / sqrtf(sqr(tan_phi) + 1.0f);
sin_phi = cos_phi * tan_phi;
}
return make_float3(sin_phi * cos_theta, sin_theta, cos_phi * cos_theta);
}
ccl_device_inline float arc_length(float e2, float gamma)
{
return e2 == 0 ? 1.0f : sqrtf(1.0f - e2 * sqr(sinf(gamma)));
}
ccl_device_inline float projected_radius(float e2, float phi)
{
return e2 == 0 ? 1.0f : sqrtf(1.0f - e2 * sqr(sinf(phi)));
}
/** \} */
/* Sample microfacets from a tilted mesonormal. */
template<MicrofacetType m_type>
ccl_device_inline float3 sample_wh(
KernelGlobals kg, const float roughness, const float3 wi, const float3 wm, const float2 rand)
{
/* Coordinate transformation for microfacet sampling. */
float3 s, t;
const float3 n = wm;
make_orthonormals(n, &s, &t);
const float3 wi_wm = make_float3(dot(wi, s), dot(wi, t), dot(wi, n));
const float3 wh_wm =
(m_type == MicrofacetType::GGX) ?
microfacet_ggx_sample_vndf(wi_wm, roughness, roughness, rand.x, rand.y) :
microfacet_beckmann_sample_vndf(wi_wm, roughness, roughness, rand.x, rand.y);
const float3 wh = wh_wm.x * s + wh_wm.y * t + wh_wm.z * n;
return wh;
}
/* Check micronormal/mesonormal direct visiblity from direction v. */
ccl_device_inline bool microfacet_visible(const float3 v, const float3 m, const float3 h)
{
return (dot(v, h) > 0.0f && dot(v, m) > 0.0f);
}
/* Check micronormal/mesonormal direct visiblity from directinos wi and wo. */
ccl_device_inline bool microfacet_visible(const float3 wi,
const float3 wo,
const float3 m,
const float3 h)
{
return microfacet_visible(wi, m, h) && microfacet_visible(wo, m, h);
}
/* Compute fresnel reflection. Also return the dot product of the refracted ray and the normal as
* `cos_theta_t`, as it is used when computing the direction of the refracted ray. */
ccl_device float fresnel(float cos_theta_i, float eta, ccl_private float *cos_theta_t)
{
kernel_assert(!isnan_safe(cos_theta_i));
/* Special cases. */
if (eta == 1.0f) {
return 0.0f;
}
if (cos_theta_i == 0.0f) {
return 1.0f;
}
cos_theta_i = fabsf(cos_theta_i);
/* Using Snell's law, calculate the squared cosine of the angle between the surface normal and
* the transmitted ray. */
const float cos_theta_t_sqr = 1.0f - (1.0f - cos_theta_i * cos_theta_i) / (eta * eta);
*cos_theta_t = safe_sqrtf(cos_theta_t_sqr);
if (cos_theta_t_sqr <= 0) {
/* Total internal reflection. */
return 1.0f;
}
/* Amplitudes of reflected waves. */
const float a_s = (cos_theta_i - eta * (*cos_theta_t)) / (cos_theta_i + eta * (*cos_theta_t));
const float a_p = (*cos_theta_t - eta * cos_theta_i) / (*cos_theta_t + eta * cos_theta_i);
/* Adjust the sign of the transmitted direction to be relative to the surface normal. */
*cos_theta_t = -(*cos_theta_t);
return 0.5f * (sqr(a_s) + sqr(a_p));
}
/* Refract the incident ray, given the cosine of the refraction angle and the inverse IOR. */
ccl_device_inline float3 refract_angle(const float3 incident,
const float3 normal,
const float cos_theta_t,
const float inv_eta)
{
return inv_eta * incident - (inv_eta * dot(normal, incident) + cos_theta_t) * normal;
}
template<MicrofacetType m_type>
ccl_device float3 bsdf_microfacet_hair_eval_r(ccl_private const ShaderClosure *sc,
const float3 wi,
const float3 wo)
{
ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc;
const float tilt = -bsdf->tilt;
const float roughness = bsdf->roughness;
const float roughness2 = sqr(roughness);
const float eta = bsdf->eta;
if (bsdf->extra->R <= 0.0f) {
return zero_float3();
}
/* Get elliptical cross section characteristic. Assuming major axis is 1. */
const float b = bsdf->aspect_ratio;
const float e2 = 1.0f - sqr(b); /* Squared Eccentricity. */
const bool is_circular = (b == 1.0f);
const float phi_i = is_circular ? 0.0f : dir_phi(wi);
const float phi_o = dir_phi(wo);
const float3 wh = normalize(wi + wo);
/* dot(wi, wmi) > 0 */
const float tan_tilt = tanf(tilt);
float phi_m_max1 = acosf(fmaxf(-tan_tilt * tan_theta(wi), 0.0f)) + phi_i;
if (isnan_safe(phi_m_max1)) {
return zero_float3();
}
float phi_m_min1 = -phi_m_max1 + 2.0f * phi_i;
/* dot(wo, wmi) > 0 */
float phi_m_max2 = acosf(fmaxf(-tan_tilt * tan_theta(wo), 0.0f)) + phi_o;
if (isnan_safe(phi_m_max2)) {
return zero_float3();
}
float phi_m_min2 = -phi_m_max2 + 2.0f * phi_o;
if (!is_circular) {
/* Try to wrap range. */
if ((phi_m_max2 - phi_m_min1) > M_2PI_F) {
phi_m_min2 -= M_2PI_F;
phi_m_max2 -= M_2PI_F;
}
if ((phi_m_max1 - phi_m_min2) > M_2PI_F) {
phi_m_min1 -= M_2PI_F;
phi_m_max1 -= M_2PI_F;
}
}
const float phi_m_min = fmaxf(phi_m_min1, phi_m_min2) + 1e-3f;
const float phi_m_max = fminf(phi_m_max1, phi_m_max2) - 1e-3f;
if (phi_m_min > phi_m_max) {
return zero_float3();
}
const float gamma_m_min = to_gamma(phi_m_min, b);
float gamma_m_max = to_gamma(phi_m_max, b);
if (gamma_m_max < gamma_m_min) {
gamma_m_max += M_2PI_F;
}
/* Maximal sample resolution. */
float res = roughness * 0.7f;
/* Number of intervals should be even. */
const size_t intervals = 2 * (size_t)ceilf((gamma_m_max - gamma_m_min) / res * 0.5f);
/* Modified resolution based on numbers of intervals. */
res = (gamma_m_max - gamma_m_min) / float(intervals);
/* Integrate using Composite Simpson's 1/3 rule. */
float integral = 0.0f;
for (size_t i = 0; i <= intervals; i++) {
const float gamma_m = gamma_m_min + i * res;
const float3 wm = sphg_dir(tilt, gamma_m, b);
if (microfacet_visible(wi, wo, make_float3(wm.x, 0.0f, wm.z), wh)) {
const float weight = (i == 0 || i == intervals) ? 0.5f : (i % 2 + 1);
/* NOTE: using separable masking and shadowing as one factor cancels out in `sample()`. */
const float G = bsdf_G<m_type>(roughness2, dot(wm, wi)) *
bsdf_G<m_type>(roughness2, dot(wm, wo));
integral += weight * bsdf_D<m_type>(roughness2, dot(wm, wh)) * G * arc_length(e2, gamma_m);
}
}
integral *= (2.0f / 3.0f * res);
const float F = fresnel_dielectric_cos(dot(wi, wh), eta);
return make_float3(bsdf->extra->R * 0.125f * F * integral / projected_radius(e2, phi_i));
}
template<MicrofacetType m_type>
ccl_device float3 bsdf_microfacet_hair_eval_tt_trt(KernelGlobals kg,
ccl_private const ShaderClosure *sc,
const float3 wi,
const float3 wo,
uint rng_quadrature)
{
ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc;
const float tilt = -bsdf->tilt;
const float roughness = bsdf->roughness;
const float roughness2 = sqr(roughness);
const float eta = bsdf->eta;
if (bsdf->extra->TT <= 0.0f && bsdf->extra->TRT <= 0.0f) {
return zero_float3();
}
/* Get elliptical cross section characteristic. Assuming major axis is 1. */
const float b = bsdf->aspect_ratio;
const float e2 = 1.0f - sqr(b); /* Squared Eccentricity. */
const bool is_circular = (b == 1.0f);
const float phi_i = is_circular ? 0.0f : dir_phi(wi);
const float tan_tilt = tanf(tilt);
const float phi_m_max = acosf(fmaxf(-tan_tilt * tan_theta(wi), 0.0f)) + phi_i;
if (isnan_safe(phi_m_max)) {
/* Early detection of dot(wi, wmi) < 0. */
return zero_float3();
}
const float phi_m_min = -phi_m_max + 2.0f * phi_i;
if (tan_tilt * tan_theta(wo) < -1.0f) {
/* Early detection of dot(wo, wmo) < 0. */
return zero_float3();
}
const float3 mu_a = bsdf->sigma;
const float inv_eta = 1.0f / eta;
const float gamma_m_min = to_gamma(phi_m_min, b) + 1e-3f;
float gamma_m_max = to_gamma(phi_m_max, b) - 1e-3f;
if (gamma_m_max < gamma_m_min) {
gamma_m_max += M_2PI_F;
}
float res = roughness * 0.8f;
const size_t intervals = 2 * (size_t)ceilf((gamma_m_max - gamma_m_min) / res * 0.5f);
res = (gamma_m_max - gamma_m_min) / intervals;
float3 S_tt = zero_float3();
float3 S_trt = zero_float3();
for (size_t i = 0; i <= intervals; i++) {
const float gamma_mi = gamma_m_min + i * res;
const float3 wmi = sphg_dir(tilt, gamma_mi, b);
const float3 wmi_ = sphg_dir(0.0f, gamma_mi, b);
/* Sample wh1. */
const float2 sample1 = make_float2(lcg_step_float(&rng_quadrature),
lcg_step_float(&rng_quadrature));
const float3 wh1 = sample_wh<m_type>(kg, roughness, wi, wmi, sample1);
const float cos_hi1 = dot(wi, wh1);
if (!(cos_hi1 > 0)) {
continue;
}
float cos_theta_t1;
const float T1 = 1.0f - fresnel(cos_hi1, eta, &cos_theta_t1);
/* Refraction at the first interface. */
const float3 wt = -refract_angle(wi, wh1, cos_theta_t1, inv_eta);
const float phi_t = dir_phi(wt);
const float gamma_mt = 2.0f * to_phi(phi_t, b) - gamma_mi;
const float3 wmt = sphg_dir(-tilt, gamma_mt, b);
const float3 wmt_ = sphg_dir(0.0f, gamma_mt, b);
const float cos_mi1 = dot(wi, wmi);
const float cos_mo1 = dot(-wt, wmi);
const float cos_mi2 = dot(-wt, wmt);
const float G1o = bsdf_G<m_type>(roughness2, cos_mo1);
if (!microfacet_visible(wi, -wt, wmi, wh1) || !microfacet_visible(wi, -wt, wmi_, wh1)) {
continue;
}
const float weight = (i == 0 || i == intervals) ? 0.5f : (i % 2 + 1);
const float3 A_t = exp(mu_a / cos_theta(wt) *
(is_circular ?
2.0f * cosf(gamma_mi - phi_t) :
-len(to_point(gamma_mi, b) - to_point(gamma_mt + M_PI_F, b))));
/* TT */
if (bsdf->extra->TT > 0.0f) {
if (dot(wo, wt) >= inv_eta - 1e-5f) { /* Total internal reflection otherwise. */
float3 wh2 = -wt + inv_eta * wo;
const float rcp_norm_wh2 = 1.0f / len(wh2);
wh2 *= rcp_norm_wh2;
const float cos_mh2 = dot(wmt, wh2);
if (cos_mh2 >= 0.0f) { /* Microfacet visiblity from macronormal. */
const float cos_hi2 = dot(-wt, wh2);
const float cos_ho2 = dot(-wo, wh2);
const float cos_mo2 = dot(-wo, wmt);
const float T2 = 1.0f - fresnel_dielectric_cos(cos_hi2, inv_eta);
const float D2 = bsdf_D<m_type>(roughness2, cos_mh2);
const float G2 = bsdf_G<m_type>(roughness2, cos_mi2) *
bsdf_G<m_type>(roughness2, cos_mo2);
const float3 result = weight * T1 * T2 * D2 * G1o * G2 * A_t / cos_mo1 * cos_mi1 *
cos_hi2 * cos_ho2 * sqr(rcp_norm_wh2);
if (isfinite_safe(result)) {
S_tt += bsdf->extra->TT * result * arc_length(e2, gamma_mt);
}
}
}
}
/* TRT */
if (bsdf->extra->TRT > 0.0f) {
/* Sample wh2. */
const float2 sample2 = make_float2(lcg_step_float(&rng_quadrature),
lcg_step_float(&rng_quadrature));
const float3 wh2 = sample_wh<m_type>(kg, roughness, -wt, wmt, sample2);
const float cos_hi2 = dot(-wt, wh2);
if (!(cos_hi2 > 0)) {
continue;
}
const float R2 = fresnel_dielectric_cos(cos_hi2, inv_eta);
const float3 wtr = -reflect(wt, wh2);
if (dot(-wtr, wo) < inv_eta - 1e-5f) {
/* Total internal reflection. */
continue;
}
if (!microfacet_visible(-wt, -wtr, wmt, wh2) || !microfacet_visible(-wt, -wtr, wmt_, wh2)) {
continue;
}
const float phi_tr = dir_phi(wtr);
const float gamma_mtr = gamma_mi - 2.0f * (to_phi(phi_t, b) - to_phi(phi_tr, b)) + M_PI_F;
const float3 wmtr = sphg_dir(-tilt, gamma_mtr, b);
const float3 wmtr_ = sphg_dir(0.0f, gamma_mtr, b);
float3 wh3 = wtr + inv_eta * wo;
const float rcp_norm_wh3 = 1.0f / len(wh3);
wh3 *= rcp_norm_wh3;
const float cos_mh3 = dot(wmtr, wh3);
if (cos_mh3 < 0.0f || !microfacet_visible(wtr, -wo, wmtr, wh3) ||
!microfacet_visible(wtr, -wo, wmtr_, wh3)) {
continue;
}
const float cos_hi3 = dot(wh3, wtr);
const float cos_ho3 = dot(wh3, -wo);
const float T3 = 1.0f - fresnel_dielectric_cos(cos_hi3, inv_eta);
const float D3 = bsdf_D<m_type>(roughness2, cos_mh3);
const float3 A_tr = exp(mu_a / cos_theta(wtr) *
(is_circular ?
2.0f * cosf(phi_tr - gamma_mt) :
-len(to_point(gamma_mtr, b) - to_point(gamma_mt, b))));
const float cos_mo2 = dot(wmt, -wtr);
const float G2o = bsdf_G<m_type>(roughness2, cos_mo2);
const float G3 = bsdf_G<m_type>(roughness2, dot(wmtr, wtr)) *
bsdf_G<m_type>(roughness2, dot(wmtr, -wo));
const float3 result = weight * T1 * R2 * T3 * D3 * G1o * G2o * G3 * A_t * A_tr /
(cos_mo1 * cos_mo2) * cos_mi1 * cos_mi2 * cos_hi3 * cos_ho3 *
sqr(rcp_norm_wh3);
if (isfinite_safe(result)) {
S_trt += bsdf->extra->TRT * result * arc_length(e2, gamma_mtr);
}
}
}
return (S_tt + S_trt) / 3.0f * res * sqr(inv_eta) * projected_radius(e2, phi_i);
}
template<MicrofacetType m_type>
ccl_device int bsdf_microfacet_hair_sample(const KernelGlobals kg,
ccl_private const ShaderClosure *sc,
ccl_private ShaderData *sd,
float3 rand,
ccl_private Spectrum *eval,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float2 *sampled_roughness,
ccl_private float *eta)
{
ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc;
*sampled_roughness = make_float2(bsdf->roughness, bsdf->roughness);
*eta = bsdf->eta;
const float inv_eta = 1.0f / *eta;
if (bsdf->extra->R <= 0.0f && bsdf->extra->TT <= 0.0f && bsdf->extra->TRT <= 0.0f) {
/* Early out for inactive lobe. */
*pdf = 0.0f;
return LABEL_NONE;
}
/* Get local coordinate system:
* . X major axis.
* . Y along the fiber tangent.
* . Z minor axis. */
const float3 X = float4_to_float3(bsdf->extra->geom);
const float3 Z = safe_normalize(cross(X, sd->dPdu));
const float3 Y = safe_normalize(cross(Z, X));
/* Transform wi from global coordinate system to local. */
const float3 wi = make_float3(dot(sd->wi, X), dot(sd->wi, Y), dot(sd->wi, Z));
/* Get elliptical cross section characteristic. Assuming major axis is 1. */
const float b = bsdf->aspect_ratio;
const float e2 = 1.0f - sqr(b); /* Squared Eccentricity. */
const bool is_circular = (b == 1.0f);
/* Macronormal. */
const float2 sincos_phi_i = sincos_phi(wi);
const float sin_phi_i = sincos_phi_i.x;
const float cos_phi_i = sincos_phi_i.y;
const float d_i = projected_radius(e2, sin_phi_i);
/* Treat as transparent material if intersection lies outside of the projected radius. */
if (fabsf(bsdf->extra->geom.w) > d_i) {
*wo = -sd->wi;
*pdf = 1;
*eval = one_spectrum();
return LABEL_TRANSMIT | LABEL_TRANSPARENT;
}
const float tilt = -bsdf->tilt;
const float roughness = bsdf->roughness;
const float roughness2 = sqr(roughness);
/* Generate samples. */
float sample_lobe = rand.x;
const float sample_h = rand.y;
const float2 sample_h1 = make_float2(rand.z, lcg_step_float(&sd->lcg_state));
const float2 sample_h2 = make_float2(lcg_step_float(&sd->lcg_state),
lcg_step_float(&sd->lcg_state));
const float2 sample_h3 = make_float2(lcg_step_float(&sd->lcg_state),
lcg_step_float(&sd->lcg_state));
const float h = sample_h * 2.0f - 1.0f;
const float gamma_mi = is_circular ?
asinf(h) :
atan2f(cos_phi_i, -b * sin_phi_i) -
acosf(h * d_i / sqrtf(sqr(cos_phi_i) + sqr(b * sin_phi_i)));
const float3 wmi_ = sphg_dir(0, gamma_mi, b); /* Macronormal. */
/* Mesonormal. */
float st, ct;
fast_sincosf(tilt, &st, &ct);
const float3 wmi = make_float3(wmi_.x * ct, st, wmi_.z * ct);
if (dot(wmi, wi) < 0.0f || dot(wmi_, wi) < 0.0f) {
/* Macro/mesonormal invisible. */
*pdf = 0.0f;
return LABEL_NONE;
}
/* Sample R lobe. */
const float3 wh1 = sample_wh<m_type>(kg, roughness, wi, wmi, sample_h1);
const float3 wr = -reflect(wi, wh1);
/* Ensure that this is a valid sample. */
if (!(dot(wr, wh1) > 0.0f) || !(dot(wr, wmi) > 0.0f) || !microfacet_visible(wi, wr, wmi_, wh1)) {
*pdf = 0.0f;
return LABEL_NONE;
}
float cos_theta_t1;
const float R1 = fresnel(dot(wi, wh1), *eta, &cos_theta_t1);
const float3 R = make_float3(bsdf->extra->R * R1);
/* Sample TT lobe. */
const float3 wt = -refract_angle(wi, wh1, cos_theta_t1, inv_eta);
const float phi_t = dir_phi(wt);
const float gamma_mt = 2.0f * to_phi(phi_t, b) - gamma_mi;
const float3 wmt = sphg_dir(-tilt, gamma_mt, b);
const float3 wmt_ = sphg_dir(0.0f, gamma_mt, b);
const float3 wh2 = sample_wh<m_type>(kg, roughness, -wt, wmt, sample_h2);
const float3 wtr = -reflect(wt, wh2);
float3 wh3;
float3 wtt, wtrt;
float3 wmtr, wmtr_;
float3 TT = zero_float3();
float3 TRT = zero_float3();
if (dot(wh2, -wt) > 0.0f && dot(wmt, -wt) > 0.0f && microfacet_visible(-wt, -wtr, wmt_, wh2)) {
const float3 mu_a = bsdf->sigma;
const float3 A_t = exp(mu_a / cos_theta(wt) *
(is_circular ?
2.0f * cosf(phi_t - gamma_mi) :
-len(to_point(gamma_mi, b) - to_point(gamma_mt + M_PI_F, b))));
float cos_theta_t2;
const float R2 = fresnel(dot(-wt, wh2), inv_eta, &cos_theta_t2);
const float3 T1 = make_float3(1.0f - R1);
const float3 T2 = make_float3(1.0f - R2);
wtt = -refract_angle(-wt, wh2, cos_theta_t2, *eta);
if (dot(wmt, -wtt) > 0.0f && cos_theta_t2 != 0.0f) {
TT = bsdf->extra->TT * T1 * A_t * T2;
}
/* Sample TRT lobe. */
const float phi_tr = dir_phi(wtr);
const float gamma_mtr = gamma_mi - 2.0f * (to_phi(phi_t, b) - to_phi(phi_tr, b)) + M_PI_F;
wmtr = sphg_dir(-tilt, gamma_mtr, b);
wh3 = sample_wh<m_type>(kg, roughness, wtr, wmtr, sample_h3);
float cos_theta_t3;
const float R3 = fresnel(dot(wtr, wh3), inv_eta, &cos_theta_t3);
wtrt = -refract_angle(wtr, wh3, cos_theta_t3, *eta);
if (cos_theta_t3 != 0.0f && dot(wtr, wh3) > 0.0f && dot(wmtr, wtr) > 0.0f &&
dot(wmtr, -wtrt) > 0.0f &&
microfacet_visible(wtr, -wtrt, make_float3(wmtr.x, 0.0f, wmtr.z), wh3)) {
const float3 T3 = make_float3(1.0f - R3);
const float3 A_tr = exp(mu_a / cos_theta(wtr) *
(is_circular ?
2.0f * cos(phi_tr - gamma_mt) :
-len(to_point(gamma_mt, b) - to_point(gamma_mtr, b))));
TRT = bsdf->extra->TRT * T1 * R2 * T3 * A_t * A_tr;
}
}
/* Select lobe based on energy. */
const float r = average(R);
const float tt = average(TT);
const float trt = average(TRT);
const float total_energy = r + tt + trt;
if (total_energy == 0.0f) {
*pdf = 0.0f;
return LABEL_NONE;
}
float3 local_O;
float visibility = 0.0f;
int label = LABEL_GLOSSY;
sample_lobe *= total_energy;
if (sample_lobe < r) {
local_O = wr;
*eval = rgb_to_spectrum(R / r * total_energy);
if (microfacet_visible(wi, wr, wmi_, wh1)) {
visibility = bsdf_G<m_type>(roughness2, dot(wmi, wr));
}
label |= LABEL_REFLECT;
}
else if (sample_lobe < (r + tt)) {
local_O = wtt;
*eval = rgb_to_spectrum(TT / tt * total_energy);
if (microfacet_visible(wi, -wt, wmi_, wh1) && microfacet_visible(-wt, -wtt, wmt_, wh2)) {
visibility = bsdf_G<m_type>(roughness2, dot(wmi, -wt)) *
bsdf_G<m_type>(roughness2, dot(wmt, -wtt));
}
label |= LABEL_TRANSMIT;
}
else { /* if (sample_lobe >= (r + tt)) */
local_O = wtrt;
*eval = rgb_to_spectrum(TRT / trt * total_energy);
if (microfacet_visible(wi, -wt, wmi_, wh1)) {
visibility = bsdf_G<m_type>(roughness2, dot(wmi, -wt)) *
bsdf_G<m_type>(roughness2, dot(wmt, -wtr)) *
bsdf_G<m_type>(roughness2, dot(wmtr, -wtrt));
}
label |= LABEL_TRANSMIT;
}
*eval *= visibility;
*wo = local_O.x * X + local_O.y * Y + local_O.z * Z;
/* Ensure the same pdf is returned for BSDF and emitter sampling. The importance sampling pdf is
* already factored in the value so this value is only used for MIS. */
*pdf = 1.0f;
return label;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// main sample and eval functions selecting model
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ccl_device Spectrum bsdf_microfacet_hair_eval(KernelGlobals kg,
ccl_private const ShaderData *sd,
ccl_private const ShaderClosure *sc,
const float3 wo,
ccl_private float *pdf)
{
ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc;
/* Get local coordinate system:
* . X major axis.
* . Y along the fiber tangent.
* . Z minor axis. */
const float3 X = float4_to_float3(bsdf->extra->geom);
const float3 Z = safe_normalize(cross(X, sd->dPdu));
const float3 Y = safe_normalize(cross(Z, X));
/* Transform wi/wo from global coordinate system to local. */
const float3 local_I = make_float3(dot(sd->wi, X), dot(sd->wi, Y), dot(sd->wi, Z));
const float3 local_O = make_float3(dot(wo, X), dot(wo, Y), dot(wo, Z));
/* Treat as transparent material if intersection lies outside of the projected radius. */
const float e2 = 1.0f - sqr(bsdf->aspect_ratio);
if (fabsf(bsdf->extra->geom.w) > projected_radius(e2, dir_phi(local_I))) {
*pdf = 0.0f;
return zero_spectrum();
}
/* Evaluate. */
float3 R;
if (bsdf->distribution_type == NODE_MICROFACET_HAIR_BECKMANN) {
R = bsdf_microfacet_hair_eval_r<MicrofacetType::BECKMANN>(sc, local_I, local_O) +
bsdf_microfacet_hair_eval_tt_trt<MicrofacetType::BECKMANN>(
kg, sc, local_I, local_O, sd->lcg_state);
}
else {
R = bsdf_microfacet_hair_eval_r<MicrofacetType::GGX>(sc, local_I, local_O) +
bsdf_microfacet_hair_eval_tt_trt<MicrofacetType::GGX>(
kg, sc, local_I, local_O, sd->lcg_state);
}
/* TODO: better estimation of the pdf */
*pdf = 1.0f;
return rgb_to_spectrum(R / cos_theta(local_I));
}
ccl_device int bsdf_microfacet_hair_sample(KernelGlobals kg,
ccl_private const ShaderClosure *sc,
ccl_private ShaderData *sd,
float3 rand,
ccl_private Spectrum *eval,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float2 *sampled_roughness,
ccl_private float *eta)
{
ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc;
if (bsdf->distribution_type == NODE_MICROFACET_HAIR_BECKMANN) {
return bsdf_microfacet_hair_sample<MicrofacetType::BECKMANN>(
kg, sc, sd, rand, eval, wo, pdf, sampled_roughness, eta);
}
return bsdf_microfacet_hair_sample<MicrofacetType::GGX>(
kg, sc, sd, rand, eval, wo, pdf, sampled_roughness, eta);
}
/* Implements Filter Glossy by capping the effective roughness. */
ccl_device void bsdf_microfacet_hair_blur(ccl_private ShaderClosure *sc, float roughness)
{
ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc;
bsdf->roughness = fmaxf(roughness, bsdf->roughness);
}
/* Hair Albedo. */
ccl_device float3 bsdf_microfacet_hair_albedo(ccl_private const ShaderClosure *sc)
{
ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc;
return exp(-sqrt(bsdf->sigma) * bsdf_hair_albedo_roughness_scale(bsdf->roughness));
}
CCL_NAMESPACE_END

View File

@@ -338,6 +338,7 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
ccl_private ShaderData *sd,
float randu,
float randv,
float randw,
ccl_private Spectrum *eval,
ccl_private float3 *wo,
ccl_private float *pdf,
@@ -357,11 +358,6 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
const float3 local_O = make_float3(dot(sd->wi, X), dot(sd->wi, Y), dot(sd->wi, Z));
float2 u[2];
u[0] = make_float2(randu, randv);
u[1].x = lcg_step_float(&sd->lcg_state);
u[1].y = lcg_step_float(&sd->lcg_state);
const float sin_theta_o = local_O.x;
const float cos_theta_o = cos_from_sin(sin_theta_o);
const float phi_o = atan2f(local_O.z, local_O.y);
@@ -385,11 +381,12 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
int p = 0;
for (; p < 3; p++) {
if (u[0].x < Ap_energy[p]) {
if (randw < Ap_energy[p]) {
break;
}
u[0].x -= Ap_energy[p];
randw -= Ap_energy[p];
}
randw /= Ap_energy[p];
float v = bsdf->v;
if (p == 1) {
@@ -399,10 +396,9 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
v *= 4.0f;
}
u[1].x = max(u[1].x, 1e-5f);
const float fac = 1.0f + v * logf(u[1].x + (1.0f - u[1].x) * expf(-2.0f / v));
float sin_theta_i = -fac * sin_theta_o +
cos_from_sin(fac) * cosf(M_2PI_F * u[1].y) * cos_theta_o;
randw = max(randw, 1e-5f);
const float fac = 1.0f + v * logf(randw + (1.0f - randw) * expf(-2.0f / v));
float sin_theta_i = -fac * sin_theta_o + cos_from_sin(fac) * cosf(M_2PI_F * randv) * cos_theta_o;
float cos_theta_i = cos_from_sin(sin_theta_i);
float angles[6];
@@ -414,10 +410,10 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
float phi;
if (p < 3) {
phi = delta_phi(p, gamma_o, gamma_t) + sample_trimmed_logistic(u[0].y, bsdf->s);
phi = delta_phi(p, gamma_o, gamma_t) + sample_trimmed_logistic(randu, bsdf->s);
}
else {
phi = M_2PI_F * u[0].y;
phi = M_2PI_F * randu;
}
const float phi_i = phi_o + phi;
@@ -469,31 +465,36 @@ ccl_device void bsdf_principled_hair_blur(ccl_private ShaderClosure *sc, float r
bsdf->m0_roughness = fmaxf(roughness, bsdf->m0_roughness);
}
/* Hair Albedo */
ccl_device_inline float bsdf_principled_hair_albedo_roughness_scale(
const float azimuthal_roughness)
/* Hair Albedo. Also used by `bsdf_hair_microfacet.h` */
ccl_device_inline float bsdf_hair_albedo_roughness_scale(const float azimuthal_roughness)
{
const float x = azimuthal_roughness;
return (((((0.245f * x) + 5.574f) * x - 10.73f) * x + 2.532f) * x - 0.215f) * x + 5.969f;
}
ccl_device Spectrum bsdf_principled_hair_albedo(ccl_private const ShaderClosure *sc)
ccl_device Spectrum bsdf_hair_albedo(ccl_private const ShaderData *sd,
ccl_private const ShaderClosure *sc)
{
ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)sc;
return exp(-sqrt(bsdf->sigma) * bsdf_principled_hair_albedo_roughness_scale(bsdf->v));
const float cos_theta_o = cos_from_sin(dot(sd->wi, safe_normalize(sd->dPdu)));
const float cos_gamma_o = cos_from_sin(bsdf->extra->geom.w);
const float f = fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta);
const float roughness_scale = bsdf_hair_albedo_roughness_scale(bsdf->v);
/* TODO(lukas): Adding the Fresnel term here as a workaround until the proper refactor. */
return exp(-sqrt(bsdf->sigma) * roughness_scale) + make_spectrum(f);
}
ccl_device_inline Spectrum
bsdf_principled_hair_sigma_from_reflectance(const Spectrum color, const float azimuthal_roughness)
ccl_device_inline Spectrum bsdf_hair_sigma_from_reflectance(const Spectrum color,
const float azimuthal_roughness)
{
const Spectrum sigma = log(color) /
bsdf_principled_hair_albedo_roughness_scale(azimuthal_roughness);
const Spectrum sigma = log(color) / bsdf_hair_albedo_roughness_scale(azimuthal_roughness);
return sigma * sigma;
}
ccl_device_inline Spectrum bsdf_principled_hair_sigma_from_concentration(const float eumelanin,
const float pheomelanin)
ccl_device_inline Spectrum bsdf_hair_sigma_from_concentration(const float eumelanin,
const float pheomelanin)
{
const float3 eumelanin_color = make_float3(0.506f, 0.841f, 1.653f);
const float3 pheomelanin_color = make_float3(0.343f, 0.733f, 1.924f);

View File

@@ -17,19 +17,52 @@
CCL_NAMESPACE_BEGIN
enum MicrofacetType {
GGX = 0,
BECKMANN,
GGX,
SHARP,
};
typedef struct MicrofacetExtra {
Spectrum color, cspec0;
} MicrofacetExtra;
enum MicrofacetFresnel {
NONE = 0,
DIELECTRIC,
DIELECTRIC_TINT, /* used by the OSL MaterialX closures */
CONDUCTOR,
GENERALIZED_SCHLICK,
CONSTANT, /* only needed by MultiGGX */
PRINCIPLED_V1,
};
typedef struct FresnelPrincipledV1 {
Spectrum color; /* only needed by MultiGGX */
Spectrum cspec0;
} FresnelPrincipledV1;
typedef struct FresnelConstant {
Spectrum color;
} FresnelConstant;
typedef struct FresnelDielectricTint {
Spectrum reflection_tint;
Spectrum transmission_tint;
} FresnelDielectricTint;
typedef struct FresnelConductor {
Spectrum n, k;
} FresnelConductor;
typedef struct FresnelGeneralizedSchlick {
Spectrum reflection_tint;
Spectrum transmission_tint;
Spectrum f0, f90;
float exponent;
} FresnelGeneralizedSchlick;
typedef struct MicrofacetBsdf {
SHADER_CLOSURE_BASE;
float alpha_x, alpha_y, ior;
ccl_private MicrofacetExtra *extra;
int fresnel_type;
ccl_private void *fresnel;
float3 T;
} MicrofacetBsdf;
@@ -183,14 +216,57 @@ ccl_device_forceinline float3 microfacet_ggx_sample_vndf(const float3 wi,
* Else it is simply white
*/
ccl_device_forceinline Spectrum microfacet_fresnel(ccl_private const MicrofacetBsdf *bsdf,
float3 wi,
float3 H)
const float3 wi,
const float3 H,
const bool refraction)
{
if (CLOSURE_IS_BSDF_MICROFACET_FRESNEL(bsdf->type)) {
return interpolate_fresnel_color(wi, H, bsdf->ior, bsdf->extra->cspec0);
if (bsdf->fresnel_type == MicrofacetFresnel::PRINCIPLED_V1) {
kernel_assert(!refraction);
ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)bsdf->fresnel;
return interpolate_fresnel_color(wi, H, bsdf->ior, fresnel->cspec0);
}
else if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
return make_spectrum(fresnel_dielectric_cos(dot(wi, H), bsdf->ior));
else if (bsdf->fresnel_type == MicrofacetFresnel::DIELECTRIC) {
const float F = fresnel_dielectric_cos(dot(wi, H), bsdf->ior);
return make_spectrum(refraction ? 1.0f - F : F);
}
else if (bsdf->fresnel_type == MicrofacetFresnel::DIELECTRIC_TINT) {
ccl_private FresnelDielectricTint *fresnel = (ccl_private FresnelDielectricTint *)
bsdf->fresnel;
const float F = fresnel_dielectric_cos(dot(wi, H), bsdf->ior);
return refraction ? (1.0f - F) * fresnel->transmission_tint : F * fresnel->reflection_tint;
}
else if (bsdf->fresnel_type == MicrofacetFresnel::CONDUCTOR) {
kernel_assert(!refraction);
ccl_private FresnelConductor *fresnel = (ccl_private FresnelConductor *)bsdf->fresnel;
return fresnel_conductor(dot(wi, H), fresnel->n, fresnel->k);
}
else if (bsdf->fresnel_type == MicrofacetFresnel::GENERALIZED_SCHLICK) {
ccl_private FresnelGeneralizedSchlick *fresnel = (ccl_private FresnelGeneralizedSchlick *)
bsdf->fresnel;
float cosI = dot(wi, H);
if (bsdf->ior < 1.0f) {
/* When going from a higher to a lower IOR, we must use the transmitted angle. */
float sinT2 = (1.0f - sqr(cosI)) / sqr(bsdf->ior);
if (sinT2 >= 1.0f) {
/* Total internal reflection */
return refraction ? zero_spectrum() : fresnel->reflection_tint;
}
cosI = safe_sqrtf(1.0f - sinT2);
}
/* TODO(lukas): Is a special case for exponent==5 worth it? */
const float s = powf(1.0f - cosI, fresnel->exponent);
const Spectrum F = mix(fresnel->f0, fresnel->f90, s);
if (refraction) {
return (one_spectrum() - F) * fresnel->transmission_tint;
}
else {
return F * fresnel->reflection_tint;
}
}
else if (bsdf->fresnel_type == MicrofacetFresnel::CONSTANT) {
kernel_assert(!refraction);
ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)bsdf->fresnel;
return fresnel->color;
}
else {
return one_spectrum();
@@ -200,7 +276,7 @@ ccl_device_forceinline Spectrum microfacet_fresnel(ccl_private const MicrofacetB
ccl_device_forceinline void bsdf_microfacet_adjust_weight(ccl_private const ShaderData *sd,
ccl_private MicrofacetBsdf *bsdf)
{
bsdf->sample_weight *= average(microfacet_fresnel(bsdf, sd->wi, bsdf->N));
bsdf->sample_weight *= average(microfacet_fresnel(bsdf, sd->wi, bsdf->N, false));
}
/* Generalized Trowbridge-Reitz for clearcoat. */
@@ -227,8 +303,8 @@ ccl_device_inline float bsdf_lambda_from_sqr_alpha_tan_n(float sqr_alpha_tan_n)
return 0.5f * (sqrtf(1.0f + sqr_alpha_tan_n) - 1.0f);
}
else {
/* m_type == MicrofacetType::BECKMANN
* Approximation from below Equation 69. */
kernel_assert(m_type == MicrofacetType::BECKMANN);
/* Approximation from below Equation 69. */
if (sqr_alpha_tan_n < 0.39f) {
/* Equivalent to a >= 1.6f, but also handles sqr_alpha_tan_n == 0.0f cleanly. */
return 0.0f;
@@ -251,6 +327,12 @@ ccl_device_inline float bsdf_aniso_lambda(float alpha_x, float alpha_y, float3 V
return bsdf_lambda_from_sqr_alpha_tan_n<m_type>(sqr_alpha_tan_n);
}
/* Monodirectional shadowing-masking term. */
template<MicrofacetType m_type> ccl_device_inline float bsdf_G(float alpha2, float cos_N)
{
return 1.0f / (1.0f + bsdf_lambda<m_type>(alpha2, cos_N));
}
/* Combined shadowing-masking term. */
template<MicrofacetType m_type>
ccl_device_inline float bsdf_G(float alpha2, float cos_NI, float cos_NO)
@@ -267,7 +349,7 @@ template<MicrofacetType m_type> ccl_device_inline float bsdf_D(float alpha2, flo
return expf((1.0f - 1.0f / cos_NH2) / alpha2) / (M_PI_F * alpha2 * sqr(cos_NH2));
}
else {
/* m_type == MicrofacetType::GGX */
kernel_assert(m_type == MicrofacetType::GGX);
return alpha2 / (M_PI_F * sqr(1.0f + (alpha2 - 1.0f) * cos_NH2));
}
}
@@ -284,7 +366,7 @@ ccl_device_inline float bsdf_aniso_D(float alpha_x, float alpha_y, float3 H)
return expf(-(sqr(H.x) + sqr(H.y)) / cos_NH2) / (M_PI_F * alpha2 * sqr(cos_NH2));
}
else {
/* m_type == MicrofacetType::GGX */
kernel_assert(m_type == MicrofacetType::GGX);
return M_1_PI_F / (alpha2 * sqr(len_squared(H)));
}
}
@@ -296,9 +378,14 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc,
const float3 wo,
ccl_private float *pdf)
{
if (m_type == MicrofacetType::SHARP) {
*pdf = 0.0f;
return zero_spectrum();
}
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
const bool m_refractive = (bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) ||
(bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID);
const bool m_refractive = CLOSURE_IS_REFRACTIVE(bsdf->type);
const bool m_glass = CLOSURE_IS_GLASS(bsdf->type);
const float3 N = bsdf->N;
const float cos_NI = dot(N, wi);
@@ -308,14 +395,23 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc,
const float alpha_x = bsdf->alpha_x;
const float alpha_y = bsdf->alpha_y;
if ((cos_NI <= 0) || ((cos_NgO < 0.0f) != m_refractive) || ((cos_NO < 0.0f) != m_refractive) ||
(alpha_x * alpha_y <= 1e-7f)) {
const bool is_refraction = (cos_NO < 0.0f);
/* Check whether the pair of directions is valid for evaluation:
* - Incoming direction has to be in the upper hemisphere (Cycles convention)
* - Specular cases can't be evaluated, only sampled.
* - The outgoing direction has to be the in the same hemisphere w.r.t. both normals.
* - Purely reflective closures can't have refraction.
* - Purely refractive closures can't have reflection.
*/
if ((cos_NI <= 0) || (alpha_x * alpha_y <= 1e-7f) || ((cos_NgO < 0.0f) != is_refraction) ||
(is_refraction && !m_refractive) || (!is_refraction && m_refractive && !m_glass)) {
*pdf = 0.0f;
return zero_spectrum();
}
/* Compute half vector. */
float3 H = m_refractive ? -(bsdf->ior * wo + wi) : (wi + wo);
float3 H = is_refraction ? -(bsdf->ior * wo + wi) : (wi + wo);
const float inv_len_H = 1.0f / len(H);
H *= inv_len_H;
@@ -323,7 +419,7 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc,
float D, lambdaI, lambdaO;
/* TODO: add support for anisotropic transmission. */
if (alpha_x == alpha_y || m_refractive) { /* Isotropic. */
if (alpha_x == alpha_y || is_refraction) { /* Isotropic. */
float alpha2 = alpha_x * alpha_y;
if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
@@ -354,23 +450,31 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc,
lambdaO = bsdf_aniso_lambda<m_type>(alpha_x, alpha_y, local_O);
}
const float common = D / cos_NI *
(m_refractive ?
sqr(bsdf->ior * inv_len_H) * fabsf(dot(H, wi) * dot(H, wo)) :
0.25f);
float common = D / cos_NI *
(is_refraction ? sqr(bsdf->ior * inv_len_H) * fabsf(dot(H, wi) * dot(H, wo)) :
0.25f);
*pdf = common / (1.0f + lambdaI);
float lobe_pdf = 1.0f;
if (m_glass) {
float fresnel = fresnel_dielectric_cos(dot(H, wi), bsdf->ior);
float reflect_pdf = (fresnel == 1.0f) ? 1.0f : clamp(fresnel, 0.125f, 0.875f);
lobe_pdf = is_refraction ? (1.0f - reflect_pdf) : reflect_pdf;
}
const Spectrum F = microfacet_fresnel(bsdf, wo, H);
*pdf = common * lobe_pdf / (1.0f + lambdaI);
const Spectrum F = microfacet_fresnel(bsdf, wi, H, is_refraction);
return F * common / (1.0f + lambdaO + lambdaI);
}
template<MicrofacetType m_type>
ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
const int path_flag,
float3 Ng,
float3 wi,
float randu,
float randv,
float randw,
ccl_private Spectrum *eval,
ccl_private float3 *wo,
ccl_private float *pdf,
@@ -380,70 +484,116 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
const float m_eta = bsdf->ior;
const bool m_refractive = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID) ||
(bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID);
int label = m_refractive ? LABEL_TRANSMIT : LABEL_REFLECT;
const bool m_refractive = CLOSURE_IS_REFRACTIVE(bsdf->type);
const float alpha_x = bsdf->alpha_x;
const float alpha_y = bsdf->alpha_y;
bool m_singular = (m_type == MicrofacetType::SHARP) || (alpha_x * alpha_y <= 1e-7f);
const float3 N = bsdf->N;
const float cos_NI = dot(N, wi);
if (cos_NI <= 0) {
return label | LABEL_GLOSSY;
*eval = zero_spectrum();
*pdf = 0.0f;
return (m_refractive ? LABEL_TRANSMIT : LABEL_REFLECT) |
(m_singular ? LABEL_SINGULAR : LABEL_GLOSSY);
}
float3 X, Y;
const float alpha_x = bsdf->alpha_x;
const float alpha_y = bsdf->alpha_y;
if (alpha_x == alpha_y) {
make_orthonormals(N, &X, &Y);
float3 H;
float cos_NH, cos_HI;
float3 local_H, local_I, X, Y; /* Needed for anisotropic microfacets later. */
if (m_singular) {
H = N;
cos_NH = 1.0f;
cos_HI = cos_NI;
}
else {
make_orthonormals_tangent(N, bsdf->T, &X, &Y);
if (alpha_x == alpha_y) {
make_orthonormals(N, &X, &Y);
}
else {
make_orthonormals_tangent(N, bsdf->T, &X, &Y);
}
/* Importance sampling with distribution of visible normals. Vectors are transformed to local
* space before and after sampling. */
local_I = make_float3(dot(X, wi), dot(Y, wi), cos_NI);
if (m_type == MicrofacetType::GGX) {
local_H = microfacet_ggx_sample_vndf(local_I, alpha_x, alpha_y, randu, randv);
}
else {
/* m_type == MicrofacetType::BECKMANN */
local_H = microfacet_beckmann_sample_vndf(local_I, alpha_x, alpha_y, randu, randv);
}
H = X * local_H.x + Y * local_H.y + N * local_H.z;
cos_NH = local_H.z;
cos_HI = dot(H, wi);
}
/* Importance sampling with distribution of visible normals. Vectors are transformed to local
* space before and after sampling. */
const float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cos_NI);
float3 local_H;
if (m_type == MicrofacetType::GGX) {
local_H = microfacet_ggx_sample_vndf(local_I, alpha_x, alpha_y, randu, randv);
}
else {
/* m_type == MicrofacetType::BECKMANN */
local_H = microfacet_beckmann_sample_vndf(local_I, alpha_x, alpha_y, randu, randv);
}
const float3 H = X * local_H.x + Y * local_H.y + N * local_H.z;
const float cos_NH = local_H.z;
const float cos_HI = dot(H, wi);
bool valid = false;
bool valid;
bool do_refract;
float lobe_pdf;
if (m_refractive) {
float3 R, T;
bool inside;
float fresnel = fresnel_dielectric(m_eta, H, wi, wo, &inside);
valid = !inside;
float fresnel = fresnel_dielectric(m_eta, H, wi, &R, &T, &inside);
*wo = T;
/* For glass closures, we decide between reflection and refraction here. */
if (CLOSURE_IS_GLASS(bsdf->type)) {
if (fresnel == 1.0f) {
/* TIR, reflection is the only option. */
do_refract = false;
lobe_pdf = 1.0f;
}
else {
/* Decide between reflection and refraction, using defensive sampling to avoid
* excessive noise for reflection highlights. */
float reflect_pdf = (path_flag & PATH_RAY_CAMERA) ? clamp(fresnel, 0.125f, 0.875f) :
fresnel;
do_refract = (randw >= reflect_pdf);
lobe_pdf = do_refract ? (1.0f - reflect_pdf) : reflect_pdf;
}
}
else {
/* For pure refractive closures, refraction is the only option. */
do_refract = true;
lobe_pdf = 1.0f;
valid = valid && (fresnel != 1.0f);
}
}
else {
/* Pure reflective closure, reflection is the only option. */
valid = true;
lobe_pdf = 1.0f;
do_refract = false;
}
valid = !inside && fresnel != 1.0f;
int label;
if (do_refract) {
/* wo was already set to the refracted direction by fresnel_dielectric. */
// valid = valid && (dot(Ng, *wo) < 0);
label = LABEL_TRANSMIT;
/* If the IOR is close enough to 1.0, just treat the interaction as specular. */
m_singular = m_singular || (fabsf(m_eta - 1.0f) < 1e-4f);
}
else {
/* Eq. 39 - compute actual reflected direction */
*wo = 2 * cos_HI * H - wi;
valid = dot(Ng, *wo) > 0;
valid = valid && (dot(Ng, *wo) > 0);
label = LABEL_REFLECT;
}
if (!valid) {
*eval = zero_spectrum();
*pdf = 0.0f;
return label | LABEL_GLOSSY;
return label | (m_singular ? LABEL_SINGULAR : LABEL_GLOSSY);
}
if (alpha_x * alpha_y <= 1e-7f || (m_refractive && fabsf(m_eta - 1.0f) < 1e-4f)) {
if (m_singular) {
label |= LABEL_SINGULAR;
/* Some high number for MIS. */
*pdf = 1e6f;
*eval = make_spectrum(1e6f) * microfacet_fresnel(bsdf, *wo, H);
*pdf = lobe_pdf * 1e6f;
*eval = make_spectrum(1e6f) * microfacet_fresnel(bsdf, wi, H, do_refract);
}
else {
label |= LABEL_GLOSSY;
@@ -451,7 +601,7 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
float D, lambdaI, lambdaO;
/* TODO: add support for anisotropic transmission. */
if (alpha_x == alpha_y || m_refractive) { /* Isotropic. */
if (alpha_x == alpha_y || do_refract) { /* Isotropic. */
float alpha2 = alpha_x * alpha_y;
if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
@@ -479,21 +629,65 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
const float cos_HO = dot(H, *wo);
const float common = D / cos_NI *
(m_refractive ? fabsf(cos_HI * cos_HO) / sqr(cos_HO + cos_HI / m_eta) :
0.25f);
(do_refract ? fabsf(cos_HI * cos_HO) / sqr(cos_HO + cos_HI / m_eta) :
0.25f);
*pdf = common / (1.0f + lambdaI);
*pdf = common * lobe_pdf / (1.0f + lambdaI);
Spectrum F = microfacet_fresnel(bsdf, *wo, H);
const Spectrum F = microfacet_fresnel(bsdf, wi, H, do_refract);
*eval = F * common / (1.0f + lambdaI + lambdaO);
}
*sampled_roughness = make_float2(alpha_x, alpha_y);
*eta = m_refractive ? 1.0f / m_eta : m_eta;
*eta = do_refract ? 1.0f / m_eta : m_eta;
return label;
}
/* Fresnel term setup functions. These get called after the distribution-specific setup functions
* like bsdf_microfacet_ggx_setup. */
ccl_device void bsdf_microfacet_setup_fresnel_principledv1(
ccl_private MicrofacetBsdf *bsdf,
ccl_private const ShaderData *sd,
ccl_private FresnelPrincipledV1 *fresnel)
{
fresnel->cspec0 = saturate(fresnel->cspec0);
bsdf->fresnel_type = MicrofacetFresnel::PRINCIPLED_V1;
bsdf->fresnel = fresnel;
bsdf_microfacet_adjust_weight(sd, bsdf);
}
ccl_device void bsdf_microfacet_setup_fresnel_conductor(ccl_private MicrofacetBsdf *bsdf,
ccl_private const ShaderData *sd,
ccl_private FresnelConductor *fresnel)
{
bsdf->fresnel_type = MicrofacetFresnel::CONDUCTOR;
bsdf->fresnel = fresnel;
bsdf_microfacet_adjust_weight(sd, bsdf);
}
ccl_device void bsdf_microfacet_setup_fresnel_dielectric_tint(
ccl_private MicrofacetBsdf *bsdf,
ccl_private const ShaderData *sd,
ccl_private FresnelDielectricTint *fresnel)
{
bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC_TINT;
bsdf->fresnel = fresnel;
bsdf_microfacet_adjust_weight(sd, bsdf);
}
ccl_device void bsdf_microfacet_setup_fresnel_generalized_schlick(
ccl_private MicrofacetBsdf *bsdf,
ccl_private const ShaderData *sd,
ccl_private FresnelGeneralizedSchlick *fresnel)
{
bsdf->fresnel_type = MicrofacetFresnel::GENERALIZED_SCHLICK;
bsdf->fresnel = fresnel;
bsdf_microfacet_adjust_weight(sd, bsdf);
}
/* GGX microfacet with Smith shadow-masking from:
*
* Microfacet Models for Refraction through Rough Surfaces
@@ -509,37 +703,22 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
ccl_device int bsdf_microfacet_ggx_setup(ccl_private MicrofacetBsdf *bsdf)
{
bsdf->extra = NULL;
bsdf->alpha_x = saturatef(bsdf->alpha_x);
bsdf->alpha_y = saturatef(bsdf->alpha_y);
bsdf->fresnel_type = MicrofacetFresnel::NONE;
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_ID;
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_ggx_fresnel_setup(ccl_private MicrofacetBsdf *bsdf,
ccl_private const ShaderData *sd)
{
bsdf->extra->cspec0 = saturate(bsdf->extra->cspec0);
bsdf->alpha_x = saturatef(bsdf->alpha_x);
bsdf->alpha_y = saturatef(bsdf->alpha_y);
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID;
bsdf_microfacet_adjust_weight(sd, bsdf);
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_ggx_clearcoat_setup(ccl_private MicrofacetBsdf *bsdf,
ccl_private const ShaderData *sd)
{
bsdf->alpha_x = saturatef(bsdf->alpha_x);
bsdf->alpha_y = bsdf->alpha_x;
bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC;
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID;
bsdf_microfacet_adjust_weight(sd, bsdf);
@@ -549,16 +728,26 @@ ccl_device int bsdf_microfacet_ggx_clearcoat_setup(ccl_private MicrofacetBsdf *b
ccl_device int bsdf_microfacet_ggx_refraction_setup(ccl_private MicrofacetBsdf *bsdf)
{
bsdf->extra = NULL;
bsdf->alpha_x = saturatef(bsdf->alpha_x);
bsdf->alpha_y = bsdf->alpha_x;
bsdf->fresnel_type = MicrofacetFresnel::NONE;
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION;
}
ccl_device int bsdf_microfacet_ggx_glass_setup(ccl_private MicrofacetBsdf *bsdf)
{
bsdf->alpha_x = saturatef(bsdf->alpha_x);
bsdf->alpha_y = bsdf->alpha_x;
bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC;
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION;
}
ccl_device void bsdf_microfacet_ggx_blur(ccl_private ShaderClosure *sc, float roughness)
{
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)sc;
@@ -577,10 +766,12 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval(ccl_private const ShaderClosure *sc
}
ccl_device int bsdf_microfacet_ggx_sample(ccl_private const ShaderClosure *sc,
const int path_flag,
float3 Ng,
float3 wi,
float randu,
float randv,
float randw,
ccl_private Spectrum *eval,
ccl_private float3 *wo,
ccl_private float *pdf,
@@ -588,7 +779,7 @@ ccl_device int bsdf_microfacet_ggx_sample(ccl_private const ShaderClosure *sc,
ccl_private float *eta)
{
return bsdf_microfacet_sample<MicrofacetType::GGX>(
sc, Ng, wi, randu, randv, eval, wo, pdf, sampled_roughness, eta);
sc, path_flag, Ng, wi, randu, randv, randw, eval, wo, pdf, sampled_roughness, eta);
}
/* Beckmann microfacet with Smith shadow-masking from:
@@ -601,6 +792,7 @@ ccl_device int bsdf_microfacet_beckmann_setup(ccl_private MicrofacetBsdf *bsdf)
bsdf->alpha_x = saturatef(bsdf->alpha_x);
bsdf->alpha_y = saturatef(bsdf->alpha_y);
bsdf->fresnel_type = MicrofacetFresnel::NONE;
bsdf->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
@@ -610,10 +802,21 @@ ccl_device int bsdf_microfacet_beckmann_refraction_setup(ccl_private MicrofacetB
bsdf->alpha_x = saturatef(bsdf->alpha_x);
bsdf->alpha_y = bsdf->alpha_x;
bsdf->fresnel_type = MicrofacetFresnel::NONE;
bsdf->type = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION;
}
ccl_device int bsdf_microfacet_beckmann_glass_setup(ccl_private MicrofacetBsdf *bsdf)
{
bsdf->alpha_x = saturatef(bsdf->alpha_x);
bsdf->alpha_y = bsdf->alpha_x;
bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC;
bsdf->type = CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID;
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION;
}
ccl_device void bsdf_microfacet_beckmann_blur(ccl_private ShaderClosure *sc, float roughness)
{
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)sc;
@@ -632,10 +835,12 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval(ccl_private const ShaderClosur
}
ccl_device int bsdf_microfacet_beckmann_sample(ccl_private const ShaderClosure *sc,
const int path_flag,
float3 Ng,
float3 wi,
float randu,
float randv,
float randw,
ccl_private Spectrum *eval,
ccl_private float3 *wo,
ccl_private float *pdf,
@@ -643,7 +848,63 @@ ccl_device int bsdf_microfacet_beckmann_sample(ccl_private const ShaderClosure *
ccl_private float *eta)
{
return bsdf_microfacet_sample<MicrofacetType::BECKMANN>(
sc, Ng, wi, randu, randv, eval, wo, pdf, sampled_roughness, eta);
sc, path_flag, Ng, wi, randu, randv, randw, eval, wo, pdf, sampled_roughness, eta);
}
/* Specular interface, not really a microfacet model but close enough that sharing code makes
* sense. */
ccl_device int bsdf_reflection_setup(ccl_private MicrofacetBsdf *bsdf)
{
bsdf->fresnel_type = MicrofacetFresnel::NONE;
bsdf->type = CLOSURE_BSDF_REFLECTION_ID;
bsdf->alpha_x = 0.0f;
bsdf->alpha_y = 0.0f;
return SD_BSDF;
}
ccl_device int bsdf_refraction_setup(ccl_private MicrofacetBsdf *bsdf)
{
bsdf->fresnel_type = MicrofacetFresnel::NONE;
bsdf->type = CLOSURE_BSDF_REFRACTION_ID;
bsdf->alpha_x = 0.0f;
bsdf->alpha_y = 0.0f;
return SD_BSDF | SD_BSDF_HAS_TRANSMISSION;
}
ccl_device int bsdf_sharp_glass_setup(ccl_private MicrofacetBsdf *bsdf)
{
bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC;
bsdf->type = CLOSURE_BSDF_SHARP_GLASS_ID;
bsdf->alpha_x = 0.0f;
bsdf->alpha_y = 0.0f;
return SD_BSDF | SD_BSDF_HAS_TRANSMISSION;
}
ccl_device Spectrum bsdf_microfacet_sharp_eval(ccl_private const ShaderClosure *sc,
const float3 Ng,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
return bsdf_microfacet_eval<MicrofacetType::SHARP>(sc, Ng, wi, wo, pdf);
}
ccl_device int bsdf_microfacet_sharp_sample(ccl_private const ShaderClosure *sc,
const int path_flag,
float3 Ng,
float3 wi,
float randu,
float randv,
float randw,
ccl_private Spectrum *eval,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float2 *sampled_roughness,
ccl_private float *eta)
{
return bsdf_microfacet_sample<MicrofacetType::SHARP>(
sc, path_flag, Ng, wi, randu, randv, randw, eval, wo, pdf, sampled_roughness, eta);
}
CCL_NAMESPACE_END

View File

@@ -377,8 +377,6 @@ ccl_device int bsdf_microfacet_multi_ggx_common_setup(ccl_private MicrofacetBsdf
{
bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
bsdf->alpha_y = clamp(bsdf->alpha_y, 1e-4f, 1.0f);
bsdf->extra->color = saturate(bsdf->extra->color);
bsdf->extra->cspec0 = saturate(bsdf->extra->cspec0);
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
}
@@ -388,6 +386,10 @@ ccl_device int bsdf_microfacet_multi_ggx_setup(ccl_private MicrofacetBsdf *bsdf)
if (is_zero(bsdf->T))
bsdf->T = make_float3(1.0f, 0.0f, 0.0f);
ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)bsdf->fresnel;
fresnel->color = saturate(fresnel->color);
bsdf->fresnel_type = MicrofacetFresnel::CONSTANT;
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
return bsdf_microfacet_multi_ggx_common_setup(bsdf);
@@ -399,7 +401,12 @@ ccl_device int bsdf_microfacet_multi_ggx_fresnel_setup(ccl_private MicrofacetBsd
if (is_zero(bsdf->T))
bsdf->T = make_float3(1.0f, 0.0f, 0.0f);
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID;
ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)bsdf->fresnel;
fresnel->color = saturate(fresnel->color);
fresnel->cspec0 = saturate(fresnel->cspec0);
bsdf->fresnel_type = MicrofacetFresnel::PRINCIPLED_V1;
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
bsdf_microfacet_adjust_weight(sd, bsdf);
@@ -410,6 +417,10 @@ ccl_device int bsdf_microfacet_multi_ggx_refraction_setup(ccl_private Microfacet
{
bsdf->alpha_y = bsdf->alpha_x;
ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)bsdf->fresnel;
fresnel->color = saturate(fresnel->color);
bsdf->fresnel_type = MicrofacetFresnel::CONSTANT;
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
return bsdf_microfacet_multi_ggx_common_setup(bsdf);
@@ -439,7 +450,21 @@ ccl_device Spectrum bsdf_microfacet_multi_ggx_eval(ccl_private const ShaderClosu
return zero_spectrum();
}
bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID);
Spectrum color, cspec0;
bool use_fresnel;
if (bsdf->fresnel_type == MicrofacetFresnel::PRINCIPLED_V1) {
ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)bsdf->fresnel;
use_fresnel = true;
color = fresnel->color;
cspec0 = fresnel->cspec0;
}
else {
kernel_assert(bsdf->fresnel_type == MicrofacetFresnel::CONSTANT);
ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)bsdf->fresnel;
use_fresnel = false;
color = fresnel->color;
cspec0 = zero_spectrum();
}
bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y);
if (is_aniso)
@@ -463,13 +488,13 @@ ccl_device Spectrum bsdf_microfacet_multi_ggx_eval(ccl_private const ShaderClosu
return mf_eval_glossy(local_I,
local_O,
true,
bsdf->extra->color,
color,
bsdf->alpha_x,
bsdf->alpha_y,
lcg_state,
bsdf->ior,
use_fresnel,
bsdf->extra->cspec0);
cspec0);
}
ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
@@ -509,7 +534,21 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
return LABEL_REFLECT | LABEL_SINGULAR;
}
bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID);
Spectrum color, cspec0;
bool use_fresnel;
if (bsdf->fresnel_type == MicrofacetFresnel::PRINCIPLED_V1) {
ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)bsdf->fresnel;
use_fresnel = true;
color = fresnel->color;
cspec0 = fresnel->cspec0;
}
else {
kernel_assert(bsdf->fresnel_type == MicrofacetFresnel::CONSTANT);
ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)bsdf->fresnel;
use_fresnel = false;
color = fresnel->color;
cspec0 = zero_spectrum();
}
*eta = bsdf->ior;
*sampled_roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
@@ -525,13 +564,13 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
*eval = mf_sample_glossy(local_I,
&local_O,
bsdf->extra->color,
color,
bsdf->alpha_x,
bsdf->alpha_y,
lcg_state,
bsdf->ior,
use_fresnel,
bsdf->extra->cspec0);
cspec0);
*wo = X * local_O.x + Y * local_O.y + Z * local_O.z;
/* Ensure that the light direction is on the outside w.r.t. the geometry normal. */
@@ -557,8 +596,11 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_setup(ccl_private MicrofacetBsdf
bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
bsdf->alpha_y = bsdf->alpha_x;
bsdf->ior = max(0.0f, bsdf->ior);
bsdf->extra->color = saturate(bsdf->extra->color);
ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)bsdf->fresnel;
fresnel->color = saturate(fresnel->color);
bsdf->fresnel_type = MicrofacetFresnel::CONSTANT;
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG | SD_BSDF_HAS_TRANSMISSION;
@@ -570,10 +612,13 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(ccl_private Microfa
bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
bsdf->alpha_y = bsdf->alpha_x;
bsdf->ior = max(0.0f, bsdf->ior);
bsdf->extra->color = saturate(bsdf->extra->color);
bsdf->extra->cspec0 = saturate(bsdf->extra->cspec0);
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID;
ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)bsdf->fresnel;
fresnel->color = saturate(fresnel->color);
fresnel->cspec0 = saturate(fresnel->cspec0);
bsdf->fresnel_type = MicrofacetFresnel::PRINCIPLED_V1;
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
bsdf_microfacet_adjust_weight(sd, bsdf);
@@ -601,21 +646,35 @@ ccl_device Spectrum bsdf_microfacet_multi_ggx_glass_eval(ccl_private const Shade
float3 local_O = make_float3(dot(wo, X), dot(wo, Y), dot(wo, Z));
const bool is_transmission = local_O.z < 0.0f;
const bool use_fresnel = !is_transmission &&
(bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID);
Spectrum color, cspec0;
bool use_fresnel;
if (bsdf->fresnel_type == MicrofacetFresnel::PRINCIPLED_V1) {
ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)bsdf->fresnel;
use_fresnel = true;
color = fresnel->color;
cspec0 = is_transmission ? fresnel->color : fresnel->cspec0;
}
else {
kernel_assert(bsdf->fresnel_type == MicrofacetFresnel::CONSTANT);
ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)bsdf->fresnel;
use_fresnel = false;
color = fresnel->color;
cspec0 = zero_spectrum();
}
*pdf = mf_glass_pdf(local_I, local_O, bsdf->alpha_x, bsdf->ior);
kernel_assert(*pdf >= 0.f);
return mf_eval_glass(local_I,
local_O,
!is_transmission,
bsdf->extra->color,
color,
bsdf->alpha_x,
bsdf->alpha_y,
lcg_state,
bsdf->ior,
use_fresnel,
(is_transmission) ? bsdf->extra->color : bsdf->extra->cspec0);
!is_transmission && use_fresnel,
cspec0);
}
ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg,
@@ -640,14 +699,14 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg,
*sampled_roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
float3 R, T;
float3 T;
bool inside;
float fresnel = fresnel_dielectric(bsdf->ior, Z, wi, &R, &T, &inside);
float fresnel = fresnel_dielectric(bsdf->ior, Z, wi, &T, &inside);
*pdf = 1e6f;
*eval = make_spectrum(1e6f);
if (randu < fresnel) {
*wo = R;
*wo = 2 * dot(Z, wi) * Z - wi;
return LABEL_REFLECT | LABEL_SINGULAR;
}
else {
@@ -656,7 +715,21 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg,
}
}
bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID);
Spectrum color, cspec0;
bool use_fresnel;
if (bsdf->fresnel_type == MicrofacetFresnel::PRINCIPLED_V1) {
ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)bsdf->fresnel;
use_fresnel = true;
color = fresnel->color;
cspec0 = fresnel->cspec0;
}
else {
kernel_assert(bsdf->fresnel_type == MicrofacetFresnel::CONSTANT);
ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)bsdf->fresnel;
use_fresnel = false;
color = fresnel->color;
cspec0 = zero_spectrum();
}
make_orthonormals(Z, &X, &Y);
@@ -665,13 +738,13 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg,
*eval = mf_sample_glass(local_I,
&local_O,
bsdf->extra->color,
color,
bsdf->alpha_x,
bsdf->alpha_y,
lcg_state,
bsdf->ior,
use_fresnel,
bsdf->extra->cspec0);
cspec0);
*pdf = mf_glass_pdf(local_I, local_O, bsdf->alpha_x, bsdf->ior);
kernel_assert(*pdf >= 0.f);
*eval *= *pdf;

View File

@@ -1,61 +0,0 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
* Adapted from Open Shading Language
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
* All Rights Reserved.
*
* Modifications Copyright 2011-2022 Blender Foundation. */
#pragma once
CCL_NAMESPACE_BEGIN
/* REFLECTION */
ccl_device int bsdf_reflection_setup(ccl_private MicrofacetBsdf *bsdf)
{
bsdf->type = CLOSURE_BSDF_REFLECTION_ID;
return SD_BSDF;
}
ccl_device Spectrum bsdf_reflection_eval(ccl_private const ShaderClosure *sc,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
*pdf = 0.0f;
return zero_spectrum();
}
ccl_device int bsdf_reflection_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float *eta)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
float3 N = bsdf->N;
*eta = bsdf->ior;
// only one direction is possible
float cosNI = dot(N, wi);
if (cosNI > 0) {
*wo = (2 * cosNI) * N - wi;
if (dot(Ng, *wo) > 0) {
/* Some high number for MIS. */
*pdf = 1e6f;
*eval = make_spectrum(1e6f);
}
}
else {
*pdf = 0.0f;
*eval = zero_spectrum();
}
return LABEL_REFLECT | LABEL_SINGULAR;
}
CCL_NAMESPACE_END

View File

@@ -1,64 +0,0 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
* Adapted from Open Shading Language
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
* All Rights Reserved.
*
* Modifications Copyright 2011-2022 Blender Foundation. */
#pragma once
CCL_NAMESPACE_BEGIN
/* REFRACTION */
ccl_device int bsdf_refraction_setup(ccl_private MicrofacetBsdf *bsdf)
{
bsdf->type = CLOSURE_BSDF_REFRACTION_ID;
return SD_BSDF;
}
ccl_device Spectrum bsdf_refraction_eval(ccl_private const ShaderClosure *sc,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
*pdf = 0.0f;
return zero_spectrum();
}
ccl_device int bsdf_refraction_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 wi,
float randu,
float randv,
ccl_private Spectrum *eval,
ccl_private float3 *wo,
ccl_private float *pdf,
ccl_private float *eta)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
float m_eta = bsdf->ior;
*eta = 1.0f / m_eta;
float3 N = bsdf->N;
float3 R, T;
bool inside;
float fresnel;
fresnel = fresnel_dielectric(m_eta, N, wi, &R, &T, &inside);
if (!inside && fresnel != 1.0f) {
/* Some high number for MIS. */
*pdf = 1e6f;
*eval = make_spectrum(1e6f);
*wo = T;
}
else {
*pdf = 0.0f;
*eval = zero_spectrum();
}
return LABEL_TRANSMIT | LABEL_SINGULAR;
}
CCL_NAMESPACE_END

View File

@@ -10,12 +10,8 @@
CCL_NAMESPACE_BEGIN
ccl_device float fresnel_dielectric(float eta,
const float3 N,
const float3 I,
ccl_private float3 *R,
ccl_private float3 *T,
ccl_private bool *is_inside)
ccl_device float fresnel_dielectric(
float eta, const float3 N, const float3 I, ccl_private float3 *T, ccl_private bool *is_inside)
{
float cos = dot(N, I), neta;
float3 Nn;
@@ -35,9 +31,6 @@ ccl_device float fresnel_dielectric(float eta,
*is_inside = true;
}
// compute reflection
*R = (2 * cos) * Nn - I;
float arg = 1 - (neta * neta * (1 - (cos * cos)));
if (arg < 0) {
*T = make_float3(0.0f, 0.0f, 0.0f);
@@ -71,17 +64,23 @@ ccl_device float fresnel_dielectric_cos(float cosi, float eta)
return 1.0f; // TIR(no refracted component)
}
ccl_device float3 fresnel_conductor(float cosi, const float3 eta, const float3 k)
ccl_device Spectrum fresnel_conductor(float cosi, const Spectrum eta, const Spectrum k)
{
float3 cosi2 = make_float3(cosi * cosi, cosi * cosi, cosi * cosi);
float3 one = make_float3(1.0f, 1.0f, 1.0f);
float3 tmp_f = eta * eta + k * k;
float3 tmp = tmp_f * cosi2;
float3 Rparl2 = (tmp - (2.0f * eta * cosi) + one) / (tmp + (2.0f * eta * cosi) + one);
float3 Rperp2 = (tmp_f - (2.0f * eta * cosi) + cosi2) / (tmp_f + (2.0f * eta * cosi) + cosi2);
Spectrum cosi2 = make_spectrum(cosi * cosi);
Spectrum one = make_spectrum(1.0f);
Spectrum tmp_f = eta * eta + k * k;
Spectrum tmp = tmp_f * cosi2;
Spectrum Rparl2 = (tmp - (2.0f * eta * cosi) + one) / (tmp + (2.0f * eta * cosi) + one);
Spectrum Rperp2 = (tmp_f - (2.0f * eta * cosi) + cosi2) / (tmp_f + (2.0f * eta * cosi) + cosi2);
return (Rparl2 + Rperp2) * 0.5f;
}
ccl_device float ior_from_F0(Spectrum f0)
{
const float sqrt_f0 = sqrtf(clamp(average(f0), 0.0f, 0.99f));
return (1.0f + sqrt_f0) / (1.0f - sqrt_f0);
}
ccl_device float schlick_fresnel(float u)
{
float m = clamp(1.0f - u, 0.0f, 1.0f);

View File

@@ -29,7 +29,7 @@ KERNEL_DATA_ARRAY(DecomposedTransform, camera_motion)
/* triangles */
KERNEL_DATA_ARRAY(uint, tri_shader)
KERNEL_DATA_ARRAY(packed_float3, tri_vnormal)
KERNEL_DATA_ARRAY(uint4, tri_vindex)
KERNEL_DATA_ARRAY(packed_uint3, tri_vindex)
KERNEL_DATA_ARRAY(uint, tri_patch)
KERNEL_DATA_ARRAY(float2, tri_patch_uv)
KERNEL_DATA_ARRAY(packed_float3, tri_verts)

View File

@@ -10,7 +10,7 @@
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
# define KERNEL_STUB
#else
/* SSE optimization disabled for now on 32 bit, see bug T36316. */
/* SSE optimization disabled for now on 32 bit, see bug #36316. */
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
# define __KERNEL_SSE__
# define __KERNEL_SSE2__

View File

@@ -10,7 +10,7 @@
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
# define KERNEL_STUB
#else
/* SSE optimization disabled for now on 32 bit, see bug T36316. */
/* SSE optimization disabled for now on 32 bit, see bug #36316. */
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
# define __KERNEL_SSE2__
# endif

View File

@@ -10,7 +10,7 @@
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
# define KERNEL_STUB
#else
/* SSE optimization disabled for now on 32 bit, see bug T36316. */
/* SSE optimization disabled for now on 32 bit, see bug #36316. */
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
# define __KERNEL_SSE2__
# define __KERNEL_SSE3__

Some files were not shown because too many files have changed in this diff Show More