Compare commits

...

357 Commits

Author SHA1 Message Date
a8490a8ee8 Merge branch 'blender-v3.1-release' into fix-normals-custom-data 2022-02-21 13:53:26 -05:00
be6bcaa8c1 Fix T93873: Wrong limits for color socket exposed to modifier
Limit the min and max of the IDProperty for the node group input
from 0 to infinity, and the soft min and max between 0 and 1.

Thanks to @PratikPB2123 for investigation.
2022-02-21 13:01:37 -05:00
aa1e3419ee Fix T95839: Data race when lazily creating mesh normal layers 2022-02-21 12:18:17 -05:00
b7171d1b82 Cleanup: Use function to check if normals are dirty
This makes the fix for T95839 simpler.
Similar to 969c4a45ce.
2022-02-21 12:17:41 -05:00
a81cc5cbcb Fix: Avoid potential use of dirty normals
Instead of accessing the `CD_NORMAL` layer directly,
use the proper API for accessing mesh normals. Even if the
layer exists, the values might be incorrect due to a deformation.
Related to ef0e21f0ae, 969c4a45ce, and T95839.
2022-02-21 11:40:59 -05:00
869dd2e699 Fix T95154 Eevee AO node: the "only local" option applies "inside" instead
The `custom2` was not being used as a bitflag as it should.
2022-02-21 17:18:45 +01:00
82ff0fa586 Weight Proximity: fix value overlap between Normalize and Invert VGroup.
The flags overlapped ever since normalize was added, so this requires
versioning to copy the flag value.

Differential Revision: https://developer.blender.org/D14165
2022-02-21 18:08:53 +03:00
38ae311706 Weight Modifiers: use the correct flags for the mask invert property.
The code was using the same flag value for different modifiers,
resulting in matching the toggle to random overlapping flags.

Differential Revision: https://developer.blender.org/D14165
2022-02-21 18:07:08 +03:00
0f242981ec Workbench: Fix missing world_data ubo during opaque prepass 2022-02-21 13:30:20 +01:00
829812f180 Fix T92467: Path Selection broken when Drag is set to Tweak
When RMB-select uses "Select Tweak" as a fallback tool,
ignore all bindings mapped to the Control key as these are
used for path selection.

This was fixed in 2a2d873124
however that caused shift-select to fail (T93100).
2022-02-21 23:09:34 +11:00
132f9a2e31 Fix T95596: Crash in versioning of node animation
The node animation versioning code passes `nullptr` to the `oldName` and
`newName` parameters, but those weren't `NULL`-safe. I added an extra
check for this.

No functional changes, just a crash fix.
2022-02-21 13:02:23 +01:00
bce810f057 Fix T95871: Non-float textures report as float.
Althought the float buffers are only used as cache, current code paths
don't look at the flags to identify which kind of image it is. Actual
fix would be to check flags, but that wouldn't be something to add one
week before release.

This commit fixes it by removing the buffers after use in the image
engine.
2022-02-21 07:48:49 +01:00
1a0a22f95a Fix T95413: Blur node size input crash
Bug was introduced in D12167.

Reading input size from an input socket is not possible in tiled compositor before execution is initialized. A similar change was done for the base class, see BlurBaseOperation::init_data().

Reviewed by: Jeroen Bakker

Differential Revision: https://developer.blender.org/D14067
2022-02-20 23:00:44 +01:00
de886884c0 Fix T95470: LineArt GPU subdiv fix.
Use evaluated mesh instead of ob->data.

Reviewed by: Antonio Vazquez (antoniov)

Differential Revision: https://developer.blender.org/D14040
2022-02-20 19:40:44 +08:00
93cc892470 Revert "OCIO: Port shader creation logic to use GPUShaderCreateInfo"
This reverts commit 7f7c614ecd.
2022-02-18 22:28:05 +01:00
32660382f5 Revert "OCIO: Fix gpu include file"
This reverts commit 3cebfadb27.
2022-02-18 22:28:01 +01:00
3cebfadb27 OCIO: Fix gpu include file
Was the cause by ef0e21f0ae
2022-02-18 21:52:29 +01:00
eba3ffc31a GL: Fix possible shift by -1
This can happen when the attribute has been optimized out by the compiler.
2022-02-18 21:33:47 +01:00
7f7c614ecd OCIO: Port shader creation logic to use GPUShaderCreateInfo
This commit should suffice to make the shader API agnostic now (given that
all users of it use the GPU API).

This makes the shaders not trigger a false positive error anymore since
the binding slots are now garanteed by the backend and not changed at
after compilation.

This also bundles all uniforms into UBOs. Making them extendable without
limitations of push constants. The generated uniforms from OCIO are not
densely packed in the UBO to avoid complexity. Another approach would be to
use GPU_uniformbuf_create_from_list but this requires converting uniforms
to GPUInputs which is too complex for what it is.

Reviewed by: brecht, jbakker

Differential Revision: https://developer.blender.org/D14123
2022-02-18 21:33:47 +01:00
ef0e21f0ae Cleanup: Remove unused argument to mesh tessellation
This removes manual handling of normals that was hard-coded
to false in the one place the function was called. This change
will help to make a fix to T95839 simpler.
2022-02-18 13:39:16 -06:00
969c4a45ce Cleanup: Use functions for accessing mesh normal dirty state
It's better not to expose the details of where the dirty flags are
stored to every place that wants to know if the normals are dirty.
Some of these places are relics from before vertex normals were
computed lazily anyway, so this is more of an incrememtal cleanup.
This will make part of the fix for T95839 simpler.
2022-02-18 13:21:36 -06:00
eaa4aa8644 Fix part of T95848: missing updates editing light object nodes
Make relation match material and world nodes. Does not address the reported
issue regarding muted nodes, but another missing update found investigating.
2022-02-18 19:50:53 +01:00
b04d42022f Fix T95338: missing image editor refresh after render compositing
This was an old issue, but recent image partial update changes made this more
likely to happen in some cases. Now ensure that whenever the rendered scene
switches the image is updated.
2022-02-18 19:50:53 +01:00
Wannes Malfait
82fc68ed90 Fix T95542: Dual Mesh crashes with some non-manifold vertices
The problem was that the code for sorting polygons around a vertex
assumed that it was a manifold or boundary vertex. However in some cases
the vertex could still be nonmanifold causing the crash. The cases where
the sorting fails are now detected and these vertices are then marked as
nonmanifold.

Differential Revision: https://developer.blender.org/D14065
2022-02-18 11:35:08 -06:00
Leon Schittek
ddc52f2e1d Fix: Curve to Mesh node creates caps when curve is cyclic
The "Fill Caps" option on the Curve to Mesh node introduced in
rBbc2f4dd8b408ee makes it possible to fill the open ends of the sweep
to create a manifold mesh.

This patch fixes an edge case, where caps were created even when the
rail curve (the curve used in the "Curve" input socket) was cyclic
making the resulting mesh non-manifold.

Differential Revision: https://developer.blender.org/D14124
2022-02-18 11:27:28 -06:00
af6a1b08e3 VSE: Refactor our code to be compatible with ffmpeg 5.0
In ffmpeg 5.0, several variables were made const to try to prevent bad API usage.
Removed some dead code that wasn't used anymore as well.

Reviewed By: Richard Antalik

Differential Revision: http://developer.blender.org/D14063
2022-02-18 18:24:16 +01:00
82c3bef765 Fix T94495: Split edges node leads to a crash in edit mode
If original indices exist on the input mesh, also copy them to
the BMesh used for the edge split operation so they aren't lost.

Part of D14018
2022-02-18 10:34:00 -06:00
1b47d07d76 Fix T95724: boundary error in BLI_str_unescape_ex
Fix boundary error in `BLI_str_unescape_ex`. The `dst_maxncpy` parameter
indicates the maximum buffer size, not the maximum number of characters.

As these are strings, the loop has to stop one byte early to allow space
for the trailing zero byte.

Thanks @mano-wii for the patch!
2022-02-18 16:34:00 +01:00
e4b7d52fe4 Fix graphics interop resources leak in Cycles
When new display driver is given to the PathTrace ensure that there are
no GPU resources used from it by the work. This solves graphics interop
descriptors leak.

This aqlso fixes Invalid graphics context in cuGraphicsUnregisterResource
error when doing final render on the display GPU.

Fixes T95837: Regression: GPU memory accumulation in Cycles render
Fixes T95733: Cycles Cuda/Optix error message with multi GPU devices. (Invalid graphics context in cuGraphicsUnregisterResource)
Fixes T95651: GPU error (Invalid graphics context in cuGraphicsUnregisterResource)
Fixes T95631: VRAM is not being freed when rendering (Invalid graphics context in cuGraphicsUnregisterResource)
Fixes T89747: Cycles Render - Textures Disappear then Crashes the Render

Maniphest Tasks: T95837, T95733, T95651, T95631, T89747

Differential Revision: https://developer.blender.org/D14146
2022-02-18 15:26:15 +01:00
02f4d63dcc Fix broken shapekeys: check for 'NULL' from pointer too.
Add check for `NULL` `from` pointer to `BLO_main_validate_shapekeys`,
and delete these shapekeys, as they are fully invalid and impossible to
recover.

Found in a studio production file (`animation
test/snow_parkour/shots/0040/0040.lighting.blend`, svn rev `1111`).
Would be nice to know how this was generated too...
2022-02-18 12:29:27 +01:00
8b4da9a191 Fix strict compilation warnings 2022-02-18 10:14:34 +01:00
fe26d18889 Fix T95809: Check color space changes to refresh image engine.
Previous commit fixed the compositor node, this commit is related to the
shader tree. Also checks if the color space or alpha mode have changed.
2022-02-18 08:22:18 +01:00
400e57b64a Fix T95809: Compositor Node not directly updated in image editor.
Image wasn't tagged to be dirty.
2022-02-18 08:11:51 +01:00
6efdfeb886 Image Engine: Store image usage to identity changes.
Previous implementation had a copy of the image user, which doesn't
contain all the data to identify changes. This patch introduces a new
struct to store the data and can be extended with other data as well
(color spaces, alpha settings).
2022-02-18 07:55:36 +01:00
Pratik Borhade
1d0d810331 Fix T93526: Missing tooltip for attribute search button
For the attribute search button, the tooltip was missing
if the input socket type has attribute toggle activated.

Differential Revision: https://developer.blender.org/D14142
2022-02-17 23:44:16 -06:00
3cdbeb32d3 Fix build error on some compilers after recent bugfix 2022-02-17 20:30:19 +01:00
da6b534274 Fix T95368: wrong white point adaptation for Linear ACES color space
This affected loading of EXR files with set to Linear ACES colorspace, as
well as the sky texture for in some custom OpenColorIO configurations.

Use the builtin OpenColorIO transform from ACES AP0 to XYZ D65 to fix this.
2022-02-17 19:51:43 +01:00
a04300c436 Cleanup: Move more cmake library variables to be advanced
I noticed that there were a few variables that should not be visible per default.
It seems to me to simply be an oversight, so I went ahead and cleaned them up.

Reviewed By: Sybren, Ray molenkamp

Differential Revision: http://developer.blender.org/D14132
2022-02-17 18:42:06 +01:00
9281ba5812 Fix part of T95654: Cycles crash with text objects in excluded view layers
This is a bug on the Blender side, where the depsgraph does not have proper
relations for text object duplis and fails to include the required materials
in the dependency graph. But at least Cycles should not crash.
2022-02-17 17:30:40 +01:00
e5100ca3ad Build: update CMake to support OpenImageIO 2.3.4
FindOpenImageIO was updated to link to separate OpenImageIO_Util for new
versions, where it is required. For older versions, we can not link to it
because there will be duplicated symbols.

Ref D14128
2022-02-17 15:21:09 +01:00
2c9931699e Build: update CMake to support OpenEXR 3
FindOpenEXR was updated to find new lib names and separate Imath. It's all
added to the list of OpenEXR include dirs and libs.

This keeps it compatible with both version 2 and 3 for now, and doesn't
require changes outside the find module.

Ref D14128
2022-02-17 15:21:09 +01:00
cd7550cfe7 Images: update code to support OpenEXR 3
Compatibility with OpenEXR 2 is preserved, since Blender releases and Linux
distribution packages can be on different versions.

Ref D14128
2022-02-17 15:21:09 +01:00
4541249360 Fix compile error on MSVC
`uint` is POSIX type, use `GLuint` like for the rest of the code.
2022-02-17 15:15:46 +01:00
c5dcfb63d9 Fix T94881: GPU subdivision fails with high polycount coarse meshes
Coarse meshes with high polycount would show as corrupted when GPU
subdivision is used with AMD cards This was caused by the OpenSubdiv
library not taking `GL_MAX_COMPUTE_WORK_GROUP_COUNT` into account when
dispatching computes. AMD drivers tend to set the limit lower than
NVidia ones (2^16 for the former, and 2^32 for the latter, at least
on my machine).

This moves the `GLComputeEvaluator` from the OpenSubdiv library into
`intern/opensubdiv` and modifies it to compute a dispatch size in a
similar way as for the draw code: we split the dispatch size into a 2
dimensional value based on `GL_MAX_COMPUTE_WORK_GROUP_COUNT` and
manually compute an index in the shader.

We could have patched the OpenSubdiv library and sent the fix upstream
(which can still be done), however, moving it to our side allows us to
better control the `GLComputeEvaluator` and in the future remove some
redundant work that it does compared to Blender (see T94644) and
probably prepare the ground for Vulkan support. As a matter of fact,
this patch also removes the OpenGL initialization that OpenSubdiv would
do here. This removal is not related to the bug fix, but necessary to not
have to copy more files/code over.

Differential Revision: https://developer.blender.org/D14131
2022-02-17 13:14:19 +01:00
be3047c500 Fix T95827: vertex groups do not display correctly with GPU subdivision
Issue caused by 993839ce85 which modified
the coarse face flags update function, but forgot the case where we have
a mapped extraction with no BMesh.
2022-02-17 08:40:38 +01:00
401383f245 Fix vertex groups not rendering properly with GPU subdivision
This was missing the BMesh case. Issue found while investigating T95827.
2022-02-17 08:38:12 +01:00
dd6fd06c15 Fix T76082: VR Scene Inspection: It shows me only a pink screen
This fixes VR pink screen issues when using the DirectX backend, caused
by `wglDXRegisterObjectNV()` failing to register the shared
OpenGL-DirectX render buffer. The issue is mainly present on AMD
graphics, however, there have been reports on NVIDIA as well.

A limited workaround for the SteamVR runtime (AMD only) was provided
in rB82ab2c167844, however this patch provides a more complete solution
that should apply to all OpenXR runtimes. For example, with this patch,
the Windows Mixed Reality runtime that exclusively uses DirectX can now
be used with AMD graphics cards.

Implementation-wise, a `GL_TEXTURE_2D` render target is used as a
fallback for the shared OpenGL-DirectX resource in the case that
registering a render buffer (`GL_RENDERBUFFER`) fails. While using a
texture render target may be less optimal than a render buffer, it
enables proper display in VR using the OpenGL/DirectX interop (tested
on AMD Vega 64).

Reviewed By: Severin

Differential Revision: https://developer.blender.org/D14100
2022-02-17 15:28:29 +09:00
05697470ab Cleanup: Remove deprecated StringGrid from our openvdb code
StringGrid has been deprecated in openvdb 9.0.0 and will be removed soon

Reviewed By: Brecht

Differential Revision: http://developer.blender.org/D14133
2022-02-16 19:49:58 +01:00
0622d2ec61 Fix T95815: missing null check when computing dupli dimensions
Some instances might be "empty" and therefore have no dimensions.
Those should be ignored here.
2022-02-16 18:58:01 +01:00
257ba175fa Fix: removing anonymous attributes before adding mesh to bmain
This was an issue when e.g. `bpy.data.meshes.new_from_object` was
used on an object that uses geometry nodes.
2022-02-16 15:58:27 +01:00
f059bdc823 Cycles: restore basic standalone GUI, now using SDL
GLUT does not support offscreen contexts, which is required for the new
display driver. So we use SDL instead. Note that this requires using a
system SDL package, the Blender precompiled SDL does not include the video
subsystem.

There is currently no text display support, instead info is printed to
the terminal. This would require adding an embedded font and GLSL shaders,
or using GUI library.

Another improvement to be made is supporting OpenColorIO display transforms,
right now we assume Rec.709 scene linear and display.

All OpenGL, GLEW and SDL code was move out of core cycles and into
app/opengl. This serves as a template for apps that want to integrate
Cycles interactive rendering, with a simple OpenGLDisplayDriver example.
In general this would be adapted to the graphics API and color management
used by the app.

Ref T91846
2022-02-16 15:30:43 +01:00
54972123f7 Fix Image GPU texture.
Due to recent changes there have been reports of incorrect loading of
GPU textures. This fix reverts a part of {D13238} that might be the
source of the issue.
2022-02-16 10:45:46 +01:00
232d5d3f13 Fix T95787: Texture paint: Apply Camera Image crash for certain images
This does not happen with **any** image, but with images that have ID
properties.

ID properties are used to store view projection matrices (e.g. for
reprojection with `Image from View` or `Quick Edit` -- these are the
ones we are interested in), but of course they can be used for anything
else, too. The images in the file from the report have ID properties from
an Addon for example.

So the crash can reliably be reproduced with **any** image doing the
following:
```
bpy.data.images['myImage']['myIDprop'] = "foo"
```
This would lead code in `texture_paint_camera_project_exec` to think the
needed `view_data` is on the image (but in reality it was just some
other IDprop).

Solution is simple: just check `view_data` is really valid after getting
it from the IDprops.

Maniphest Tasks: T95787

Differential Revision: https://developer.blender.org/D14116
2022-02-16 08:35:15 +01:00
53fe4f62fe Fix T95806: subdivision missing in Cycles when using autosmooth
Although rB56407432a6a did fix missing subdivision in some cases, in
other cases it did not return the mesh wrapper (like when using
autosmooth, which requires a copy of the mesh), so the non-subdivided
mesh was still returned.
2022-02-15 20:40:58 +01:00
48b26d9c2e Fix T95697: GPU subdivision ignores custom normals
Similarly to the CPU subdivision, we interpolate custom loop normals
from the coarse mesh, and this for the final normals.
2022-02-15 17:53:22 +01:00
430ced76d5 GPU subdiv: fix custom data interpolation for N-gons
Not all coarse vertices were used to compute the center value (off by
one), and the interpolation for the current would always start at the
base corner for the base face instead of the base corner for the current
patch.
2022-02-15 17:53:12 +01:00
7083ea36e2 Fix T94085: Crash with empty stroke list 2022-02-15 19:49:02 +11:00
d1c7a252eb Fix T95791: Unable to switch between multiviews.
Root cause is copy pasting buggy code.
2022-02-15 09:41:10 +01:00
facd9d8268 Cleanup: clang-format 2022-02-15 01:05:25 +01:00
1f7f7ca14e Fix T95720: Spreadsheet missing volume grid info
The cell drawing code in 474adc6f88 was missing an
implementation for virtual arrays of strings.
2022-02-14 18:00:45 -06:00
d7d827789b GLShaderInterface: Fix undefined behavior when attributes are optimized away.
Optimized out attributes returns an invalid location `-1` resulting in
an undefined behavior shift.
2022-02-15 00:48:18 +01:00
b744081f83 GLDebug: Fix severity check
The check was reversed, leading to less errors being reported.
2022-02-15 00:02:31 +01:00
19b21563d6 GPUTexture: Fix missing enum cases in to_component_len()
This might have caused undersized buffer if using the wrong formats with
`GPU_texture_read()`.
2022-02-15 00:01:04 +01:00
33d5ecd5b5 Fix T95252: Move duplicate node doesn't do edge-panning
Set "view2d_edge_pan" to true for the NODE_OT_translate_attach operator,
which is used by the duplication operator. This is done in the keymap so
that it's not hard-coded.

Differential Revision: https://developer.blender.org/D13934
2022-02-14 12:34:54 -06:00
6ae08da5c8 Fix T95756: Crash inserting geometry node after linking modifier
The root issue was caused by a mistake in modifier copy data which was
wrongly re-generating source modifier data identifier.

The c8cca88851 simply exposed a bug in code which always was there
since the modifiers session UUID was introduced.

Shows an importance of const qualifier :)
2022-02-14 18:19:13 +01:00
a5edff4b73 Fix T95778, the macOS minimum versions have been increased for Metal. 2022-02-14 17:47:35 +01:00
56407432a6 Fix T94479: GPU Subdivision surface modifier does not apply to Cycles renders
Since now we delegate the evaluation of the last subsurf modifier in the stack
to the draw code, Cycles does not get a subdivided mesh anymore. This is because
the subdivision wrapper for generating a CPU side subdivision is never created
as it is only ever created via `BKE_object_get_evaluated_mesh` which Cycles does
not call (rather, it accesses the Mesh either via `object.data()`, or via
`object.to_mesh()`).

This ensures that a subdivision wrapper is created when accessing the object data
or converting an Object to a Mesh via the RNA/Python API.

Reviewed by: brecht

Differential Revision: https://developer.blender.org/D14048
2022-02-14 16:36:32 +01:00
0999a01b03 Fix T95320: CacheFile templates crash when used through Python
The crash is caused as we did not check that the RNA pointer is null
before trying to use it. This moves the existing checks from the
modifier panels into the template functions so the logic is a bit
centralized.
2022-02-14 16:13:25 +01:00
65d4c58060 Fix Cycles assert in debug mode after recent changes
We sometimes call start() on already started renders, just do nothing then.

Ref D14086
2022-02-14 15:45:11 +01:00
993839ce85 Fix T95177: GPU subdiv crashes mirror modifier in edit-mode
The issue has two causes: on one hand origin indices were not handled
properly, on the other hand the extraction type (Mesh, BMesh, or mapped)
was not detected correctly.

For the second case reuse the MeshRenderData creation from the coarse
code path so that we make the same decisions. Loose geometry extraction
had to be updated to properly handle the BMesh cases.

For the origin indices, in some cases (for edges and faces), the arrays
used by the subdivision code already have the origin indices baked into
them, so mapping them a second time through the origin index layer is
wrong, and could cause out of bounds accesses.

For vertices especially, we would use two arrays: one for mapping
subdivision vertices to coarse vertices, and another one to map coarse
vertices to subdivision loops used for the selection index buffer. The
second one is now removed (which saves a bit of memory) as it is did not
have the proper data setup for use with the origin indices and we can
easily compute it using the first array anyway.
2022-02-14 14:48:44 +01:00
3a9a37d6dc Fix T95601: Missing handling of keyingsets ID pointers in lib_query/foreach_id code.
This will have to be backported to 2.93 and possibly 2.83 if possible.
2022-02-14 12:05:11 +01:00
e0fd31f083 Fix segfault calling id_properties_ui("prop").update()
Fix segfault when calling `some_id.id_properties_ui("propname").update()`,
i.e. call the `update()` function without any keyword arguments. In such
a case, Python passes `kwargs = NULL`, but `PyDict_Contains()` is not
`NULL`-safe.
2022-02-14 11:08:53 +01:00
1236d2aea8 Cleanup use c style comments. 2022-02-14 10:58:45 +01:00
d23cf42ba7 Fix T95725: Changing render slot doesn't update displayed image.
Fixed by checking the requested pass, layer and view against the
previous used one.
2022-02-14 10:54:21 +01:00
ab71d833c7 Phase out IMA_GPU_REFRESH.
IMA_GPU_REFRESH is replaced by
BKE_image_partial_update_mark_full_update and should not be used
anymore.
2022-02-14 10:33:56 +01:00
f0e32ef4ff Fix T95699: Compostior backdrop not updated.
The Viewer marked the gpu texture to be out of date. But it should have used
the mark_full_update as the gpu textures
are only used by the render/draw engines.

The image/node editor uses the image engine that have its own GPU textures.
2022-02-14 09:21:05 +01:00
f663a1dc09 Image Engine: Remove region_uv_bounds.
They have been replaced by clipping_uv_bounds. Using region_uv_bounds
could lead to problems when drawing the compositor backdrop.
2022-02-14 09:21:04 +01:00
fe9b3dd5f9 Image Engine: Limit the number of interal textures.
Currently one a single texture slot is used to update the screen.
Current design is implemented to use multiple textures.
for now limit the number of texture slots to 1.
2022-02-14 09:21:04 +01:00
33dde170ce Fix T95749: missing update when normal node changes
This node is a bit of a weird case, because it uses the value stored in an
output socket as an input. So when we want to determine if the Dot
changed, we also have to check if the Normal output changed.

A cleaner solution would be to refactor this by either storing the normal
on the node directly (instead of in an output socket), or by exposing it
by a separate input. This refactor should be done separately though.
2022-02-14 09:08:54 +01:00
517afcc858 Fix T91423: View Animation not working with stereoscopic animations
The animation playback did not take into account individual stereoscopic views.

This patch fixes this by playing back the active view render.

Reviewed By: campbellbarton

Maniphest Tasks: T91423

Differential Revision: https://developer.blender.org/D14070
2022-02-11 20:56:51 -05:00
27d3140b13 Cycles: Fix Metal kernel compilation for AMD GPUs
Workaround for a compilation issue preventing kernels compiling for AMD GPUs: Avoid problematic use of templates on Metal by making `gpu_parallel_active_index_array` a wrapper macro, and moving `blocksize` to be a macro parameter.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D14081
2022-02-11 22:52:48 +00:00
40fce61a6a Cycles: enable Metal on AMD GPUs, set macOS minimum versions
* Apple Silicon support enabled on macOS 12.2+
* AMD support enabled on macOS 12.3+

This patch also fixes a device enumeration crash on certain AMD configs which
was caused by over-release of MTLDevice objects.

Differential Revision: https://developer.blender.org/D14090
2022-02-11 19:22:16 +01:00
8fb2926a53 Cycles: show Metal device in preferences also on Intel Macs
In anticipation of enabling AMD Metal support.

Ref D14090, T92212
2022-02-11 17:51:55 +01:00
9ac1735205 Fix Cycles compilation on 32bit ARM platform
The rbit instruction is only available starting with ARMv6T2 and
the register prefix is different from what AARCH64 uses.

Separate the 32 and 64 bit ARM branches, add missing ISA checks.

Made sure the code works as intended on macMini with Apple silicon,
and on Raspberry Pi 4 B running 32bit Raspbian OS.

Differential Revision: https://developer.blender.org/D14056
2022-02-11 15:27:29 +01:00
6ec83afb1d Cycles: refactor to keep session thread alive for duration of session
Instead of creating and destroying threads when starting and stopping renders,
keep a single thread alive for the duration of the session. This makes it so all
display driver OpenGL resource allocation and destruction can happen in the same
thread.

This was implemented as part of trying to solve another bug, but it did not
help. Still I prefer this behavior, to eliminate potential future issues wit
graphics drivers or with future Cycles display driver implementations.

Differential Revision: https://developer.blender.org/D14086
2022-02-11 14:35:10 +01:00
e2728a0056 Fix T95420: Cycles crash with stereo render and tiles
For reasons unclear, destroying and then recreating a vertex buffer in the
render OpenGL context is affecting the immediate mode vertex buffer in the
draw manager OpenGL context.

Instead just create a single vertex buffer and use it for the lifetime of
the render OpenGL context. There's not really any need to have a separate
one per tile as far as I can tell.

Differential Revision: https://developer.blender.org/D14084
2022-02-11 14:35:10 +01:00
6175c569f9 Tests: enable full Cycles Metal device regression tests on buildbot
Now that all tests are passing. This does add about 5 minutes to the macOS
builds on buildbot.

Ref T92212
2022-02-11 14:35:10 +01:00
2496a94384 Fix T95698: deadlock with GPU subdivision
Multithreaded tasks have to be isolated when holding a mutex, which was
missing for the generation of the subdivision wrapper.
2022-02-11 13:45:12 +01:00
675f38aca7 Fix excessive re-creation of VR viewport textures
Due to the freeing and re-creation of textures performed when binding
offscreen viewports, VR viewport textures would be needlessly
re-created every drawing iteration, leading to a negative impact on VR
frame rate.

This was brought to light by 6738ecb64e, which introduced an
additional texture clear operation on initialization and was
prohibitively costly on some systems when performed every frame.

Now, the textures for VR viewports will not be always re-created
during offscreen binding, but only when necessary using a pre-drawing
step (`wm_xr_session_surface_offscreen_ensure()`).

Reviewed By: jbakker, fclem

Differential Revision: https://developer.blender.org/D14059
2022-02-11 20:46:55 +09:00
2cad80cbc4 Fix incompatible swapchain format for Quest 2
When using a RGBA16 (`GL_RGBA16`, `DXGI_FORMAT_R16G16B16A16_UNORM`)
swapchain format with Quest 2, no image is presented to the headset.
This can occur when using the SteamVR runtime with an AMD graphics card
(ex. T95374).

Workaround is to move this format after the Quest 2-compatible RGBA16F
formats in the candidates list so that the RGBA16F formats are chosen
instead.

Reviewed By: Severin

Differential Revision: https://developer.blender.org/D14024
2022-02-11 20:46:38 +09:00
4fbd00e04c Fix T94268: Closing SteamVR and restarting VR Session crashes Blender
Crash was caused since the function pointers
`s_xrGetOpenGLGraphicsRequirementsKHR_fn`/
`s_xrGetD3D11GraphicsRequirementsKHR_fn` were static and were not
updated with the correct proc address after being set the first time.

As stated in the OpenXR spec: "function pointers returned by
xrGetInstanceProcAddr using one XrInstance may not be valid when used
with objects related to a different XrInstance".

Although it would seem reasonable that the proc address would not
change if the instance was the same (hence the `static XrInstance s_instance;`),
in testing, repeated calls to `xrGetInstanceProcAddress()`
with the same instance still can result in changes (at least for the
SteamVR runtime) so the workaround is to simply set the function pointers
every time, essentially trivializing their `static` designations.

Reviewed By: Severin

Maniphest Tasks: T94268

Differential Revision: https://developer.blender.org/D14023
2022-02-11 20:46:26 +09:00
b38f40e904 Geometry Nodes: show indicator when realize instances node is in legacy mode
For the majority of node groups created in Blender 3.0 the behavior does not change.
So far we only found a single file where this setting has an effect.

Differential Revision: https://developer.blender.org/D14078
2022-02-11 12:24:07 +01:00
0263c8238b Remove 'New' from new Obj exporter menu entry. 2022-02-10 19:00:40 -05:00
f39698de77 Revert "Split Python OBJ importer and exporter, enabling only the importer."
This reverts commit ff9dc1986e.
2022-02-10 18:29:29 -05:00
Henrik Dick
39bac58cdf Fix: Enable edge bevel weight in solidify if needed
Complex Solidify creates edge bevel weights on the rim if the
according vertex has some vertex bevel weight. If there are no
edge bevel weights, they were left disabled even if vertex bevel
weights are used.
2022-02-10 22:29:10 +01:00
Henrik Dick
5cac5a1a69 Fix: Bevel vertex didn't use weights in some cases
Bevel Vertices did not use vertex/bevel weights if the Width Type
was set to Width or Depth.
2022-02-10 22:14:02 +01:00
88ff5e5fb9 Fix T95458: Line art ignores curve objects with no evaluated mesh
Some curve objects don't have an evaluated mesh at all, but line art
currently assumes that all curve objects have one before converting
it to a mesh internally. Fix this by checking if the curve object has an
evaluated mesh before skipping it.

The remaining problem is that evalauted from non-mesh objects or
evaluated curves from non-curve objects, etc. will be ignored if
"Allow Duplicates" is off. That's a different problem though.

Differential Revision: https://developer.blender.org/D14036
2022-02-10 11:33:36 -06:00
a44366a642 Cycles: Expose "Use MetalRT" checkbox
For curve-heavy scenes, memory consumption regressed when we switched from MetalRT to bvh2. Allow users to opt in to MetalRT to workaround this.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D14071
2022-02-10 17:32:46 +00:00
35dedc11d5 Fix T95477: Report error instead of crashing when Metal texture size limits exceeded.
Reviewed By: brecht

Differential Revision: https://developer.blender.org/D14074
2022-02-10 17:06:29 +00:00
3d12dd59ce Cycles: Workaround for failing "bake" unit tests in Metal
Allocate "RenderBuffers" with MTLResourceStorageModeShared.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D14073
2022-02-10 17:05:13 +00:00
410e4e7ce1 Workaround for T94142: Cycles Metal crash with simultaneous viewport and final render
Disable binary archives on Apple Silicon (issue stems from instancing multiple PSOs from the same binary archive). Pipeline creation still filters through the OS shader cache, mitigating any impact on setup times after the initial render.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D14072
2022-02-10 17:04:08 +00:00
25c4000796 Fix T95613: remove anonymous attributes when converting object
This is the same behavior as when applying a geometry nodes modifier
that adds anonymous attributes.
2022-02-10 18:03:37 +01:00
720d653b41 Fix T95624: video texture not refreshing when changing offset in node
The main issue is that the image and image user is not updated correctly
in `rna_ImageUser_update`. `BKE_image_user_frame_calc` does not set the
correct frame, because the image is null. Also `IMA_GPU_REFRESH` is not
set for the same reason.

When gpu materials are first created, it is expected that the frame is set
correctly, and the flag is set if necessary. Therefore, somewhere during
depsgraph evaluation, those have to be updated. The depsgraph node
to do the update existed already. Now there is a new relation so that it is
executed when the node tree changed, not only when the frame changed.
2022-02-10 17:31:25 +01:00
c0674aa145 Fix T95334: Crash with no vertex normals in multires bake
This is partially caused by a stupid mistake in cfa53e0fbe
where I missed initializing the `vert_normals` pointer in
`MResolvePixelData`. It's also caused by questionable assumptions
from DerivedMesh code that vertex normals would be valid.

The fix used here is to create a temporary mesh with the data necessary
to compute vertex normals, and ensure them here. This is used because
normal calculation is only implemented for `Mesh` and edit mesh, not
`DerivedMesh`. While this might not be great for performance, it's
potentially aligned with future refactoring of this code to remove
`DerivedMesh` completely. Since this is one of the last places the data
structure is used, that would be a great improvement.

Differential Revision: https://developer.blender.org/D13960
2022-02-10 10:10:45 -06:00
94f0230230 Fix T95666: Crash when attempting multires linear subdivide
The crash was happening when the mesh had loose edges.

Loose edges are not part of OpenSubdiv topology and hence should not be
communicated to the refiner. Pass ta boolean flag indicating whether an
edge is loose or not in the mesh foreach routines, which seems to be
the easiest way.
2022-02-10 15:51:19 +01:00
04d55038ee Fix size_t -> int -> size_t round trip in Cycles
There are two things achieved by this change:

- No possible downcast of size_t to int when calculating motion steps.
- Disambiguate call to `min()` which was for some reason considered
  ambiguous on 32bit platforms `min(int, unsigned int)`.
- Do the same for the `max()` call to keep them symmetrical.

On an implementation side the `min()` is defined for a fixed width
integer type to disambiguate uint from size_t on 32bit platforms,
and yet be able to use it for 32bit operands on 64bit platforms without
upcast.

This ended up in a bit bigger change as the conditional compile-in of
functions is easiest if the functions is templated. Making the functions
templated required to remove the other source of ambiguity which is
`algorithm.h` which was pulling min/max from std.

Now it is the `math.h` which is the source of truth for min/max.
It was only one place which was relying on `algorithm.h` for these
functions, hence the choice of `math.h` as the safest and least
intrusive.

Fixes 32bit platforms (such as i386) in Debian package build system.

Differential Revision: https://developer.blender.org/D14062
2022-02-10 12:39:41 +01:00
87d2de88fd Fix T95664: missing update after changing active output node 2022-02-10 12:07:48 +01:00
5312cf50a1 Fix strict warning initializing texture result in compositor
From a strict language point of view the code required a braces around
`trgba` initialization. But it is easier to rely on the fact that fields
which are not specified are zero-initialized.
2022-02-10 10:46:06 +01:00
507a4deef1 Fix invalid creation of partial image updater 2022-02-10 10:42:25 +01:00
d1202bd641 Fix T95620: Crash When Entering Edit Mode on a Curve
Under some circumstances, simply adding a curve object and going
to edit mode would cause a crash. This is because the evaluated
`CurveEval` was accessed but also freed by the dependency graph.

The fix reverts the part of b76918717d that uses the
`CurveEval` for the curve object bounds. While this isn't ideal,
it was the previous behavior, and some unexpected behavior
with object bounds is much better than a crash. Plus, given the plans
of using the new "Curves" data-block for evaluated curves, this
situation will change relatively soon anyway.
2022-02-09 11:06:10 -06:00
c69ee218d7 Revert "Fix size_t -> int -> size_t round trip in Cycles"
This reverts commit d74bb7be19.

Need to re-iterate to have a proper support of all platforms.
2022-02-09 16:16:21 +01:00
7313a84c5a Fix T95612: only overwrite existing attributes with matching domain and type
Also fixes T95611 and T95610.

Differential Revision: https://developer.blender.org/D14051
2022-02-09 15:50:03 +01:00
d74bb7be19 Fix size_t -> int -> size_t round trip in Cycles
There are two things achieved by this change:

- No possible downcast of size_t to int when calculating motion steps.
- Disambiguate call to min() which was for some reason considered
  ambiguous on 32bit platforms `min(int, unsigned int)`.

On an implementation side the `min()` is defined for a fixed width
integer type to disambiguate uint from size_t on 32bit platforms,
and yet be able to use it for 32bit operands on 64bit platforms without
upcast.

Fixes 32bit platforms (such as i386) in Debian package build system.

Differential Revision: https://developer.blender.org/D13992
2022-02-09 14:45:39 +01:00
d82384f7e1 Fix T95640: missing null check in previous commit 2022-02-09 12:36:49 +01:00
Alaska
fd6506626b Adjust "Show Backface" tool tip to be more accurate
Reviewed By: fclem

Differential Revision: https://developer.blender.org/D13849
2022-02-09 11:28:39 +01:00
Alaska
d3d9e2abbf Fix small grammatical mistake in Refraction Depth tooltip
Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D13850
2022-02-09 11:26:21 +01:00
06ac599261 Fix T91840: do not create invalid links when inserting a node
Differential Revision: https://developer.blender.org/D14050
2022-02-09 11:19:23 +01:00
de71860555 Fix T95570: missing task isolation when computing normals 2022-02-08 12:12:49 +01:00
1995aae6e3 Fix T94415: Nodes: poor selection behavior inside frame nodes
Previously, node selection made no distinction between a frame node and
other nodes. So a frame node would be selected by their whole rect or
center (depending on box/lasso/circle select). As a consequence of this,
box and lasso could not pratically be started inside a frame node (with
the intention to select a subset of contained child nodes) because the
frame would be selected immediately and tweak-transforming started.
Circle selecting would always contain the frame node as well (making
transforming a subset of nodes without also transforming the whole frame
impossible).

Now change selection behavior so that for all selection modes only the
border [the margin area that is automatically added around all nodes,
see note below] of a frame node is considered in selection. This makes
for a much more intuitive experience when arranging nodes inside frames.

note: to make the area of interest for selection/moving more obvious,
the cursor changes when hovering over (as is done for resizing).
note: this also makes the resize margin consistent with other nodes.
note: this also fixes right resize border (was exclusive instead of
inclusive as every other border)

Also fixes T46540.
2022-02-08 10:14:14 +01:00
b76918717d Fix T95573: Incorrect bounding box of evaluated curve
Account for `CurveEval`, which stores the proper deformed and
procedurally created data, unlike the `nurb` list, which has always
just meant a copy of the original curve.

Also account for the case when the curve is empty by using a -1, 1,
fallback bounding box in that case, just like mesh objects.
2022-02-07 18:42:31 -06:00
Wannes Malfait
229d0ace02 Fix T95532: Merge node deletes everything for empty selections
The problem was that nullptr was returned which is a valid value for
Mesh * and hence the returned optional was treated as having some value.
There was no check for point clouds so that was fixed as well.

Differential Revision: https://developer.blender.org/D14026
2022-02-07 16:08:36 -06:00
11d785edea Fix T95502: macOS app has both python 3.9 and 3.10 executables 2022-02-07 20:51:03 +01:00
Myles Walcott
880e85fc80 Cleanup: Grammar in doc/python_api
* Its -> It's
* Scripts -> Script's
* then -> than

Several phrasing grammar fixes.

Reviewed By: Blendify

Differential Revision: https://developer.blender.org/D14021
2022-02-07 14:28:12 -05:00
65d287a14a Fix T95543: incorrect handling of implicit field inputs in ui 2022-02-07 18:44:30 +01:00
eb071e3d3c Fix: missing null check
This fixes https://github.com/JacquesLucke/animation_nodes/issues/1827.
2022-02-07 18:16:35 +01:00
2f868e5647 Fix T95578: missing update when linking selected nodes
This removes a "narrow" update in `snode_autoconnect` in favor
of the more general update in `node_make_link_exec`.
2022-02-07 17:56:25 +01:00
3cd686cae8 Fix UI messages (typos etc.). 2022-02-07 11:12:37 +01:00
Aras Pranckevicius
1d59a7aa77 Fix T95384: new obj exporter inaccurate roughness value in new exporter.
Fixes T95384. New exporter was missing a fix for T94516 that recently got applied to the python exporter.

Also changed the obj export tests code so that when save_failing_test_output is requested and MTL result is different from the golden expectation, it is saved as well, similar to how it's done for the OBJ file result.
2022-02-06 14:53:07 -05:00
8be20fcc61 GPU: Fix assert when running without --debug-gpu option on older GL
This was caused by rB3a90f93507a344d2b6eb3ae631371348ff977047
2022-02-06 12:39:17 +01:00
59a8bdd48c Fix: Displaying any point cloud in the viewport causes crash
Caused by rBf75449b5f2b04b79, which was missing a null check when
attempting to extract a `CustomData` pointer from an mesh that might
be null if the object isn't a mesh object. The commit added null checks
elsewhere, so simply adding them here is a straightforward fix.

Fixes T95526, T95539
2022-02-05 17:52:04 -06:00
Aras Pranckevicius
c24b2cdebf Fix T95360, new 3.1 obj exporter losing nurbs curve "endpoint".
The new wavefront .obj exporter in 3.1 was producing slightly invalid parm line syntax (missing u), and was not setting first/last N params to zeroes and ones for curves with "endpoint" flag properly.
2022-02-05 17:51:03 -05:00
3a90f93507 GPU: Debug: Avoid double printing of compilation issues
To avoid that, we simply filter using a debug group.
2022-02-05 23:08:49 +01:00
f2087dfc69 GPUTexture: Fix missing/wrong cases in to_data_format() 2022-02-05 19:29:45 +01:00
edc0e77afe GPU: Enable CLOG for gpu when --debug-gpu option is set
This is because all of the debug printing is done through CLog now. Without
it the is little point in this option.
2022-02-05 19:27:21 +01:00
7bdfce687b GL: Fix compute shader label error 2022-02-05 19:27:09 +01:00
0b4cf2984f Fix: Remove incorrect assert in mesh modifier evaluation
Since we have a node that sets a mesh's auto smooth angle
(unfortunately, in retrospect), we generally can't assume at all
that value is the same as whatever input mesh. Similar asserts
were removed previously in 8216b759e9. While the attempt
at assertions to clarify assumptions is noble, this one doesn't
make sense anymore.

I found this while investigating T95479.

Differential Revision: https://developer.blender.org/D14009
2022-02-04 14:19:04 -06:00
a5be935966 Fix uninitialized value in Cycles BVH after recent changes
Found by asan, unknown if it actually caused an issue.
2022-02-04 20:27:49 +01:00
260e6fd46b Workbench: Fix unreported heavily quantized mesh due to driver issue
Detected on `amdgpu-pro` libGL implementation. The workaround is to not
use explicit location for vertex attributes. This is not a real problem
as we don't rely on them for now.
2022-02-04 19:34:48 +01:00
0446c9c875 Fix: Incorrect default distance for merge by distance node
This was an oversight in the patch that added this node,
the default merge distance is meant to be the same as the weld
modifier, 0.001m, meaning by in most situations it removes
vertices generally at the same location.
2022-02-04 12:21:27 -06:00
b61cb67e6d Fix T94410: stopping Cycles render in 3D viewport quad view keeps using CPU
Only one of the four renders was being stopped.
2022-02-04 18:55:07 +01:00
edb0e7ca30 Fix T95471: baking normals wrong after recent MVert normals refactor 2022-02-04 18:15:39 +01:00
0f40855a09 Fix T93851: Cycles wrong glossy indirect pass with volumes 2022-02-04 17:53:39 +01:00
b2e43a4a9d deps_builder: Update to freetype 2.11.1
Required to solve a crash on windows (T95367)

Mostly an uneventful update, except for FreeType
giving its cmake options a rename.

Reviewed By: brecht, sybren
Differential Revision: https://developer.blender.org/D13968
2022-02-04 09:19:10 -07:00
f75449b5f2 Fix T95467: Textures disappear when going to Edit Mesh on Solid Texture mode
The check for existence of custom data layers did not take wrapper nature of
mesh into account.

Quickest and safest for 3.1 solution is to take care of branching of checks
in the draw manager.

Ideally both wrapper and mesh access will happen via the same public API
without branching in the "user" code. That is something outside of the fix
for the coming release though.

Differential Revision: https://developer.blender.org/D14013
2022-02-04 15:54:25 +01:00
2e766ff762 Image Editor: Fix slowdown with 8b colormanaged images.
Byte images are converted to float. Due to an issue how VSE cache is
freeing its images we cannot store these float buffers what leads
to recalculating it for each change in the image editor.

This fix will reduce the slowdown to areas that have the root cause of
the memory leak, so the buffers can be reused between refreshes.

NOTE: The root cause should still be fixed.

Thanks for reporting Sybren!
2022-02-04 15:32:28 +01:00
080dd18cdf Fix T95427: Crash during dragging a link in a node editor
This was caused by macros interpreted as recursive. Workaround by
not using macros at all and just define local variables which
hopefully will be optimized.
2022-02-04 14:05:17 +01:00
8e0763827e Fix T95284 Workbench: "World" Cavity Type Doesn't Render Anything
This was caused by a faulty UBO bind (not updated after renaming).
2022-02-04 14:05:17 +01:00
cb986446e2 Fix Crash: Switching to wireframe mode.
Crash introduced by {rB0cb5eae}.

When switching to between drawing modes the region.draw_buffer could be
uninitialized when the gizmo depth test is performed. When the mouse is
placed on top of a gizmo part that could be highlighted would crash.

This fix adds a early exit when depth testing is requested, but there
isn't a draw_buffer. Not sure this is an root cause fix.

Reported by multiple animators in Blender Studio.
2022-02-04 14:00:06 +01:00
b8a634cb1d Fix T95489: support writing to vertex groups with geometry nodes again
Technically, this can't be relied upon in the long term. It worked more or
less accidentally before. It was broken by a previous fix accidentally. I mainly
bring it back because rBa985f558a6eb16cd6f0 was not expected to have
this side effect.

Note, this change can result in slower performance. Writing to a vertex
groups is less efficient than using a generic attribute.
2022-02-04 13:10:02 +01:00
5088d907e5 Compositor: Backdrop mode changes node grid.
When viewing backdrop on top of the node grid, the grid would be
rendered black when the mode wasn't set to RGBA. This fix fixes this by
reverting the previous fix of drawing the backdrop and implement a
different one that recomputes the UV coordinates on the screen edges.
2022-02-04 09:51:25 +01:00
lictex_
f7a6e8db04 Fix T88579: scale cage doesn't work well for small/large objects
Apply proper view scale for cage 3d's draw_select,
same as draw.

Reviewed By: campbellbarton

Ref D13956
2022-02-04 15:37:07 +11:00
ef2685afea Fix assertion snapping to selected in mesh edit-mode
ED_transverts_create_from_obedit expected an evaluated object.

Add flag to request TX_VERT_USE_MAPLOC to be set, which avoids having to
calculate this data when it's not used as well as the requirement
that the input object be evaluated from the depsgraph.
2022-02-04 11:08:34 +11:00
a0c1306e8c Py Docs: Fix error is version switch
Slile parameter of 4 was looking for the language in the URL but the API docs do not have a language in the URL.
2022-02-03 15:21:44 -05:00
bda210d74a Py Docs: Fix json URL
In the future when we have a docs staging area it will be
important to change where this JSON is pulled from.
For now, always pull from the "Production" versions
2022-02-03 15:06:11 -05:00
e7f74a7d6a Py Docs: Fix typo in previous commit
- Correct spacing
- Add missing comma
2022-02-03 14:37:55 -05:00
6a2fc3230f Py Docs: Implement version switch to switch between versions on the website
This commit adds a version switch similar to the one on the user manual,
in the future it would be nice to refactor both of these into a more generic
code that works for both. Maybe develop this into a sphinx extension.

As part of this change I had to change how the blender hash is displayed.
Instead of the version hash in the top left it has been moved to the page footer.

This change will also be backported to 2.93 LTS, 2.93 LTS, and 3.0.
2022-02-03 14:25:26 -05:00
71cd9f9fbb Fix (unreported) broken logic in proxy to liboverride conversion.
Iterating over scene's objects while we modify those (through proxy to
override conversion code) is call for problems (use after free etc.).

Instead, all proxy objects need to be gathered first in a temporary
list, and processed all at once in a second loop.
2022-02-03 17:19:04 +01:00
4be87e97f4 Fix T94435: remove anonymous attributes when applying modifier
Differential Revision: https://developer.blender.org/D13994
2022-02-03 16:52:16 +01:00
946c70e6a7 Fix (unreported) broken do_version of hidden layers from pre-2.8 files.
`BKE_collection_object_add` ensures given object is added to an editable
collection, and not e.g. a linked or override one.

However, some processes like do_version manipulate collections also from
libraries, i.e. linked collections, in those cases we need a version of
the code that unconditionnally adds the given object to the given
colleciton.
2022-02-03 15:37:05 +01:00
3bcbbf8992 Split Python OBJ importer and exporter, enabling only the importer.
This is from patch D13988. It removes the "- New" from the menu of the
new obj exporter, changes the default addon to just io_import_obj,
and does the right versioning thing.
Also disables the python tests for the old python exporter.
2022-02-03 09:30:55 -05:00
e4c179f1d8 Cleanup: clang-format 2022-02-03 14:54:03 +01:00
Sebastian Herholz
01f1b51a2e Fix T93565: revert Cycles to old normal behavior for point lights
This patch reverts the normal behavior of the spotlights. In the last fix,
the returned normal of a spot light was equal to its direction. This broke
some texturing methods used by artists.

Differential Revision: https://developer.blender.org/D13991
2022-02-03 14:50:06 +01:00
e5a110719f Fix T91254: Some editing operation indirectly delete objects from override collections.
Those cases are fairly hard to track down... Added some more checks,
also at lower levels, more generic levels of object editing, and fixed
core check in liboverride (previously code was assuming that an override
of a collection only could have overrides of objects or linked objects,
but this is not necessarily true).
2022-02-03 14:00:12 +01:00
6c6556c5bd Docs: correct weight paint sample description 2022-02-03 22:57:24 +11:00
59b777eedd Fix T95137: Spline calc_length not working with just 1 NURB point
The NURB case did not properly handle a curve with only 1 point.

Ref D13904
2022-02-03 22:40:32 +11:00
35aedd87e7 Fix T66913: undo after frame-change doesn't refresh properly
Use the ID.recalc flag to detect when updates after frame-change is
needed. Since comparing the last calculated frame doesn't take undo into
account (see code-comment for details).

`ID_RECALC_AUDIO_SEEK` has been renamed to `ID_RECALC_FRAME_CHANGE`
since this is not only related to audio however internally this flag is
still categorized in `NodeType::AUDIO`.

Reviewed By: sergey

Ref D13942
2022-02-03 21:37:42 +11:00
98cc3c6009 Cleanup: clang-format 2022-02-03 21:32:31 +11:00
c8cca88851 Fix assert in original modifiers pointer update function
The issue was happening with a specific file where the ID management
code was not fully copying all modifiers because of the extra check
in the `BKE_object_support_modifier_type_check()`.

While it is arguable that copy-on-write should be a 1:1 copy there is
no real need to maintain the per-modifier pointer to its original.
Use its SessionUUID to perform lookup in the original datablock.

Downside of this approach is that it is a linear lookup instead of
direct pointer access, but the upside is that there is less pointers
to manage and that the file with unsupported modifiers does behave
correct without any asserts.

Differential Revision: https://developer.blender.org/D13993
2022-02-03 10:02:20 +01:00
45d5773519 Cleanup: Use utility function to access original modifier in RNA 2022-02-03 10:02:20 +01:00
c80411ce3b Despgraph: Remove asserts from object modifier backup
The modifiers are mapped between original and evaluated objects based on
their session IDs. The pointer to original modifier is no longer needed
for the backup: it remained from the initial implementation which was
rewritten at some point.

This is a preparation for removal of the pointer to original modifier.
2022-02-03 10:02:20 +01:00
c379223053 Fix wrong function call in Cycles acceleration UI poll.
Thanks to Sergey for spotting this mistake.
2022-02-03 09:57:24 +01:00
b0847eff2a Fix T93625: fallback tools don't work with RMB select
c9d9bfa84a caused a regression in when
the right-mouse select action was set to "Select & Tweak" (default).

Now the fallback tool works with RMB select as it did before.
2022-02-03 17:14:07 +11:00
43b0ff3054 Fix (unreported) bug in liboverride resync code.
Part of the resynching code would access collections' objects base
cache, which can be invalid at that point (due to previous ID remapping
and/or deletion). Use a custom recursive iterator over collections'
objects instead, since those 'raw' data like collection's objects list,
and collection's children lists, should always be valid.

Found while investigating a studio production file.
2022-02-02 16:25:41 +01:00
40b84ffc50 Draw Manager: Marked work around code.
Mark the work around that was added for the VSE memory leak.
2022-02-02 15:05:06 +01:00
fd35aa48d1 Workaround for VSE memory leak.
This is a temp fix for a memory leak where the VSE isn't aware that a
float representation of the image could exist. The VSE somehow doens't
clears it (refcounter is still 1).

The work around is just to let the image engine clean up all the data it
created. Potential this would add more overhead when buffers are needed
more than once.
2022-02-02 14:20:18 +01:00
bf8597febe BLI: fix memory leak in VectorSet
The leak happened when the vector set had to grow when it
was empty but it had allocated the keys array already.
2022-02-02 13:11:33 +01:00
a985f558a6 Fix T95084: evaluate all output attributes before changing geometry
This refactors how output attributes are computed in the geometry
nodes modifier. Previously, all output attributes were computed one
after the other. Every attribute was stored on the geometry directly
after computing it. The issue was that other output attributes might
depend on the already overwritten attributes, leading to unexpected
behavior.

The solution is to compute all output attributes first before changing the
geometry. Under specific circumstances, this refactor can result in a speedup,
because output attributes on the same domain are evaluated together now.
Overwriting existing might have become a bit slower, because we write the
attribute into  new buffer instead of using the existing one.

Differential Revision: https://developer.blender.org/D13983
2022-02-02 10:54:54 +01:00
71b451bb62 Fix T95288: Shrinkwrap selection broken in edit mode
Mistake in the 974981a637: f the edit data is not present then the
origindex codepath is to be used. Added a brief note about it on the
top of the file.

More ideally would be to remove edit mesh from non-bmesh-wrappers
but this would require changes in the draw manager to make a proper
decision about drawing edit mode overlays.
2022-02-02 10:35:32 +01:00
4927919613 Cleanup: Use correct identifier for ShaderParameters.
Code use struct and class, but should only have used struct.
2022-02-02 08:32:32 +01:00
95fcb41841 Fix T95378: Seek problems when timecodes are used
Function `IMB_indexer_get_seek_pos()` can return non 0 seek position for
frame index 0. This causes seeking to incorrect GOP and scanning ends
with failiure.

Hard-code first frame index seek position to 0.

Differential Revision: https://developer.blender.org/D13974
2022-02-01 22:53:24 +01:00
a12265f048 Fix T95353: Crash with proxy auto building
Proxy building data were freed before process was started.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D13972
2022-02-01 22:46:04 +01:00
83b6c8f2b1 Fix T95278: Crash on startup because of GLSL recursion
Bypassing the defines which are only there for error checking.
2022-02-01 19:22:50 +01:00
Falk David
ffb0ecb498 Fix T91463: Separate points makes gap on cyclic stroke
If an entire cyclic stroke was selected, calling "Separate by Points"
would leave a gap in the new object (making the new stroke non-cyclic).

The patch makes sure that if we separate by points and all points are
selected, we fall back to separate by stroke.

Reviewed By: antoniov

Maniphest Tasks: T91463

Differential Revision: https://developer.blender.org/D12527
2022-02-01 18:09:34 +01:00
2bd71b49e7 Fix T95395: dangling parent pointer when creating node group
Differential Revision: https://developer.blender.org/D13981
2022-02-01 17:48:44 +01:00
Falk David
e9150ac317 Fix T89514: GP draw mode not saved when scene is not the active one
This patch fixes the error that pops up
(`Error: Unable to execute '... Mode Toggle', error changing modes`)
when trying to switch to e.g. draw mode from a grease pencil object
that was saved in draw mode in an inactive scene when the file was loaded.

Note that this does not fix the bigger issue described in T91243.

The fix makes sure that we reset all the mode flags on the grease pencil
data when we set the mode to object mode.

Reviewed By: antoniov

Maniphest Tasks: T89514

Differential Revision: https://developer.blender.org/D12419
2022-02-01 16:02:03 +01:00
b03fb70eff Silence draw manager warning.
This message isn't useful for users so silenced it.
2022-02-01 13:50:19 +01:00
f8713aae5e Cleanup: Remove unused datatoc definitions. 2022-02-01 12:14:52 +01:00
217e0a2ce6 Fix T95262: instances ignored in Frame Selected operator
The issue was that the code only looked at `dob->ob`
instead of `dob->ob_data` which is necessary since
rB5a9a16334c573c4566dc9b2a314cf0d0ccdcb54f.

This now uses the same pattern that is used in other places
where `BKE_object_replace_data_on_shallow_copy` is used.
2022-02-01 11:58:53 +01:00
84dab8b597 Fix T95314: constant values not shown in spreadsheet 2022-02-01 11:43:48 +01:00
6f9828289f Fix T95356: Crash in armature edit mode and certain condition
Blender would have crashed when renaming bone in Edit Mode, Saving, and
than selecting/deselecting.

Caused by a mistake in the 0f89bcdbeb: can not "short-circuit" the
CoW update if it was explicitly requested.

Safest for now solution seems to be to store whether the CoW component
has been explicitly tagged, so that the following configuration can be
supported:

    DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
    DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);

Differential Revision: https://developer.blender.org/D13966
2022-02-01 11:04:19 +01:00
396413dedf Partial Fix: Showing Compositor Backdrop in node editor.
Since splitting the depth and the color shader in the image engine the
backdrop wasn't visible anymore. The reson is that the min max uv
coordinates were never working for the node editor backdrop that uses
its own coordinate space.

This partial fix will ignore the depth test when drawing the color part
of the backdrop. This will still have artifacts that are visible when
showing other options as RGBA.

Proper fix would be to calculate the the uv vbo in uv space and not in
image space.
2022-02-01 10:49:28 +01:00
146618fb22 Fix T95376: Fix crash when switching to UV workspace.
Can also happen in other places when the overlay engine is active. Some
parts of the overlay engine uses builtin shaders, but disable the color
space conversion to the target texture.

Currently there the overlay engine has its own set of libraries it could
include and defined a macro to pass-throught the color space conversion.

The library include mechanism currently fails when it couldn't find the
builtin library in the libraries of the overlay engine. This only
happened in debug mode.

This change will not fail, but warns the developer if a library could
not be included. In the future this should be replaced by a different
mechanism that can disable the builtin library. See {T95382}.
2022-02-01 08:38:34 +01:00
c8814fb610 Fix T95185: Invalid normals after undo in sculpt mode
Since d9c6ceb3b8 partial updates to
normals in sculpt-mode were accumulating into the current normal
instead of a zeroed value.

Zero vertex normal values tagged for calculation before accumulation.

Reviewed By: HooglyBoogly

Ref D13975
2022-02-01 15:35:08 +11:00
9ce1135440 Cleanup: remove duplicate vertex normal array in SculptSession
From investigating T95185, it's important the normal returned by
SCULPT_vertex_normal_get always match the PBVH normal array.

Since this is always initialized in the PBVH, there is no advantage
in storing the normal array in two places, it only adds the possibility
that changes in the future causing different meshes normals to be used.

Split out from D13975.
2022-02-01 13:39:19 +11:00
2e4a1a70da Fix building with audaspace disabled 2022-02-01 13:33:50 +11:00
f420118335 Fix T93856: VP9 lossless render missing alpha
Since 0ea0ccc4ff, `AV_PIX_FMT_YUV444P` pixel format was used for
lossless renders, which did override `AV_PIX_FMT_YUVA420P` format when
"RGBA" output is chosen. VP9 encoder doesn't seem to support
`AV_PIX_FMT_YUVA444P` pixel format, so use `AV_PIX_FMT_YUVA420P` for
lossless RGBA ouput instead.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D13947
2022-02-01 00:00:29 +01:00
68c2650b03 Fix T94287: gaps between strips when adding movies
Currently, audio and video strips are synchronized based on data from
media stream, which is nice, but this causes gaps between strips.
This synchronization was implemented by moving movie strip position
relative to sound, which doesn't make much sense for user which is
mostly interested in editing video.

Code was bit hard to read, so it has been simplified. Ideally video
stream time would be easily accessible so synchronization could be done
at any time, but this is not necessary at this point.

Reviewed By: zeddb

Differential Revision: https://developer.blender.org/D13948
2022-01-31 22:22:36 +01:00
c8c9965df2 Fix crash with non-closed meshes in recent bugfix for texture margin
Ref T95249, D13935
2022-01-31 20:59:25 +01:00
5fabbedb04 Fix Cycles assert in light sampling
There is no object transform on lights.
2022-01-31 20:45:12 +01:00
716d8436f0 Fix: Unutilized curve mapping in vector shader node
This could result in a shading errors is some cases such as undo.

Follow up to rB1405787142d1f87f18631114167675ed145f6d75
2022-01-31 12:56:40 -05:00
Leon Schittek
5edb924e57 UI Papercut: Fix gap in node outline
Correct corner radius of the node outline to prevent a noticeable gap in
some cases.

---

Currently we make a small mistake in the creation of the node outline:
We offset the rectangle describing the outline by the outline thickness,
but we don't adjust the corner radius accordingly.
Therefore the rounded corner of the outline and the node body are not
concentric which can sometimes lead to a visible gap at the corner.
How noticeable it is depends on the theme, the screen's dpi and the
line thickness set in the preferences.

Simply adjusting the corner radius for the outline to also be increased
by the outline thickness fixes this small issue.

| display, line thickness | **patch** | **master** |
| --- | --- | --- |
| 1080p, default/thin  | {F12835304} | {F12835305} |
| retina, thin | {F12835306} | {F12835307} |

The issue was mentioned by @hitrpr

Reviewed By: Blendify

Differential Revision: https://developer.blender.org/D13955
2022-01-31 12:31:54 -05:00
Martijn Versteegh
8ad5241778 Fix T95250: bake margin adjacent faces uses stale UV map in edit mode
Use the evaluated mesh to generate the Adjacent Faces margin.

Baking used the evaluated mesh, but generating the margin used the base
mesh. This would lead to generating the margin from a stale UV map when the
UV editor was open and the UV map was changed. Fix it by passing the same
mesh as used for baking through to the margin generation.

Differential Revision: https://developer.blender.org/D13938
2022-01-31 18:18:05 +01:00
Martijn Versteegh
83fa6a1b2a Fix T95249: bake margin adjacent faces fails in some directions
The new adjacent faces method border lookup fails in some directions around
45 degrees

* Use 8 Dijkstra directions (also diagonally) to determine which polygon is the
  closest to each pixel. Using only Manhattan distance lead to large parts of
  the texture which were matched with the wrong polygon.

* Use neighbroing polygons for edge search. The Adjacent Faces algorithm needs
  to determine the closest edge, in UV space, each pixel. To speed this up
  first as map is built which finds the closest polygon for each pixel along
  horizontal, vertical and diagonal steps. Because this can sometimes be one
  edge off we first look in the polygon from the map, if that fails also
  check the edges of its neighbouring UV polygons.

Differential Revision: https://developer.blender.org/D13935
2022-01-31 18:18:04 +01:00
Martijn Versteegh
c626301f19 Cleanup: remove wrong assert
Was accidentally left in after refactoring.

Fixes T95347

Differential Revision: https://developer.blender.org/D13963
2022-01-31 18:18:02 +01:00
5257257539 Fix T95205: remove attribute only once
The bug was caused by a typo.
2022-01-31 17:40:55 +01:00
9578fe3068 Fix T95341: BGL renders incorrect color
Missing include statements of the gpu_shader_colorspace_lib.glsl in
various shaders ignored the target texture color space.
2022-01-31 15:43:13 +01:00
2216699c64 Cleanup: Change NULL to nullptr. 2022-01-31 15:43:13 +01:00
180a68c1dc Fix (studio-reported) missing RNA path for EEVEE render passes.
For those EEVEE passes a bit of trickery with pointer offsets allows to
get the owning viewlayer, so path generation is not too bad.

Also moved ViewLayer path generation itself into a public utils, to
avoid duplicating code.

NOTE: Doing the same for AOV would be needed, but since pointer offsets
won't help us here to find the owning viewlayer, not sure how to do it
nicely yet (only solution I think is to loop over all AOVs of all
ViewLayer of the scene to find it :( ).

Reported by Beau Gerbrands (@Beaug), thanks.
2022-01-31 15:16:36 +01:00
b9718899fa Python: default to version to 3.10 for Linux
This doesn't bump the minimum version, see D13943.
2022-01-31 23:57:10 +11:00
deb90557ea Fix T95332: Crash loading older files.
Image buffer was visible but buffer wasn't available. In the case
the color only overlay of the render result was displayed the image
buffer was not check to be valid.

This patch adds a null pointer check to check in `IMB_alpha_affects_rgb`
to solve this crash.
2022-01-31 12:25:18 +01:00
869180548c Image editor: Fix drawing artifacts with render results.
Use the input depth texture to determine if the color of the texture
should be shown.
2022-01-31 11:59:16 +01:00
dfc959eed6 Fix T95299: Empty render results show transparency checkerboard.
When an image buffer cannot be read the checkerboard should not be
drawn.
2022-01-31 10:51:25 +01:00
cfa235b89d Image Editor: Fix background drawing of empty tiles.
Empty (UDIM) tiles where drawn with a transparency checkerboard. They
should be rendered with a border background. The cause is that the image
engine would select a single area that contained all tiles and draw them
as being part of an image.

The fix is to separate the color and depth part of the image engine
shader and only draw the depths of tiles that are enabled.
2022-01-31 09:57:51 +01:00
Aras Pranckevicius
07514def19 Fix T95328, new obj exporter not exporting custom normals.
Previously, the new obj exporter was only exporting per-vertex normals for faces
marked as "smooth". But a face can have custom normals, as soon as the normals
data layer exists. This change makes it follow the behavior of USD & Collada
exporters and the old Python one, which also export per-vertex normals as soon
as the layer is there. (From Patch D13957.)
2022-01-30 13:48:03 -05:00
2cf3ed13da Fix T95315: "Override Layers" panel open crash with null CacheFile 2022-01-30 01:06:56 +01:00
c9d35ee07c Fix: Eevee: Float Curve node causes issues with compiled shader
This fixes a regression from rBa0edee712a79239133ff840f911f6416d4c41855.
Issue being the curve map not being initialized in the GPU shader function.

Fixes T95221
2022-01-29 13:14:26 -05:00
544a0f2880 Fix memory leak when adding movie strips
Introduced by b45e71e22c.
2022-01-29 01:31:53 +01:00
03b57d3973 Fix T94476: Threading/performance issue with curve to points node
For every spline, *all* of the normals and tangents in the output
were normalized. The node is multithreaded, so sometimes a thread
overwrote the normalized result from another thread.

Fixing this problem also made the node orders of magnitude
faster when there are many splines.
2022-01-28 17:47:14 -06:00
afdc35b636 Fix typos in rB0a8fa07735cdb89081b652c032c73863e34f8ff1 2022-01-28 23:50:49 +01:00
0a8fa07735 Fix T95278: Crash on startup because of GLSL compiler bug
The GLSL defines used to make the uniform names unusable for local variable
is being interpreted as recursive on some implementation.

This avoids it by create a second macro avoiding the recursion.
2022-01-28 23:28:53 +01:00
cb09485ff2 UI: Use property split in new operator popup
This attribute conversion operator was just added.
The UI looks more consistent with property split.
2022-01-28 10:03:07 -06:00
391bb6e9ba Cleanup: Clang-tidy warning gl_shader.cc 2022-01-28 16:35:05 +01:00
b6f640b953 Cleanup: Clang-tidy warnings.
Silence Clang-tidy warnings in gpu module.
2022-01-28 16:18:13 +01:00
3b2a1ff716 Image Engine: Remove unused shader parameter Color.
This change removes an unused shader parameter that also collided when a
local varialble with the same name was used on different platforms.
2022-01-28 15:03:45 +01:00
75e61e5a6d Image Engine: Use GPUShaderCreateInfo.
Ported the image engine shaders to use the GPUShaderCreateInfo struct.
No functional changes.
2022-01-28 15:03:45 +01:00
430f71fce2 Fix insufficient CPU flags checks for Cycles OIDN
Sometime throughout development some checks got lost during refactor.
This change makes it so that if OIDN is not supported on the current
CPU Cycles will report an error and stop rendering. This behavior is
similar to when an OptiX denoiser is requested and there is no OptiX
compatible device available.

The easiest way to verify this change is to force return false from
the `openimagedenoise_supported()`.

Fixes Cycles part of the T94127.

Differential Revision: https://developer.blender.org/D13944
2022-01-28 14:28:04 +01:00
29a1d8b1d3 Fix compilation error in previous commit. 2022-01-28 14:01:25 +01:00
cdcbdf8ce4 Remove compilation warnings TexResult. 2022-01-28 13:28:31 +01:00
7c48196056 Silent compilation warning in space_graph. 2022-01-28 11:48:47 +01:00
be921a04f2 Image engine: Remove unused parameter.
Parameter was used to still be compatible with the previous drawing mode.
The previous mode isn't available anymore so the parameter can should be
removed.
2022-01-28 11:48:47 +01:00
dcb7b3f9f7 Image Engine: Fix issue show alpha flag not reset.
After showing the alpha in the image editor the setting was not reset
so all images in the editor showed as being transparent.

This commit fixes this by resetting the flag before updating.
2022-01-28 11:48:47 +01:00
379814a118 Draw: Remove unused code in image engine shader. 2022-01-28 11:48:47 +01:00
3aa56608f7 3.1 splashscreen
Credit: Lorenzo Aiello - https://orencloud.artstation.com/
2022-01-28 11:32:12 +01:00
f756dc4812 Blender 3.1 Beta- subversion bump 2022-01-28 11:11:11 +01:00
5d4583683b Update pipeline config and point to 3.1 branches. 2022-01-28 11:01:11 +01:00
d45098024e Blender 3.1 bcon3 (beta) 2022-01-28 10:55:28 +01:00
c37b837244 Fix T95060: Outliner: Broken 'make override hierarchy' in indirect linked casae.
In Outliner, 'Make Override Hierarchy' on an indirectly linked data would
fail in case some items higher up in the hierarchy also needed to be
overridden was also indirectly linked.
2022-01-28 10:53:53 +01:00
49b9b0251b Draw: Remove unused shader.
tile images aren't a special case anymore for the image engine.
2022-01-28 10:47:52 +01:00
e1be275878 Fix typo in comment. 2022-01-28 09:24:11 +01:00
Jeroen Bakker
bdd74e1e93 DrawManager: Image engine support huge images.
Adding better support for drawing huge images in the image/uv editor. Also solved tearing artifacts.
The approach is that for each image/uv editor a screen space gpu texture is created that only contains
the visible pixels. When zooming or panning the gpu texture is rebuild.

Although the solution isn't memory intensive other parts of blender memory usage scales together with
the image size.

* Due to complexity we didn't implement partial updates when drawing images tiled (wrap repeat).
  This could be added, but is complicated as a change in the source could mean many different
  changes on the GPU texture. The work around for now is to tag all gpu textures to be dirty when
  changes are detected.

Original plan was to have 4 screen space images to support panning without gpu texture creation.
For now we don't see the need to implement it as the solution is already fast. Especially when
GPU memory is shared with CPU ram.

Reviewed By: fclem

Maniphest Tasks: T92525, T92903

Differential Revision: https://developer.blender.org/D13424
2022-01-28 08:37:45 +01:00
0a32ac02e9 Image: Partial Update Redesign.
This patch reimplements the image partial updates. Biggest design motivation for the redesign
is that currently GPUTextures must be owned by the image. This reduces flexibility and adds
complexity to a single component especially when we want to have different structures.

The new design is not limited to GPUTextures and can also be used by reducing overhead in image
operations like scaling. Or partial image updating in Cycles.

The usecase in hand is that we want to support virtual images in the image editor so we can
work with images that don't fit in a single GPUTexture.

Using `BKE_image_partial_update_mark_region` or `BKE_image_partial_update_mark_full_update`
a part of an image can be marked as dirty. These regions are stored per ImageTile (UDIM).

When a part of the code wants to receive partial changes it needs to construct a `PartialUpdateUser`
by calling `BKE_image_partial_update_create`. As long as this instance is kept alive the changes can
be received.

When a user wants to update its own data it will call `BKE_image_partial_update_collect_changes`
This will collect the changes since the last time the user called this function. When the partial changes
are available the partial change can be read by calling `BKE_image_partial_update_get_next_change`

It can happen that the introduced mechanism doesn't have the data anymore to construct the
changes since the last time a PartialUpdateUser requested it. In this case it will get a request
to perform a full update.

Maniphest Tasks: T92613

Differential Revision: https://developer.blender.org/D13238
2022-01-28 08:06:19 +01:00
1e0758333d Cleanup: add compiler attributes to BLI_path functions 2022-01-28 15:06:29 +11:00
9523b1478e BLI_path: assert passing relative paths to BLI_path_cmp_normalized
Assert when "//" prefixed relative paths are passed to
BLI_path_cmp_normalized as this can't be expanded
and it's possible the paths come from different blend files.
2022-01-28 15:05:21 +11:00
ebd0e76088 Cleanup: indentation for CMake files
Also minor white-space & case changes.
2022-01-28 14:52:47 +11:00
9f6b19526d Cleanup: spelling in comments
Also minor wording improvements.
2022-01-28 14:52:47 +11:00
7475012e24 Cleanup: rename BLI_paths_equal to BLI_path_cmp_normalized
Changes to recent addition: c85c52f2ce.

Having both BLI_paths_equal and BLI_path_cmp made it ambiguous
which should be used, as `BLI_paths_equal` wasn't the equivalent to
`BLI_path_cmp(..) == 0` as it is for string equals macro `STREQ(..)`.
It's also a more specialized function which is not used for path
comparison throughout Blender's internal path handling logic.

Instead rename this `BLI_path_cmp_normalized` and return the result of
`BLI_path_cmp` to make it clear paths are modified before comparison.

Also add comments about the conventions for Blender's path comparison
as well as a possible equivalent to Python's `os.path.samefile`
for checking if two paths point to the same location on the file-system.
2022-01-28 14:50:16 +11:00
f2b24272dd Fix T93328: Movie seeking doesn't work.
Caused by integer overflow in `steps_per_frame` calculation.
2022-01-27 23:21:45 +01:00
da848b7440 GPUShader: Abort in case of dependency issues.
This is to avoid being flooded with compilation errors that are not helpful.
2022-01-27 22:57:02 +01:00
423bbbbaae BLI_float4x4: Add operator[]
This makes porting existing code using `float[4][4]` easier.
2022-01-27 21:35:43 +01:00
Germano Cavalcante
3775615aea Outliner: avoid creating unnecessary undo steps
The `OUTLINER_OT_item_activate` operator, although it detects when
something changes, always returns `OPERATOR_FINISHED` and thus induces
the creation of undo steps.

So return `OPERATOR_CANCELLED` when nothing changes.

Ref T94080

Reviewed By: Severin

Maniphest Tasks: T94080

Differential Revision: https://developer.blender.org/D13638
2022-01-27 15:41:40 -03:00
a21f1e81e0 DRW: Fix some issues with DRW_gpu_wrapper.hh
- Fix assert on size.
- Fix void * casting.
- Pass extent by values.
- Add swap function to avoid letting the types copyable.
- Add back the GPUTexture * operator on TextureFromPool.
2022-01-27 18:46:01 +01:00
87c13ac68c UX: Prevent click-through panels and used header area
Does two main changes:
* Handle regions in the order as visible on screen. Practically this
  just means handling overlapping regions before non-overlapping ones.
* Don't handle any other regions after having found one containing the
  mouse pointer.

Fixes: T94016, T91538, T91579, T71899 (and a whole bunch of duplicates)
Addresses: T92364

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

Reviewed by: Campbell Barton
2022-01-27 18:40:54 +01:00
4710f3346a Event System: Add debug sanity check "always pass" events
Asserts that such events actually always lead to a handler return value
that actually keeps the event passing.

Reviewed by Campbell Barton as part of
https://developer.blender.org/D13539.
2022-01-27 18:40:54 +01:00
74d68e50d3 Revert "Cleanup: Remove unused variables in winstuff.c"
This reverts commit 32a96b80a3.

this needed an ifdef, not a removal, will land a proper fix later
2022-01-27 10:21:35 -07:00
89dbad9085 Fix T95202: Curve to mesh node inconsistent edge vertex order
Though the edge vertices aren't really meant to have an order,
it can make a difference in operations when there isn't any other
information to make decisions from, like etruding a circle of
loose edges (the situation in the report). This commit changes
the order of the vertices in the final cyclic edge to go in the
same direction as all of the other edges.
2022-01-27 11:21:07 -06:00
834b966b41 Fix T95212: Mirror modifier normals crash
The vertex and face normals from the input mesh
were used to calculate the normals on the result,
which could cause a crash because the result should
be about twice as large.

Also remove an unnecessary dirty tag, since it is handled
automatically when creating a new mesh or in the case
of the mirror modifier, when calculating the new custom
face corner normals.
2022-01-27 11:02:10 -06:00
d7ac659e02 Cleanup: Clang tidy
Use nullptr, use named parameters, fix deprecated header
2022-01-27 10:53:53 -06:00
9c341153a2 Fix T95062: Outliner Library Overrides not refreshed when removing overrides.
Those operations were missing the necessary notification for the
Outliner. This was also affecting RNA API of liboverrides.
2022-01-27 17:52:09 +01:00
279a73e429 Fix: Complete transfer attribute input renaming
Complete the renaming from 6a16a9e661
to include variable names and warning messages.
2022-01-27 10:41:41 -06:00
32a96b80a3 Cleanup: Remove unused variables in winstuff.c
This clears up 4 unused variable warnings coming
from BLI_windows_register_blend_extension
2022-01-27 09:37:11 -07:00
25ac6aa5e4 Fix T85233: Transfer Weights tooltip is wrong.
Swap "active" and "selected" in the tooltip if the `use_reverse_transfer`
option is activated.

Reviewed By: mont29

Maniphest Tasks: T85233

Differential Revision: https://developer.blender.org/D13499
2022-01-27 17:21:01 +01:00
658ae5d63f DRW: Fix DRW_gpu_wrapper.hh
The UBYTE datatype is not supported by the clear fallback. Also fix vector
types headers.
2022-01-27 17:05:02 +01:00
Yevgeny Makarov
58e0aa36ea Fix T93766: 'New Collection' entry in 'Move to collection' menu is not translated.
Also fixes similar issues regarding some liboverride menu entries.

Reviewed By: mont29

Maniphest Tasks: T93766

Differential Revision: https://developer.blender.org/D13513
2022-01-27 16:51:14 +01:00
99ffe1153a install_deps: Downgrade python-ztandard to 0.16.0.
Higher version requires a new version of the ztandard library itself.

Ref. T93161/D13922.
2022-01-27 16:16:14 +01:00
6c483479b8 GLFramebuffer: Add assert to check if framebuffer has the expected data
It came to light that there is no error checking when trying to read
a framebuffer plane without anything attached to it.
2022-01-27 16:13:49 +01:00
Michael Kowalski
c85c52f2ce USD Preview Surface material export.
Add `USD Preview Surface From Nodes` export option, to convert a
Principled BSDF material node network to an approximate USD Preview
Surface shader representation. If this option is disabled, the original
material export behavior is maintained, where viewport setting are saved
to the Preview Surface shader.

Also added the following options for texture export.

  - `Export Textures`: If converting Preview Surface, export textures
    referenced by shader nodes to a 'textures' directory which is a
    sibling of the USD file.
  - `Overwrite Textures`: Allow overwriting existing texture files when
    exporting textures (this option is off by default).
  - `Relative Texture Paths`:  Make texture asset paths relative to the
    USD.

The entry point for the new functionality is
`create_usd_preview_surface_material()`, called from
`USDAbstractWriter::ensure_usd_material()`.  The material conversion
currently handles a small subset of Blender shading nodes,
`BSDF_DIFFUSE`, `BSDF_PRINCIPLED`, `TEX_IMAGE` and `UVMAP`.

Texture export is handled by copying texture files from their original
location to a `textures` folder in the same directory as the USD.
In-memory and packed textures are saved directly to the textures folder.

This patch is based, in part, on code in Tangent Animation's USD
exporter branch.

Reviewed By: sybren, HooglyBoogly

Differential Revision: https://developer.blender.org/D13647
2022-01-27 15:51:50 +01:00
d518550c46 Fix crash on older platform due to unsupported clear command
Clearing using GPU_texture_create_2d for unorm texture needs to use
GPU_DATA_FLOAT to match the conversion requirements.
2022-01-27 15:50:38 +01:00
aa2164da33 Cleanup: Fix const correctness warning 2022-01-27 15:26:43 +01:00
5730668dea Downgrade Python zstandard module to 0.16.0
Downgrade the Python zstandard from 0.17.0 to 0.16.0. The Python package
should be linked against the exact same version of libzstd as Blender is,
otherwise it will refuse to load from within the Blender executable.

Python zstandard 0.17.0 links to 1.5.1, whereas we need 1.5.0.
2022-01-27 15:10:05 +01:00
8a20aec403 CMake/Linux/Python:copy either chardet or charset_normalizer
`chardet` was replaced by `charset_normalizer` for modern `requests`.
With this change, `{make,ninja} install` will also copy the latter into
Blender's install directory.
2022-01-27 15:10:05 +01:00
5400018106 Build: enable Python 3.10 on macOS 2022-01-27 15:03:11 +01:00
6f1ab97c53 Cleanup: Add more const correctness to some functions
These are functions that are used by eevee-rewrite which has more strict
const correctness.
2022-01-27 14:59:37 +01:00
78f29c0467 cmake/windows: Enable Python 3.10 2022-01-27 06:57:25 -07:00
0379ddac7d GPUShaderCreateInfo: Add optionnal check for optimized out resources
This opt-in functionnality enabled developper keep track of unused
resources present in the `GPUShaderCreateInfo` descriptors of their
shaders.

The output is pretty noisy at the moment so we do not enforce its usage.
2022-01-27 10:30:06 +01:00
cf31c4ba18 install_deps: Update OSL to 1.11.17.0 for llvm13 compatibility.
While install_deps tries to stay as close as possible from official
Blender versions of the libraries, it also strives to use as many distro
packages as possible.

OSL 1.11.16.0 is the minimal version that builds with llvm13, which is
the default llvm/clang version in e.g. Debian testing.
2022-01-27 09:06:50 +01:00
a99e43b2b7 install_deps: Update python and deps versions as per T93161/D13922. 2022-01-27 09:06:50 +01:00
5abab0a41a GPUShaderCreateInfo: Remove push_constant indexing
This is too much impractical and offers no real benefit.
2022-01-27 08:54:24 +01:00
a7f7b0b77e Deps builder: Python 3.10.2
Also included:

IDNA 3.2 -> 3.2
Charset Normalizer 2.0.6 -> 2.0.10
UrlLib3 1.26.7 -> 1.26.8
Requests 2.26.0 -> 2.27.1
Cython 0.29.24 -> 0.29.26
ZStandard 0.15.2 -> 0.17.0
Numpy 1.12.2 -> 1.22.0

Reviewed by: brecht
Differential Revision: https://developer.blender.org/D13922
2022-01-26 18:09:50 -07:00
1edf520439 Windows: Retire MSVC 2017 support
The lower bar for building blender
is now MSVC 2019 16.9.16.
2022-01-26 17:56:38 -07:00
0e86c60c28 Geometry Nodes: String to Curves Line/Pivot Point
Adds two new attribute outputs:
"Line" outputs the line number of the character.
"Pivot Point" outputs the selected pivot point position per char.
Some refactoring of the text layout code.

Differential Revision: https://developer.blender.org/D13694
2022-01-26 22:12:50 +01:00
bb1e2a80e4 Cleanup: Workbench: Remove extern shader strings
This is not needed anymore with the new dependency system.
2022-01-26 22:04:49 +01:00
710e46cb2d Cleanup: Move specific node tree execution functions into respective module
`node_exec` had some code that was specific to texture/shader nodes.
These functions  arent used outside there module so limit there declarations.

Also make a function static that is only used in `node_exec.c`

Reviewed By: JacquesLucke

Differential Revision: https://developer.blender.org/D13899
2022-01-26 15:29:31 -05:00
cab1f1d9a2 Geometry Nodes: Add or improve various socket descriptions 2022-01-26 14:22:23 -06:00
7b615ca186 Cleanup: Remove RNA data from TreeElement, get via type specific class
The `TreeElement.rnaptr` was only needed for RNA tree-elements. Now it
can be gotten through the new type specific classes, e.g.
`TreeElementRNAProperty.getPointerRNA()`.
2022-01-26 19:15:57 +01:00
9dc0379dc0 Cleanup: Improve function name, introduced in own recent commit
I prefer it this way around now, especially since I'm adding a
`getPointerRNA()` too. Good to keep it match the actual struct names.
2022-01-26 19:15:57 +01:00
f6296e502a Cleanup: Small improvements to Outliner RNA path build function
Smaller cleanups to improve readability of a complex function.
2022-01-26 19:15:57 +01:00
fdd84d36ce Fix incorrect index-key in RNA path built from Outliner
Bug introduced in 7cbcfb7f49.
2022-01-26 19:15:57 +01:00
b57db4b79e Cleanup: Reduce void * reliance of new RNA C++ Outliner elements
Continuation of the previous commit, this time addressing the same for
RNA tree-elements.
2022-01-26 19:15:57 +01:00
fc0dd5583c Cleanup: Reduce void * reliance of new sequencer C++ Outliner elements
Plan is to remove things like `TreeElement.directdata` and to instead
expose specific queries in the new type specific tree-element classes.
e.g. like here: `TreeElementSequence.getSequence()`

For now uses `tree_element_cast<>()` to get the new type specific
tree-element, later these should replace `TreeElement` all together.
2022-01-26 19:15:57 +01:00
08e2885796 Outliner: Function to "cast" C-style TreeElement to typed C++ pendant
Add function to safely request the type-specific C++ element from a
C-style `TreeElement`. Looks like this:
```
TreeElementFoo *te_foo = tree_element_cast<TreeElementFoo>(te);
```
The "cast" will return null if the tree-element doesn't match the
requested type.

This is useful for the transition from the C-style type to the new ones.
2022-01-26 19:15:57 +01:00
da1b6c4c02 Outliner: Port sequencer elements to new tree-element design
Continuation of work started in 2e221de4ce and 249e4df110.

Adds new tree-element classes for sequences, strips and strip
duplicates.
2022-01-26 19:15:57 +01:00
d74c2b5c1f Outliner: Add missing sanity checks for RNA tree-elements
Forgot to add these in 9bce134e56. Also tweaked assert to print a
message that was previously communicated via a comment only.
2022-01-26 19:15:57 +01:00
57dfec79f4 DRW: Fix builtin uniform name mismatch
This lead to severe unreported regression, like volume rendering broken
in workbench.
2022-01-26 19:09:05 +01:00
13f2df3c28 Fix/workaround failing Cycles tests on macOS after ray offset changes
Temporarily blacklist a few tests with overlapping objects as they seem to
give different results on this platform.
2022-01-26 18:52:56 +01:00
489b484b7b Cleanup: GPUShaderShared: Complete vector support
Move some declaration from `GPU_shader_shared.h` to the main
common file and add missing vector declarations.
2022-01-26 18:10:59 +01:00
b42adab3a2 GPUShader: Add GLSL source modification pass to support enums
This uses a light parser / string modification pass to convert
C++ enum declaration syntax to GLSL compatible one.

GLSL having no support for enums, we are forced to convert the
enum values to a series of constant uints.

The parser (not really one by the way), being stupidly simple,
will not change anything to the values and thus make some C++
syntax (like omitting the values) not work.

The string replacement happens on all GLSL files on startup.
I did not measure significant changes in blender startup speed.
There is plans to do all of this at compile time.

We limit the scope of the search to `.h` and `.hh` files to prevent
confusing syntax in `.glsl` files.

There is basic error reporting with file, line and char logging
for easy debuggabiliy.

The requirements to use this enum sharing system are already listed in
`gpu_shader_shared_utils.h` and repeated on top of the preprocessor
function.
2022-01-26 18:10:59 +01:00
e729abb0e2 BLI_string_ref: Add back missing rfind()
Must have been removed in a bad merge or something.
2022-01-26 18:10:59 +01:00
William Leeson
74afc86d4b Cycles: remove ray offsetting
Remove small ray offsets that were used to avoid self intersection, and leave
that to the newly added primitive object/prim comparison. These changes together
significantly reduce artifacts on small, large or far away objects.

The balance here is that overlapping primitives are not handled well and should
be avoided (though this was already an issue). The upside is that this is
something a user has control over, whereas the other artifacts had no good
manual solution in many cases.

There is a known issue where the Blender particle system generates overlapping
objects and in turn leads to render differences between CPU and GPU. This will
be addressed separately.

Differential Revision: https://developer.blender.org/D12954
2022-01-26 17:51:05 +01:00
William Leeson
ae44070341 Cycles: explicitly skip self-intersection
Remember the last intersected primitive and skip any intersections with the
same primitive.

Ref D12954
2022-01-26 17:51:05 +01:00
William Leeson
a9bb460766 Cycles: compute triangle location from barycentric instead of re-intersecting
This is a bit more efficient than what we did before.

Ref D12954
2022-01-26 17:51:05 +01:00
974981a637 Fix T95222: Crash selecting vertices with modifier applied on cage
Caused by 0f89bcdbeb where it was needed for cage and evaluated mesh
to have same behavior in respect of having edit_mesh pointer assigned.
This change makes it so that edit_data is not implied to exist when the
edit_mesh pointer is not null. This was already the case in some other
code.
2022-01-26 17:48:45 +01:00
79927e730e LibOverride: Resync: Do not process overrides that should already have been resynced.
Those cases are almost always synptoms of either bug in code, or broken
files. Re-doin resync on them only costs time and causes extra trash
data as a result, without really helping in any way.
2022-01-26 16:20:08 +01:00
990ed109f2 Fix (unreported) missing 'override-exclusion' flag on new RNA mesh data accessors.
Both new normals (from rBb7fe27314b25) and vpaint (from rBf7bbc7cdbb6c)
RNA arrays were missing the `PROPOVERRIDE_IGNORE`. Those huge blobs of
geometry data should never be processed by liboverride code.
2022-01-26 16:20:08 +01:00
37848d1c8e Assets: enable node group assets
This enables support for node group assets. Previously, node group
assets only worked when the "extended asset browser" experimental
features is enabled.

Differential Revision: https://developer.blender.org/D13748
2022-01-26 15:22:15 +01:00
12b26d21b0 Assets: allow creating preview image by rendering active object
For node groups there is no good default preview generation.
Nevertheless, t would be useful to generate a preview image for a
node group by rendering an object in some cases.

This commit adds a new operator that allows updating the preview
image for the active asset by rendering the active object.
Note, the operator can also be used for other asset types, not just
node groups.

The operator can be found in a menu right below the refresh-preview
button. Currently it is the only operator in that menu. In the future,
more operators to create previews may be added.

Differential Revision: https://developer.blender.org/D13747
2022-01-26 15:10:49 +01:00
6738ecb64e Fix T94900: Fix drawing artifacts sequencer+node editor.
The VSE and node editor only uses an overlay buffer to draw to the screen. The
GPUViewport assumes that platforms clears all textures during creation, but
they do not on selected platforms. What would lead to drawing from
uncleared memory.

This patch fixes this by clearing all viewport textures during creation.
2022-01-26 14:48:28 +01:00
5b299e5999 D13910: Workbench: Port shaders to use GPUShaderCreateInfo
Also adds a few things to GPUShader for easily create shaders.
Heavy usage of macros to compose the createInfo and avoid
duplications and copy paste bugs.
This makes the link between the shader request functions
(in workbench_shader.cc) and the actual createInfo a bit
obscure since the names are composed and not searchable.

Reviewed By: jbakker
Differential Revision: https://developer.blender.org/D13910
2022-01-26 12:46:37 +01:00
9bce134e56 Outliner: Port RNA elements to new tree-element design
Continuation of work started in 2e221de4ce and 249e4df110.

Adds new tree-element classes for RNA structs, properties and array
elements. This isn't exactly a copy and paste, even though logic should
effectively be the same. Further cleanups are included to share code in
a nice way, improve code with simple C++ features, etc.
2022-01-26 11:44:58 +01:00
1bf6a880ab ID: Fix failing test cases.
This fixes failing test cases when using `make test`.
See {D13615} for more information.

The fix will perform the id remapping one item at a time. Although not
really nice, this isn't a bottleneck.

The failing test cases is because space_node stores pointers multiple
times and didn't update all pointers. It was not clear why it didn't do
it, but changing the behavior more to the previous behavior fixes the
issue at hand.

I prefer to remove the double storage of the node tree pointers (in
snode and path) to reduce pointer management complexity.
2022-01-26 11:12:52 +01:00
Jeroen Bakker
a21bca0e20 Performance: Remap multiple items in UI
During sprite fright loading of complex scenes would spend a long time in remapping ID's
The remapping process is done on a per ID instance that resulted in a very time consuming
process that goes over every possible ID reference to find out if it needs to be updated.

If there are N of references to ID blocks and there are M ID blocks that needed to be remapped
it would take N*M checks. These checks are scattered around the place and memory.
Each reference would only be updated at most once, but most of the time no update is needed at all.

Idea: By grouping the changes together will reduce the number of checks resulting in improved performance.
This would only require N checks. Additional benefits is improved data locality as data is only loaded once
in the L2 cache.

It has be implemented for the resyncing process and UI editors.
On an Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz 16Gig the resyncing process went
from 170 seconds to 145 seconds (during hotspot recording).

After this patch has been applied we could add similar approach
to references (references between data blocks) and functionality (tagged deletion).
In my understanding this could reduce the resyncing process to less than a second.
Opening the village production file between 10 and 20 seconds.

Flame graphs showing that UI remapping isn't visible anymore (`WM_main_remap_editor_id_reference`)
* Master {F12769210 size=full}
* This patch {F12769211 size=full}

Reviewed By: mont29

Maniphest Tasks: T94185

Differential Revision: https://developer.blender.org/D13615
2022-01-26 11:12:35 +01:00
b3bf46b78d Revert "CMake: include BROTLI_LIBRARIES in FREETYPE_LIBRARIES on UNIX"
This reverts commit 086f191169.

There was apparently a problem using APPEND which wasn't referenced
in the commit log.

Added comment noting the reason for the discrepancy.
2022-01-26 20:51:04 +11:00
0cb5eae9d0 Gizmo: optimize intersection tests, fix selection bias
Use more efficient logic for detecting when gizmos are under the cursor.
Even though this isn't a bottleneck, it runs on cursor motion in the
3D viewport, so avoiding any lag here is beneficial.

The common case for cursor motion without any gizmos was always
drawing two passes (one small, then again if nothing was found).

Now a single draw call at the larger size is used.

In isolation this gives around 1.2x-1.4x speedup.

When there are multiple gizmos a depth-buffer picking is used
(similar to object / bone selection) which is more involved but
still only performs 2x draw calls since the result is cached for reuse.

See note in gizmo_find_intersected_3d for a more detailed explanation.

Also restore the depth values in the selection result as they're
needed for gizmos to use selection bias.
Broken since support for GL_SELECT was removed.
2022-01-26 17:24:21 +11:00
1758dcd423 Fix T94794: Gizmo selection doesn't pick the front-most gizmo
Early on in 2.8x development gizmo-depth used GL_SELECT,
which has been removed. Bind the depth buffer so occlusion queries
use the front-most gizmo.

While this report only mentions face-maps, gizmo depth was ignored in
all cases. This wasn't noticeable in most cases though since the
transform gizmo for example was placed so gizmos didn't overlap.
2022-01-26 17:21:10 +11:00
9338126ecc Fix error using GPU selection cache for selection picking
When calling GPU_select_cache_begin, checking the selection mode used
the last used selection mode, not the one about to be used.

Using border select, then picking would not use the selection cache.

This wasn't noticeable by users as failing to use cache just completes
the selection without it (drawing the depth buffer unnecessarily).
2022-01-26 17:21:10 +11:00
46ae083113 Fix: OSL not recognizing UVTILE images
The OSL image compilation step needed to be taught about the new UVTILE
format for UDIM textures.

A small missing feature from OIIO[1] means this is a bit uglier than it
needs to be. Once we update to a version of OIIO with the fix we can
remove the string replace part.

[1] 35cb6a83e2

Differential Revision: https://developer.blender.org/D13912
2022-01-25 22:00:23 -08:00
b06fff4737 Cleanup: spelling in comments 2022-01-26 16:06:22 +11:00
94d2a611ec Cleanup: unused variable warning, formatting 2022-01-26 16:01:34 +11:00
37e555d2fe CMake: mark all BROTLI libraries as advanced 2022-01-26 16:01:00 +11:00
086f191169 CMake: include BROTLI_LIBRARIES in FREETYPE_LIBRARIES on UNIX
This was already done for APPLE & WIN32, which would
reference these libraries twice.

Now append BROTLI_LIBRARIES to FREETYPE_LIBRARIES when they're
required for linking.

No functional changes as all references to FREETYPE_LIBRARIES also
used BROTLI_LIBRARIES.
2022-01-26 16:00:55 +11:00
4c951bfa82 CMake: add WITH_SYSTEM_FREETYPE to link against the systems freetype 2022-01-26 15:31:30 +11:00
4530449317 CMake: resolve issues using pre-compiled & system libraries for Unix
When LIBDIR existed, searching for system libraries would always
first search 'LIBDIR'.

This meant "WITH_SYSTEM_*" would still prefer LIBDIR versions of
libraries if they exist.

The presence of LIBDIR also ignored the setting for WITH_STATIC_LIBS
which is now restored to the cached value once pre-compiled libraries
have been handled.
2022-01-26 15:20:32 +11:00
c4bedeb018 GLShader: Fix crash caused by redundant uniform declaration
This slipped through during a rebase.
2022-01-26 00:03:27 +01:00
83094d9a0d Fix T94149: Incorrect sound strip length
Fix formula in function `SEQ_sound_update_length`.

Formula for sound strip length was changed in commit ded68fb102, when
strip is added to timeline, but it was not changed in function
mentioned above.
2022-01-25 23:59:50 +01:00
c1b5cea63a Cleanup: Remove useless comments 2022-01-25 16:54:36 -06:00
b45e71e22c VSE: Build proxies only for slow movies
This change applies only for automatic proxy building, when strip
is added to timeline. Manual building process is not affected.

Don't build proxy file if movie is already fast enough to seek.
To determine seek performance, check if whole GOP can be decoded
in 100 milliseconds.

To consider some variation in GOP size, large number of packets are
read, assuming that each packet will produce 1 frame. While this is not
technically correct, it does give quite accurate estimate of maximum GOP
size.

This test will ensure consistent performance on wide array of machines.
Check should be done in order of few milliseconds.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D11671
2022-01-25 22:06:46 +01:00
597eaeaa11 Deps builder: add VS2019, remove 2013/2015 support
This will allow building most deps with VS2019
SDL has some linker issues that are resolved in
a newer version, but that would be better handled
in a separate change.

VS2013 and VS2015 support which was broken has
been removed.
2022-01-25 13:55:18 -07:00
52b2769b9c Fix T95169: Assert in weld modifier code
Return early before accessing the array when all edges are merged.
2022-01-25 13:56:00 -06:00
c847122096 Cleanup: Remove leftover hair fade code in Cycles
Missed in rB1687903fb813f6656453fbc7c49237b06437370c
2022-01-25 14:14:39 -05:00
1687903fb8 Cleanup: Remove leftover hair fade code in Cycles. 2022-01-25 19:46:10 +01:00
c89d6b0953 Workbench: Use GPU_ARB_gpu_shader5 instead of GL variant
This is to be able to turn off the extension usage on demand.
2022-01-25 18:51:31 +01:00
2637f94358 GLShader: Fix buffer overflow caused by workaround uniform
In order to use a workaround builtin uniform, we need to count it
just like other uniforms and give it some space in the name buffer.

This also fixes extensions being added after the uniform declaration.
All `#extension` directives are now part of the gl backend.
2022-01-25 18:48:58 +01:00
3e2591c83e Cleanup: Remove unused variable
Mistake in a18bd403bf
2022-01-25 11:08:34 -06:00
0ec94d5359 Geometry Nodes: Port weld modifier to the merge by distance node
This commit moves the weld modifier code to the geometry module
so that it can be used in the "Merge by Distance" geometry node
from ec1b0c2014. The "All" mode is exposed in the node
for now, though we could expose the "Connected" mode in the future.

The modifier itself is responsible for creating the selections from
the vertex group. The "All" mode takes an `IndexMask` for the
selection, and the "Connected" mode takes a boolean array,
since it actually iterates over all edges.

Some disabled code for a BVH mode has not been copied over,
it's still accessible through the patches and git history anyway,
and it made the port slightly simpler.

Differential Revision: https://developer.blender.org/D13907
2022-01-25 11:07:31 -06:00
932d8dba52 Point Cloud: expose in Python API for release, now that Cycles uses it
Previously it was only part of experimental features in beta, however now
renderers can render point clouds generated by geometry nodes. Adding or
converting a point cloud object directly is still hidden by default, since
there is no good way to edit it.
2022-01-25 18:03:52 +01:00
ec1b0c2014 Geometry Nodes: Initial merge by distance node
This implements a merge by distance operation for point clouds.
Besides the geometry input, there are two others-- a selection
input to limit the operation to certain points, and the merge
distance. While it would be a reasonable feature, the distance
does not support a field currently, since that would make
the algorithm significantly more complex.

All attributes are merged to the merged points, with the values
mixed together. This same generic method is used for all attributes,
including `position`. The `id` attribute uses the value from the
first merged index for each point.

For the implementation, most of the effort goes into creating a
merge map to speed up attribute mixing. Some parts are inherently
single-threaded, like finding the final indices accounting for the
merged points. By far most of the time is spend balancing the
KD tree.

Mesh support will be added in the next commit.

Differential Revision: https://developer.blender.org/D13649
2022-01-25 10:51:52 -06:00
97a023a0d5 Cycles: Reorganize Acceleration Structure UI panel.
Only show options that are valid for the used device (CPU, GPU, Multi).

Note: The panel isn't shown for OPTIX anymore, unless Multi device is used.

Reference: https://developer.blender.org/D13592
2022-01-25 17:33:41 +01:00
e2a36a6e45 Cycles: Make Embree compact BVH optional
Make the Embree RTC_SCENE_FLAG_COMPACT flag optional and enabled per default.
Disabling it makes CPU rendering a bit faster in some scenes at the cost of a higher memory usage.

Barbershop renders about 3% faster, victor about 4% on CPU with compact BVH disabled.

Differential Revision: https://developer.blender.org/D13592
2022-01-25 17:22:08 +01:00
f26c36c96b make.bat: unify python detection
Several sub commands tried on their own
to locate python, given I wanted to look
in several locations for a broader libdir
compatibility this is best done in a
central location.

Python 3.9 is still preferred, but if
3.10-3.12 are available that be accepted
as well.

note: this is about the python version
make.bat uses to run various python helper
scripts, this change has no influence on
the python version blender itself uses.
2022-01-25 09:19:03 -07:00
c813a1b358 Cycles: add Point Info node
With (center) position, radius and random value outputs.

Eevee does not yet support rendering point clouds, but an untested
implementation of this node was added for when it does.

Ref T92573
2022-01-25 17:14:20 +01:00
eab066cbf2 VSE: Use timecodes by default
Movies with variable frame rate can cause mismatch of displayed frame
when proxies are used. Since proxies are not used for rendering, this
means, that output may be different than expected. This problem can be
avoided when timecodes are used.

Set used timecode to Record Run. Timecodes are built with proxies at
the same time, therefore if proxies are built and used this will
resolve possible mismatch of output.

Record run is chosen, because it will show frames based on time they
were encoded by encoder and should match behavior as if movie was
played back at normal speed. This change is done only for new strips
in order to not overwrite user defined settings.

Other minor changes:
- When proxies are enabled, size 25% is no longer set by default. It was mostly annoying anyway.
- Silence warning when timecode file is not present. This was introduced in 4adbe31e2f.
  Previously use of timecodes was hard-coded in sequencer and this error would spam console if timecodes would be
  enabled by default and proxies would be never built.

ref: T95093

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D13905
2022-01-25 17:07:11 +01:00
Michael
2ed73fc97e Fix T94237: Glitch when copying unaligned ffmpeg buffer
Using a negative linesize to flip an image vertically is supported in
ffmpeg but not for every function.

This method treats frames that need and those that do not need alignment
the same. An RGBA frame buffer with alignment that ffmpeg decides is
optimal for the CPU and build options is allocated by ffmpeg.
The `sws_scale` does the colorspace transformation into this RGBA frame
buffer without flipping. Now the image is upside down and aligned.
The combined unaligning and vertical flipping is then done by
`av_image_copy_to_buffer` which seems to handle negative linesize
correctly.

Reviewed By: ISS

Differential Revision: https://developer.blender.org/D13908
2022-01-25 17:07:11 +01:00
a18bd403bf Nodes: Improve link-drag search support for boolean math node
List the operations in the search instead of the "Boolean" socket names.
2022-01-25 09:51:20 -06:00
96667e3391 Fix T93058: Crash on opening old pre-2.80 .blend files.
Layer resync code would not yet fully properly deal with all possible
invalid status of ViewLayer comming from those older files.

Now put 2.80-doversion specific fixes into their own dedicated
function, so that they do not affect actual regular layer resync code
anymore. Also added some sanity-checks in main
`BKE_layer_collection_sync` code.
2022-01-25 16:44:55 +01:00
6c25aabddf GLShader: Fix fallback to gl_BaseInstance
All `#entension` directives needs to be first before any other
token. Add missing `;` after uniform declaration.
2022-01-25 16:23:54 +01:00
0477ca75f0 CMake/Linux: only link to brotli when using static precompiled libraries
The Brotli library only needs to be explicitly linked when using the
statically linked libraries. When using system libs they're shared, and
the .so loading mechanism takes care of dependencies.
2022-01-25 16:18:59 +01:00
Hallam Roberts
14f6afb090 Geometry Nodes: Expand the Boolean Math node
Currently the Boolean Math node only has 3 basic logic gates:
AND, OR, and NOT. This commit adds 6 additional logic gates
for convenience and ease of use.

- **Not And (NAND)** returns true when at least one input is false.
- **Nor (NOR)** returns true when both inputs are false.
- **Equal (XNOR)** returns true when both inputs are equal.
- **Not Equal (XOR)** returns true when both inputs are different.
- **Imply (IMPLY)** returns true unless the first input is true and
  the second is false.
- **Subtract (NIMPLY)** returns true when the first input is true and
  the second is false.

Differential Revision: https://developer.blender.org/D13774
2022-01-25 09:09:39 -06:00
368bfa80f9 Fix: Build issue with MSVC + Python 3.10
ssize_t is a posix type pyconfig.h previously
supplied for MSVC, it appears to have stopped
doing this in the python 3.10 headers.

Py_ssize_t is the type of the field this macro
actually returns, so best to to use that in our
code as well.
2022-01-25 07:54:28 -07:00
460e0a1347 Revert "Performance: Remap multiple items in UI"
This reverts commit 948211679f.
This commit introduced some regressions in the test suite.
As this change is a core part of blender Bastien and I decided to revert
it as the solution isn't clear and needs more investigation.

The following tests FAILED:
	 62 - blendfile_liblink (SEGFAULT)
	 63 - blendfile_library_overrides (SEGFAULT)

It fails in (id_us_ensure_real)
2022-01-25 15:31:46 +01:00
33ba298b5d GPUShader: Add optionnal single shader stage interface for in and out
This makes optionnal the use of a different interface for the geometry
shader stage output. When the vertex and geometry interface instance name
matches, a `_in` and `_out` suffix is added to the end of the instance name.

This makes it easier to have optional geometry shader stages.

# Conflicts:
#	source/blender/gpu/intern/gpu_shader_create_info.hh
2022-01-25 15:08:11 +01:00
Jeroen Bakker
948211679f Performance: Remap multiple items in UI
During sprite fright loading of complex scenes would spend a long time in remapping ID's
The remapping process is done on a per ID instance that resulted in a very time consuming
process that goes over every possible ID reference to find out if it needs to be updated.

If there are N of references to ID blocks and there are M ID blocks that needed to be remapped
it would take N*M checks. These checks are scattered around the place and memory.
Each reference would only be updated at most once, but most of the time no update is needed at all.

Idea: By grouping the changes together will reduce the number of checks resulting in improved performance.
This would only require N checks. Additional benefits is improved data locality as data is only loaded once
in the L2 cache.

It has be implemented for the resyncing process and UI editors.
On an Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz 16Gig the resyncing process went
from 170 seconds to 145 seconds (during hotspot recording).

After this patch has been applied we could add similar approach
to references (references between data blocks) and functionality (tagged deletion).
In my understanding this could reduce the resyncing process to less than a second.
Opening the village production file between 10 and 20 seconds.

Flame graphs showing that UI remapping isn't visible anymore (`WM_main_remap_editor_id_reference`)
* Master {F12769210 size=full}
* This patch {F12769211 size=full}

Reviewed By: mont29

Maniphest Tasks: T94185

Differential Revision: https://developer.blender.org/D13615
2022-01-25 14:51:44 +01:00
Jeroen Bakker
3f42417cd4 Draw: Migrate hair refine compute shader to use create info.
This patch migrates the draw manager hair refine compute shader to use
GPUShaderCreateInfo.

Reviewed By: fclem

Differential Revision: https://developer.blender.org/D13915
2022-01-25 14:46:45 +01:00
196da819ba Python: Expose crazyspace correction functionality via RNA
Allows to perform correction of coordinate delta/displacement in a
similar way of how sculpt mode handles sculpting on a deformed mesh.
An example of usecase of this is allowing riggers and sciprters to
improve corrective shapekey workflow.

The usage consists of pre-processing and access. For example:

  object.crazyspace_eval(depsgraph, scene)

  # When we have a difference between two vertices and want to convert
  # it to a space to be stored, say, in shapekey:
  delta_in_orig_space = rigged_ob.crazyspace_displacement_to_original(
      vertex_index=i, displacement=delta)

  # The reverse of above.
  delta_in_deformed_space = rigged_ob.crazyspace_displacement_to_deformed(
      vertex_index=i, displacement=delta)

  object.crazyspace_eval_clear()

Fuller explanation with actual usecases and studio examples are written in
the comment:

  https://developer.blender.org/D13892#368898

Differential Revision: https://developer.blender.org/D13892
2022-01-25 14:43:44 +01:00
31296f6f9d CMake/Linux: Fix Brotli library finding on standard distros.
Brotli seems to add a custom postfix to its static libraries by default,
but in Debian at least libraries are just named the same for both shared
and static versions, as usual.

So add standard name after static-specific ones.

Follow-up to rB4c617c06e9cb and rBa000de7c2a4d.
2022-01-25 14:34:33 +01:00
0f89bcdbeb Fix depsgraphs sharing IDs via evaluated edit mesh
The evaluated mesh is a result of evaluated modifiers, and referencing
other evaluated IDs such as materials.
It can not be stored in the EditMesh structure which is intended to be
re-used by many areas. Such sharing was causing ownership errors causing
bugs like

  T93855: Cycles crash with edit mode and simultaneous viewport and final render

The proposed solution is to store the evaluated edit mesh and its cage in
the object's runtime field. The motivation goes as following:

- It allows to avoid ownership problems like the ones in the linked report.
- Object level is chosen over mesh level is because the evaluated mesh
  is affected by modifiers, which are on the object level.

This patch allows to have modifier stack of an object which shares mesh with
an object which is in edit mode to be properly taken into account (before
the change the modifier stack from the active object will be used for all
objects which share the mesh).

There is a change in the way how copy-on-write is handled in the edit mode to
allow proper state update when changing active scene (or having two windows
with different scenes). Previously, the copt-on-write would have been ignored
by skipping tagging CoW component. Now it is ignored from within the CoW
operation callback. This allows to update edit pointers for objects which are
not from the current depsgraph and where the edit_mesh was never assigned in
the case when the depsgraph was evaluated prior the active depsgraph.

There is no user level changes changes expected with the CoW handling changes:
should not affect on neither performance, nor memory consumption.

Tested scenarios:

- Various modifiers configurations of objects sharing mesh and be part of the
  same scene.

- Steps from the reports: T93855, T82952, T77359

This also fixes T76609, T72733 and perhaps other reports.

Differential Revision: https://developer.blender.org/D13824
2022-01-25 14:32:23 +01:00
c5980ada4f GPU: Add GPU_shader_create_from_info_name
This function will be used as the way to build shaders from
create_infos. The previous used method was using a private function.
2022-01-25 14:22:44 +01:00
Kevin C. Burke
17b0c06946 Animation: Equalize Handle Operator
The Equalize Handles operator allows users to make selected handle
lengths uniform: either respecting their original angle from the key
control point or by flattening their angle (removing the overshoot
sometimes produced by certain handle types).

Design: T94172

Reviewed by: sybren

Differential Revision: https://developer.blender.org/D13702
2022-01-25 11:41:40 +01:00
a000de7c2a CMake/Linux: find Brotli library the proper way
Use a `FindBrotli.cmake` module instead of manually appending library
paths.

This is just for Linux; Windows and macOS will be reviewed separately.
2022-01-25 11:34:13 +01:00
682 changed files with 21136 additions and 8747 deletions

View File

@@ -273,11 +273,13 @@ endif()
if(UNIX AND NOT APPLE)
option(WITH_SYSTEM_GLEW "Use GLEW OpenGL wrapper library provided by the operating system" OFF)
option(WITH_SYSTEM_GLES "Use OpenGL ES library provided by the operating system" ON)
option(WITH_SYSTEM_GLEW "Use GLEW OpenGL wrapper library provided by the operating system" OFF)
option(WITH_SYSTEM_FREETYPE "Use the freetype library provided by the operating system" OFF)
else()
# not an option for other OS's
set(WITH_SYSTEM_GLEW OFF)
set(WITH_SYSTEM_GLES OFF)
set(WITH_SYSTEM_FREETYPE OFF)
endif()
@@ -683,7 +685,7 @@ if(WIN32 OR XCODE)
option(IDE_GROUP_PROJECTS_IN_FOLDERS "Organize the projects according to source folder structure." ON)
mark_as_advanced(IDE_GROUP_PROJECTS_IN_FOLDERS)
if (IDE_GROUP_PROJECTS_IN_FOLDERS)
if(IDE_GROUP_PROJECTS_IN_FOLDERS)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
endif()
endif()

View File

@@ -25,8 +25,13 @@ else()
endif()
if(WIN32)
set(BOOST_TOOLSET toolset=msvc-14.1)
set(BOOST_COMPILER_STRING -vc141)
if(MSVC_VERSION GREATER_EQUAL 1920) # 2019
set(BOOST_TOOLSET toolset=msvc-14.2)
set(BOOST_COMPILER_STRING -vc142)
else() # 2017
set(BOOST_TOOLSET toolset=msvc-14.1)
set(BOOST_COMPILER_STRING -vc141)
endif()
set(BOOST_CONFIGURE_COMMAND bootstrap.bat)
set(BOOST_BUILD_COMMAND b2)

View File

@@ -19,13 +19,10 @@
set(FREETYPE_EXTRA_ARGS
-DCMAKE_RELEASE_POSTFIX:STRING=2ST
-DCMAKE_DEBUG_POSTFIX:STRING=2ST_d
-DWITH_BZip2=OFF
-DWITH_HarfBuzz=OFF
-DFT_WITH_HARFBUZZ=OFF
-DFT_WITH_BZIP2=OFF
-DFT_WITH_BROTLI=ON
-DCMAKE_DISABLE_FIND_PACKAGE_HarfBuzz=TRUE
-DCMAKE_DISABLE_FIND_PACKAGE_BZip2=TRUE
-DFT_DISABLE_BZIP2=ON
-DFT_DISABLE_HARFBUZZ=ON
-DFT_DISABLE_PNG=ON
-DFT_REQUIRE_BROTLI=ON
-DPC_BROTLIDEC_INCLUDEDIR=${LIBDIR}/brotli/include
-DPC_BROTLIDEC_LIBDIR=${LIBDIR}/brotli/lib
)

View File

@@ -31,7 +31,7 @@ ExternalProject_Add(external_python_site_packages
CONFIGURE_COMMAND ${PIP_CONFIGURE_COMMAND}
BUILD_COMMAND ""
PREFIX ${BUILD_DIR}/site_packages
INSTALL_COMMAND ${PYTHON_BINARY} -m pip install ${SITE_PACKAGES_EXTRA} cython==${CYTHON_VERSION} idna==${IDNA_VERSION} charset-normalizer==${CHARSET_NORMALIZER_VERSION} urllib3==${URLLIB3_VERSION} certifi==${CERTIFI_VERSION} requests==${REQUESTS_VERSION} zstandard==${ZSTANDARD_VERSION} --no-binary :all:
INSTALL_COMMAND ${PYTHON_BINARY} -m pip install --no-cache-dir ${SITE_PACKAGES_EXTRA} cython==${CYTHON_VERSION} idna==${IDNA_VERSION} charset-normalizer==${CHARSET_NORMALIZER_VERSION} urllib3==${URLLIB3_VERSION} certifi==${CERTIFI_VERSION} requests==${REQUESTS_VERSION} zstandard==${ZSTANDARD_VERSION} --no-binary :all:
)
if(USE_PIP_NUMPY)

View File

@@ -83,9 +83,9 @@ else()
set(OPENEXR_VERSION_POSTFIX)
endif()
set(FREETYPE_VERSION 2.11.0)
set(FREETYPE_VERSION 2.11.1)
set(FREETYPE_URI http://prdownloads.sourceforge.net/freetype/freetype-${FREETYPE_VERSION}.tar.gz)
set(FREETYPE_HASH cf09172322f6b50cf8f568bf8fe14bde)
set(FREETYPE_HASH bd4e3b007474319909a6b79d50908e85)
set(FREETYPE_HASH_TYPE MD5)
set(FREETYPE_FILE freetype-${FREETYPE_VERSION}.tar.gz)
@@ -189,11 +189,11 @@ set(OSL_HASH 1abd7ce40481771a9fa937f19595d2f2)
set(OSL_HASH_TYPE MD5)
set(OSL_FILE OpenShadingLanguage-${OSL_VERSION}.tar.gz)
set(PYTHON_VERSION 3.9.7)
set(PYTHON_SHORT_VERSION 3.9)
set(PYTHON_SHORT_VERSION_NO_DOTS 39)
set(PYTHON_VERSION 3.10.2)
set(PYTHON_SHORT_VERSION 3.10)
set(PYTHON_SHORT_VERSION_NO_DOTS 310)
set(PYTHON_URI https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tar.xz)
set(PYTHON_HASH fddb060b483bc01850a3f412eea1d954)
set(PYTHON_HASH 14e8c22458ed7779a1957b26cde01db9)
set(PYTHON_HASH_TYPE MD5)
set(PYTHON_FILE Python-${PYTHON_VERSION}.tar.xz)
@@ -215,18 +215,20 @@ set(NANOVDB_HASH e7b9e863ec2f3b04ead171dec2322807)
set(NANOVDB_HASH_TYPE MD5)
set(NANOVDB_FILE nano-vdb-${NANOVDB_GIT_UID}.tar.gz)
set(IDNA_VERSION 3.2)
set(CHARSET_NORMALIZER_VERSION 2.0.6)
set(URLLIB3_VERSION 1.26.7)
set(IDNA_VERSION 3.3)
set(CHARSET_NORMALIZER_VERSION 2.0.10)
set(URLLIB3_VERSION 1.26.8)
set(CERTIFI_VERSION 2021.10.8)
set(REQUESTS_VERSION 2.26.0)
set(CYTHON_VERSION 0.29.24)
set(ZSTANDARD_VERSION 0.15.2 )
set(REQUESTS_VERSION 2.27.1)
set(CYTHON_VERSION 0.29.26)
# The version of the zstd library used to build the Python package should match ZSTD_VERSION defined below.
# At this time of writing, 0.17.0 was already released, but built against zstd 1.5.1, while we use 1.5.0.
set(ZSTANDARD_VERSION 0.16.0)
set(NUMPY_VERSION 1.21.2)
set(NUMPY_SHORT_VERSION 1.21)
set(NUMPY_VERSION 1.22.0)
set(NUMPY_SHORT_VERSION 1.22)
set(NUMPY_URI https://github.com/numpy/numpy/releases/download/v${NUMPY_VERSION}/numpy-${NUMPY_VERSION}.zip)
set(NUMPY_HASH 5638d5dae3ca387be562912312db842e)
set(NUMPY_HASH 252de134862a27bd66705d29622edbfe)
set(NUMPY_HASH_TYPE MD5)
set(NUMPY_FILE numpy-${NUMPY_VERSION}.zip)

View File

@@ -379,27 +379,27 @@ USE_CXX11=true
CLANG_FORMAT_VERSION_MIN="6.0"
CLANG_FORMAT_VERSION_MEX="10.0"
PYTHON_VERSION="3.9.7"
PYTHON_VERSION_SHORT="3.9"
PYTHON_VERSION_MIN="3.7"
PYTHON_VERSION_MEX="3.11"
PYTHON_VERSION="3.10.2"
PYTHON_VERSION_SHORT="3.10"
PYTHON_VERSION_MIN="3.9"
PYTHON_VERSION_MEX="3.12"
PYTHON_VERSION_INSTALLED=$PYTHON_VERSION_SHORT
PYTHON_FORCE_BUILD=false
PYTHON_FORCE_REBUILD=false
PYTHON_SKIP=false
# Additional Python modules.
PYTHON_IDNA_VERSION="3.2"
PYTHON_IDNA_VERSION="3.3"
PYTHON_IDNA_VERSION_MIN="2.0"
PYTHON_IDNA_VERSION_MEX="4.0"
PYTHON_IDNA_NAME="idna"
PYTHON_CHARSET_NORMALIZER_VERSION="2.0.6"
PYTHON_CHARSET_NORMALIZER_VERSION="2.0.10"
PYTHON_CHARSET_NORMALIZER_VERSION_MIN="2.0.6"
PYTHON_CHARSET_NORMALIZER_VERSION_MEX="2.1.0" # requests uses `charset_normalizer~=2.0.0`
PYTHON_CHARSET_NORMALIZER_NAME="charset-normalizer"
PYTHON_URLLIB3_VERSION="1.26.7"
PYTHON_URLLIB3_VERSION="1.26.8"
PYTHON_URLLIB3_VERSION_MIN="1.0"
PYTHON_URLLIB3_VERSION_MEX="2.0"
PYTHON_URLLIB3_NAME="urllib3"
@@ -409,17 +409,17 @@ PYTHON_CERTIFI_VERSION_MIN="2021.0"
PYTHON_CERTIFI_VERSION_MEX="2023.0"
PYTHON_CERTIFI_NAME="certifi"
PYTHON_REQUESTS_VERSION="2.23.0"
PYTHON_REQUESTS_VERSION="2.27.1"
PYTHON_REQUESTS_VERSION_MIN="2.0"
PYTHON_REQUESTS_VERSION_MEX="3.0"
PYTHON_REQUESTS_NAME="requests"
PYTHON_ZSTANDARD_VERSION="0.15.2"
PYTHON_ZSTANDARD_VERSION="0.16.0"
PYTHON_ZSTANDARD_VERSION_MIN="0.15.2"
PYTHON_ZSTANDARD_VERSION_MEX="0.16.0"
PYTHON_ZSTANDARD_VERSION_MEX="0.20.0"
PYTHON_ZSTANDARD_NAME="zstandard"
PYTHON_NUMPY_VERSION="1.21.2"
PYTHON_NUMPY_VERSION="1.22.0"
PYTHON_NUMPY_VERSION_MIN="1.14"
PYTHON_NUMPY_VERSION_MEX="2.0"
PYTHON_NUMPY_NAME="numpy"
@@ -499,7 +499,7 @@ LLVM_FORCE_REBUILD=false
LLVM_SKIP=false
# OSL needs to be compiled for now!
OSL_VERSION="1.11.14.1"
OSL_VERSION="1.11.17.0"
OSL_VERSION_SHORT="1.11"
OSL_VERSION_MIN="1.11"
OSL_VERSION_MEX="2.0"

View File

@@ -1,64 +1,39 @@
@echo off
if NOT "%1" == "" (
if "%1" == "2013" (
echo "Building for VS2013"
set VSVER=12.0
set VSVER_SHORT=12
set BuildDir=VS12
goto par2
)
if "%1" == "2015" (
echo "Building for VS2015"
set VSVER=14.0
set VSVER_SHORT=14
set BuildDir=VS14
goto par2
)
if "%1" == "2017" (
echo "Building for VS2017"
set VSVER=15.0
set VSVER_SHORT=15
set BuildDir=VS15
goto par2
)
if "%1" == "2019" (
echo "Building for VS2019"
set VSVER=15.0
set VSVER_SHORT=15
set BuildDir=VS15
goto par2
)
)
:usage
Echo Usage build_deps 2013/2015/2017 x64/x86
Echo Usage build_deps 2017/2019 x64
goto exit
:par2
if NOT "%2" == "" (
if "%2" == "x86" (
echo "Building for x86"
set HARVESTROOT=Windows_vc
set ARCH=86
if "%1" == "2013" (
set CMAKE_BUILDER=Visual Studio 12 2013
)
if "%1" == "2015" (
set CMAKE_BUILDER=Visual Studio 14 2015
)
if "%1" == "2017" (
set CMAKE_BUILDER=Visual Studio 15 2017
)
goto start
)
if "%2" == "x64" (
echo "Building for x64"
set HARVESTROOT=Win64_vc
set ARCH=64
if "%1" == "2013" (
set CMAKE_BUILDER=Visual Studio 12 2013 Win64
)
if "%1" == "2015" (
set CMAKE_BUILDER=Visual Studio 14 2015 Win64
if "%1" == "2019" (
set CMAKE_BUILDER=Visual Studio 16 2019
set CMAKE_BUILD_ARCH=-A x64
)
if "%1" == "2017" (
set CMAKE_BUILDER=Visual Studio 15 2017 Win64
set CMAKE_BUILD_ARCH=
)
goto start
)
)
@@ -120,7 +95,7 @@ set path=%BUILD_DIR%\downloads\mingw\mingw64\msys\1.0\bin\;%BUILD_DIR%\downloads
mkdir %STAGING%\%BuildDir%%ARCH%R
cd %Staging%\%BuildDir%%ARCH%R
echo %DATE% %TIME% : Start > %StatusFile%
cmake -G "%CMAKE_BUILDER%" -Thost=x64 %SOURCE_DIR% -DPACKAGE_DIR=%BUILD_DIR%/packages -DDOWNLOAD_DIR=%BUILD_DIR%/downloads -DBUILD_MODE=Release -DHARVEST_TARGET=%HARVEST_DIR%/%HARVESTROOT%%VSVER_SHORT%/
cmake -G "%CMAKE_BUILDER%" %CMAKE_BUILD_ARCH% -Thost=x64 %SOURCE_DIR% -DPACKAGE_DIR=%BUILD_DIR%/packages -DDOWNLOAD_DIR=%BUILD_DIR%/downloads -DBUILD_MODE=Release -DHARVEST_TARGET=%HARVEST_DIR%/%HARVESTROOT%%VSVER_SHORT%/
echo %DATE% %TIME% : Release Configuration done >> %StatusFile%
if "%dobuild%" == "1" (
msbuild /m "ll.vcxproj" /p:Configuration=Release /fl /flp:logfile=BlenderDeps_llvm.log;Verbosity=normal
@@ -133,7 +108,7 @@ if "%NODEBUG%" == "1" goto exit
cd %BUILD_DIR%
mkdir %STAGING%\%BuildDir%%ARCH%D
cd %Staging%\%BuildDir%%ARCH%D
cmake -G "%CMAKE_BUILDER%" -Thost=x64 %SOURCE_DIR% -DPACKAGE_DIR=%BUILD_DIR%/packages -DDOWNLOAD_DIR=%BUILD_DIR%/downloads -DCMAKE_BUILD_TYPE=Debug -DBUILD_MODE=Debug -DHARVEST_TARGET=%HARVEST_DIR%/%HARVESTROOT%%VSVER_SHORT%/ %CMAKE_DEBUG_OPTIONS%
cmake -G "%CMAKE_BUILDER%" %CMAKE_BUILD_ARCH% -Thost=x64 %SOURCE_DIR% -DPACKAGE_DIR=%BUILD_DIR%/packages -DDOWNLOAD_DIR=%BUILD_DIR%/downloads -DCMAKE_BUILD_TYPE=Debug -DBUILD_MODE=Debug -DHARVEST_TARGET=%HARVEST_DIR%/%HARVESTROOT%%VSVER_SHORT%/ %CMAKE_DEBUG_OPTIONS%
echo %DATE% %TIME% : Debug Configuration done >> %StatusFile%
if "%dobuild%" == "1" (
msbuild /m "ll.vcxproj" /p:Configuration=Debug /fl /flp:logfile=BlenderDeps_llvm.log;;Verbosity=normal

View File

@@ -0,0 +1,83 @@
# - Find Brotli library (compression for freetype/woff2).
# This module defines
# BROTLI_INCLUDE_DIRS, where to find Brotli headers, Set when
# BROTLI_INCLUDE_DIR is found.
# BROTLI_LIBRARIES, libraries to link against to use Brotli.
# BROTLI_ROOT_DIR, The base directory to search for Brotli.
# This can also be an environment variable.
# BROTLI_FOUND, If false, do not try to use Brotli.
#
#=============================================================================
# Copyright 2022 Blender Foundation.
#
# Distributed under the OSI-approved BSD 3-Clause License,
# see accompanying file BSD-3-Clause-license.txt for details.
#=============================================================================
# If BROTLI_ROOT_DIR was defined in the environment, use it.
IF(NOT BROTLI_ROOT_DIR AND NOT $ENV{BROTLI_ROOT_DIR} STREQUAL "")
SET(BROTLI_ROOT_DIR $ENV{BROTLI_ROOT_DIR})
ENDIF()
SET(_BROTLI_SEARCH_DIRS
${BROTLI_ROOT_DIR}
)
FIND_PATH(BROTLI_INCLUDE_DIR
NAMES
brotli/decode.h
HINTS
${_BROTLI_SEARCH_DIRS}
PATH_SUFFIXES
include
DOC "Brotli header files"
)
FIND_LIBRARY(BROTLI_LIBRARY_COMMON
NAMES
# Some builds use a special `-static` postfix in their static libraries names.
brotlicommon-static
brotlicommon
HINTS
${_BROTLI_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib lib/static
DOC "Brotli static common library"
)
FIND_LIBRARY(BROTLI_LIBRARY_DEC
NAMES
# Some builds use a special `-static` postfix in their static libraries names.
brotlidec-static
brotlidec
HINTS
${_BROTLI_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib lib/static
DOC "Brotli static decode library"
)
IF(${BROTLI_LIBRARY_COMMON_NOTFOUND} or ${BROTLI_LIBRARY_DEC_NOTFOUND})
set(BROTLI_FOUND FALSE)
ELSE()
# handle the QUIETLY and REQUIRED arguments and set BROTLI_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Brotli DEFAULT_MSG BROTLI_LIBRARY_COMMON BROTLI_LIBRARY_DEC BROTLI_INCLUDE_DIR)
IF(BROTLI_FOUND)
get_filename_component(BROTLI_LIBRARY_DIR ${BROTLI_LIBRARY_COMMON} DIRECTORY)
SET(BROTLI_INCLUDE_DIRS ${BROTLI_INCLUDE_DIR})
SET(BROTLI_LIBRARIES ${BROTLI_LIBRARY_DEC} ${BROTLI_LIBRARY_COMMON})
ENDIF()
ENDIF()
MARK_AS_ADVANCED(
BROTLI_INCLUDE_DIR
BROTLI_LIBRARY_COMMON
BROTLI_LIBRARY_DEC
BROTLI_LIBRARY_DIR
)
UNSET(_BROTLI_SEARCH_DIRS)

View File

@@ -82,4 +82,6 @@ mark_as_advanced(
unset(_ffmpeg_SEARCH_DIRS)
unset(_ffmpeg_LIBRARIES)
unset(_ffmpeg_INCLUDE_DIR)
# In cmake version 3.21 and up, we can instead use the NO_CACHE option for
# find_path so we don't need to clear it from the cache here.
unset(_ffmpeg_INCLUDE_DIR CACHE)

View File

@@ -76,6 +76,7 @@ FIND_PATH(OSL_SHADER_DIR
/usr/include/OSL/
PATH_SUFFIXES
share/OSL/shaders
shaders
)
# handle the QUIETLY and REQUIRED arguments and set OSL_FOUND to TRUE if
@@ -99,6 +100,7 @@ ENDIF()
MARK_AS_ADVANCED(
OSL_INCLUDE_DIR
OSL_SHADER_DIR
)
FOREACH(COMPONENT ${_osl_FIND_COMPONENTS})
STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)

View File

@@ -87,12 +87,14 @@ ENDIF()
MARK_AS_ADVANCED(
OPENCOLORIO_INCLUDE_DIR
OPENCOLORIO_LIBRARY
OPENCOLORIO_OPENCOLORIO_LIBRARY
OPENCOLORIO_TINYXML_LIBRARY
OPENCOLORIO_YAML-CPP_LIBRARY
OPENCOLORIO_VERSION
)
FOREACH(COMPONENT ${_opencolorio_FIND_COMPONENTS})
STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
MARK_AS_ADVANCED(OPENCOLORIO_${UPPERCOMPONENT}_LIBRARY)
ENDFOREACH()
UNSET(COMPONENT)
UNSET(UPPERCOMPONENT)
UNSET(_opencolorio_FIND_COMPONENTS)

View File

@@ -33,14 +33,6 @@ ENDIF()
# Old versions (before 2.0?) do not have any version string, just assuming this should be fine though.
SET(_openexr_libs_ver_init "2.0")
SET(_openexr_FIND_COMPONENTS
Half
Iex
IlmImf
IlmThread
Imath
)
SET(_openexr_SEARCH_DIRS
${OPENEXR_ROOT_DIR}
/opt/lib/openexr
@@ -93,6 +85,24 @@ UNSET(_openexr_libs_ver_init)
STRING(REGEX REPLACE "([0-9]+)[.]([0-9]+).*" "\\1_\\2" _openexr_libs_ver ${OPENEXR_VERSION})
# Different library names in 3.0, and Imath and Half moved out.
IF(OPENEXR_VERSION VERSION_GREATER_EQUAL "3.0.0")
SET(_openexr_FIND_COMPONENTS
Iex
IlmThread
OpenEXR
OpenEXRCore
)
ELSE()
SET(_openexr_FIND_COMPONENTS
Half
Iex
IlmImf
IlmThread
Imath
)
ENDIF()
SET(_openexr_LIBRARIES)
FOREACH(COMPONENT ${_openexr_FIND_COMPONENTS})
STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
@@ -111,6 +121,57 @@ ENDFOREACH()
UNSET(_openexr_libs_ver)
IF(OPENEXR_VERSION VERSION_GREATER_EQUAL "3.0.0")
# For OpenEXR 3.x, we also need to find the now separate Imath library.
# For simplicity we add it to the OpenEXR includes and libraries, as we
# have no direct dependency on Imath and it's simpler to support both
# 2.x and 3.x this way.
# Find include directory
FIND_PATH(IMATH_INCLUDE_DIR
NAMES
Imath/ImathMath.h
HINTS
${_openexr_SEARCH_DIRS}
PATH_SUFFIXES
include
)
# Find version
FIND_FILE(_imath_config
NAMES
ImathConfig.h
PATHS
${IMATH_INCLUDE_DIR}/Imath
NO_DEFAULT_PATH
)
# Find line with version, extract string, and format for library suffix.
FILE(STRINGS "${_imath_config}" _imath_build_specification
REGEX "^[ \t]*#define[ \t]+IMATH_VERSION_STRING[ \t]+\"[.0-9]+\".*$")
STRING(REGEX REPLACE ".*#define[ \t]+IMATH_VERSION_STRING[ \t]+\"([.0-9]+)\".*"
"\\1" _imath_libs_ver ${_imath_build_specification})
STRING(REGEX REPLACE "([0-9]+)[.]([0-9]+).*" "\\1_\\2" _imath_libs_ver ${_imath_libs_ver})
# Find library, with or without version number.
FIND_LIBRARY(IMATH_LIBRARY
NAMES
Imath-${_imath_libs_ver} Imath
NAMES_PER_DIR
HINTS
${_openexr_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib
)
LIST(APPEND _openexr_LIBRARIES "${IMATH_LIBRARY}")
# In cmake version 3.21 and up, we can instead use the NO_CACHE option for
# FIND_FILE so we don't need to clear it from the cache here.
UNSET(_imath_config CACHE)
UNSET(_imath_libs_ver)
UNSET(_imath_build_specification)
ENDIF()
# handle the QUIETLY and REQUIRED arguments and set OPENEXR_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
@@ -119,13 +180,25 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenEXR DEFAULT_MSG
IF(OPENEXR_FOUND)
SET(OPENEXR_LIBRARIES ${_openexr_LIBRARIES})
# Both include paths are needed because of dummy OSL headers mixing #include <OpenEXR/foo.h> and #include <foo.h> :(
SET(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR} ${OPENEXR_INCLUDE_DIR}/OpenEXR)
# Both include paths are needed because of dummy OSL headers mixing
# #include <OpenEXR/foo.h> and #include <foo.h>, as well as Alembic
# include <half.h> directly.
SET(OPENEXR_INCLUDE_DIRS
${OPENEXR_INCLUDE_DIR}
${OPENEXR_INCLUDE_DIR}/OpenEXR)
IF(OPENEXR_VERSION VERSION_GREATER_EQUAL "3.0.0")
LIST(APPEND OPENEXR_INCLUDE_DIRS
${IMATH_INCLUDE_DIR}
${IMATH_INCLUDE_DIR}/Imath)
ENDIF()
ENDIF()
MARK_AS_ADVANCED(
OPENEXR_INCLUDE_DIR
OPENEXR_VERSION
IMATH_INCLUDE_DIR
IMATH_LIBRARY
)
FOREACH(COMPONENT ${_openexr_FIND_COMPONENTS})
STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)

View File

@@ -110,6 +110,7 @@ ENDIF()
MARK_AS_ADVANCED(
OPENIMAGEDENOISE_INCLUDE_DIR
OPENIMAGEDENOISE_LIBRARY
)
FOREACH(COMPONENT ${_openimagedenoise_FIND_COMPONENTS})

View File

@@ -48,6 +48,8 @@ FIND_LIBRARY(OPENIMAGEIO_LIBRARY
lib64 lib
)
set(_openimageio_LIBRARIES ${OPENIMAGEIO_LIBRARY})
FIND_FILE(OPENIMAGEIO_IDIFF
NAMES
idiff
@@ -57,14 +59,47 @@ FIND_FILE(OPENIMAGEIO_IDIFF
bin
)
# Additionally find util library if needed. In old versions this library was
# included in libOpenImageIO and linking to both would duplicate symbols. In
# new versions we need to link to both.
FIND_FILE(_openimageio_export
NAMES
export.h
PATHS
${OPENIMAGEIO_INCLUDE_DIR}/OpenImageIO
NO_DEFAULT_PATH
)
# Use existence of OIIO_UTIL_API to check if it's a separate lib.
FILE(STRINGS "${_openimageio_export}" _openimageio_util_define
REGEX "^[ \t]*#[ \t]*define[ \t]+OIIO_UTIL_API.*$")
IF(_openimageio_util_define)
FIND_LIBRARY(OPENIMAGEIO_UTIL_LIBRARY
NAMES
OpenImageIO_Util
HINTS
${_openimageio_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib
)
LIST(APPEND _openimageio_LIBRARIES ${OPENIMAGEIO_UTIL_LIBRARY})
ENDIF()
# In cmake version 3.21 and up, we can instead use the NO_CACHE option for
# FIND_FILE so we don't need to clear it from the cache here.
UNSET(_openimageio_export CACHE)
UNSET(_openimageio_util_define)
# handle the QUIETLY and REQUIRED arguments and set OPENIMAGEIO_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenImageIO DEFAULT_MSG
OPENIMAGEIO_LIBRARY OPENIMAGEIO_INCLUDE_DIR)
_openimageio_LIBRARIES OPENIMAGEIO_INCLUDE_DIR)
IF(OPENIMAGEIO_FOUND)
SET(OPENIMAGEIO_LIBRARIES ${OPENIMAGEIO_LIBRARY})
SET(OPENIMAGEIO_LIBRARIES ${_openimageio_LIBRARIES})
SET(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO_INCLUDE_DIR})
IF(EXISTS ${OPENIMAGEIO_INCLUDE_DIR}/OpenImageIO/pugixml.hpp)
SET(OPENIMAGEIO_PUGIXML_FOUND TRUE)
@@ -78,7 +113,9 @@ ENDIF()
MARK_AS_ADVANCED(
OPENIMAGEIO_INCLUDE_DIR
OPENIMAGEIO_LIBRARY
OPENIMAGEIO_UTIL_LIBRARY
OPENIMAGEIO_IDIFF
)
UNSET(_openimageio_SEARCH_DIRS)
UNSET(_openimageio_LIBRARIES)

View File

@@ -34,7 +34,7 @@ IF(NOT PYTHON_ROOT_DIR AND NOT $ENV{PYTHON_ROOT_DIR} STREQUAL "")
SET(PYTHON_ROOT_DIR $ENV{PYTHON_ROOT_DIR})
ENDIF()
SET(PYTHON_VERSION 3.9 CACHE STRING "Python Version (major and minor only)")
SET(PYTHON_VERSION 3.10 CACHE STRING "Python Version (major and minor only)")
MARK_AS_ADVANCED(PYTHON_VERSION)

View File

@@ -1197,21 +1197,21 @@ endfunction()
macro(openmp_delayload
projectname
)
if(MSVC)
if(WITH_OPENMP)
if(MSVC_CLANG)
set(OPENMP_DLL_NAME "libomp")
elseif(MSVC_VERSION EQUAL 1800)
set(OPENMP_DLL_NAME "vcomp120")
else()
set(OPENMP_DLL_NAME "vcomp140")
endif()
set_property(TARGET ${projectname} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE " /DELAYLOAD:${OPENMP_DLL_NAME}.dll delayimp.lib")
set_property(TARGET ${projectname} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " /DELAYLOAD:${OPENMP_DLL_NAME}d.dll delayimp.lib")
set_property(TARGET ${projectname} APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO " /DELAYLOAD:${OPENMP_DLL_NAME}.dll delayimp.lib")
set_property(TARGET ${projectname} APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL " /DELAYLOAD:${OPENMP_DLL_NAME}.dll delayimp.lib")
if(MSVC)
if(WITH_OPENMP)
if(MSVC_CLANG)
set(OPENMP_DLL_NAME "libomp")
elseif(MSVC_VERSION EQUAL 1800)
set(OPENMP_DLL_NAME "vcomp120")
else()
set(OPENMP_DLL_NAME "vcomp140")
endif()
set_property(TARGET ${projectname} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE " /DELAYLOAD:${OPENMP_DLL_NAME}.dll delayimp.lib")
set_property(TARGET ${projectname} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " /DELAYLOAD:${OPENMP_DLL_NAME}d.dll delayimp.lib")
set_property(TARGET ${projectname} APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO " /DELAYLOAD:${OPENMP_DLL_NAME}.dll delayimp.lib")
set_property(TARGET ${projectname} APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL " /DELAYLOAD:${OPENMP_DLL_NAME}.dll delayimp.lib")
endif()
endif()
endmacro()
macro(set_and_warn_dependency

View File

@@ -128,25 +128,20 @@ if(WITH_CODEC_SNDFILE)
endif()
if(WITH_PYTHON)
# we use precompiled libraries for py 3.9 and up by default
set(PYTHON_VERSION 3.9)
# Use precompiled libraries by default.
set(PYTHON_VERSION 3.10)
if(NOT WITH_PYTHON_MODULE AND NOT WITH_PYTHON_FRAMEWORK)
# normally cached but not since we include them with blender
# Normally cached but not since we include them with blender.
set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}")
set(PYTHON_EXECUTABLE "${LIBDIR}/python/bin/python${PYTHON_VERSION}")
set(PYTHON_LIBRARY ${LIBDIR}/python/lib/libpython${PYTHON_VERSION}.a)
set(PYTHON_LIBPATH "${LIBDIR}/python/lib/python${PYTHON_VERSION}")
# set(PYTHON_LINKFLAGS "-u _PyMac_Error") # won't build with this enabled
else()
# module must be compiled against Python framework
# Module must be compiled against Python framework.
set(_py_framework "/Library/Frameworks/Python.framework/Versions/${PYTHON_VERSION}")
set(PYTHON_INCLUDE_DIR "${_py_framework}/include/python${PYTHON_VERSION}")
set(PYTHON_EXECUTABLE "${_py_framework}/bin/python${PYTHON_VERSION}")
set(PYTHON_LIBPATH "${_py_framework}/lib/python${PYTHON_VERSION}")
# set(PYTHON_LIBRARY python${PYTHON_VERSION})
# set(PYTHON_LINKFLAGS "-u _PyMac_Error -framework Python") # won't build with this enabled
unset(_py_framework)
endif()

View File

@@ -48,6 +48,9 @@ if(NOT DEFINED LIBDIR)
unset(LIBDIR_CENTOS7_ABI)
endif()
# Support restoring this value once pre-compiled libraries have been handled.
set(WITH_STATIC_LIBS_INIT ${WITH_STATIC_LIBS})
if(EXISTS ${LIBDIR})
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
@@ -101,12 +104,21 @@ find_package_wrapper(PNG REQUIRED)
find_package_wrapper(ZLIB REQUIRED)
find_package_wrapper(Zstd REQUIRED)
# FreeType compiled with Brotli compression for woff2.
find_package_wrapper(Freetype REQUIRED)
list(APPEND FREETYPE_LIBRARIES
${LIBDIR}/brotli/lib/libbrotlidec-static.a
${LIBDIR}/brotli/lib/libbrotlicommon-static.a
)
if(NOT WITH_SYSTEM_FREETYPE)
# FreeType compiled with Brotli compression for woff2.
find_package_wrapper(Freetype REQUIRED)
if(EXISTS ${LIBDIR})
find_package_wrapper(Brotli REQUIRED)
# NOTE: This is done on WIN32 & APPLE but fails on some Linux systems.
# See: https://devtalk.blender.org/t/22536
# So `BROTLI_LIBRARIES` need to be added directly after `FREETYPE_LIBRARIES`.
#
# list(APPEND FREETYPE_LIBRARIES
# ${BROTLI_LIBRARIES}
# )
endif()
endif()
if(WITH_PYTHON)
# No way to set py35, remove for now.
@@ -350,6 +362,7 @@ if(WITH_BOOST)
find_package(IcuLinux)
endif()
mark_as_advanced(Boost_DIR) # why doesn't boost do this?
mark_as_advanced(Boost_INCLUDE_DIR) # why doesn't boost do this?
endif()
set(BOOST_INCLUDE_DIR ${Boost_INCLUDE_DIRS})
@@ -542,6 +555,21 @@ add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
#
# Keep last, so indirectly linked libraries don't override our own pre-compiled libs.
if(EXISTS ${LIBDIR})
# Clear the prefix path as it causes the `LIBDIR` to override system locations.
unset(CMAKE_PREFIX_PATH)
# Since the pre-compiled `LIBDIR` directories have been handled, don't prefer static libraries.
set(WITH_STATIC_LIBS ${WITH_STATIC_LIBS_INIT})
endif()
if(WITH_SYSTEM_FREETYPE)
find_package_wrapper(Freetype)
if(NOT FREETYPE_FOUND)
message(FATAL_ERROR "Failed finding system FreeType version!")
endif()
endif()
if(WITH_LZO AND WITH_SYSTEM_LZO)
find_package_wrapper(LZO)
if(NOT LZO_FOUND)

View File

@@ -55,6 +55,10 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang")
message(WARNING "stripped pdb not supported with clang, disabling..")
set(WITH_WINDOWS_STRIPPED_PDB OFF)
endif()
else()
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.28.29921) # MSVC 2019 16.9.16
message(FATAL_ERROR "Compiler is unsupported, MSVC 2019 16.9.16 or newer is required for building blender.")
endif()
endif()
if(NOT WITH_PYTHON_MODULE)
@@ -265,12 +269,6 @@ if(NOT DEFINED LIBDIR)
elseif(MSVC_VERSION GREATER 1919)
message(STATUS "Visual Studio 2019 detected.")
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_BASE}_vc15)
elseif(MSVC_VERSION GREATER 1909)
message(STATUS "Visual Studio 2017 detected.")
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_BASE}_vc15)
elseif(MSVC_VERSION EQUAL 1900)
message(STATUS "Visual Studio 2015 detected.")
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_BASE}_vc15)
endif()
else()
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
@@ -465,7 +463,7 @@ if(WITH_JACK)
endif()
if(WITH_PYTHON)
set(PYTHON_VERSION 3.9) # CACHE STRING)
set(PYTHON_VERSION 3.10) # CACHE STRING)
string(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
set(PYTHON_LIBRARY ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/libs/python${_PYTHON_VERSION_NO_DOTS}.lib)

View File

@@ -5,38 +5,38 @@
update-code:
git:
submodules:
- branch: master
- branch: blender-v3.1-release
commit_id: HEAD
path: release/scripts/addons
- branch: master
- branch: blender-v3.1-release
commit_id: HEAD
path: release/scripts/addons_contrib
- branch: master
- branch: blender-v3.1-release
commit_id: HEAD
path: release/datafiles/locale
- branch: master
- branch: blender-v3.1-release
commit_id: HEAD
path: source/tools
svn:
libraries:
darwin-arm64:
branch: trunk
branch: tags/blender-3.1-release
commit_id: HEAD
path: lib/darwin_arm64
darwin-x86_64:
branch: trunk
branch: tags/blender-3.1-release
commit_id: HEAD
path: lib/darwin
linux-x86_64:
branch: trunk
branch: tags/blender-3.1-release
commit_id: HEAD
path: lib/linux_centos7_x86_64
windows-amd64:
branch: trunk
branch: tags/blender-3.1-release
commit_id: HEAD
path: lib/win64_vc15
tests:
branch: trunk
branch: tags/blender-3.1-release
commit_id: HEAD
path: lib/tests
benchmarks:

View File

@@ -3,9 +3,6 @@ echo No explicit msvc version requested, autodetecting version.
call "%~dp0\detect_msvc2019.cmd"
if %ERRORLEVEL% EQU 0 goto DetectionComplete
call "%~dp0\detect_msvc2017.cmd"
if %ERRORLEVEL% EQU 0 goto DetectionComplete
call "%~dp0\detect_msvc2022.cmd"
if %ERRORLEVEL% EQU 0 goto DetectionComplete

View File

@@ -1,4 +1,3 @@
if "%BUILD_VS_YEAR%"=="2017" set BUILD_VS_LIBDIRPOST=vc15
if "%BUILD_VS_YEAR%"=="2019" set BUILD_VS_LIBDIRPOST=vc15
if "%BUILD_VS_YEAR%"=="2022" set BUILD_VS_LIBDIRPOST=vc15

View File

@@ -19,12 +19,6 @@ if "%WITH_PYDEBUG%"=="1" (
set PYDEBUG_CMAKE_ARGS=-DWINDOWS_PYTHON_DEBUG=On
)
if "%BUILD_VS_YEAR%"=="2017" (
set BUILD_GENERATOR_POST=%WINDOWS_ARCH%
) else (
set BUILD_PLATFORM_SELECT=-A %MSBUILD_PLATFORM%
)
set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -G "Visual Studio %BUILD_VS_VER% %BUILD_VS_YEAR%%BUILD_GENERATOR_POST%" %BUILD_PLATFORM_SELECT% %TESTS_CMAKE_ARGS% %CLANG_CMAKE_ARGS% %ASAN_CMAKE_ARGS% %PYDEBUG_CMAKE_ARGS%
if NOT EXIST %BUILD_DIR%\nul (

View File

@@ -37,15 +37,9 @@ set LLVM_DIR=
:DetectionComplete
set CC=%LLVM_DIR%\bin\clang-cl
set CXX=%LLVM_DIR%\bin\clang-cl
if "%BUILD_VS_YEAR%" == "2019" (
rem build and tested against 2019 16.2
set CFLAGS=-m64 -fmsc-version=1922
set CXXFLAGS=-m64 -fmsc-version=1922
) else (
rem build and tested against 2017 15.7
set CFLAGS=-m64 -fmsc-version=1914
set CXXFLAGS=-m64 -fmsc-version=1914
)
rem build and tested against 2019 16.2
set CFLAGS=-m64 -fmsc-version=1922
set CXXFLAGS=-m64 -fmsc-version=1922
)
if "%WITH_ASAN%"=="1" (

View File

@@ -1,3 +0,0 @@
set BUILD_VS_VER=15
set BUILD_VS_YEAR=2017
call "%~dp0\detect_msvc_vswhere.cmd"

View File

@@ -3,7 +3,32 @@ for %%X in (svn.exe) do (set SVN=%%~$PATH:X)
for %%X in (cmake.exe) do (set CMAKE=%%~$PATH:X)
for %%X in (ctest.exe) do (set CTEST=%%~$PATH:X)
for %%X in (git.exe) do (set GIT=%%~$PATH:X)
REM For python, default on 39 but if that does not exist also check
REM the 310,311 and 312 folders to see if those are there, it checks
REM this far ahead to ensure good lib folder compatiblity in the future.
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\39\bin\python.exe
if EXIST %PYTHON% (
goto detect_python_done
)
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\310\bin\python.exe
if EXIST %PYTHON% (
goto detect_python_done
)
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\311\bin\python.exe
if EXIST %PYTHON% (
goto detect_python_done
)
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\312\bin\python.exe
if EXIST %PYTHON% (
goto detect_python_done
)
if NOT EXIST %PYTHON% (
echo Warning: Python not found, there is likely an issue with the library folder
set PYTHON=""
)
:detect_python_done
if NOT "%verbose%" == "" (
echo svn : "%SVN%"
echo cmake : "%CMAKE%"
@@ -11,7 +36,3 @@ if NOT "%verbose%" == "" (
echo git : "%GIT%"
echo python : "%PYTHON%"
)
if "%CMAKE%" == "" (
echo Cmake not found in path, required for building, exiting...
exit /b 1
)

View File

@@ -9,17 +9,11 @@ exit /b 1
:detect_done
echo found clang-format in %CF_PATH%
if EXIST %PYTHON% (
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\39\bin\python.exe
goto detect_python_done
if NOT EXIST %PYTHON% (
echo python not found, required for this operation
exit /b 1
)
echo python not found in lib folder
exit /b 1
:detect_python_done
echo found python (%PYTHON%)
set FORMAT_PATHS=%BLENDER_DIR%\source\tools\utils_maintenance\clang_format_paths.py
REM The formatting script expects clang-format to be in the current PATH.

View File

@@ -1,18 +1,8 @@
if EXIST "%PYTHON%" (
goto detect_python_done
if NOT EXIST %PYTHON% (
echo python not found, required for this operation
exit /b 1
)
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\39\bin\python.exe
if EXIST %PYTHON% (
goto detect_python_done
)
echo python not found at %PYTHON%
exit /b 1
:detect_python_done
echo found python (%PYTHON%)
call "%~dp0\find_inkscape.cmd"
if EXIST "%INKSCAPE_BIN%" (

View File

@@ -1,18 +1,8 @@
if EXIST %PYTHON% (
goto detect_python_done
if NOT EXIST %PYTHON% (
echo python not found, required for this operation
exit /b 1
)
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\39\bin\python.exe
if EXIST %PYTHON% (
goto detect_python_done
)
echo python not found at %PYTHON%
exit /b 1
:detect_python_done
echo found python (%PYTHON%)
call "%~dp0\find_blender.cmd"
if EXIST "%BLENDER_BIN%" (

View File

@@ -50,14 +50,6 @@ if NOT "%1" == "" (
goto ERR
) else if "%1" == "x64" (
set BUILD_ARCH=x64
) else if "%1" == "2017" (
set BUILD_VS_YEAR=2017
) else if "%1" == "2017pre" (
set BUILD_VS_YEAR=2017
set VSWHERE_ARGS=-prerelease
) else if "%1" == "2017b" (
set BUILD_VS_YEAR=2017
set VSWHERE_ARGS=-products Microsoft.VisualStudio.Product.BuildTools
) else if "%1" == "2019" (
set BUILD_VS_YEAR=2019
) else if "%1" == "2019pre" (

View File

@@ -24,12 +24,12 @@ echo - nobuildinfo ^(disable buildinfo^)
echo - debug ^(Build an unoptimized debuggable build^)
echo - packagename [newname] ^(override default cpack package name^)
echo - builddir [newdir] ^(override default build folder^)
echo - 2017 ^(build with visual studio 2017^)
echo - 2017pre ^(build with visual studio 2017 pre-release^)
echo - 2017b ^(build with visual studio 2017 Build Tools^)
echo - 2019 ^(build with visual studio 2019^)
echo - 2019pre ^(build with visual studio 2019 pre-release^)
echo - 2019b ^(build with visual studio 2019 Build Tools^)
echo - 2022 ^(build with visual studio 2022^)
echo - 2022pre ^(build with visual studio 2022 pre-release^)
echo - 2022b ^(build with visual studio 2022 Build Tools^)
echo.
echo Documentation Targets ^(Not associated with building^)

View File

@@ -1,4 +1,3 @@
if "%BUILD_VS_YEAR%"=="2017" set BUILD_VS_LIBDIRPOST=vc15
if "%BUILD_VS_YEAR%"=="2019" set BUILD_VS_LIBDIRPOST=vc15
if "%BUILD_VS_YEAR%"=="2022" set BUILD_VS_LIBDIRPOST=vc15

View File

@@ -1,10 +1,7 @@
if EXIST %PYTHON% (
goto detect_python_done
if NOT EXIST %PYTHON% (
echo python not found, required for this operation
exit /b 1
)
echo python not found in lib folder
exit /b 1
:detect_python_done
REM Use -B to avoid writing __pycache__ in lib directory and causing update conflicts.

View File

@@ -22,7 +22,7 @@ Data Access
===========
The most common case for using the reference API is to find out how to access data in the blend-file.
Before going any further its best to be aware of ID data-blocks in Blender since you will often find properties
Before going any further it's best to be aware of ID data-blocks in Blender since you will often find properties
relative to them.
@@ -55,9 +55,9 @@ Start by collecting the information where the data is located.
First find this setting in the interface ``Properties editor -> Object -> Transform -> Location``.
From the button context menu select *Online Python Reference*, this will link you to:
:class:`bpy.types.Object.location`.
Being an API reference, this link often gives little more information then the tooltip, though some of the pages
Being an API reference, this link often gives little more information than the tooltip, though some of the pages
include examples (normally at the top of the page).
But you now know that you have to use ``.location`` and that its an array of three floats.
But you now know that you have to use ``.location`` and that it's an array of three floats.
So the next step is to find out where to access objects, go down to the bottom of the page to the references section,
for objects there are many references, but one of the most common places to access objects is via the context.
@@ -154,7 +154,7 @@ The tooltip includes :class:`bpy.types.SubsurfModifier.levels` but you want the
Note that the text copied won't include the ``bpy.data.collection["name"].`` component since its assumed that
you won't be doing collection look-ups on every access and typically you'll want to use the context rather
then access each :class:`bpy.types.ID` instance by name.
than access each :class:`bpy.types.ID` instance by name.
Type in the ID path into a Python console :mod:`bpy.context.active_object`.
Include the trailing dot and don't execute the code, yet.
@@ -252,6 +252,6 @@ Each entry can be selected, then copied :kbd:`Ctrl-C`, usually to paste in the t
.. note::
Not all operators get registered for display,
zooming the view for example isn't so useful to repeat so its excluded from the output.
zooming the view for example isn't so useful to repeat so it's excluded from the output.
To display *every* operator that runs see :ref:`Show All Operators <info_show_all_operators>`.

View File

@@ -229,7 +229,7 @@ removing the last items first, which is faster (as explained above):
This example shows a fast way of removing items,
for use in cases where you can alter the list order without breaking the scripts functionality.
for use in cases where you can alter the list order without breaking the script's functionality.
This works by swapping two list items, so the item you remove is always last:
.. code-block:: python
@@ -278,7 +278,7 @@ Here are three ways of joining multiple strings into one string for writing.
This also applies to any area of your code that involves a lot of string joining:
String concatenation
This is the slowest option, do **not** use if you can avoid it, especially when writing data in a loop.
This is the slowest option, do **not** use this if you can avoid it, especially when writing data in a loop.
>>> file.write(str1 + " " + str2 + " " + str3 + "\n")
@@ -288,7 +288,7 @@ String formatting
>>> file.write("%s %s %s\n" % (str1, str2, str3))
String joining
Use to join a list of strings (the list may be temporary). In the following example, the strings are joined with
Use this to join a list of strings (the list may be temporary). In the following example, the strings are joined with
a space " " in between, other examples are "" or ", ".
>>> file.write(" ".join((str1, str2, str3, "\n")))

View File

@@ -12,7 +12,7 @@ that can be troublesome and avoid practices that are known to cause instability.
Using Operators
===============
Blender's operators are tools for users to access, that can access with Python too which is very useful.
Blender's operators are tools for users to access, that can be accessed with Python too which is very useful.
Still operators have limitations that can make them cumbersome to script.
The main limits are:
@@ -20,13 +20,13 @@ The main limits are:
- Can't pass data such as objects, meshes or materials to operate on (operators use the context instead).
- The return value from calling an operator is the success (if it finished or was canceled),
in some cases it would be more logical from an API perspective to return the result of the operation.
- Operators poll function can fail where an API function would raise an exception giving details on exactly why.
- Operators' poll function can fail where an API function would raise an exception giving details on exactly why.
Why does an operator's poll fail?
---------------------------------
When calling an operator gives an error like this:
When calling an operator it gives an error like this:
>>> bpy.ops.action.clean(threshold=0.001)
RuntimeError: Operator bpy.ops.action.clean.poll() failed, context is incorrect
@@ -49,9 +49,9 @@ you should be able to find the poll function with no knowledge of C.
.. note::
Blender does have the functionality for poll functions to describe why they fail,
but its currently not used much, if you're interested to help improve the API
but it's currently not used much, if you're interested to help improve the API
feel free to add calls to :class:`bpy.types.Operator.poll_message_set` (``CTX_wm_operator_poll_msg_set`` in C)
where its not obvious why poll fails, e.g:
where it's not obvious why poll fails, e.g:
>>> bpy.ops.gpencil.draw()
RuntimeError: Operator bpy.ops.gpencil.draw.poll() Failed to find Grease Pencil data to draw into
@@ -107,7 +107,7 @@ In this case you need to call :class:`bpy.types.ViewLayer.update` after modifyin
Now all dependent data (child objects, modifiers, drivers, etc.)
has been recalculated and is available to the script within active view layer.
have been recalculated and are available to the script within the active view layer.
Can I redraw during script execution?
@@ -116,13 +116,13 @@ Can I redraw during script execution?
The official answer to this is no, or... *"You don't want to do that"*.
To give some background on the topic:
While a script executes Blender waits for it to finish and is effectively locked until its done,
While a script executes, Blender waits for it to finish and is effectively locked until it's done;
while in this state Blender won't redraw or respond to user input.
Normally this is not such a problem because scripts distributed with Blender
tend not to run for an extended period of time,
nevertheless scripts *can* take a long time to complete and it would be nice to see progress in the viewport.
When tools lock Blender in a loop redraw are highly discouraged
Tools that lock Blender in a loop redraw are highly discouraged
since they conflict with Blender's ability to run multiple operators
at once and update different parts of the interface as the tool runs.
@@ -130,7 +130,7 @@ So the solution here is to write a **modal** operator, which is an operator that
See the modal operator template in the text editor.
Modal operators execute on user input or setup their own timers to run frequently,
they can handle the events or pass through to be handled by the keymap or other modal operators.
Examples of a modal operators are Transform, Painting, Fly Navigation and File Select.
Examples of modal operators are Transform, Painting, Fly Navigation and File Select.
Writing modal operators takes more effort than a simple ``for`` loop
that contains draw calls but is more flexible and integrates better with Blender's design.
@@ -240,7 +240,7 @@ Editing
Editing is where the three data types vary most.
- Polygons are very limited for editing,
changing materials and options like smooth works but for anything else
changing materials and options like smooth works, but for anything else
they are too inflexible and are only intended for storage.
- Tessfaces should not be used for editing geometry because doing so will cause existing n-gons to be tessellated.
- BMesh-faces are by far the best way to manipulate geometry.
@@ -256,7 +256,7 @@ the choice mostly depends on whether the target format supports n-gons or not.
- Tessfaces work well for exporting to formats which don't support n-gons,
in fact this is the only place where their use is encouraged.
- BMesh-Faces can work for exporting too but may not be necessary if polygons can be used
since using BMesh gives some overhead because its not the native storage format in Object-Mode.
since using BMesh gives some overhead because it's not the native storage format in Object-Mode.
Edit Bones, Pose Bones, Bone... Bones
@@ -348,7 +348,7 @@ Armature Mode Switching
While writing scripts that deal with armatures you may find you have to switch between modes,
when doing so take care when switching out of Edit-Mode not to keep references
to the edit bones or their head/tail vectors.
Further access to these will crash Blender so its important the script
Further access to these will crash Blender so it's important that the script
clearly separates sections of the code which operate in different modes.
This is mainly an issue with Edit-Mode since pose data can be manipulated without having to be in Pose-Mode,
@@ -386,11 +386,11 @@ Or with name assignment:
Data names may not match the assigned values if they exceed the maximum length, are already used or an empty string.
Its better practice not to reference objects by names at all,
It's better practice not to reference objects by names at all,
once created you can store the data in a list, dictionary, on a class, etc;
there is rarely a reason to have to keep searching for the same data by name.
If you do need to use name references, its best to use a dictionary to maintain
If you do need to use name references, it's best to use a dictionary to maintain
a mapping between the names of the imported assets and the newly created data,
this way you don't run this risk of referencing existing data from the blend-file, or worse modifying it.
@@ -414,11 +414,11 @@ Library Collisions
Blender keeps data names unique (:class:`bpy.types.ID.name`) so you can't name two objects,
meshes, scenes, etc., the same by accident.
However, when linking in library data from another blend-file naming collisions can occur,
so its best to avoid referencing data by name at all.
so it's best to avoid referencing data by name at all.
This can be tricky at times and not even Blender handles this correctly in some case
This can be tricky at times and not even Blender handles this correctly in some cases
(when selecting the modifier object for e.g. you can't select between multiple objects with the same name),
but its still good to try avoiding these problems in this area.
but it's still good to try avoiding these problems in this area.
If you need to select between local and library data, there is a feature in ``bpy.data`` members to allow for this.
.. code-block:: python
@@ -467,11 +467,11 @@ writing a script in ``latin1`` or ``iso-8859-15``.
See `PEP 263 <https://www.python.org/dev/peps/pep-0263/>`__.
However, this complicates matters for Blender's Python API because ``.blend`` files don't have an explicit encoding.
To avoid the problem for Python integration and script authors we have decided all strings in blend-files
To avoid the problem for Python integration and script authors we have decided that all strings in blend-files
**must** be ``UTF-8``, ``ASCII`` compatible.
This means assigning strings with different encodings to an object names for instance will raise an error.
This means assigning strings with different encodings to an object name, for instance, will raise an error.
Paths are an exception to this rule since the existence of non-UTF-8 paths on user's file system cannot be ignored.
Paths are an exception to this rule since the existence of non-UTF-8 paths on the user's file system cannot be ignored.
This means seemingly harmless expressions can raise errors, e.g:
>>> print(bpy.data.filepath)
@@ -505,7 +505,7 @@ to keep it short about encoding problems -- here are some suggestions:
.. note::
Sometimes it's preferable to avoid string encoding issues by using bytes instead of Python strings,
when reading some input its less trouble to read it as binary data
when reading some input it's less trouble to read it as binary data
though you will still need to decide how to treat any strings you want to use with Blender,
some importers do this.
@@ -679,7 +679,7 @@ Undo/Redo
---------
For safety, you should assume that undo and redo always invalidates all :class:`bpy.types.ID`
instances (Object, Scene, Mesh, Light, etc.), as weel obviously as all of their sub-data.
instances (Object, Scene, Mesh, Light, etc.), as well obviously as all of their sub-data.
This example shows how you can tell undo changes the memory locations:
@@ -716,7 +716,7 @@ Tools in Blender are not allowed to modify library data.
But Python does not enforce this restriction.
This can be useful in some cases, using a script to adjust material values for example.
But its also possible to use a script to make library data point to newly created local data,
But it's also possible to use a script to make library data point to newly created local data,
which is not supported since a call to undo will remove the local data
but leave the library referencing it and likely crash.

View File

@@ -81,7 +81,7 @@ but reference an external file rather than including it directly.
Executing External Scripts
--------------------------
This is the equivalent to running the script directly, referencing a scripts path from a two line code block.
This is the equivalent to running the script directly, referencing a script's path from a two line code block.
.. code-block:: python
@@ -124,7 +124,7 @@ small script which is often useful for testing different settings quickly.
The other issue with this is the script has to be in Python's module search path.
While this is not best practice -- for testing purposes you can extend the search path,
this following example adds the current blend-files directory to the search path
this following example adds the current blend-file's directory to the search path
and then loads the script as a module.
.. code-block:: python
@@ -302,7 +302,7 @@ Python Safety (Build Option)
----------------------------
Since it's possible to access data which has been removed (see :doc:`Gotchas <info_gotcha>`),
can make it hard to track down the cause of crashes.
it can be hard to track down the cause of crashes.
To raise Python exceptions on accessing freed data (rather than crashing),
enable the CMake build option ``WITH_PYTHON_SAFETY``.
This enables data tracking which makes data access about two times slower

View File

@@ -417,7 +417,8 @@ MODULE_GROUPING = {
BLENDER_REVISION = str(bpy.app.build_hash, 'utf_8')
# '2.83.0 Beta' or '2.83.0' or '2.83.1'
BLENDER_VERSION_DOTS = bpy.app.version_string
BLENDER_VERSION_STRING = bpy.app.version_string
BLENDER_VERSION_DOTS = "%d.%d" % (bpy.app.version[0], bpy.app.version[1])
if BLENDER_REVISION != "Unknown":
# SHA1 Git hash
@@ -1724,11 +1725,11 @@ def write_sphinx_conf_py(basepath):
fw("import sys, os\n\n")
fw("extensions = ['sphinx.ext.intersphinx']\n\n")
fw("intersphinx_mapping = {'blender_manual': ('https://docs.blender.org/manual/en/dev/', None)}\n\n")
fw("project = 'Blender %s Python API'\n" % BLENDER_VERSION_DOTS)
fw("project = 'Blender %s Python API'\n" % BLENDER_VERSION_STRING)
fw("master_doc = 'index'\n")
fw("copyright = u'Blender Foundation'\n")
fw("version = '%s'\n" % BLENDER_VERSION_HASH)
fw("release = '%s'\n" % BLENDER_VERSION_HASH)
fw("version = '%s'\n" % BLENDER_VERSION_DOTS)
fw("release = '%s'\n" % BLENDER_VERSION_DOTS)
# Quiet file not in table-of-contents warnings.
fw("exclude_patterns = [\n")
@@ -1749,6 +1750,7 @@ except ModuleNotFoundError:
fw("if html_theme == 'sphinx_rtd_theme':\n")
fw(" html_theme_options = {\n")
fw(" 'display_version': False,\n")
# fw(" 'analytics_id': '',\n")
# fw(" 'collapse_navigation': True,\n")
fw(" 'sticky_navigation': False,\n")
@@ -1765,10 +1767,15 @@ except ModuleNotFoundError:
fw("html_show_search_summary = True\n")
fw("html_split_index = True\n")
fw("html_static_path = ['static']\n")
fw("templates_path = ['templates']\n")
fw("html_context = {'commit': '%s'}\n" % BLENDER_VERSION_HASH)
fw("html_extra_path = ['static/favicon.ico', 'static/blender_logo.svg']\n")
fw("html_favicon = 'static/favicon.ico'\n")
fw("html_logo = 'static/blender_logo.svg'\n")
fw("html_last_updated_fmt = '%m/%d/%Y'\n\n")
fw("if html_theme == 'sphinx_rtd_theme':\n")
fw(" html_css_files = ['css/version_switch.css']\n")
fw(" html_js_files = ['js/version_switch.js']\n")
# needed for latex, pdf gen
fw("latex_elements = {\n")
@@ -2125,6 +2132,9 @@ def copy_theme_assets(basepath):
shutil.copytree(os.path.join(SCRIPT_DIR, "static"),
os.path.join(basepath, "static"),
copy_function=shutil.copy)
shutil.copytree(os.path.join(SCRIPT_DIR, "templates"),
os.path.join(basepath, "templates"),
copy_function=shutil.copy)
def rna2sphinx(basepath):

View File

@@ -0,0 +1,127 @@
/* Override RTD theme */
.rst-versions {
border-top: 0px;
overflow: visible;
}
.version-btn.vdeact {
cursor: default;
color: dimgray;
}
.version-btn.vdeact::after {
content: "";
}
#versionwrap {
display: flex;
padding-top: 2px;
font-size: 90%;
justify-content: center;
flex-wrap: wrap;
}
.version-btn {
display: inline-block;
background-color: #272525;
width: 140px;
text-align: center;
padding: 3px 10px;
margin: 0px 5px 4px;
vertical-align: middle;
color: #27AE60;
border: solid 1px #444444;
border-radius: 3px;
cursor: pointer;
z-index: 400;
transition: border-color 0.4s;
}
.version-btn::after {
content:"\f0d8";
display: inline;
font: normal normal normal 16px/1 FontAwesome;
color: #8d8c8c;
vertical-align: top;
padding-left: 0.5em;
}
.version-btn-open::after {
color: gray;
}
.version-btn:hover, .version-btn:focus {
border-color: #525252;
}
.version-btn-open {
color: gray;
border: solid 1px gray;
}
.version-btn.wait {
cursor: wait;
}
.version-btn.disabled {
cursor: not-allowed;
color: dimgray;
}
.version-dialog {
display: none;
position: absolute;
bottom: 28px;
width: 140px;
margin: 0 5px;
padding-bottom: 4px;
background-color: #0003;
border-radius: 3px;
box-shadow: 0 0 6px #000C;
z-index: 999;
max-height: calc(100vh - 30px);
overflow-y: auto;
cursor: default;
}
.version-title {
padding: 5px;
color: black;
text-align: center;
font-size: 102%;
background-color: #27ae60;
border-bottom: solid 1.5px #444;
}
.version-list {
margin-bottom: 4px;
text-align: center;
background-color: #000C;
border: solid 1px gray;
border-radius: 0px 0px 3px 3px;
}
.version-list a, .version-list span, .version-list li {
position: relative;
display: block;
font-size: 98%;
line-height: 1.15;
width: 100%;
margin: 0;
padding: 4px 0px;
color: #404040;
}
.version-list li {
background-color: #ede9e9;
color: #404040;
padding: 1px;
}
.version-list li:hover, .version-list li a:focus {
background-color: #b9cfda;
}
.version-list li.selected, .version-list li.selected:hover {
background-color: #8d8c8c;
}
.version-list li.selected span {
cursor: default;
outline-color: red;
}
.version-arrow {
position: absolute;
width: 8px;
height: 8px;
left: 50%;
bottom: 4px;
margin-left: -4px;
transform: rotate(225deg);
background: #ede9e9;
border: 1px solid gray;
border-width: 1px 0 0 1px;
}

View File

@@ -0,0 +1,323 @@
(function() { // switch: v1.2
"use strict";
var versionsFileUrl = "https://docs.blender.org/PROD/versions.json"
var all_versions;
var Popover = function() {
function Popover(id)
{
this.isOpen = false;
this.type = (id === "version-popover");
this.$btn = $('#' + id);
this.$dialog = this.$btn.next();
this.$list = this.$dialog.children("ul");
this.sel = null;
this.beforeInit();
}
Popover.prototype = {
beforeInit : function() {
var that = this;
this.$btn.on("click", function(e) {
that.init();
e.preventDefault();
e.stopPropagation();
});
this.$btn.on("keydown", function(e) {
if (that.btnKeyFilter(e)) {
that.init();
e.preventDefault();
e.stopPropagation();
}
});
},
init : function() {
this.$btn.off("click");
this.$btn.off("keydown");
if (all_versions === undefined) {
this.$btn.addClass("wait");
this.loadVL(this);
}
else {
this.afterLoad();
}
},
loadVL : function(that) {
$.getJSON(versionsFileUrl, function(data) {
all_versions = data;
that.afterLoad();
return true;
}).fail(function() {
console.log("Version Switch Error: versions.json could not be loaded.");
that.$btn.addClass("disabled");
return false;
});
},
afterLoad : function() {
var release = DOCUMENTATION_OPTIONS.VERSION;
const m = release.match(/\d\.\d+/g);
if (m) {
release = m[0];
}
this.warnOld(release, all_versions);
var version = this.getNamed(release);
var list = this.buildList(version);
this.$list.children(":first-child").remove();
this.$list.append(list);
var that = this;
this.$list.on("keydown", function(e) {
that.keyMove(e);
});
this.$btn.removeClass("wait");
this.btnOpenHandler();
this.$btn.on("mousedown", function(e) {
that.btnOpenHandler();
e.preventDefault()
});
this.$btn.on("keydown", function(e) {
if (that.btnKeyFilter(e)) {
that.btnOpenHandler();
}
});
},
warnOld : function(release, all_versions) {
// Note this is effectively disabled now, two issues must fixed:
// * versions.js does not contain a current entry, because that leads to
// duplicate version numbers in the menu. These need to be deduplicated.
// * It only shows the warning after opening the menu to switch version
// when versions.js is loaded. This is too late to be useful.
var current = all_versions.current
if (!current)
{
// console.log("Version Switch Error: no 'current' in version.json.");
return;
}
const m = current.match(/\d\.\d+/g);
if (m) {
current = parseFloat(m[0]);
}
if (release < current) {
var currentURL = window.location.pathname.replace(release, current);
var warning = $('<div class="admonition warning"> ' +
'<p class="first admonition-title">Note</p> ' +
'<p class="last"> ' +
'You are not using the most up to date version of the documentation. ' +
'<a href="#"></a> is the newest version.' +
'</p>' +
'</div>');
warning.find('a').attr('href', currentURL).text(current);
var body = $("div.body");
if (!body.length) {
body = $("div.document");
}
body.prepend(warning);
}
},
buildList : function(v) {
var url = new URL(window.location.href);
let pathSplit = [ "", "api", v ];
if (url.pathname.startsWith("/api/")) {
pathSplit.push(url.pathname.split('/').slice(3).join('/'));
}
else {
pathSplit.push(url.pathname.substring(1));
}
if (this.type) {
var dyn = all_versions;
var cur = v;
}
var buf = [];
var that = this;
$.each(dyn, function(ix, title) {
buf.push("<li");
if (ix === cur) {
buf.push(
' class="selected" tabindex="-1" role="presentation"><span tabindex="-1" role="menuitem" aria-current="page">' +
title + '</spanp></li>');
}
else {
pathSplit[2 + that.type] = ix;
var href = new URL(url);
href.pathname = pathSplit.join('/');
buf.push(' tabindex="-1" role="presentation"><a href ="' + href + '" tabindex="-1">' +
title + '</a></li>');
}
});
return buf.join('');
},
getNamed : function(v) {
$.each(all_versions, function(ix, title) {
if (ix === "master" || ix === "latest") {
var m = title.match(/\d\.\d[\w\d\.]*/)[0];
if (parseFloat(m) == v) {
v = ix;
return false;
}
}
});
return v;
},
dialogToggle : function(speed) {
var wasClose = !this.isOpen;
var that = this;
if (!this.isOpen) {
this.$btn.addClass("version-btn-open");
this.$btn.attr("aria-pressed", true);
this.$dialog.attr("aria-hidden", false);
this.$dialog.fadeIn(speed, function() {
that.$btn.parent().on("focusout", function(e) {
that.focusoutHandler();
e.stopImmediatePropagation();
})
that.$btn.parent().on("mouseleave", function(e) {
that.mouseoutHandler();
e.stopImmediatePropagation();
});
});
this.isOpen = true;
}
else {
this.$btn.removeClass("version-btn-open");
this.$btn.attr("aria-pressed", false);
this.$dialog.attr("aria-hidden", true);
this.$btn.parent().off("focusout");
this.$btn.parent().off("mouseleave");
this.$dialog.fadeOut(speed, function() {
if (this.$sel) {
this.$sel.attr("tabindex", -1);
}
that.$btn.attr("tabindex", 0);
if (document.activeElement !== null && document.activeElement !== document &&
document.activeElement !== document.body) {
that.$btn.focus();
}
});
this.isOpen = false;
}
if (wasClose) {
if (this.$sel) {
this.$sel.attr("tabindex", -1);
}
if (document.activeElement !== null && document.activeElement !== document &&
document.activeElement !== document.body) {
var $nw = this.listEnter();
$nw.attr("tabindex", 0);
$nw.focus();
this.$sel = $nw;
}
}
},
btnOpenHandler : function() {
this.dialogToggle(300);
},
focusoutHandler : function() {
var list = this.$list;
var that = this;
setTimeout(function() {
if (list.find(":focus").length === 0) {
that.dialogToggle(200);
}
}, 200);
},
mouseoutHandler : function() {
this.dialogToggle(200);
},
btnKeyFilter : function(e) {
if (e.ctrlKey || e.shiftKey) {
return false;
}
if (e.key === " " || e.key === "Enter" || (e.key === "ArrowDown" && e.altKey) ||
e.key === "ArrowDown" || e.key === "ArrowUp") {
return true;
}
return false;
},
keyMove : function(e) {
if (e.ctrlKey || e.shiftKey) {
return true;
}
var p = true;
var $nw = $(e.target);
switch (e.key) {
case "ArrowUp":
$nw = this.listPrev($nw);
break;
case "ArrowDown":
$nw = this.listNext($nw);
break;
case "Home":
$nw = this.listFirst();
break;
case "End":
$nw = this.listLast();
break;
case "Escape":
$nw = this.listExit();
break;
case "ArrowLeft":
$nw = this.listExit();
break;
case "ArrowRight":
$nw = this.listExit();
break;
default:
p = false;
}
if (p) {
$nw.attr("tabindex", 0);
$nw.focus();
if (this.$sel) {
this.$sel.attr("tabindex", -1);
}
this.$sel = $nw;
e.preventDefault();
e.stopPropagation();
}
},
listPrev : function($nw) {
if ($nw.parent().prev().length !== 0) {
return $nw.parent().prev().children(":first-child");
}
else {
return this.listLast();
}
},
listNext : function($nw) {
if ($nw.parent().next().length !== 0) {
return $nw.parent().next().children(":first-child");
}
else {
return this.listFirst();
}
},
listFirst : function() {
return this.$list.children(":first-child").children(":first-child");
},
listLast : function() {
return this.$list.children(":last-child").children(":first-child");
},
listExit : function() {
this.mouseoutHandler();
return this.$btn;
},
listEnter : function() {
return this.$list.children(":first-child").children(":first-child");
}
};
return Popover
}();
$(document).ready(function() {
var lng_popover = new Popover("version-popover");
});
})();

View File

@@ -0,0 +1,17 @@
<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="document versions">
<ul id="versionwrap" role="presentation">
<li role="presentation">
<span id="version-popover" class="version-btn" tabindex="0" role="button" aria-label="versions selector" aria-haspopup="true" aria-controls="version-vsnlist" aria-disabled="true">
{{ release }}
</span>
<div class="version-dialog" aria-hidden="true">
<div class="version-arrow" aria-hidden="true"></div>
<div class="version-title">Versions</div>
<ul id="version-vsnlist" class="version-list" role="menu" aria-labelledby="version-popover" aria-hidden="true">
<li role="presentation">Loading...</li>
</ul>
</div>
</li>
</ul>
</div>

View File

@@ -113,6 +113,6 @@ if(WITH_MOD_FLUID)
add_subdirectory(mantaflow)
endif()
if (WITH_COMPOSITOR)
if(WITH_COMPOSITOR)
add_subdirectory(smaa_areatex)
endif()

View File

@@ -177,7 +177,7 @@ void FFMPEGReader::init(int stream)
// get a decoder and open it
#ifndef FFMPEG_OLD_CODE
AVCodec* aCodec = avcodec_find_decoder(m_formatCtx->streams[m_stream]->codecpar->codec_id);
const AVCodec* aCodec = avcodec_find_decoder(m_formatCtx->streams[m_stream]->codecpar->codec_id);
if(!aCodec)
AUD_THROW(FileException, "File couldn't be read, no decoder found with ffmpeg.");

View File

@@ -23,6 +23,7 @@
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avio.h>
#include <libavutil/channel_layout.h>
}
AUD_NAMESPACE_BEGIN
@@ -171,66 +172,66 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
if(avformat_alloc_output_context2(&m_formatCtx, nullptr, formats[format], filename.c_str()) < 0)
AUD_THROW(FileException, "File couldn't be written, format couldn't be found with ffmpeg.");
AVOutputFormat* outputFmt = m_formatCtx->oformat;
const AVOutputFormat* outputFmt = m_formatCtx->oformat;
if(!outputFmt) {
avformat_free_context(m_formatCtx);
AUD_THROW(FileException, "File couldn't be written, output format couldn't be found with ffmpeg.");
}
outputFmt->audio_codec = AV_CODEC_ID_NONE;
AVCodecID audio_codec = AV_CODEC_ID_NONE;
switch(codec)
{
case CODEC_AAC:
outputFmt->audio_codec = AV_CODEC_ID_AAC;
audio_codec = AV_CODEC_ID_AAC;
break;
case CODEC_AC3:
outputFmt->audio_codec = AV_CODEC_ID_AC3;
audio_codec = AV_CODEC_ID_AC3;
break;
case CODEC_FLAC:
outputFmt->audio_codec = AV_CODEC_ID_FLAC;
audio_codec = AV_CODEC_ID_FLAC;
break;
case CODEC_MP2:
outputFmt->audio_codec = AV_CODEC_ID_MP2;
audio_codec = AV_CODEC_ID_MP2;
break;
case CODEC_MP3:
outputFmt->audio_codec = AV_CODEC_ID_MP3;
audio_codec = AV_CODEC_ID_MP3;
break;
case CODEC_OPUS:
outputFmt->audio_codec = AV_CODEC_ID_OPUS;
audio_codec = AV_CODEC_ID_OPUS;
break;
case CODEC_PCM:
switch(specs.format)
{
case FORMAT_U8:
outputFmt->audio_codec = AV_CODEC_ID_PCM_U8;
audio_codec = AV_CODEC_ID_PCM_U8;
break;
case FORMAT_S16:
outputFmt->audio_codec = AV_CODEC_ID_PCM_S16LE;
audio_codec = AV_CODEC_ID_PCM_S16LE;
break;
case FORMAT_S24:
outputFmt->audio_codec = AV_CODEC_ID_PCM_S24LE;
audio_codec = AV_CODEC_ID_PCM_S24LE;
break;
case FORMAT_S32:
outputFmt->audio_codec = AV_CODEC_ID_PCM_S32LE;
audio_codec = AV_CODEC_ID_PCM_S32LE;
break;
case FORMAT_FLOAT32:
outputFmt->audio_codec = AV_CODEC_ID_PCM_F32LE;
audio_codec = AV_CODEC_ID_PCM_F32LE;
break;
case FORMAT_FLOAT64:
outputFmt->audio_codec = AV_CODEC_ID_PCM_F64LE;
audio_codec = AV_CODEC_ID_PCM_F64LE;
break;
default:
outputFmt->audio_codec = AV_CODEC_ID_NONE;
audio_codec = AV_CODEC_ID_NONE;
break;
}
break;
case CODEC_VORBIS:
outputFmt->audio_codec = AV_CODEC_ID_VORBIS;
audio_codec = AV_CODEC_ID_VORBIS;
break;
default:
outputFmt->audio_codec = AV_CODEC_ID_NONE;
audio_codec = AV_CODEC_ID_NONE;
break;
}
@@ -268,10 +269,10 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
try
{
if(outputFmt->audio_codec == AV_CODEC_ID_NONE)
if(audio_codec == AV_CODEC_ID_NONE)
AUD_THROW(FileException, "File couldn't be written, audio codec not found with ffmpeg.");
AVCodec* codec = avcodec_find_encoder(outputFmt->audio_codec);
const AVCodec* codec = avcodec_find_encoder(audio_codec);
if(!codec)
AUD_THROW(FileException, "File couldn't be written, audio encoder couldn't be found with ffmpeg.");

View File

@@ -44,15 +44,13 @@ else()
endif()
if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI)
list(APPEND LIBRARIES ${GLUT_LIBRARIES})
add_definitions(${GL_DEFINITIONS})
list(APPEND INC_SYS ${GLEW_INCLUDE_DIR} ${SDL2_INCLUDE_DIRS})
list(APPEND LIBRARIES ${CYCLES_GL_LIBRARIES} ${SDL2_LIBRARIES})
endif()
list(APPEND LIBRARIES ${CYCLES_GL_LIBRARIES})
# Common configuration.
add_definitions(${GL_DEFINITIONS})
include_directories(${INC})
include_directories(SYSTEM ${INC_SYS})
@@ -66,6 +64,18 @@ if(WITH_CYCLES_STANDALONE)
oiio_output_driver.cpp
oiio_output_driver.h
)
if(WITH_CYCLES_STANDALONE_GUI)
list(APPEND SRC
opengl/display_driver.cpp
opengl/display_driver.h
opengl/shader.cpp
opengl/shader.h
opengl/window.cpp
opengl/window.h
)
endif()
add_executable(cycles ${SRC} ${INC} ${INC_SYS})
unset(SRC)
@@ -80,6 +90,10 @@ if(WITH_CYCLES_STANDALONE)
# OpenImageDenoise uses BNNS from the Accelerate framework.
set_property(TARGET cycles APPEND_STRING PROPERTY LINK_FLAGS " -framework Accelerate")
endif()
if(WITH_CYCLES_STANDALONE_GUI)
set_property(TARGET cycles APPEND_STRING PROPERTY LINK_FLAGS
" -framework Cocoa -framework CoreAudio -framework AudioUnit -framework AudioToolbox -framework ForceFeedback -framework CoreVideo")
endif()
endif()
if(UNIX AND NOT APPLE)

View File

@@ -40,11 +40,10 @@
#include "app/oiio_output_driver.h"
#ifdef WITH_CYCLES_STANDALONE_GUI
# include "util/view.h"
# include "opengl/display_driver.h"
# include "opengl/window.h"
#endif
#include "app/cycles_xml.h"
CCL_NAMESPACE_BEGIN
struct Options {
@@ -130,7 +129,14 @@ static void session_init()
options.output_pass = "combined";
options.session = new Session(options.session_params, options.scene_params);
if (!options.output_filepath.empty()) {
#ifdef WITH_CYCLES_STANDALONE_GUI
if (!options.session_params.background) {
options.session->set_display_driver(make_unique<OpenGLDisplayDriver>(
window_opengl_context_enable, window_opengl_context_disable));
}
else
#endif
if (!options.output_filepath.empty()) {
options.session->set_output_driver(make_unique<OIIOOutputDriver>(
options.output_filepath, options.output_pass, session_print));
}
@@ -139,7 +145,7 @@ static void session_init()
options.session->progress.set_update_callback(function_bind(&session_print_status));
#ifdef WITH_CYCLES_STANDALONE_GUI
else
options.session->progress.set_update_callback(function_bind(&view_redraw));
options.session->progress.set_update_callback(function_bind(&window_redraw));
#endif
/* load scene */
@@ -204,10 +210,10 @@ static void display_info(Progress &progress)
sample_time,
interactive.c_str());
view_display_info(str.c_str());
window_display_info(str.c_str());
if (options.show_help)
view_display_help();
window_display_help();
}
static void display()
@@ -538,15 +544,15 @@ int main(int argc, const char **argv)
string title = "Cycles: " + path_filename(options.filepath);
/* init/exit are callback so they run while GL is initialized */
view_main_loop(title.c_str(),
options.width,
options.height,
session_init,
session_exit,
resize,
display,
keyboard,
motion);
window_main_loop(title.c_str(),
options.width,
options.height,
session_init,
session_exit,
resize,
display,
keyboard,
motion);
}
#endif

View File

@@ -0,0 +1,398 @@
/*
* Copyright 2011-2022 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "app/opengl/display_driver.h"
#include "app/opengl/shader.h"
#include "util/log.h"
#include "util/string.h"
#include <GL/glew.h>
#include <SDL.h>
CCL_NAMESPACE_BEGIN
/* --------------------------------------------------------------------
* OpenGLDisplayDriver.
*/
OpenGLDisplayDriver::OpenGLDisplayDriver(const function<bool()> &gl_context_enable,
const function<void()> &gl_context_disable)
: gl_context_enable_(gl_context_enable), gl_context_disable_(gl_context_disable)
{
}
OpenGLDisplayDriver::~OpenGLDisplayDriver()
{
}
/* --------------------------------------------------------------------
* Update procedure.
*/
void OpenGLDisplayDriver::next_tile_begin()
{
/* Assuming no tiles used in interactive display. */
}
bool OpenGLDisplayDriver::update_begin(const Params &params, int texture_width, int texture_height)
{
/* Note that it's the responsibility of OpenGLDisplayDriver to ensure updating and drawing
* the texture does not happen at the same time. This is achieved indirectly.
*
* When enabling the OpenGL context, it uses an internal mutex lock DST.gl_context_lock.
* This same lock is also held when do_draw() is called, which together ensure mutual
* exclusion.
*
* This locking is not performed on the Cycles side, because that would cause lock inversion. */
if (!gl_context_enable_()) {
return false;
}
if (gl_render_sync_) {
glWaitSync((GLsync)gl_render_sync_, 0, GL_TIMEOUT_IGNORED);
}
if (!gl_texture_resources_ensure()) {
gl_context_disable_();
return false;
}
/* Update texture dimensions if needed. */
if (texture_.width != texture_width || texture_.height != texture_height) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA16F, texture_width, texture_height, 0, GL_RGBA, GL_HALF_FLOAT, 0);
texture_.width = texture_width;
texture_.height = texture_height;
glBindTexture(GL_TEXTURE_2D, 0);
/* Texture did change, and no pixel storage was provided. Tag for an explicit zeroing out to
* avoid undefined content. */
texture_.need_clear = true;
}
/* Update PBO dimensions if needed.
*
* NOTE: Allocate the PBO for the the size which will fit the final render resolution (as in,
* at a resolution divider 1. This was we don't need to recreate graphics interoperability
* objects which are costly and which are tied to the specific underlying buffer size.
* The downside of this approach is that when graphics interoperability is not used we are
* sending too much data to GPU when resolution divider is not 1. */
const int buffer_width = params.full_size.x;
const int buffer_height = params.full_size.y;
if (texture_.buffer_width != buffer_width || texture_.buffer_height != buffer_height) {
const size_t size_in_bytes = sizeof(half4) * buffer_width * buffer_height;
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
glBufferData(GL_PIXEL_UNPACK_BUFFER, size_in_bytes, 0, GL_DYNAMIC_DRAW);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
texture_.buffer_width = buffer_width;
texture_.buffer_height = buffer_height;
}
/* New content will be provided to the texture in one way or another, so mark this in a
* centralized place. */
texture_.need_update = true;
return true;
}
void OpenGLDisplayDriver::update_end()
{
gl_upload_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
gl_context_disable_();
}
/* --------------------------------------------------------------------
* Texture buffer mapping.
*/
half4 *OpenGLDisplayDriver::map_texture_buffer()
{
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
half4 *mapped_rgba_pixels = reinterpret_cast<half4 *>(
glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
if (!mapped_rgba_pixels) {
LOG(ERROR) << "Error mapping OpenGLDisplayDriver pixel buffer object.";
}
if (texture_.need_clear) {
const int64_t texture_width = texture_.width;
const int64_t texture_height = texture_.height;
memset(reinterpret_cast<void *>(mapped_rgba_pixels),
0,
texture_width * texture_height * sizeof(half4));
texture_.need_clear = false;
}
return mapped_rgba_pixels;
}
void OpenGLDisplayDriver::unmap_texture_buffer()
{
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
/* --------------------------------------------------------------------
* Graphics interoperability.
*/
OpenGLDisplayDriver::GraphicsInterop OpenGLDisplayDriver::graphics_interop_get()
{
GraphicsInterop interop_dst;
interop_dst.buffer_width = texture_.buffer_width;
interop_dst.buffer_height = texture_.buffer_height;
interop_dst.opengl_pbo_id = texture_.gl_pbo_id;
interop_dst.need_clear = texture_.need_clear;
texture_.need_clear = false;
return interop_dst;
}
void OpenGLDisplayDriver::graphics_interop_activate()
{
gl_context_enable_();
}
void OpenGLDisplayDriver::graphics_interop_deactivate()
{
gl_context_disable_();
}
/* --------------------------------------------------------------------
* Drawing.
*/
void OpenGLDisplayDriver::clear()
{
texture_.need_clear = true;
}
void OpenGLDisplayDriver::draw(const Params &params)
{
/* See do_update_begin() for why no locking is required here. */
if (texture_.need_clear) {
/* Texture is requested to be cleared and was not yet cleared.
* Do early return which should be equivalent of drawing all-zero texture. */
return;
}
if (!gl_draw_resources_ensure()) {
return;
}
if (gl_upload_sync_) {
glWaitSync((GLsync)gl_upload_sync_, 0, GL_TIMEOUT_IGNORED);
}
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
display_shader_.bind(params.full_size.x, params.full_size.y);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
if (texture_.width != params.size.x || texture_.height != params.size.y) {
/* Resolution divider is different from 1, force nearest interpolation. */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
texture_update_if_needed();
vertex_buffer_update(params);
GLuint vertex_array_object;
glGenVertexArrays(1, &vertex_array_object);
glBindVertexArray(vertex_array_object);
const int texcoord_attribute = display_shader_.get_tex_coord_attrib_location();
const int position_attribute = display_shader_.get_position_attrib_location();
glEnableVertexAttribArray(texcoord_attribute);
glEnableVertexAttribArray(position_attribute);
glVertexAttribPointer(
texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
glVertexAttribPointer(position_attribute,
2,
GL_FLOAT,
GL_FALSE,
4 * sizeof(float),
(const GLvoid *)(sizeof(float) * 2));
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glDeleteVertexArrays(1, &vertex_array_object);
display_shader_.unbind();
glDisable(GL_BLEND);
gl_render_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
}
bool OpenGLDisplayDriver::gl_draw_resources_ensure()
{
if (!texture_.gl_id) {
/* If there is no texture allocated, there is nothing to draw. Inform the draw call that it can
* can not continue. Note that this is not an unrecoverable error, so once the texture is known
* we will come back here and create all the GPU resources needed for draw. */
return false;
}
if (gl_draw_resource_creation_attempted_) {
return gl_draw_resources_created_;
}
gl_draw_resource_creation_attempted_ = true;
if (!vertex_buffer_) {
glGenBuffers(1, &vertex_buffer_);
if (!vertex_buffer_) {
LOG(ERROR) << "Error creating vertex buffer.";
return false;
}
}
gl_draw_resources_created_ = true;
return true;
}
void OpenGLDisplayDriver::gl_resources_destroy()
{
gl_context_enable_();
if (vertex_buffer_ != 0) {
glDeleteBuffers(1, &vertex_buffer_);
}
if (texture_.gl_pbo_id) {
glDeleteBuffers(1, &texture_.gl_pbo_id);
texture_.gl_pbo_id = 0;
}
if (texture_.gl_id) {
glDeleteTextures(1, &texture_.gl_id);
texture_.gl_id = 0;
}
gl_context_disable_();
}
bool OpenGLDisplayDriver::gl_texture_resources_ensure()
{
if (texture_.creation_attempted) {
return texture_.is_created;
}
texture_.creation_attempted = true;
DCHECK(!texture_.gl_id);
DCHECK(!texture_.gl_pbo_id);
/* Create texture. */
glGenTextures(1, &texture_.gl_id);
if (!texture_.gl_id) {
LOG(ERROR) << "Error creating texture.";
return false;
}
/* Configure the texture. */
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
/* Create PBO for the texture. */
glGenBuffers(1, &texture_.gl_pbo_id);
if (!texture_.gl_pbo_id) {
LOG(ERROR) << "Error creating texture pixel buffer object.";
return false;
}
/* Creation finished with a success. */
texture_.is_created = true;
return true;
}
void OpenGLDisplayDriver::texture_update_if_needed()
{
if (!texture_.need_update) {
return;
}
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
glTexSubImage2D(
GL_TEXTURE_2D, 0, 0, 0, texture_.width, texture_.height, GL_RGBA, GL_HALF_FLOAT, 0);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
texture_.need_update = false;
}
void OpenGLDisplayDriver::vertex_buffer_update(const Params &params)
{
/* Invalidate old contents - avoids stalling if the buffer is still waiting in queue to be
* rendered. */
glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
float *vpointer = reinterpret_cast<float *>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
if (!vpointer) {
return;
}
vpointer[0] = 0.0f;
vpointer[1] = 0.0f;
vpointer[2] = params.full_offset.x;
vpointer[3] = params.full_offset.y;
vpointer[4] = 1.0f;
vpointer[5] = 0.0f;
vpointer[6] = (float)params.size.x + params.full_offset.x;
vpointer[7] = params.full_offset.y;
vpointer[8] = 1.0f;
vpointer[9] = 1.0f;
vpointer[10] = (float)params.size.x + params.full_offset.x;
vpointer[11] = (float)params.size.y + params.full_offset.y;
vpointer[12] = 0.0f;
vpointer[13] = 1.0f;
vpointer[14] = params.full_offset.x;
vpointer[15] = (float)params.size.y + params.full_offset.y;
glUnmapBuffer(GL_ARRAY_BUFFER);
}
CCL_NAMESPACE_END

View File

@@ -0,0 +1,130 @@
/*
* Copyright 2011-2022 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <atomic>
#include "app/opengl/shader.h"
#include "session/display_driver.h"
#include "util/function.h"
#include "util/unique_ptr.h"
CCL_NAMESPACE_BEGIN
class OpenGLDisplayDriver : public DisplayDriver {
public:
/* Callbacks for enabling and disabling the OpenGL context. Must be provided to support enabling
* the context on the Cycles render thread independent of the main thread. */
OpenGLDisplayDriver(const function<bool()> &gl_context_enable,
const function<void()> &gl_context_disable);
~OpenGLDisplayDriver();
virtual void graphics_interop_activate() override;
virtual void graphics_interop_deactivate() override;
virtual void clear() override;
void set_zoom(float zoom_x, float zoom_y);
protected:
virtual void next_tile_begin() override;
virtual bool update_begin(const Params &params, int texture_width, int texture_height) override;
virtual void update_end() override;
virtual half4 *map_texture_buffer() override;
virtual void unmap_texture_buffer() override;
virtual GraphicsInterop graphics_interop_get() override;
virtual void draw(const Params &params) override;
/* Make sure texture is allocated and its initial configuration is performed. */
bool gl_texture_resources_ensure();
/* Ensure all runtime GPU resources needed for drawing are allocated.
* Returns true if all resources needed for drawing are available. */
bool gl_draw_resources_ensure();
/* Destroy all GPU resources which are being used by this object. */
void gl_resources_destroy();
/* Update GPU texture dimensions and content if needed (new pixel data was provided).
*
* NOTE: The texture needs to be bound. */
void texture_update_if_needed();
/* Update vertex buffer with new coordinates of vertex positions and texture coordinates.
* This buffer is used to render texture in the viewport.
*
* NOTE: The buffer needs to be bound. */
void vertex_buffer_update(const Params &params);
/* Texture which contains pixels of the render result. */
struct {
/* Indicates whether texture creation was attempted and succeeded.
* Used to avoid multiple attempts of texture creation on GPU issues or GPU context
* misconfiguration. */
bool creation_attempted = false;
bool is_created = false;
/* OpenGL resource IDs of the texture itself and Pixel Buffer Object (PBO) used to write
* pixels to it.
*
* NOTE: Allocated on the engine's context. */
uint gl_id = 0;
uint gl_pbo_id = 0;
/* Is true when new data was written to the PBO, meaning, the texture might need to be resized
* and new data is to be uploaded to the GPU. */
bool need_update = false;
/* Content of the texture is to be filled with zeroes. */
std::atomic<bool> need_clear = true;
/* Dimensions of the texture in pixels. */
int width = 0;
int height = 0;
/* Dimensions of the underlying PBO. */
int buffer_width = 0;
int buffer_height = 0;
} texture_;
OpenGLShader display_shader_;
/* Special track of whether GPU resources were attempted to be created, to avoid attempts of
* their re-creation on failure on every redraw. */
bool gl_draw_resource_creation_attempted_ = false;
bool gl_draw_resources_created_ = false;
/* Vertex buffer which hold vertices of a triangle fan which is textures with the texture
* holding the render result. */
uint vertex_buffer_ = 0;
void *gl_render_sync_ = nullptr;
void *gl_upload_sync_ = nullptr;
float2 zoom_ = make_float2(1.0f, 1.0f);
function<bool()> gl_context_enable_ = nullptr;
function<void()> gl_context_disable_ = nullptr;
};
CCL_NAMESPACE_END

View File

@@ -0,0 +1,210 @@
/*
* Copyright 2011-2022 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "app/opengl/shader.h"
#include "util/log.h"
#include "util/string.h"
#include <GL/glew.h>
CCL_NAMESPACE_BEGIN
/* --------------------------------------------------------------------
* OpenGLShader.
*/
static const char *VERTEX_SHADER =
"#version 330\n"
"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 *FRAGMENT_SHADER =
"#version 330\n"
"uniform sampler2D image_texture;\n"
"in vec2 texCoord_interp;\n"
"out vec4 fragColor;\n"
"\n"
"void main()\n"
"{\n"
" vec4 rgba = texture(image_texture, texCoord_interp);\n"
/* Harcoded Rec.709 gamma, should use OpenColorIO eventually. */
" fragColor = pow(rgba, vec4(0.45, 0.45, 0.45, 1.0));\n"
"}\n\0";
static void shader_print_errors(const char *task, const char *log, const char *code)
{
LOG(ERROR) << "Shader: " << task << " error:";
LOG(ERROR) << "===== shader string ====";
stringstream stream(code);
string partial;
int line = 1;
while (getline(stream, partial, '\n')) {
if (line < 10) {
LOG(ERROR) << " " << line << " " << partial;
}
else {
LOG(ERROR) << line << " " << partial;
}
line++;
}
LOG(ERROR) << log;
}
static int compile_shader_program(void)
{
const struct Shader {
const char *source;
const GLenum type;
} shaders[2] = {{VERTEX_SHADER, GL_VERTEX_SHADER}, {FRAGMENT_SHADER, GL_FRAGMENT_SHADER}};
const GLuint program = glCreateProgram();
for (int i = 0; i < 2; i++) {
const GLuint shader = glCreateShader(shaders[i].type);
string source_str = shaders[i].source;
const char *c_str = source_str.c_str();
glShaderSource(shader, 1, &c_str, NULL);
glCompileShader(shader);
GLint compile_status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
if (!compile_status) {
GLchar log[5000];
GLsizei length = 0;
glGetShaderInfoLog(shader, sizeof(log), &length, log);
shader_print_errors("compile", log, c_str);
return 0;
}
glAttachShader(program, shader);
}
/* Link output. */
glBindFragDataLocation(program, 0, "fragColor");
/* Link and error check. */
glLinkProgram(program);
GLint link_status;
glGetProgramiv(program, GL_LINK_STATUS, &link_status);
if (!link_status) {
GLchar log[5000];
GLsizei length = 0;
glGetShaderInfoLog(program, sizeof(log), &length, log);
shader_print_errors("linking", log, VERTEX_SHADER);
shader_print_errors("linking", log, FRAGMENT_SHADER);
return 0;
}
return program;
}
int OpenGLShader::get_position_attrib_location()
{
if (position_attribute_location_ == -1) {
const uint shader_program = get_shader_program();
position_attribute_location_ = glGetAttribLocation(shader_program, position_attribute_name);
}
return position_attribute_location_;
}
int OpenGLShader::get_tex_coord_attrib_location()
{
if (tex_coord_attribute_location_ == -1) {
const uint shader_program = get_shader_program();
tex_coord_attribute_location_ = glGetAttribLocation(shader_program, tex_coord_attribute_name);
}
return tex_coord_attribute_location_;
}
void OpenGLShader::bind(int width, int height)
{
create_shader_if_needed();
if (!shader_program_) {
return;
}
glUseProgram(shader_program_);
glUniform1i(image_texture_location_, 0);
glUniform2f(fullscreen_location_, width, height);
}
void OpenGLShader::unbind()
{
}
uint OpenGLShader::get_shader_program()
{
return shader_program_;
}
void OpenGLShader::create_shader_if_needed()
{
if (shader_program_ || shader_compile_attempted_) {
return;
}
shader_compile_attempted_ = true;
shader_program_ = compile_shader_program();
if (!shader_program_) {
return;
}
glUseProgram(shader_program_);
image_texture_location_ = glGetUniformLocation(shader_program_, "image_texture");
if (image_texture_location_ < 0) {
LOG(ERROR) << "Shader doesn't contain the 'image_texture' uniform.";
destroy_shader();
return;
}
fullscreen_location_ = glGetUniformLocation(shader_program_, "fullscreen");
if (fullscreen_location_ < 0) {
LOG(ERROR) << "Shader doesn't contain the 'fullscreen' uniform.";
destroy_shader();
return;
}
}
void OpenGLShader::destroy_shader()
{
glDeleteProgram(shader_program_);
shader_program_ = 0;
}
CCL_NAMESPACE_END

View File

@@ -0,0 +1,58 @@
/*
* Copyright 2011-2022 OpenGL Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "util/types.h"
CCL_NAMESPACE_BEGIN
class OpenGLShader {
public:
static constexpr const char *position_attribute_name = "pos";
static constexpr const char *tex_coord_attribute_name = "texCoord";
OpenGLShader() = default;
virtual ~OpenGLShader() = default;
/* Get attribute location for position and texture coordinate respectively.
* NOTE: The shader needs to be bound to have access to those. */
int get_position_attrib_location();
int get_tex_coord_attrib_location();
void bind(int width, int height);
void unbind();
protected:
uint get_shader_program();
void create_shader_if_needed();
void destroy_shader();
/* Cached values of various OpenGL resources. */
int position_attribute_location_ = -1;
int tex_coord_attribute_location_ = -1;
uint shader_program_ = 0;
int image_texture_location_ = -1;
int fullscreen_location_ = -1;
/* Shader compilation attempted. Which means, that if the shader program is 0 then compilation or
* linking has failed. Do not attempt to re-compile the shader. */
bool shader_compile_attempted_ = false;
};
CCL_NAMESPACE_END

View File

@@ -0,0 +1,365 @@
/*
* Copyright 2011-2022 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include "app/opengl/window.h"
#include "util/string.h"
#include "util/thread.h"
#include "util/time.h"
#include "util/version.h"
#include <GL/glew.h>
#include <SDL.h>
CCL_NAMESPACE_BEGIN
/* structs */
struct Window {
WindowInitFunc initf = nullptr;
WindowExitFunc exitf = nullptr;
WindowResizeFunc resize = nullptr;
WindowDisplayFunc display = nullptr;
WindowKeyboardFunc keyboard = nullptr;
WindowMotionFunc motion = nullptr;
bool first_display = true;
bool redraw = false;
int mouseX = 0, mouseY = 0;
int mouseBut0 = 0, mouseBut2 = 0;
int width = 0, height = 0;
SDL_Window *window = nullptr;
SDL_GLContext gl_context = nullptr;
thread_mutex gl_context_mutex;
} V;
/* public */
static void window_display_text(int x, int y, const char *text)
{
/* Not currently supported, need to add text rendering support. */
#if 0
const char *c;
glRasterPos3f(x, y, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
printf("display %s\n", text);
for (c = text; *c != '\0'; c++) {
const uint8_t *bitmap = helvetica10_character_map[*c];
glBitmap(bitmap[0],
helvetica10_height,
helvetica10_x_offset,
helvetica10_y_offset,
bitmap[0],
0.0f,
bitmap + 1);
}
#else
static string last_text = "";
if (text != last_text) {
printf("%s\n", text);
last_text = text;
}
#endif
}
void window_display_info(const char *info)
{
const int height = 20;
#if 0
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(0.1f, 0.1f, 0.1f, 0.8f);
glRectf(0.0f, V.height - height, V.width, V.height);
glDisable(GL_BLEND);
glColor3f(0.5f, 0.5f, 0.5f);
#endif
window_display_text(10, 7 + V.height - height, info);
#if 0
glColor3f(1.0f, 1.0f, 1.0f);
#endif
}
void window_display_help()
{
const int w = (int)((float)V.width / 1.15f);
const int h = (int)((float)V.height / 1.15f);
const int x1 = (V.width - w) / 2;
#if 0
const int x2 = x1 + w;
#endif
const int y1 = (V.height - h) / 2;
const int y2 = y1 + h;
#if 0
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(0.5f, 0.5f, 0.5f, 0.8f);
glRectf(x1, y1, x2, y2);
glDisable(GL_BLEND);
glColor3f(0.8f, 0.8f, 0.8f);
#endif
string info = string("Cycles Renderer ") + CYCLES_VERSION_STRING;
window_display_text(x1 + 20, y2 - 20, info.c_str());
window_display_text(x1 + 20, y2 - 40, "(C) 2011-2016 Blender Foundation");
window_display_text(x1 + 20, y2 - 80, "Controls:");
window_display_text(x1 + 20, y2 - 100, "h: Info/Help");
window_display_text(x1 + 20, y2 - 120, "r: Reset");
window_display_text(x1 + 20, y2 - 140, "p: Pause");
window_display_text(x1 + 20, y2 - 160, "esc: Cancel");
window_display_text(x1 + 20, y2 - 180, "q: Quit program");
window_display_text(x1 + 20, y2 - 210, "i: Interactive mode");
window_display_text(x1 + 20, y2 - 230, "Left mouse: Move camera");
window_display_text(x1 + 20, y2 - 250, "Right mouse: Rotate camera");
window_display_text(x1 + 20, y2 - 270, "W/A/S/D: Move camera");
window_display_text(x1 + 20, y2 - 290, "0/1/2/3: Set max bounces");
#if 0
glColor3f(1.0f, 1.0f, 1.0f);
#endif
}
static void window_display()
{
if (V.first_display) {
if (V.initf) {
V.initf();
}
if (V.exitf) {
atexit(V.exitf);
}
V.first_display = false;
}
window_opengl_context_enable();
glViewport(0, 0, V.width, V.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.05f, 0.05f, 0.05f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, V.width, 0, V.height, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRasterPos3f(0, 0, 0);
if (V.display)
V.display();
SDL_GL_SwapWindow(V.window);
window_opengl_context_disable();
}
static void window_reshape(int width, int height)
{
if (V.width != width || V.height != height) {
if (V.resize) {
V.resize(width, height);
}
}
V.width = width;
V.height = height;
}
static bool window_keyboard(unsigned char key)
{
if (V.keyboard)
V.keyboard(key);
if (key == 'q') {
if (V.exitf)
V.exitf();
return true;
}
return false;
}
static void window_mouse(int button, int state, int x, int y)
{
if (button == SDL_BUTTON_LEFT) {
if (state == SDL_MOUSEBUTTONDOWN) {
V.mouseX = x;
V.mouseY = y;
V.mouseBut0 = 1;
}
else if (state == SDL_MOUSEBUTTONUP) {
V.mouseBut0 = 0;
}
}
else if (button == SDL_BUTTON_RIGHT) {
if (state == SDL_MOUSEBUTTONDOWN) {
V.mouseX = x;
V.mouseY = y;
V.mouseBut2 = 1;
}
else if (state == SDL_MOUSEBUTTONUP) {
V.mouseBut2 = 0;
}
}
}
static void window_motion(int x, int y)
{
const int but = V.mouseBut0 ? 0 : 2;
const int distX = x - V.mouseX;
const int distY = y - V.mouseY;
if (V.motion)
V.motion(distX, distY, but);
V.mouseX = x;
V.mouseY = y;
}
bool window_opengl_context_enable()
{
V.gl_context_mutex.lock();
SDL_GL_MakeCurrent(V.window, V.gl_context);
return true;
}
void window_opengl_context_disable()
{
SDL_GL_MakeCurrent(V.window, nullptr);
V.gl_context_mutex.unlock();
}
void window_main_loop(const char *title,
int width,
int height,
WindowInitFunc initf,
WindowExitFunc exitf,
WindowResizeFunc resize,
WindowDisplayFunc display,
WindowKeyboardFunc keyboard,
WindowMotionFunc motion)
{
V.width = width;
V.height = height;
V.first_display = true;
V.redraw = false;
V.initf = initf;
V.exitf = exitf;
V.resize = resize;
V.display = display;
V.keyboard = keyboard;
V.motion = motion;
SDL_Init(SDL_INIT_VIDEO);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
V.window = SDL_CreateWindow(title,
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
width,
height,
SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
if (V.window == nullptr) {
fprintf(stderr, "Failed to create window: %s\n", SDL_GetError());
return;
}
SDL_RaiseWindow(V.window);
V.gl_context = SDL_GL_CreateContext(V.window);
glewInit();
SDL_GL_MakeCurrent(V.window, nullptr);
window_reshape(width, height);
window_display();
while (true) {
bool quit = false;
SDL_Event event;
while (!quit && SDL_PollEvent(&event)) {
if (event.type == SDL_TEXTINPUT) {
quit = window_keyboard(event.text.text[0]);
}
else if (event.type == SDL_MOUSEMOTION) {
window_motion(event.motion.x, event.motion.y);
}
else if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) {
window_mouse(event.button.button, event.button.state, event.button.x, event.button.y);
}
else if (event.type == SDL_WINDOWEVENT) {
if (event.window.event == SDL_WINDOWEVENT_RESIZED ||
event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
window_reshape(event.window.data1, event.window.data2);
}
}
else if (event.type == SDL_QUIT) {
if (V.exitf) {
V.exitf();
}
quit = true;
}
}
if (quit) {
break;
}
if (V.redraw) {
V.redraw = false;
window_display();
}
SDL_WaitEventTimeout(NULL, 100);
}
SDL_GL_DeleteContext(V.gl_context);
SDL_DestroyWindow(V.window);
SDL_Quit();
}
void window_redraw()
{
V.redraw = true;
}
CCL_NAMESPACE_END

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2011-2022 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
/* Functions to display a simple OpenGL window using SDL, simplified to the
* bare minimum we need to reduce boilerplate code in tests apps. */
CCL_NAMESPACE_BEGIN
typedef void (*WindowInitFunc)();
typedef void (*WindowExitFunc)();
typedef void (*WindowResizeFunc)(int width, int height);
typedef void (*WindowDisplayFunc)();
typedef void (*WindowKeyboardFunc)(unsigned char key);
typedef void (*WindowMotionFunc)(int x, int y, int button);
void window_main_loop(const char *title,
int width,
int height,
WindowInitFunc initf,
WindowExitFunc exitf,
WindowResizeFunc resize,
WindowDisplayFunc display,
WindowKeyboardFunc keyboard,
WindowMotionFunc motion);
void window_display_info(const char *info);
void window_display_help();
void window_redraw();
bool window_opengl_context_enable();
void window_opengl_context_disable();
CCL_NAMESPACE_END

View File

@@ -74,7 +74,7 @@ enum_panorama_types = (
"Similar to most fisheye modern lens, takes sensor dimensions into consideration"),
('MIRRORBALL', "Mirror Ball", "Uses the mirror ball mapping"),
('FISHEYE_LENS_POLYNOMIAL', "Fisheye Lens Polynomial",
"Defines the lens projection as polynomial to allow real world camera lenses to be mimicked."),
"Defines the lens projection as polynomial to allow real world camera lenses to be mimicked"),
)
enum_curve_shape = (
@@ -667,6 +667,11 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
description="Use special type BVH optimized for hair (uses more ram but renders faster)",
default=True,
)
debug_use_compact_bvh: BoolProperty(
name="Use Compact BVH",
description="Use compact BVH structure (uses less ram but renders slower)",
default=True,
)
debug_bvh_time_steps: IntProperty(
name="BVH Time Steps",
description="Split BVH primitives by this number of time steps to speed up render time in cost of memory",
@@ -896,27 +901,27 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
fisheye_polynomial_k0: FloatProperty(
name="Fisheye Polynomial K0",
description="Coefficient K0 of the lens polinomial",
description="Coefficient K0 of the lens polynomial",
default=camera.default_fisheye_polynomial[0], precision=6, step=0.1, subtype='ANGLE',
)
fisheye_polynomial_k1: FloatProperty(
name="Fisheye Polynomial K1",
description="Coefficient K1 of the lens polinomial",
description="Coefficient K1 of the lens polynomial",
default=camera.default_fisheye_polynomial[1], precision=6, step=0.1, subtype='ANGLE',
)
fisheye_polynomial_k2: FloatProperty(
name="Fisheye Polynomial K2",
description="Coefficient K2 of the lens polinomial",
description="Coefficient K2 of the lens polynomial",
default=camera.default_fisheye_polynomial[2], precision=6, step=0.1, subtype='ANGLE',
)
fisheye_polynomial_k3: FloatProperty(
name="Fisheye Polynomial K3",
description="Coefficient K3 of the lens polinomial",
description="Coefficient K3 of the lens polynomial",
default=camera.default_fisheye_polynomial[3], precision=6, step=0.1, subtype='ANGLE',
)
fisheye_polynomial_k4: FloatProperty(
name="Fisheye Polynomial K4",
description="Coefficient K4 of the lens polinomial",
description="Coefficient K4 of the lens polynomial",
default=camera.default_fisheye_polynomial[4], precision=6, step=0.1, subtype='ANGLE',
)
@@ -1369,6 +1374,12 @@ class CyclesPreferences(bpy.types.AddonPreferences):
default=False,
)
use_metalrt: BoolProperty(
name="MetalRT (Experimental)",
description="MetalRT for ray tracing uses less memory for scenes which use curves extensively, and can give better performance in specific cases. However this support is experimental and some scenes may render incorrectly",
default=False,
)
def find_existing_device_entry(self, device):
for device_entry in self.devices:
if device_entry.id == device[2] and device_entry.type == device[1]:
@@ -1447,6 +1458,19 @@ class CyclesPreferences(bpy.types.AddonPreferences):
num += 1
return num
def has_multi_device(self):
import _cycles
compute_device_type = self.get_compute_device_type()
device_list = _cycles.available_devices(compute_device_type)
for device in device_list:
if device[1] == compute_device_type:
continue
for dev in self.devices:
if dev.use and dev.id == device[2]:
return True
return False
def has_active_device(self):
return self.get_num_gpu_devices() > 0
@@ -1474,7 +1498,8 @@ class CyclesPreferences(bpy.types.AddonPreferences):
if sys.platform[:3] == "win":
col.label(text="and AMD Radeon Pro 21.Q4 driver or newer", icon='BLANK1')
elif device_type == 'METAL':
col.label(text="Requires Apple Silicon and macOS 12.0 or newer", icon='BLANK1')
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')
return
for device in devices:
@@ -1501,6 +1526,12 @@ class CyclesPreferences(bpy.types.AddonPreferences):
row.use_property_split = True
row.prop(self, "peer_memory")
if compute_device_type == 'METAL':
row = layout.row()
row.use_property_split = True
row.prop(self, "use_metalrt")
def draw(self, context):
self.draw_impl(self.layout, context)

View File

@@ -118,6 +118,12 @@ def use_optix(context):
return (get_device_type(context) == 'OPTIX' and cscene.device == 'GPU')
def use_multi_device(context):
cscene = context.scene.cycles
if cscene.device != 'GPU':
return False
return context.preferences.addons[__package__].preferences.has_multi_device()
def show_device_active(context):
cscene = context.scene.cycles
@@ -661,6 +667,10 @@ class CYCLES_RENDER_PT_performance_acceleration_structure(CyclesButtonsPanel, Pa
bl_label = "Acceleration Structure"
bl_parent_id = "CYCLES_RENDER_PT_performance"
@classmethod
def poll(cls, context):
return not use_optix(context) or use_multi_device(context)
def draw(self, context):
import _cycles
@@ -673,21 +683,33 @@ class CYCLES_RENDER_PT_performance_acceleration_structure(CyclesButtonsPanel, Pa
col = layout.column()
use_embree = False
use_embree = _cycles.with_embree
if use_cpu(context):
use_embree = _cycles.with_embree
if not use_embree:
col.prop(cscene, "debug_use_spatial_splits")
if use_embree:
col.prop(cscene, "debug_use_compact_bvh")
else:
sub = col.column()
sub.active = not cscene.debug_use_spatial_splits
sub.prop(cscene, "debug_bvh_time_steps")
col.prop(cscene, "debug_use_hair_bvh")
sub = col.column(align=True)
sub.label(text="Cycles built without Embree support")
sub.label(text="CPU raytracing performance will be poor")
else:
col.prop(cscene, "debug_use_spatial_splits")
sub = col.column()
sub.active = not cscene.debug_use_spatial_splits
sub.prop(cscene, "debug_bvh_time_steps")
col.prop(cscene, "debug_use_spatial_splits")
sub = col.column()
sub.active = not use_embree
sub.prop(cscene, "debug_use_hair_bvh")
sub = col.column()
sub.active = not cscene.debug_use_spatial_splits and not use_embree
sub.prop(cscene, "debug_bvh_time_steps")
col.prop(cscene, "debug_use_hair_bvh")
# CPU is used in addition to a GPU
if use_multi_device(context) and use_embree:
col.prop(cscene, "debug_use_compact_bvh")
class CYCLES_RENDER_PT_performance_final_render(CyclesButtonsPanel, Panel):

View File

@@ -118,6 +118,10 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
device.has_peer_memory = false;
}
if (get_boolean(cpreferences, "use_metalrt")) {
device.use_metalrt = true;
}
return device;
}

View File

@@ -480,26 +480,12 @@ class DrawTile {
return false;
}
if (!gl_vertex_buffer) {
glGenBuffers(1, &gl_vertex_buffer);
if (!gl_vertex_buffer) {
LOG(ERROR) << "Error allocating tile VBO.";
gl_resources_destroy();
return false;
}
}
return true;
}
void gl_resources_destroy()
{
texture.gl_resources_destroy();
if (gl_vertex_buffer) {
glDeleteBuffers(1, &gl_vertex_buffer);
gl_vertex_buffer = 0;
}
}
inline bool ready_to_draw() const
@@ -512,9 +498,6 @@ class DrawTile {
/* Display parameters the texture of this tile has been updated for. */
BlenderDisplayDriver::Params params;
/* OpenGL resources needed for drawing. */
uint gl_vertex_buffer = 0;
};
class DrawTileAndPBO {
@@ -560,6 +543,30 @@ struct BlenderDisplayDriver::Tiles {
tiles.clear();
}
} finished_tiles;
/* OpenGL vertex buffer needed for drawing. */
uint gl_vertex_buffer = 0;
bool gl_resources_ensure()
{
if (!gl_vertex_buffer) {
glGenBuffers(1, &gl_vertex_buffer);
if (!gl_vertex_buffer) {
LOG(ERROR) << "Error allocating tile VBO.";
return false;
}
}
return true;
}
void gl_resources_destroy()
{
if (gl_vertex_buffer) {
glDeleteBuffers(1, &gl_vertex_buffer);
gl_vertex_buffer = 0;
}
}
};
BlenderDisplayDriver::BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene)
@@ -626,6 +633,12 @@ bool BlenderDisplayDriver::update_begin(const Params &params,
need_clear_ = false;
}
if (!tiles_->gl_resources_ensure()) {
tiles_->gl_resources_destroy();
gl_context_disable();
return false;
}
if (!tiles_->current_tile.gl_resources_ensure()) {
tiles_->current_tile.gl_resources_destroy();
gl_context_disable();
@@ -825,7 +838,8 @@ static void vertex_buffer_update(const DisplayDriver::Params &params)
static void draw_tile(const float2 &zoom,
const int texcoord_attribute,
const int position_attribute,
const DrawTile &draw_tile)
const DrawTile &draw_tile,
const uint gl_vertex_buffer)
{
if (!draw_tile.ready_to_draw()) {
return;
@@ -834,9 +848,9 @@ static void draw_tile(const float2 &zoom,
const GLTexture &texture = draw_tile.texture;
DCHECK_NE(texture.gl_id, 0);
DCHECK_NE(draw_tile.gl_vertex_buffer, 0);
DCHECK_NE(gl_vertex_buffer, 0);
glBindBuffer(GL_ARRAY_BUFFER, draw_tile.gl_vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, gl_vertex_buffer);
/* Draw at the parameters for which the texture has been updated for. This allows to always draw
* texture during bordered-rendered camera view without flickering. The validness of the display
@@ -956,10 +970,14 @@ void BlenderDisplayDriver::draw(const Params &params)
glEnableVertexAttribArray(texcoord_attribute);
glEnableVertexAttribArray(position_attribute);
draw_tile(zoom_, texcoord_attribute, position_attribute, tiles_->current_tile.tile);
draw_tile(zoom_,
texcoord_attribute,
position_attribute,
tiles_->current_tile.tile,
tiles_->gl_vertex_buffer);
for (const DrawTile &tile : tiles_->finished_tiles.tiles) {
draw_tile(zoom_, texcoord_attribute, position_attribute, tile);
draw_tile(zoom_, texcoord_attribute, position_attribute, tile, tiles_->gl_vertex_buffer);
}
display_shader_->unbind();
@@ -1062,6 +1080,7 @@ void BlenderDisplayDriver::gl_resources_destroy()
tiles_->current_tile.gl_resources_destroy();
tiles_->finished_tiles.gl_resources_destroy_and_clear();
tiles_->gl_resources_destroy();
gl_context_disable();

View File

@@ -506,8 +506,13 @@ void BlenderSession::render_frame_finish()
session->set_output_driver(nullptr);
session->full_buffer_written_cb = function_null;
/* The display driver holds OpenGL resources which belong to an OpenGL context held by the render
* engine on Blender side. Force destruction of those resources. */
/* The display driver is the source of drawing context for both drawing and possible graphics
* interop objects in the path trace. Once the frame is finished the OpenGL context might be
* freed form Blender side. Need to ensure that all GPU resources are freed prior to that
* point.
* Ideally would only do this when OpenGL context is actually destroyed, but there is no way to
* know when this happens (at least in the code at the time when this comment was written).
* The penalty of re-creating resources on every frame is unlikely to be noticed. */
display_driver_ = nullptr;
session->set_display_driver(nullptr);

View File

@@ -45,7 +45,8 @@ typedef map<string, ConvertNode *> ProxyMap;
void BlenderSync::find_shader(BL::ID &id, array<Node *> &used_shaders, Shader *default_shader)
{
Shader *shader = (id) ? shader_map.find(id) : default_shader;
Shader *synced_shader = (id) ? shader_map.find(id) : nullptr;
Shader *shader = (synced_shader) ? synced_shader : default_shader;
used_shaders.push_back_slow(shader);
shader->tag_used(scene);
@@ -689,6 +690,9 @@ static ShaderNode *add_node(Scene *scene,
else if (b_node.is_a(&RNA_ShaderNodeHairInfo)) {
node = graph->create_node<HairInfoNode>();
}
else if (b_node.is_a(&RNA_ShaderNodePointInfo)) {
node = graph->create_node<PointInfoNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeVolumeInfo)) {
node = graph->create_node<VolumeInfoNode>();
}

View File

@@ -787,6 +787,7 @@ SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background)
params.bvh_type = BVH_TYPE_DYNAMIC;
params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
params.use_bvh_compact_structure = RNA_boolean_get(&cscene, "debug_use_compact_bvh");
params.use_bvh_unaligned_nodes = RNA_boolean_get(&cscene, "debug_use_hair_bvh");
params.num_bvh_time_steps = RNA_int_get(&cscene, "debug_bvh_time_steps");

View File

@@ -61,6 +61,26 @@ static_assert(Object::MAX_MOTION_STEPS == Geometry::MAX_MOTION_STEPS,
# define IS_HAIR(x) (x & 1)
/* This gets called by Embree at every valid ray/object intersection.
* Things like recording subsurface or shadow hits for later evaluation
* as well as filtering for volume objects happen here.
* Cycles' own BVH does that directly inside the traversal calls.
*/
static void rtc_filter_intersection_func(const RTCFilterFunctionNArguments *args)
{
/* Current implementation in Cycles assumes only single-ray intersection queries. */
assert(args->N == 1);
RTCHit *hit = (RTCHit *)args->hit;
CCLIntersectContext *ctx = ((IntersectContext *)args->context)->userRayExt;
const KernelGlobalsCPU *kg = ctx->kg;
const Ray *cray = ctx->ray;
if (kernel_embree_is_self_intersection(kg, hit, cray)) {
*args->valid = 0;
}
}
/* This gets called by Embree at every valid ray/object intersection.
* Things like recording subsurface or shadow hits for later evaluation
* as well as filtering for volume objects happen here.
@@ -75,12 +95,16 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
RTCHit *hit = (RTCHit *)args->hit;
CCLIntersectContext *ctx = ((IntersectContext *)args->context)->userRayExt;
const KernelGlobalsCPU *kg = ctx->kg;
const Ray *cray = ctx->ray;
switch (ctx->type) {
case CCLIntersectContext::RAY_SHADOW_ALL: {
Intersection current_isect;
kernel_embree_convert_hit(kg, ray, hit, &current_isect);
if (intersection_skip_self_shadow(cray->self, current_isect.object, current_isect.prim)) {
*args->valid = 0;
return;
}
/* If no transparent shadows or max number of hits exceeded, all light is blocked. */
const int flags = intersection_get_shader_flags(kg, current_isect.prim, current_isect.type);
if (!(flags & (SD_HAS_TRANSPARENT_SHADOW)) || ctx->num_hits >= ctx->max_hits) {
@@ -160,6 +184,10 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
break;
}
}
if (intersection_skip_self_local(cray->self, current_isect.prim)) {
*args->valid = 0;
return;
}
/* No intersection information requested, just return a hit. */
if (ctx->max_hits == 0) {
@@ -225,6 +253,11 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
if (ctx->num_hits < ctx->max_hits) {
Intersection current_isect;
kernel_embree_convert_hit(kg, ray, hit, &current_isect);
if (intersection_skip_self(cray->self, current_isect.object, current_isect.prim)) {
*args->valid = 0;
return;
}
Intersection *isect = &ctx->isect_s[ctx->num_hits];
++ctx->num_hits;
*isect = current_isect;
@@ -236,12 +269,15 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
}
/* This tells Embree to continue tracing. */
*args->valid = 0;
break;
}
break;
}
case CCLIntersectContext::RAY_REGULAR:
default:
/* Nothing to do here. */
if (kernel_embree_is_self_intersection(kg, hit, cray)) {
*args->valid = 0;
return;
}
break;
}
}
@@ -257,6 +293,14 @@ static void rtc_filter_func_backface_cull(const RTCFilterFunctionNArguments *arg
*args->valid = 0;
return;
}
CCLIntersectContext *ctx = ((IntersectContext *)args->context)->userRayExt;
const KernelGlobalsCPU *kg = ctx->kg;
const Ray *cray = ctx->ray;
if (kernel_embree_is_self_intersection(kg, hit, cray)) {
*args->valid = 0;
}
}
static void rtc_filter_occluded_func_backface_cull(const RTCFilterFunctionNArguments *args)
@@ -355,10 +399,12 @@ void BVHEmbree::build(Progress &progress, Stats *stats, RTCDevice rtc_device_)
}
const bool dynamic = params.bvh_type == BVH_TYPE_DYNAMIC;
const bool compact = params.use_compact_structure;
scene = rtcNewScene(rtc_device);
const RTCSceneFlags scene_flags = (dynamic ? RTC_SCENE_FLAG_DYNAMIC : RTC_SCENE_FLAG_NONE) |
RTC_SCENE_FLAG_COMPACT | RTC_SCENE_FLAG_ROBUST;
(compact ? RTC_SCENE_FLAG_COMPACT : RTC_SCENE_FLAG_NONE) |
RTC_SCENE_FLAG_ROBUST;
rtcSetSceneFlags(scene, scene_flags);
build_quality = dynamic ? RTC_BUILD_QUALITY_LOW :
(params.use_spatial_split ? RTC_BUILD_QUALITY_HIGH :
@@ -425,7 +471,7 @@ void BVHEmbree::add_instance(Object *ob, int i)
assert(instance_bvh != NULL);
const size_t num_object_motion_steps = ob->use_motion() ? ob->get_motion().size() : 1;
const size_t num_motion_steps = min(num_object_motion_steps, RTC_MAX_TIME_STEP_COUNT);
const size_t num_motion_steps = min(num_object_motion_steps, (size_t)RTC_MAX_TIME_STEP_COUNT);
assert(num_object_motion_steps <= RTC_MAX_TIME_STEP_COUNT);
RTCGeometry geom_id = rtcNewGeometry(rtc_device, RTC_GEOMETRY_TYPE_INSTANCE);
@@ -476,7 +522,7 @@ void BVHEmbree::add_triangles(const Object *ob, const Mesh *mesh, int i)
}
assert(num_motion_steps <= RTC_MAX_TIME_STEP_COUNT);
num_motion_steps = min(num_motion_steps, RTC_MAX_TIME_STEP_COUNT);
num_motion_steps = min(num_motion_steps, (size_t)RTC_MAX_TIME_STEP_COUNT);
const size_t num_triangles = mesh->num_triangles();
@@ -503,6 +549,7 @@ void BVHEmbree::add_triangles(const Object *ob, const Mesh *mesh, int i)
rtcSetGeometryUserData(geom_id, (void *)prim_offset);
rtcSetGeometryOccludedFilterFunction(geom_id, rtc_filter_occluded_func);
rtcSetGeometryIntersectFilterFunction(geom_id, rtc_filter_intersection_func);
rtcSetGeometryMask(geom_id, ob->visibility_for_tracing());
rtcCommitGeometry(geom_id);
@@ -728,7 +775,7 @@ void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i)
}
assert(num_motion_steps <= RTC_MAX_TIME_STEP_COUNT);
num_motion_steps = min(num_motion_steps, RTC_MAX_TIME_STEP_COUNT);
num_motion_steps = min(num_motion_steps, (size_t)RTC_MAX_TIME_STEP_COUNT);
const size_t num_curves = hair->num_curves();
size_t num_segments = 0;
@@ -765,6 +812,7 @@ void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i)
rtcSetGeometryUserData(geom_id, (void *)prim_offset);
if (hair->curve_shape == CURVE_RIBBON) {
rtcSetGeometryIntersectFilterFunction(geom_id, rtc_filter_intersection_func);
rtcSetGeometryOccludedFilterFunction(geom_id, rtc_filter_occluded_func);
}
else {

View File

@@ -97,6 +97,9 @@ class BVHParams {
*/
bool use_unaligned_nodes;
/* Use compact acceleration structure (Embree)*/
bool use_compact_structure;
/* Split time range to this number of steps and create leaf node for each
* of this time steps.
*
@@ -139,6 +142,7 @@ class BVHParams {
top_level = false;
bvh_layout = BVH_LAYOUT_BVH2;
use_compact_structure = true;
use_unaligned_nodes = false;
num_motion_curve_steps = 0;

View File

@@ -491,26 +491,22 @@ else()
endif()
###########################################################################
# GLUT
# SDL
###########################################################################
if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI)
if(MSVC AND EXISTS ${_cycles_lib_dir})
add_definitions(-DFREEGLUT_STATIC -DFREEGLUT_LIB_PRAGMAS=0)
set(GLUT_LIBRARIES "${_cycles_lib_dir}/opengl/lib/freeglut_static.lib")
set(GLUT_INCLUDE_DIR "${_cycles_lib_dir}/opengl/include")
else()
find_package(GLUT)
# We can't use the version from the Blender precompiled libraries because
# it does not include the video subsystem.
find_package(SDL2)
if(NOT GLUT_FOUND)
set(WITH_CYCLES_STANDALONE_GUI OFF)
message(STATUS "GLUT not found, disabling Cycles standalone GUI")
endif()
if(NOT SDL2_FOUND)
set(WITH_CYCLES_STANDALONE_GUI OFF)
message(STATUS "SDL not found, disabling Cycles standalone GUI")
endif()
include_directories(
SYSTEM
${GLUT_INCLUDE_DIR}
${SDL2_INCLUDE_DIRS}
)
endif()
@@ -559,10 +555,10 @@ if(WITH_CYCLES_DEVICE_METAL)
find_library(METAL_LIBRARY Metal)
# This file was added in the 12.0 SDK, use it as a way to detect the version.
if (METAL_LIBRARY AND NOT EXISTS "${METAL_LIBRARY}/Headers/MTLFunctionStitching.h")
if(METAL_LIBRARY AND NOT EXISTS "${METAL_LIBRARY}/Headers/MTLFunctionStitching.h")
message(STATUS "Metal version too old, must be SDK 12.0 or newer, disabling WITH_CYCLES_DEVICE_METAL")
set(WITH_CYCLES_DEVICE_METAL OFF)
elseif (NOT METAL_LIBRARY)
elseif(NOT METAL_LIBRARY)
message(STATUS "Metal not found, disabling WITH_CYCLES_DEVICE_METAL")
set(WITH_CYCLES_DEVICE_METAL OFF)
else()

View File

@@ -328,6 +328,7 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
info.has_osl = true;
info.has_profiling = true;
info.has_peer_memory = false;
info.use_metalrt = false;
info.denoisers = DENOISER_ALL;
foreach (const DeviceInfo &device, subdevices) {
@@ -335,7 +336,7 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
if (device.type == DEVICE_CPU && subdevices.size() > 1) {
if (background) {
int orig_cpu_threads = (threads) ? threads : TaskScheduler::max_concurrency();
int cpu_threads = max(orig_cpu_threads - (subdevices.size() - 1), 0);
int cpu_threads = max(orig_cpu_threads - (subdevices.size() - 1), size_t(0));
VLOG(1) << "CPU render threads reduced from " << orig_cpu_threads << " to " << cpu_threads
<< ", to dedicate to GPU.";
@@ -374,6 +375,7 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
info.has_osl &= device.has_osl;
info.has_profiling &= device.has_profiling;
info.has_peer_memory |= device.has_peer_memory;
info.use_metalrt |= device.use_metalrt;
info.denoisers &= device.denoisers;
}

View File

@@ -79,6 +79,7 @@ class DeviceInfo {
bool has_profiling; /* Supports runtime collection of profiling info. */
bool has_peer_memory; /* GPU has P2P access to memory of another GPU. */
bool has_gpu_queue; /* Device supports GPU queue. */
bool use_metalrt; /* Use MetalRT to accelerate ray queries (Metal only). */
DenoiserTypeMask denoisers; /* Supported denoiser types. */
int cpu_threads;
vector<DeviceInfo> multi_devices;
@@ -96,6 +97,7 @@ class DeviceInfo {
has_profiling = false;
has_peer_memory = false;
has_gpu_queue = false;
use_metalrt = false;
denoisers = DENOISER_NONE;
}

View File

@@ -25,8 +25,6 @@
# ifdef WITH_HIP_DYNLOAD
# include "hipew.h"
# else
# include "util/opengl.h"
# endif
CCL_NAMESPACE_BEGIN

View File

@@ -311,7 +311,7 @@ template<typename T> class device_only_memory : public device_memory {
: device_memory(device, name, allow_host_memory_fallback ? MEM_READ_WRITE : MEM_DEVICE_ONLY)
{
data_type = device_type_traits<T>::data_type;
data_elements = max(device_type_traits<T>::num_elements, 1);
data_elements = max(device_type_traits<T>::num_elements, size_t(1));
}
device_only_memory(device_only_memory &&other) noexcept : device_memory(std::move(other))

View File

@@ -761,7 +761,7 @@ bool BVHMetal::build_TLAS(Progress &progress,
num_instances++;
if (ob->use_motion()) {
num_motion_transforms += max(1, ob->get_motion().size());
num_motion_transforms += max((size_t)1, ob->get_motion().size());
}
else {
num_motion_transforms++;

View File

@@ -39,33 +39,20 @@ bool device_metal_init()
return true;
}
static int device_metal_get_num_devices_safe(uint32_t *num_devices)
{
*num_devices = MTLCopyAllDevices().count;
return 0;
}
void device_metal_info(vector<DeviceInfo> &devices)
{
uint32_t num_devices = 0;
device_metal_get_num_devices_safe(&num_devices);
if (num_devices == 0) {
return;
}
vector<MetalPlatformDevice> usable_devices;
MetalInfo::get_usable_devices(&usable_devices);
auto usable_devices = MetalInfo::get_usable_devices();
/* Devices are numbered consecutively across platforms. */
set<string> unique_ids;
int device_index = 0;
for (MetalPlatformDevice &device : usable_devices) {
for (id<MTLDevice> &device : usable_devices) {
/* Compute unique ID for persistent user preferences. */
const string &device_name = device.device_name;
string device_name = [device.name UTF8String];
string id = string("METAL_") + device_name;
/* Hardware ID might not be unique, add device number in that case. */
if (unique_ids.find(id) != unique_ids.end()) {
id += string_printf("_ID_%d", num_devices);
id += string_printf("_ID_%d", device_index);
}
unique_ids.insert(id);
@@ -94,15 +81,13 @@ void device_metal_info(vector<DeviceInfo> &devices)
string device_metal_capabilities()
{
string result = "";
string error_msg = "";
uint32_t num_devices = 0;
assert(device_metal_get_num_devices_safe(&num_devices));
auto allDevices = MTLCopyAllDevices();
uint32_t num_devices = allDevices.count;
if (num_devices == 0) {
return "No Metal devices found\n";
}
result += string_printf("Number of devices: %u\n", num_devices);
NSArray<id<MTLDevice>> *allDevices = MTLCopyAllDevices();
for (id<MTLDevice> device in allDevices) {
result += string_printf("\t\tDevice: %s\n", [device.name UTF8String]);
}

View File

@@ -53,16 +53,10 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile
mtlDevId = info.num;
/* select chosen device */
vector<MetalPlatformDevice> usable_devices;
MetalInfo::get_usable_devices(&usable_devices);
if (usable_devices.size() == 0) {
set_error("Metal: no devices found.");
return;
}
auto usable_devices = MetalInfo::get_usable_devices();
assert(mtlDevId < usable_devices.size());
MetalPlatformDevice &platform_device = usable_devices[mtlDevId];
mtlDevice = platform_device.device_id;
device_name = platform_device.device_name;
mtlDevice = usable_devices[mtlDevId];
device_name = [mtlDevice.name UTF8String];
device_vendor = MetalInfo::get_vendor_from_device_name(device_name);
assert(device_vendor != METAL_GPU_UNKNOWN);
metal_printf("Creating new Cycles device for Metal: %s\n", device_name.c_str());
@@ -100,6 +94,7 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile
}
}
use_metalrt = info.use_metalrt;
if (auto metalrt = getenv("CYCLES_METALRT")) {
use_metalrt = (atoi(metalrt) != 0);
}
@@ -455,8 +450,15 @@ MetalDevice::MetalMem *MetalDevice::generic_alloc(device_memory &mem)
mem.device_pointer = 0;
id<MTLBuffer> metal_buffer = nil;
MTLResourceOptions options = default_storage_mode;
/* Workaround for "bake" unit tests which fail if RenderBuffers is allocated with
* MTLResourceStorageModeShared. */
if (strstr(mem.name, "RenderBuffers")) {
options = MTLResourceStorageModeManaged;
}
if (size > 0) {
MTLResourceOptions options = default_storage_mode;
if (mem.type == MEM_DEVICE_ONLY) {
options = MTLResourceStorageModePrivate;
}
@@ -490,7 +492,7 @@ MetalDevice::MetalMem *MetalDevice::generic_alloc(device_memory &mem)
mmem->mtlBuffer = metal_buffer;
mmem->offset = 0;
mmem->size = size;
if (mem.type != MEM_DEVICE_ONLY) {
if (options != MTLResourceStorageModePrivate) {
mmem->hostPtr = [metal_buffer contents];
}
else {
@@ -759,6 +761,17 @@ void MetalDevice::tex_alloc_as_buffer(device_texture &mem)
void MetalDevice::tex_alloc(device_texture &mem)
{
/* Check that dimensions fit within maximum allowable size.
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;
}
MTLStorageMode storage_mode = MTLStorageModeManaged;
if (@available(macos 10.15, *)) {
if ([mtlDevice hasUnifiedMemory] &&

View File

@@ -59,10 +59,15 @@ bool MetalDeviceKernel::load(MetalDevice *device,
}
bool use_binary_archive = true;
if (getenv("CYCLES_METAL_DISABLE_BINARY_ARCHIVES")) {
if (device->device_vendor == METAL_GPU_APPLE) {
/* Workaround for T94142: Cycles Metal crash with simultaneous viewport and final render */
use_binary_archive = false;
}
if (auto str = getenv("CYCLES_METAL_DISABLE_BINARY_ARCHIVES")) {
use_binary_archive = (atoi(str) == 0);
}
id<MTLBinaryArchive> archive = nil;
string metalbin_path;
if (use_binary_archive) {

View File

@@ -36,33 +36,10 @@ enum MetalGPUVendor {
METAL_GPU_INTEL = 3,
};
/* Retains a named MTLDevice for device enumeration. */
struct MetalPlatformDevice {
MetalPlatformDevice(id<MTLDevice> device, const string &device_name)
: device_id(device), device_name(device_name)
{
[device_id retain];
}
~MetalPlatformDevice()
{
[device_id release];
}
id<MTLDevice> device_id;
string device_name;
};
/* Contains static Metal helper functions. */
struct MetalInfo {
static bool device_version_check(id<MTLDevice> device);
static void get_usable_devices(vector<MetalPlatformDevice> *usable_devices);
static vector<id<MTLDevice>> const &get_usable_devices();
static MetalGPUVendor get_vendor_from_device_name(string const &device_name);
/* Platform information. */
static bool get_num_devices(uint32_t *num_platforms);
static uint32_t get_num_devices();
static bool get_device_name(id<MTLDevice> device_id, string *device_name);
static string get_device_name(id<MTLDevice> device_id);
};
/* Pool of MTLBuffers whose lifetime is linked to a single MTLCommandBuffer */

View File

@@ -43,83 +43,45 @@ MetalGPUVendor MetalInfo::get_vendor_from_device_name(string const &device_name)
return METAL_GPU_UNKNOWN;
}
bool MetalInfo::device_version_check(id<MTLDevice> device)
vector<id<MTLDevice>> const &MetalInfo::get_usable_devices()
{
/* Metal Cycles doesn't work correctly on macOS versions older than 12.0 */
if (@available(macos 12.0, *)) {
MetalGPUVendor vendor = get_vendor_from_device_name([[device name] UTF8String]);
static vector<id<MTLDevice>> usable_devices;
static bool already_enumerated = false;
/* Metal Cycles works on Apple Silicon GPUs at present */
return (vendor == METAL_GPU_APPLE);
if (already_enumerated) {
return usable_devices;
}
return false;
}
metal_printf("Usable Metal devices:\n");
for (id<MTLDevice> device in MTLCopyAllDevices()) {
const char *device_name = [device.name UTF8String];
void MetalInfo::get_usable_devices(vector<MetalPlatformDevice> *usable_devices)
{
static bool first_time = true;
# define FIRST_VLOG(severity) \
if (first_time) \
VLOG(severity)
MetalGPUVendor vendor = get_vendor_from_device_name(device_name);
bool usable = false;
usable_devices->clear();
NSArray<id<MTLDevice>> *allDevices = MTLCopyAllDevices();
for (id<MTLDevice> device in allDevices) {
string device_name;
if (!get_device_name(device, &device_name)) {
FIRST_VLOG(2) << "Failed to get device name, ignoring.";
continue;
if (@available(macos 12.2, *)) {
usable |= (vendor == METAL_GPU_APPLE);
}
static const char *forceIntelStr = getenv("CYCLES_METAL_FORCE_INTEL");
bool forceIntel = forceIntelStr ? (atoi(forceIntelStr) != 0) : false;
if (forceIntel && device_name.find("Intel") == string::npos) {
FIRST_VLOG(2) << "CYCLES_METAL_FORCE_INTEL causing non-Intel device " << device_name
<< " to be ignored.";
continue;
if (@available(macos 12.3, *)) {
usable |= (vendor == METAL_GPU_AMD);
}
if (!device_version_check(device)) {
FIRST_VLOG(2) << "Ignoring device " << device_name << " due to too old compiler version.";
continue;
if (usable) {
metal_printf("- %s\n", device_name);
[device retain];
usable_devices.push_back(device);
}
else {
metal_printf(" (skipping \"%s\")\n", device_name);
}
FIRST_VLOG(2) << "Adding new device " << device_name << ".";
string hardware_id;
usable_devices->push_back(MetalPlatformDevice(device, device_name));
}
first_time = false;
}
bool MetalInfo::get_num_devices(uint32_t *num_devices)
{
*num_devices = MTLCopyAllDevices().count;
return true;
}
uint32_t MetalInfo::get_num_devices()
{
uint32_t num_devices;
if (!get_num_devices(&num_devices)) {
return 0;
if (usable_devices.empty()) {
metal_printf(" No usable Metal devices found\n");
}
return num_devices;
}
already_enumerated = true;
bool MetalInfo::get_device_name(id<MTLDevice> device, string *platform_name)
{
*platform_name = [device.name UTF8String];
return true;
}
string MetalInfo::get_device_name(id<MTLDevice> device)
{
string platform_name;
if (!get_device_name(device, &platform_name)) {
return "";
}
return platform_name;
return usable_devices;
}
id<MTLBuffer> MetalBufferPool::get_buffer(id<MTLDevice> device,

View File

@@ -226,7 +226,7 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
pipeline_options.usesMotionBlur = false;
pipeline_options.traversableGraphFlags =
OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_LEVEL_INSTANCING;
pipeline_options.numPayloadValues = 6;
pipeline_options.numPayloadValues = 8;
pipeline_options.numAttributeValues = 2; /* u, v */
pipeline_options.exceptionFlags = OPTIX_EXCEPTION_FLAG_NONE;
pipeline_options.pipelineLaunchParamsVariableName = "__params"; /* See globals.h */
@@ -1586,7 +1586,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
if (ob->is_traceable() && ob->use_motion()) {
total_motion_transform_size = align_up(total_motion_transform_size,
OPTIX_TRANSFORM_BYTE_ALIGNMENT);
const size_t motion_keys = max(ob->get_motion().size(), 2) - 2;
const size_t motion_keys = max(ob->get_motion().size(), (size_t)2) - 2;
total_motion_transform_size = total_motion_transform_size +
sizeof(OptixSRTMotionTransform) +
motion_keys * sizeof(OptixSRTData);
@@ -1660,7 +1660,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
/* Insert motion traversable if object has motion. */
if (motion_blur && ob->use_motion()) {
size_t motion_keys = max(ob->get_motion().size(), 2) - 2;
size_t motion_keys = max(ob->get_motion().size(), (size_t)2) - 2;
size_t motion_transform_size = sizeof(OptixSRTMotionTransform) +
motion_keys * sizeof(OptixSRTData);

View File

@@ -125,20 +125,41 @@ static Device *find_best_device(Device *device, DenoiserType type)
return best_device;
}
static DeviceInfo find_best_denoiser_device_info(const vector<DeviceInfo> &device_infos,
DenoiserType denoiser_type)
{
for (const DeviceInfo &device_info : device_infos) {
if ((device_info.denoisers & denoiser_type) == 0) {
continue;
}
/* TODO(sergey): Use one of the already configured devices, so that OptiX denoising can happen
* on a physical CUDA device which is already used for rendering. */
/* TODO(sergey): Choose fastest device for denoising. */
return device_info;
}
DeviceInfo none_device;
none_device.type = DEVICE_NONE;
return none_device;
}
static unique_ptr<Device> create_denoiser_device(Device *path_trace_device,
const uint device_type_mask)
const uint device_type_mask,
DenoiserType denoiser_type)
{
const vector<DeviceInfo> device_infos = Device::available_devices(device_type_mask);
if (device_infos.empty()) {
return nullptr;
}
/* TODO(sergey): Use one of the already configured devices, so that OptiX denoising can happen on
* a physical CUDA device which is already used for rendering. */
/* TODO(sergey): Choose fastest device for denoising. */
const DeviceInfo denoiser_device_info = device_infos.front();
const DeviceInfo denoiser_device_info = find_best_denoiser_device_info(device_infos,
denoiser_type);
if (denoiser_device_info.type == DEVICE_NONE) {
return nullptr;
}
unique_ptr<Device> denoiser_device(
Device::create(denoiser_device_info, path_trace_device->stats, path_trace_device->profiler));
@@ -186,7 +207,8 @@ Device *Denoiser::ensure_denoiser_device(Progress *progress)
device_creation_attempted_ = true;
const uint device_type_mask = get_device_type_mask();
local_denoiser_device_ = create_denoiser_device(path_trace_device_, device_type_mask);
local_denoiser_device_ = create_denoiser_device(
path_trace_device_, device_type_mask, params_.type);
denoiser_device_ = local_denoiser_device_.get();
return denoiser_device_;

View File

@@ -37,8 +37,6 @@ OIDNDenoiser::OIDNDenoiser(Device *path_trace_device, const DenoiseParams &param
: Denoiser(path_trace_device, params)
{
DCHECK_EQ(params.type, DENOISER_OPENIMAGEDENOISE);
DCHECK(openimagedenoise_supported()) << "OpenImageDenoiser is not supported on this platform.";
}
#ifdef WITH_OPENIMAGEDENOISE
@@ -585,6 +583,9 @@ bool OIDNDenoiser::denoise_buffer(const BufferParams &buffer_params,
const int num_samples,
bool allow_inplace_modification)
{
DCHECK(openimagedenoise_supported())
<< "OpenImageDenoiser is not supported on this platform or build.";
#ifdef WITH_OPENIMAGEDENOISE
thread_scoped_lock lock(mutex_);
@@ -635,4 +636,20 @@ uint OIDNDenoiser::get_device_type_mask() const
return DEVICE_MASK_CPU;
}
Device *OIDNDenoiser::ensure_denoiser_device(Progress *progress)
{
#ifndef WITH_OPENIMAGEDENOISE
path_trace_device_->set_error("Build without OpenImageDenoiser");
return nullptr;
#else
if (!openimagedenoise_supported()) {
path_trace_device_->set_error(
"OpenImageDenoiser is not supported on this CPU: missing SSE 4.1 support");
return nullptr;
}
return Denoiser::ensure_denoiser_device(progress);
#endif
}
CCL_NAMESPACE_END

View File

@@ -38,6 +38,7 @@ class OIDNDenoiser : public Denoiser {
protected:
virtual uint get_device_type_mask() const override;
virtual Device *ensure_denoiser_device(Progress *progress) override;
/* We only perform one denoising at a time, since OpenImageDenoise itself is multithreaded.
* Use this mutex whenever images are passed to the OIDN and needs to be denoised. */

View File

@@ -67,14 +67,7 @@ PathTrace::PathTrace(Device *device,
PathTrace::~PathTrace()
{
/* Destroy any GPU resource which was used for graphics interop.
* Need to have access to the PathTraceDisplay as it is the only source of drawing context which
* is used for interop. */
if (display_) {
for (auto &&path_trace_work : path_trace_works_) {
path_trace_work->destroy_gpu_resources(display_.get());
}
}
destroy_gpu_resources();
}
void PathTrace::load_kernels()
@@ -572,6 +565,11 @@ void PathTrace::set_output_driver(unique_ptr<OutputDriver> driver)
void PathTrace::set_display_driver(unique_ptr<DisplayDriver> driver)
{
/* The display driver is the source of the drawing context which might be used by
* path trace works. Make sure there is no graphics interop using resources from
* the old display, as it might no longer be available after this call. */
destroy_gpu_resources();
if (driver) {
display_ = make_unique<PathTraceDisplay>(move(driver));
}
@@ -1088,6 +1086,18 @@ bool PathTrace::has_denoised_result() const
return render_state_.has_denoised_result;
}
void PathTrace::destroy_gpu_resources()
{
/* Destroy any GPU resource which was used for graphics interop.
* Need to have access to the PathTraceDisplay as it is the only source of drawing context which
* is used for interop. */
if (display_) {
for (auto &&path_trace_work : path_trace_works_) {
path_trace_work->destroy_gpu_resources(display_.get());
}
}
}
/* --------------------------------------------------------------------
* Report generation.
*/

View File

@@ -239,6 +239,9 @@ class PathTrace {
void progress_set_status(const string &status, const string &substatus = "");
/* Destroy GPU resources (such as graphics interop) used by work. */
void destroy_gpu_resources();
/* Pointer to a device which is configured to be used for path tracing. If multiple devices
* are configured this is a `MultiDevice`. */
Device *device_ = nullptr;

View File

@@ -173,15 +173,16 @@ ccl_device_intersect bool scene_intersect(KernelGlobals kg,
uint p3 = 0;
uint p4 = visibility;
uint p5 = PRIMITIVE_NONE;
uint p6 = ((uint64_t)ray) & 0xFFFFFFFF;
uint p7 = (((uint64_t)ray) >> 32) & 0xFFFFFFFF;
uint ray_mask = visibility & 0xFF;
uint ray_flags = OPTIX_RAY_FLAG_NONE;
uint ray_flags = OPTIX_RAY_FLAG_ENFORCE_ANYHIT;
if (0 == ray_mask && (visibility & ~0xFF) != 0) {
ray_mask = 0xFF;
ray_flags = OPTIX_RAY_FLAG_ENFORCE_ANYHIT;
}
else if (visibility & PATH_RAY_SHADOW_OPAQUE) {
ray_flags = OPTIX_RAY_FLAG_TERMINATE_ON_FIRST_HIT;
ray_flags |= OPTIX_RAY_FLAG_TERMINATE_ON_FIRST_HIT;
}
optixTrace(scene_intersect_valid(ray) ? kernel_data.bvh.scene : 0,
@@ -200,7 +201,9 @@ ccl_device_intersect bool scene_intersect(KernelGlobals kg,
p2,
p3,
p4,
p5);
p5,
p6,
p7);
isect->t = __uint_as_float(p0);
isect->u = __uint_as_float(p1);
@@ -242,6 +245,7 @@ ccl_device_intersect bool scene_intersect(KernelGlobals kg,
}
MetalRTIntersectionPayload payload;
payload.self = ray->self;
payload.u = 0.0f;
payload.v = 0.0f;
payload.visibility = visibility;
@@ -309,6 +313,7 @@ ccl_device_intersect bool scene_intersect(KernelGlobals kg,
CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_REGULAR);
IntersectContext rtc_ctx(&ctx);
RTCRayHit ray_hit;
ctx.ray = ray;
kernel_embree_setup_rayhit(*ray, ray_hit, visibility);
rtcIntersect1(kernel_data.bvh.scene, &rtc_ctx.context, &ray_hit);
if (ray_hit.hit.geomID != RTC_INVALID_GEOMETRY_ID &&
@@ -356,6 +361,9 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals kg,
uint p2 = pointer_pack_to_uint_0(local_isect);
uint p3 = pointer_pack_to_uint_1(local_isect);
uint p4 = local_object;
uint p6 = ((uint64_t)ray) & 0xFFFFFFFF;
uint p7 = (((uint64_t)ray) >> 32) & 0xFFFFFFFF;
/* Is set to zero on miss or if ray is aborted, so can be used as return value. */
uint p5 = max_hits;
@@ -379,7 +387,9 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals kg,
p2,
p3,
p4,
p5);
p5,
p6,
p7);
return p5;
# elif defined(__METALRT__)
@@ -417,6 +427,7 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals kg,
}
MetalRTIntersectionLocalPayload payload;
payload.self = ray->self;
payload.local_object = local_object;
payload.max_hits = max_hits;
payload.local_isect.num_hits = 0;
@@ -460,6 +471,7 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals kg,
kg, has_bvh ? CCLIntersectContext::RAY_SSS : CCLIntersectContext::RAY_LOCAL);
ctx.lcg_state = lcg_state;
ctx.max_hits = max_hits;
ctx.ray = ray;
ctx.local_isect = local_isect;
if (local_isect) {
local_isect->num_hits = 0;
@@ -532,6 +544,8 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals kg,
uint p3 = max_hits;
uint p4 = visibility;
uint p5 = false;
uint p6 = ((uint64_t)ray) & 0xFFFFFFFF;
uint p7 = (((uint64_t)ray) >> 32) & 0xFFFFFFFF;
uint ray_mask = visibility & 0xFF;
if (0 == ray_mask && (visibility & ~0xFF) != 0) {
@@ -555,7 +569,9 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals kg,
p2,
p3,
p4,
p5);
p5,
p6,
p7);
*num_recorded_hits = uint16_unpack_from_uint_0(p2);
*throughput = __uint_as_float(p1);
@@ -588,6 +604,7 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals kg,
}
MetalRTIntersectionShadowPayload payload;
payload.self = ray->self;
payload.visibility = visibility;
payload.max_hits = max_hits;
payload.num_hits = 0;
@@ -634,6 +651,7 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals kg,
Intersection *isect_array = (Intersection *)state->shadow_isect;
ctx.isect_s = isect_array;
ctx.max_hits = max_hits;
ctx.ray = ray;
IntersectContext rtc_ctx(&ctx);
RTCRay rtc_ray;
kernel_embree_setup_ray(*ray, rtc_ray, visibility);
@@ -685,6 +703,8 @@ ccl_device_intersect bool scene_intersect_volume(KernelGlobals kg,
uint p3 = 0;
uint p4 = visibility;
uint p5 = PRIMITIVE_NONE;
uint p6 = ((uint64_t)ray) & 0xFFFFFFFF;
uint p7 = (((uint64_t)ray) >> 32) & 0xFFFFFFFF;
uint ray_mask = visibility & 0xFF;
if (0 == ray_mask && (visibility & ~0xFF) != 0) {
@@ -708,7 +728,9 @@ ccl_device_intersect bool scene_intersect_volume(KernelGlobals kg,
p2,
p3,
p4,
p5);
p5,
p6,
p7);
isect->t = __uint_as_float(p0);
isect->u = __uint_as_float(p1);
@@ -744,6 +766,7 @@ ccl_device_intersect bool scene_intersect_volume(KernelGlobals kg,
}
MetalRTIntersectionPayload payload;
payload.self = ray->self;
payload.visibility = visibility;
typename metalrt_intersector_type::result_type intersection;
@@ -820,6 +843,7 @@ ccl_device_intersect uint scene_intersect_volume_all(KernelGlobals kg,
ctx.isect_s = isect;
ctx.max_hits = max_hits;
ctx.num_hits = 0;
ctx.ray = ray;
IntersectContext rtc_ctx(&ctx);
RTCRay rtc_ray;
kernel_embree_setup_ray(*ray, rtc_ray, visibility);

View File

@@ -22,6 +22,8 @@
#include "kernel/device/cpu/compat.h"
#include "kernel/device/cpu/globals.h"
#include "kernel/bvh/util.h"
#include "util/vector.h"
CCL_NAMESPACE_BEGIN
@@ -38,6 +40,9 @@ struct CCLIntersectContext {
KernelGlobals kg;
RayType type;
/* For avoiding self intersections */
const Ray *ray;
/* for shadow rays */
Intersection *isect_s;
uint max_hits;
@@ -56,6 +61,7 @@ struct CCLIntersectContext {
{
kg = kg_;
type = type_;
ray = NULL;
max_hits = 1;
num_hits = 0;
num_recorded_hits = 0;
@@ -102,7 +108,34 @@ ccl_device_inline void kernel_embree_setup_rayhit(const Ray &ray,
{
kernel_embree_setup_ray(ray, rayhit.ray, visibility);
rayhit.hit.geomID = RTC_INVALID_GEOMETRY_ID;
rayhit.hit.primID = RTC_INVALID_GEOMETRY_ID;
rayhit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID;
}
ccl_device_inline bool kernel_embree_is_self_intersection(const KernelGlobals kg,
const RTCHit *hit,
const Ray *ray)
{
bool status = false;
if (hit->instID[0] != RTC_INVALID_GEOMETRY_ID) {
const int oID = hit->instID[0] / 2;
if ((ray->self.object == oID) || (ray->self.light_object == oID)) {
RTCScene inst_scene = (RTCScene)rtcGetGeometryUserData(
rtcGetGeometry(kernel_data.bvh.scene, hit->instID[0]));
const int pID = hit->primID +
(intptr_t)rtcGetGeometryUserData(rtcGetGeometry(inst_scene, hit->geomID));
status = intersection_skip_self_shadow(ray->self, oID, pID);
}
}
else {
const int oID = hit->geomID / 2;
if ((ray->self.object == oID) || (ray->self.light_object == oID)) {
const int pID = hit->primID + (intptr_t)rtcGetGeometryUserData(
rtcGetGeometry(kernel_data.bvh.scene, hit->geomID));
status = intersection_skip_self_shadow(ray->self, oID, pID);
}
}
return status;
}
ccl_device_inline void kernel_embree_convert_hit(KernelGlobals kg,

View File

@@ -157,7 +157,11 @@ ccl_device_inline
}
}
/* Skip self intersection. */
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
if (intersection_skip_self_local(ray->self, prim)) {
continue;
}
if (triangle_intersect_local(kg,
local_isect,
@@ -188,7 +192,11 @@ ccl_device_inline
}
}
/* Skip self intersection. */
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
if (intersection_skip_self_local(ray->self, prim)) {
continue;
}
if (motion_triangle_intersect_local(kg,
local_isect,

View File

@@ -15,6 +15,7 @@
*/
struct MetalRTIntersectionPayload {
RaySelfPrimitives self;
uint visibility;
float u, v;
int prim;
@@ -25,6 +26,7 @@ struct MetalRTIntersectionPayload {
};
struct MetalRTIntersectionLocalPayload {
RaySelfPrimitives self;
uint local_object;
uint lcg_state;
short max_hits;
@@ -34,6 +36,7 @@ struct MetalRTIntersectionLocalPayload {
};
struct MetalRTIntersectionShadowPayload {
RaySelfPrimitives self;
uint visibility;
#if defined(__METALRT_MOTION__)
float time;

View File

@@ -160,6 +160,9 @@ ccl_device_inline
kernel_tex_fetch(__prim_object, prim_addr) :
object;
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
if (intersection_skip_self_shadow(ray->self, prim_object, prim)) {
continue;
}
switch (type & PRIMITIVE_ALL) {
case PRIMITIVE_TRIANGLE: {

View File

@@ -133,35 +133,29 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
--stack_ptr;
/* primitive intersection */
switch (type & PRIMITIVE_ALL) {
case PRIMITIVE_TRIANGLE: {
for (; prim_addr < prim_addr2; prim_addr++) {
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
for (; prim_addr < prim_addr2; prim_addr++) {
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
const int prim_object = (object == OBJECT_NONE) ?
kernel_tex_fetch(__prim_object, prim_addr) :
object;
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
const int prim_object = (object == OBJECT_NONE) ?
kernel_tex_fetch(__prim_object, prim_addr) :
object;
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
if (intersection_skip_self_shadow(ray->self, prim_object, prim)) {
continue;
}
switch (type & PRIMITIVE_ALL) {
case PRIMITIVE_TRIANGLE: {
if (triangle_intersect(
kg, isect, P, dir, isect->t, visibility, prim_object, prim, prim_addr)) {
/* shadow ray early termination */
if (visibility & PATH_RAY_SHADOW_OPAQUE)
return true;
}
break;
}
break;
}
#if BVH_FEATURE(BVH_MOTION)
case PRIMITIVE_MOTION_TRIANGLE: {
for (; prim_addr < prim_addr2; prim_addr++) {
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
const int prim_object = (object == OBJECT_NONE) ?
kernel_tex_fetch(__prim_object, prim_addr) :
object;
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
case PRIMITIVE_MOTION_TRIANGLE: {
if (motion_triangle_intersect(kg,
isect,
P,
@@ -176,28 +170,21 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
if (visibility & PATH_RAY_SHADOW_OPAQUE)
return true;
}
break;
}
break;
}
#endif /* BVH_FEATURE(BVH_MOTION) */
#if BVH_FEATURE(BVH_HAIR)
case PRIMITIVE_CURVE_THICK:
case PRIMITIVE_MOTION_CURVE_THICK:
case PRIMITIVE_CURVE_RIBBON:
case PRIMITIVE_MOTION_CURVE_RIBBON: {
for (; prim_addr < prim_addr2; prim_addr++) {
case PRIMITIVE_CURVE_THICK:
case PRIMITIVE_MOTION_CURVE_THICK:
case PRIMITIVE_CURVE_RIBBON:
case PRIMITIVE_MOTION_CURVE_RIBBON: {
if ((type & PRIMITIVE_MOTION) && kernel_data.bvh.use_bvh_steps) {
const float2 prim_time = kernel_tex_fetch(__prim_time, prim_addr);
if (ray->time < prim_time.x || ray->time > prim_time.y) {
continue;
break;
}
}
const int prim_object = (object == OBJECT_NONE) ?
kernel_tex_fetch(__prim_object, prim_addr) :
object;
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
const int curve_type = kernel_tex_fetch(__prim_type, prim_addr);
const bool hit = curve_intersect(
kg, isect, P, dir, isect->t, prim_object, prim, ray->time, curve_type);
@@ -206,26 +193,19 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
if (visibility & PATH_RAY_SHADOW_OPAQUE)
return true;
}
break;
}
break;
}
#endif /* BVH_FEATURE(BVH_HAIR) */
#if BVH_FEATURE(BVH_POINTCLOUD)
case PRIMITIVE_POINT:
case PRIMITIVE_MOTION_POINT: {
for (; prim_addr < prim_addr2; prim_addr++) {
case PRIMITIVE_POINT:
case PRIMITIVE_MOTION_POINT: {
if ((type & PRIMITIVE_MOTION) && kernel_data.bvh.use_bvh_steps) {
const float2 prim_time = kernel_tex_fetch(__prim_time, prim_addr);
if (ray->time < prim_time.x || ray->time > prim_time.y) {
continue;
break;
}
}
const int prim_object = (object == OBJECT_NONE) ?
kernel_tex_fetch(__prim_object, prim_addr) :
object;
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
const int point_type = kernel_tex_fetch(__prim_type, prim_addr);
const bool hit = point_intersect(
kg, isect, P, dir, isect->t, prim_object, prim, ray->time, point_type);
@@ -234,10 +214,10 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
if (visibility & PATH_RAY_SHADOW_OPAQUE)
return true;
}
break;
}
break;
}
#endif /* BVH_FEATURE(BVH_POINTCLOUD) */
}
}
}
else {

View File

@@ -21,54 +21,22 @@ CCL_NAMESPACE_BEGIN
/* Ray offset to avoid self intersection.
*
* This function should be used to compute a modified ray start position for
* rays leaving from a surface. */
* rays leaving from a surface. This is from "A Fast and Robust Method for Avoiding
* Self-Intersection" see https://research.nvidia.com/publication/2019-03_A-Fast-and
*/
ccl_device_inline float3 ray_offset(float3 P, float3 Ng)
{
#ifdef __INTERSECTION_REFINE__
const float epsilon_f = 1e-5f;
/* ideally this should match epsilon_f, but instancing and motion blur
* precision makes it problematic */
const float epsilon_test = 1.0f;
const int epsilon_i = 32;
const float int_scale = 256.0f;
int3 of_i = make_int3((int)(int_scale * Ng.x), (int)(int_scale * Ng.y), (int)(int_scale * Ng.z));
float3 res;
/* x component */
if (fabsf(P.x) < epsilon_test) {
res.x = P.x + Ng.x * epsilon_f;
}
else {
uint ix = __float_as_uint(P.x);
ix += ((ix ^ __float_as_uint(Ng.x)) >> 31) ? -epsilon_i : epsilon_i;
res.x = __uint_as_float(ix);
}
/* y component */
if (fabsf(P.y) < epsilon_test) {
res.y = P.y + Ng.y * epsilon_f;
}
else {
uint iy = __float_as_uint(P.y);
iy += ((iy ^ __float_as_uint(Ng.y)) >> 31) ? -epsilon_i : epsilon_i;
res.y = __uint_as_float(iy);
}
/* z component */
if (fabsf(P.z) < epsilon_test) {
res.z = P.z + Ng.z * epsilon_f;
}
else {
uint iz = __float_as_uint(P.z);
iz += ((iz ^ __float_as_uint(Ng.z)) >> 31) ? -epsilon_i : epsilon_i;
res.z = __uint_as_float(iz);
}
return res;
#else
const float epsilon_f = 1e-4f;
return P + epsilon_f * Ng;
#endif
float3 p_i = make_float3(__int_as_float(__float_as_int(P.x) + ((P.x < 0) ? -of_i.x : of_i.x)),
__int_as_float(__float_as_int(P.y) + ((P.y < 0) ? -of_i.y : of_i.y)),
__int_as_float(__float_as_int(P.z) + ((P.z < 0) ? -of_i.z : of_i.z)));
const float origin = 1.0f / 32.0f;
const float float_scale = 1.0f / 65536.0f;
return make_float3(fabsf(P.x) < origin ? P.x + float_scale * Ng.x : p_i.x,
fabsf(P.y) < origin ? P.y + float_scale * Ng.y : p_i.y,
fabsf(P.z) < origin ? P.z + float_scale * Ng.z : p_i.z);
}
#if defined(__KERNEL_CPU__)
@@ -227,4 +195,25 @@ ccl_device_inline float intersection_curve_shadow_transparency(KernelGlobals kg,
return (1.0f - u) * f0 + u * f1;
}
ccl_device_inline bool intersection_skip_self(ccl_private const RaySelfPrimitives &self,
const int object,
const int prim)
{
return (self.prim == prim) && (self.object == object);
}
ccl_device_inline bool intersection_skip_self_shadow(ccl_private const RaySelfPrimitives &self,
const int object,
const int prim)
{
return ((self.prim == prim) && (self.object == object)) ||
((self.light_prim == prim) && (self.light_object == object));
}
ccl_device_inline bool intersection_skip_self_local(ccl_private const RaySelfPrimitives &self,
const int prim)
{
return (self.prim == prim);
}
CCL_NAMESPACE_END

View File

@@ -144,6 +144,9 @@ ccl_device_inline
kernel_tex_fetch(__prim_object, prim_addr) :
object;
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
if (intersection_skip_self(ray->self, prim_object, prim)) {
continue;
}
int object_flag = kernel_tex_fetch(__object_flag, prim_object);
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
@@ -164,6 +167,9 @@ ccl_device_inline
kernel_tex_fetch(__prim_object, prim_addr) :
object;
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
if (intersection_skip_self(ray->self, prim_object, prim)) {
continue;
}
int object_flag = kernel_tex_fetch(__object_flag, prim_object);
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
continue;

View File

@@ -147,6 +147,9 @@ ccl_device_inline
kernel_tex_fetch(__prim_object, prim_addr) :
object;
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
if (intersection_skip_self(ray->self, prim_object, prim)) {
continue;
}
int object_flag = kernel_tex_fetch(__object_flag, prim_object);
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
continue;
@@ -188,6 +191,9 @@ ccl_device_inline
kernel_tex_fetch(__prim_object, prim_addr) :
object;
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
if (intersection_skip_self(ray->self, prim_object, prim)) {
continue;
}
int object_flag = kernel_tex_fetch(__object_flag, prim_object);
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
continue;

View File

@@ -295,8 +295,11 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
int kernel_index);
ccl_gpu_kernel_lambda_pass.kernel_index = kernel_index;
gpu_parallel_active_index_array<GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE>(
num_states, indices, num_indices, ccl_gpu_kernel_lambda_pass);
gpu_parallel_active_index_array(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE,
num_states,
indices,
num_indices,
ccl_gpu_kernel_lambda_pass);
}
ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
@@ -310,8 +313,11 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
int kernel_index);
ccl_gpu_kernel_lambda_pass.kernel_index = kernel_index;
gpu_parallel_active_index_array<GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE>(
num_states, indices, num_indices, ccl_gpu_kernel_lambda_pass);
gpu_parallel_active_index_array(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE,
num_states,
indices,
num_indices,
ccl_gpu_kernel_lambda_pass);
}
ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
@@ -322,8 +328,11 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
{
ccl_gpu_kernel_lambda(INTEGRATOR_STATE(state, path, queued_kernel) != 0);
gpu_parallel_active_index_array<GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE>(
num_states, indices, num_indices, ccl_gpu_kernel_lambda_pass);
gpu_parallel_active_index_array(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE,
num_states,
indices,
num_indices,
ccl_gpu_kernel_lambda_pass);
}
ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
@@ -335,8 +344,11 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
{
ccl_gpu_kernel_lambda(INTEGRATOR_STATE(state, path, queued_kernel) == 0);
gpu_parallel_active_index_array<GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE>(
num_states, indices + indices_offset, num_indices, ccl_gpu_kernel_lambda_pass);
gpu_parallel_active_index_array(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE,
num_states,
indices + indices_offset,
num_indices,
ccl_gpu_kernel_lambda_pass);
}
ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
@@ -348,8 +360,11 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
{
ccl_gpu_kernel_lambda(INTEGRATOR_STATE(state, shadow_path, queued_kernel) == 0);
gpu_parallel_active_index_array<GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE>(
num_states, indices + indices_offset, num_indices, ccl_gpu_kernel_lambda_pass);
gpu_parallel_active_index_array(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE,
num_states,
indices + indices_offset,
num_indices,
ccl_gpu_kernel_lambda_pass);
}
ccl_gpu_kernel_threads(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE)
@@ -391,8 +406,11 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
int num_active_paths);
ccl_gpu_kernel_lambda_pass.num_active_paths = num_active_paths;
gpu_parallel_active_index_array<GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE>(
num_states, indices, num_indices, ccl_gpu_kernel_lambda_pass);
gpu_parallel_active_index_array(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE,
num_states,
indices,
num_indices,
ccl_gpu_kernel_lambda_pass);
}
ccl_gpu_kernel_threads(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE)
@@ -424,8 +442,11 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
int num_active_paths);
ccl_gpu_kernel_lambda_pass.num_active_paths = num_active_paths;
gpu_parallel_active_index_array<GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE>(
num_states, indices, num_indices, ccl_gpu_kernel_lambda_pass);
gpu_parallel_active_index_array(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE,
num_states,
indices,
num_indices,
ccl_gpu_kernel_lambda_pass);
}
ccl_gpu_kernel_threads(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE)

View File

@@ -31,44 +31,27 @@ CCL_NAMESPACE_BEGIN
# define GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE 512
#endif
#ifdef __KERNEL_METAL__
struct ActiveIndexContext {
ActiveIndexContext(int _thread_index,
int _global_index,
int _threadgroup_size,
int _simdgroup_size,
int _simd_lane_index,
int _simd_group_index,
int _num_simd_groups,
threadgroup int *_simdgroup_offset)
: thread_index(_thread_index),
global_index(_global_index),
blocksize(_threadgroup_size),
ccl_gpu_warp_size(_simdgroup_size),
thread_warp(_simd_lane_index),
warp_index(_simd_group_index),
num_warps(_num_simd_groups),
warp_offset(_simdgroup_offset)
{
}
const int thread_index, global_index, blocksize, ccl_gpu_warp_size, thread_warp, warp_index,
num_warps;
threadgroup int *warp_offset;
template<uint blocksizeDummy, typename IsActiveOp>
void active_index_array(const uint num_states,
ccl_global int *indices,
ccl_global int *num_indices,
IsActiveOp is_active_op)
{
const uint state_index = global_index;
#else
#ifndef __KERNEL_METAL__
template<uint blocksize, typename IsActiveOp>
__device__ void gpu_parallel_active_index_array(const uint num_states,
ccl_global int *indices,
ccl_global int *num_indices,
IsActiveOp is_active_op)
__device__
#endif
void
gpu_parallel_active_index_array_impl(const uint num_states,
ccl_global int *indices,
ccl_global int *num_indices,
#ifdef __KERNEL_METAL__
const uint is_active,
const uint blocksize,
const int thread_index,
const uint state_index,
const int ccl_gpu_warp_size,
const int thread_warp,
const int warp_index,
const int num_warps,
threadgroup int *warp_offset)
{
#else
IsActiveOp is_active_op)
{
extern ccl_gpu_shared int warp_offset[];
@@ -79,61 +62,71 @@ __device__ void gpu_parallel_active_index_array(const uint num_states,
const uint num_warps = blocksize / ccl_gpu_warp_size;
const uint state_index = ccl_gpu_block_idx_x * blocksize + thread_index;
/* Test if state corresponding to this thread is active. */
const uint is_active = (state_index < num_states) ? is_active_op(state_index) : 0;
#endif
/* Test if state corresponding to this thread is active. */
const uint is_active = (state_index < num_states) ? is_active_op(state_index) : 0;
/* For each thread within a warp compute how many other active states precede it. */
const uint thread_offset = popcount(ccl_gpu_ballot(is_active) &
ccl_gpu_thread_mask(thread_warp));
/* For each thread within a warp compute how many other active states precede it. */
const uint thread_offset = popcount(ccl_gpu_ballot(is_active) &
ccl_gpu_thread_mask(thread_warp));
/* Last thread in warp stores number of active states for each warp. */
if (thread_warp == ccl_gpu_warp_size - 1) {
warp_offset[warp_index] = thread_offset + is_active;
}
ccl_gpu_syncthreads();
/* Last thread in block converts per-warp sizes to offsets, increments global size of
* index array and gets offset to write to. */
if (thread_index == blocksize - 1) {
/* TODO: parallelize this. */
int offset = 0;
for (int i = 0; i < num_warps; i++) {
int num_active = warp_offset[i];
warp_offset[i] = offset;
offset += num_active;
}
const uint block_num_active = warp_offset[warp_index] + thread_offset + is_active;
warp_offset[num_warps] = atomic_fetch_and_add_uint32(num_indices, block_num_active);
}
ccl_gpu_syncthreads();
/* Write to index array. */
if (is_active) {
const uint block_offset = warp_offset[num_warps];
indices[block_offset + warp_offset[warp_index] + thread_offset] = state_index;
}
/* Last thread in warp stores number of active states for each warp. */
if (thread_warp == ccl_gpu_warp_size - 1) {
warp_offset[warp_index] = thread_offset + is_active;
}
#ifdef __KERNEL_METAL__
}; /* end class ActiveIndexContext */
ccl_gpu_syncthreads();
/* Last thread in block converts per-warp sizes to offsets, increments global size of
* index array and gets offset to write to. */
if (thread_index == blocksize - 1) {
/* TODO: parallelize this. */
int offset = 0;
for (int i = 0; i < num_warps; i++) {
int num_active = warp_offset[i];
warp_offset[i] = offset;
offset += num_active;
}
const uint block_num_active = warp_offset[warp_index] + thread_offset + is_active;
warp_offset[num_warps] = atomic_fetch_and_add_uint32(num_indices, block_num_active);
}
ccl_gpu_syncthreads();
/* Write to index array. */
if (is_active) {
const uint block_offset = warp_offset[num_warps];
indices[block_offset + warp_offset[warp_index] + thread_offset] = state_index;
}
}
#ifdef __KERNEL_METAL__
# define gpu_parallel_active_index_array(dummy, num_states, indices, num_indices, is_active_op) \
const uint is_active = (ccl_gpu_global_id_x() < num_states) ? \
is_active_op(ccl_gpu_global_id_x()) : \
0; \
gpu_parallel_active_index_array_impl(num_states, \
indices, \
num_indices, \
is_active, \
metal_local_size, \
metal_local_id, \
metal_global_id, \
simdgroup_size, \
simd_lane_index, \
simd_group_index, \
num_simd_groups, \
simdgroup_offset)
#else
# define gpu_parallel_active_index_array( \
blocksize, num_states, indices, num_indices, is_active_op) \
gpu_parallel_active_index_array_impl<blocksize>(num_states, indices, num_indices, is_active_op)
/* inject the required thread params into a struct, and redirect to its templated member function
*/
# define gpu_parallel_active_index_array \
ActiveIndexContext(metal_local_id, \
metal_global_id, \
metal_local_size, \
simdgroup_size, \
simd_lane_index, \
simd_group_index, \
num_simd_groups, \
simdgroup_offset) \
.active_index_array
#endif
CCL_NAMESPACE_END

View File

@@ -40,6 +40,27 @@ struct TriangleIntersectionResult
enum { METALRT_HIT_TRIANGLE, METALRT_HIT_BOUNDING_BOX };
ccl_device_inline bool intersection_skip_self(ray_data const RaySelfPrimitives& self,
const int object,
const int prim)
{
return (self.prim == prim) && (self.object == object);
}
ccl_device_inline bool intersection_skip_self_shadow(ray_data const RaySelfPrimitives& self,
const int object,
const int prim)
{
return ((self.prim == prim) && (self.object == object)) ||
((self.light_prim == prim) && (self.light_object == object));
}
ccl_device_inline bool intersection_skip_self_local(ray_data const RaySelfPrimitives& self,
const int prim)
{
return (self.prim == prim);
}
template<typename TReturn, uint intersection_type>
TReturn metalrt_local_hit(constant KernelParamsMetal &launch_params_metal,
ray_data MetalKernelContext::MetalRTIntersectionLocalPayload &payload,
@@ -53,8 +74,8 @@ TReturn metalrt_local_hit(constant KernelParamsMetal &launch_params_metal,
#ifdef __BVH_LOCAL__
uint prim = primitive_id + kernel_tex_fetch(__object_prim_offset, object);
if (object != payload.local_object) {
/* Only intersect with matching object */
if ((object != payload.local_object) || intersection_skip_self_local(payload.self, prim)) {
/* Only intersect with matching object and skip self-intersecton. */
result.accept = false;
result.continue_search = true;
return result;
@@ -166,6 +187,11 @@ bool metalrt_shadow_all_hit(constant KernelParamsMetal &launch_params_metal,
}
# endif
if (intersection_skip_self_shadow(payload.self, object, prim)) {
/* continue search */
return true;
}
float u = 0.0f, v = 0.0f;
int type = 0;
if (intersection_type == METALRT_HIT_TRIANGLE) {
@@ -322,21 +348,35 @@ inline TReturnType metalrt_visibility_test(constant KernelParamsMetal &launch_pa
}
# endif
# ifdef __VISIBILITY_FLAG__
uint visibility = payload.visibility;
# ifdef __VISIBILITY_FLAG__
if ((kernel_tex_fetch(__objects, object).visibility & visibility) == 0) {
result.accept = false;
result.continue_search = true;
return result;
}
# endif
/* Shadow ray early termination. */
if (visibility & PATH_RAY_SHADOW_OPAQUE) {
result.accept = true;
result.continue_search = false;
return result;
if (intersection_skip_self_shadow(payload.self, object, prim)) {
result.accept = false;
result.continue_search = true;
return result;
}
else {
result.accept = true;
result.continue_search = false;
return result;
}
}
else {
if (intersection_skip_self(payload.self, object, prim)) {
result.accept = false;
result.continue_search = true;
return result;
}
}
# endif
result.accept = true;
result.continue_search = true;

View File

@@ -45,6 +45,11 @@ template<typename T> ccl_device_forceinline T *get_payload_ptr_2()
return pointer_unpack_from_uint<T>(optixGetPayload_2(), optixGetPayload_3());
}
template<typename T> ccl_device_forceinline T *get_payload_ptr_6()
{
return (T *)(((uint64_t)optixGetPayload_7() << 32) | optixGetPayload_6());
}
ccl_device_forceinline int get_object_id()
{
#ifdef __OBJECT_MOTION__
@@ -111,6 +116,12 @@ extern "C" __global__ void __anyhit__kernel_optix_local_hit()
return optixIgnoreIntersection();
}
const int prim = optixGetPrimitiveIndex();
ccl_private Ray *const ray = get_payload_ptr_6<Ray>();
if (intersection_skip_self_local(ray->self, prim)) {
return optixIgnoreIntersection();
}
const uint max_hits = optixGetPayload_5();
if (max_hits == 0) {
/* Special case for when no hit information is requested, just report that something was hit */
@@ -149,8 +160,6 @@ extern "C" __global__ void __anyhit__kernel_optix_local_hit()
local_isect->num_hits = 1;
}
const int prim = optixGetPrimitiveIndex();
Intersection *isect = &local_isect->hits[hit];
isect->t = optixGetRayTmax();
isect->prim = prim;
@@ -185,6 +194,11 @@ extern "C" __global__ void __anyhit__kernel_optix_shadow_all_hit()
}
# endif
ccl_private Ray *const ray = get_payload_ptr_6<Ray>();
if (intersection_skip_self_shadow(ray->self, object, prim)) {
return optixIgnoreIntersection();
}
float u = 0.0f, v = 0.0f;
int type = 0;
if (optixIsTriangleHit()) {
@@ -314,6 +328,12 @@ extern "C" __global__ void __anyhit__kernel_optix_volume_test()
if ((kernel_tex_fetch(__object_flag, object) & SD_OBJECT_HAS_VOLUME) == 0) {
return optixIgnoreIntersection();
}
const int prim = optixGetPrimitiveIndex();
ccl_private Ray *const ray = get_payload_ptr_6<Ray>();
if (intersection_skip_self(ray->self, object, prim)) {
return optixIgnoreIntersection();
}
}
extern "C" __global__ void __anyhit__kernel_optix_visibility_test()
@@ -330,18 +350,31 @@ extern "C" __global__ void __anyhit__kernel_optix_visibility_test()
# endif
#endif
#ifdef __VISIBILITY_FLAG__
const uint object = get_object_id();
const uint visibility = optixGetPayload_4();
#ifdef __VISIBILITY_FLAG__
if ((kernel_tex_fetch(__objects, object).visibility & visibility) == 0) {
return optixIgnoreIntersection();
}
/* Shadow ray early termination. */
if (visibility & PATH_RAY_SHADOW_OPAQUE) {
return optixTerminateRay();
}
#endif
const int prim = optixGetPrimitiveIndex();
ccl_private Ray *const ray = get_payload_ptr_6<Ray>();
if (visibility & PATH_RAY_SHADOW_OPAQUE) {
if (intersection_skip_self_shadow(ray->self, object, prim)) {
return optixIgnoreIntersection();
}
else {
/* Shadow ray early termination. */
return optixTerminateRay();
}
}
else {
if (intersection_skip_self(ray->self, object, prim)) {
return optixIgnoreIntersection();
}
}
}
extern "C" __global__ void __closesthit__kernel_optix_hit()

View File

@@ -226,6 +226,18 @@ ccl_device float curve_thickness(KernelGlobals kg, ccl_private const ShaderData
return r * 2.0f;
}
/* Curve random */
ccl_device float curve_random(KernelGlobals kg, ccl_private const ShaderData *sd)
{
if (sd->type & PRIMITIVE_CURVE) {
const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_CURVE_RANDOM);
return (desc.offset != ATTR_STD_NOT_FOUND) ? curve_attribute_float(kg, sd, desc, NULL, NULL) :
0.0f;
}
return 0.0f;
}
/* Curve location for motion pass, linear interpolation between keys and
* ignoring radius because we do the same for the motion keys */

View File

@@ -29,46 +29,19 @@
CCL_NAMESPACE_BEGIN
/* Refine triangle intersection to more precise hit point. For rays that travel
* far the precision is often not so good, this reintersects the primitive from
* a closer distance.
/**
* Use the barycentric coordinates to get the intersection location
*/
ccl_device_inline float3 motion_triangle_refine(KernelGlobals kg,
ccl_private ShaderData *sd,
float3 P,
float3 D,
float t,
const int isect_object,
const int isect_prim,
float3 verts[3])
ccl_device_inline float3 motion_triangle_point_from_uv(KernelGlobals kg,
ccl_private ShaderData *sd,
const int isect_object,
const int isect_prim,
const float u,
const float v,
float3 verts[3])
{
#ifdef __INTERSECTION_REFINE__
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
if (UNLIKELY(t == 0.0f)) {
return P;
}
const Transform tfm = object_get_inverse_transform(kg, sd);
P = transform_point(&tfm, P);
D = transform_direction(&tfm, D * t);
D = normalize_len(D, &t);
}
P = P + D * t;
/* Compute refined intersection distance. */
const float3 e1 = verts[0] - verts[2];
const float3 e2 = verts[1] - verts[2];
const float3 s1 = cross(D, e2);
const float invdivisor = 1.0f / dot(s1, e1);
const float3 d = P - verts[2];
const float3 s2 = cross(d, e1);
float rt = dot(e2, s2) * invdivisor;
/* Compute refined position. */
P = P + D * rt;
float w = 1.0f - u - v;
float3 P = u * verts[0] + v * verts[1] + w * verts[2];
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
const Transform tfm = object_get_transform(kg, sd);
@@ -76,71 +49,8 @@ ccl_device_inline float3 motion_triangle_refine(KernelGlobals kg,
}
return P;
#else
return P + D * t;
#endif
}
/* Same as above, except that t is assumed to be in object space
* for instancing.
*/
#ifdef __BVH_LOCAL__
# if defined(__KERNEL_CUDA__) && (defined(i386) || defined(_M_IX86))
ccl_device_noinline
# else
ccl_device_inline
# endif
float3
motion_triangle_refine_local(KernelGlobals kg,
ccl_private ShaderData *sd,
float3 P,
float3 D,
float t,
const int isect_object,
const int isect_prim,
float3 verts[3])
{
# if defined(__KERNEL_GPU_RAYTRACING__)
/* t is always in world space with OptiX and MetalRT. */
return motion_triangle_refine(kg, sd, P, D, t, isect_object, isect_prim, verts);
# else
# ifdef __INTERSECTION_REFINE__
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
const Transform tfm = object_get_inverse_transform(kg, sd);
P = transform_point(&tfm, P);
D = transform_direction(&tfm, D);
D = normalize(D);
}
P = P + D * t;
/* compute refined intersection distance */
const float3 e1 = verts[0] - verts[2];
const float3 e2 = verts[1] - verts[2];
const float3 s1 = cross(D, e2);
const float invdivisor = 1.0f / dot(s1, e1);
const float3 d = P - verts[2];
const float3 s2 = cross(d, e1);
float rt = dot(e2, s2) * invdivisor;
P = P + D * rt;
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
const Transform tfm = object_get_transform(kg, sd);
P = transform_point(&tfm, P);
}
return P;
# else /* __INTERSECTION_REFINE__ */
return P + D * t;
# endif /* __INTERSECTION_REFINE__ */
# endif
}
#endif /* __BVH_LOCAL__ */
/* Ray intersection. We simply compute the vertex positions at the given ray
* time and do a ray intersection with the resulting triangle.
*/

View File

@@ -68,15 +68,7 @@ ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals kg,
verts[1] = (1.0f - t) * verts[1] + t * next_verts[1];
verts[2] = (1.0f - t) * verts[2] + t * next_verts[2];
/* Compute refined position. */
#ifdef __BVH_LOCAL__
if (is_local) {
sd->P = motion_triangle_refine_local(kg, sd, P, D, ray_t, isect_object, isect_prim, verts);
}
else
#endif /* __BVH_LOCAL__*/
{
sd->P = motion_triangle_refine(kg, sd, P, D, ray_t, isect_object, isect_prim, verts);
}
sd->P = motion_triangle_point_from_uv(kg, sd, isect_object, isect_prim, sd->u, sd->v, verts);
/* Compute face normal. */
float3 Ng;
if (sd->object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {

View File

@@ -109,17 +109,59 @@ ccl_device float4 point_attribute_float4(KernelGlobals kg,
}
}
/* Point position */
ccl_device float3 point_position(KernelGlobals kg, ccl_private const ShaderData *sd)
{
if (sd->type & PRIMITIVE_POINT) {
/* World space center. */
float3 P = (sd->type & PRIMITIVE_MOTION) ?
float4_to_float3(motion_point(kg, sd->object, sd->prim, sd->time)) :
float4_to_float3(kernel_tex_fetch(__points, sd->prim));
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
object_position_transform(kg, sd, &P);
}
return P;
}
return zero_float3();
}
/* Point radius */
ccl_device float point_radius(KernelGlobals kg, ccl_private const ShaderData *sd)
{
if (sd->type & PRIMITIVE_POINT) {
return kernel_tex_fetch(__points, sd->prim).w;
/* World space radius. */
const float r = kernel_tex_fetch(__points, sd->prim).w;
if (sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED) {
return r;
}
else {
float3 dir = make_float3(r, r, r);
object_dir_transform(kg, sd, &dir);
return average(dir);
}
}
return 0.0f;
}
/* Point random */
ccl_device float point_random(KernelGlobals kg, ccl_private const ShaderData *sd)
{
if (sd->type & PRIMITIVE_POINT) {
const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_POINT_RANDOM);
return (desc.offset != ATTR_STD_NOT_FOUND) ? point_attribute_float(kg, sd, desc, NULL, NULL) :
0.0f;
}
return 0.0f;
}
/* Point location for motion pass, linear interpolation between keys and
* ignoring radius because we do the same for the motion keys */

View File

@@ -89,7 +89,7 @@ ccl_device_inline void shader_setup_from_ray(KernelGlobals kg,
sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
/* vectors */
sd->P = triangle_refine(kg, sd, ray->P, ray->D, isect->t, isect->object, isect->prim);
sd->P = triangle_point_from_uv(kg, sd, isect->object, isect->prim, isect->u, isect->v);
sd->Ng = Ng;
sd->N = Ng;
@@ -190,40 +190,46 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals kg,
#ifdef __OBJECT_MOTION__
shader_setup_object_transforms(kg, sd, time);
#endif
}
else if (lamp != LAMP_NONE) {
sd->lamp = lamp;
}
/* transform into world space */
if (object_space) {
object_position_transform_auto(kg, sd, &sd->P);
object_normal_transform_auto(kg, sd, &sd->Ng);
sd->N = sd->Ng;
object_dir_transform_auto(kg, sd, &sd->I);
}
/* transform into world space */
if (object_space) {
object_position_transform_auto(kg, sd, &sd->P);
object_normal_transform_auto(kg, sd, &sd->Ng);
sd->N = sd->Ng;
object_dir_transform_auto(kg, sd, &sd->I);
}
if (sd->type == PRIMITIVE_TRIANGLE) {
/* smooth normal */
if (sd->shader & SHADER_SMOOTH_NORMAL) {
sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
if (sd->type == PRIMITIVE_TRIANGLE) {
/* smooth normal */
if (sd->shader & SHADER_SMOOTH_NORMAL) {
sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
object_normal_transform_auto(kg, sd, &sd->N);
}
}
/* dPdu/dPdv */
#ifdef __DPDU__
triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
object_normal_transform_auto(kg, sd, &sd->N);
object_dir_transform_auto(kg, sd, &sd->dPdu);
object_dir_transform_auto(kg, sd, &sd->dPdv);
}
}
/* dPdu/dPdv */
#ifdef __DPDU__
triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
object_dir_transform_auto(kg, sd, &sd->dPdu);
object_dir_transform_auto(kg, sd, &sd->dPdv);
}
#endif
}
else {
#ifdef __DPDU__
sd->dPdu = zero_float3();
sd->dPdv = zero_float3();
#endif
}
}
else {
if (lamp != LAMP_NONE) {
sd->lamp = lamp;
}
#ifdef __DPDU__
sd->dPdu = zero_float3();
sd->dPdv = zero_float3();

View File

@@ -142,58 +142,23 @@ ccl_device_inline bool triangle_intersect_local(KernelGlobals kg,
}
#endif /* __BVH_LOCAL__ */
/* Refine triangle intersection to more precise hit point. For rays that travel
* far the precision is often not so good, this reintersects the primitive from
* a closer distance. */
/* Reintersections uses the paper:
*
* Tomas Moeller
* Fast, minimum storage ray/triangle intersection
* http://www.cs.virginia.edu/~gfx/Courses/2003/ImageSynthesis/papers/Acceleration/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf
/**
* Use the barycentric coordinates to get the intersection location
*/
ccl_device_inline float3 triangle_refine(KernelGlobals kg,
ccl_private ShaderData *sd,
float3 P,
float3 D,
float t,
const int isect_object,
const int isect_prim)
ccl_device_inline float3 triangle_point_from_uv(KernelGlobals kg,
ccl_private ShaderData *sd,
const int isect_object,
const int isect_prim,
const float u,
const float v)
{
#ifdef __INTERSECTION_REFINE__
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
if (UNLIKELY(t == 0.0f)) {
return P;
}
const Transform tfm = object_get_inverse_transform(kg, sd);
P = transform_point(&tfm, P);
D = transform_direction(&tfm, D * t);
D = normalize_len(D, &t);
}
P = P + D * t;
const uint tri_vindex = kernel_tex_fetch(__tri_vindex, isect_prim).w;
const packed_float3 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
tri_c = kernel_tex_fetch(__tri_verts, tri_vindex + 2);
float3 edge1 = make_float3(tri_a.x - tri_c.x, tri_a.y - tri_c.y, tri_a.z - tri_c.z);
float3 edge2 = make_float3(tri_b.x - tri_c.x, tri_b.y - tri_c.y, tri_b.z - tri_c.z);
float3 tvec = make_float3(P.x - tri_c.x, P.y - tri_c.y, P.z - tri_c.z);
float3 qvec = cross(tvec, edge1);
float3 pvec = cross(D, edge2);
float det = dot(edge1, pvec);
if (det != 0.0f) {
/* If determinant is zero it means ray lies in the plane of
* the triangle. It is possible in theory due to watertight
* nature of triangle intersection. For such cases we simply
* don't refine intersection hoping it'll go all fine.
*/
float rt = dot(edge2, qvec) / det;
P = P + D * rt;
}
float w = 1.0f - u - v;
float3 P = u * tri_a + v * tri_b + w * tri_c;
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
const Transform tfm = object_get_transform(kg, sd);
@@ -201,65 +166,6 @@ ccl_device_inline float3 triangle_refine(KernelGlobals kg,
}
return P;
#else
return P + D * t;
#endif
}
/* Same as above, except that t is assumed to be in object space for
* instancing.
*/
ccl_device_inline float3 triangle_refine_local(KernelGlobals kg,
ccl_private ShaderData *sd,
float3 P,
float3 D,
float t,
const int isect_object,
const int isect_prim)
{
#if defined(__KERNEL_GPU_RAYTRACING__)
/* t is always in world space with OptiX and MetalRT. */
return triangle_refine(kg, sd, P, D, t, isect_object, isect_prim);
#else
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
const Transform tfm = object_get_inverse_transform(kg, sd);
P = transform_point(&tfm, P);
D = transform_direction(&tfm, D);
D = normalize(D);
}
P = P + D * t;
# ifdef __INTERSECTION_REFINE__
const uint tri_vindex = kernel_tex_fetch(__tri_vindex, isect_prim).w;
const packed_float3 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
tri_c = kernel_tex_fetch(__tri_verts, tri_vindex + 2);
float3 edge1 = make_float3(tri_a.x - tri_c.x, tri_a.y - tri_c.y, tri_a.z - tri_c.z);
float3 edge2 = make_float3(tri_b.x - tri_c.x, tri_b.y - tri_c.y, tri_b.z - tri_c.z);
float3 tvec = make_float3(P.x - tri_c.x, P.y - tri_c.y, P.z - tri_c.z);
float3 qvec = cross(tvec, edge1);
float3 pvec = cross(D, edge2);
float det = dot(edge1, pvec);
if (det != 0.0f) {
/* If determinant is zero it means ray lies in the plane of
* the triangle. It is possible in theory due to watertight
* nature of triangle intersection. For such cases we simply
* don't refine intersection hoping it'll go all fine.
*/
float rt = dot(edge2, qvec) / det;
P = P + D * rt;
}
# endif /* __INTERSECTION_REFINE__ */
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
const Transform tfm = object_get_transform(kg, sd);
P = transform_point(&tfm, P);
}
return P;
#endif
}
CCL_NAMESPACE_END

View File

@@ -328,6 +328,12 @@ ccl_device void integrator_intersect_closest(KernelGlobals kg,
/* Scene Intersection. */
Intersection isect ccl_optional_struct_init;
isect.object = OBJECT_NONE;
isect.prim = PRIM_NONE;
ray.self.object = last_isect_object;
ray.self.prim = last_isect_prim;
ray.self.light_object = OBJECT_NONE;
ray.self.light_prim = PRIM_NONE;
bool hit = scene_intersect(kg, &ray, visibility, &isect);
/* TODO: remove this and do it in the various intersection functions instead. */

View File

@@ -156,7 +156,10 @@ ccl_device void integrator_intersect_shadow(KernelGlobals kg, IntegratorShadowSt
/* Read ray from integrator state into local memory. */
Ray ray ccl_optional_struct_init;
integrator_state_read_shadow_ray(kg, state, &ray);
ray.self.object = INTEGRATOR_STATE_ARRAY(state, shadow_isect, 0, object);
ray.self.prim = INTEGRATOR_STATE_ARRAY(state, shadow_isect, 0, prim);
ray.self.light_object = INTEGRATOR_STATE_ARRAY(state, shadow_isect, 1, object);
ray.self.light_prim = INTEGRATOR_STATE_ARRAY(state, shadow_isect, 1, prim);
/* Compute visibility. */
const uint visibility = integrate_intersect_shadow_visibility(kg, state);

View File

@@ -38,7 +38,10 @@ ccl_device void integrator_volume_stack_update_for_subsurface(KernelGlobals kg,
Ray volume_ray ccl_optional_struct_init;
volume_ray.P = from_P;
volume_ray.D = normalize_len(to_P - from_P, &volume_ray.t);
volume_ray.self.object = INTEGRATOR_STATE(state, isect, object);
volume_ray.self.prim = INTEGRATOR_STATE(state, isect, prim);
volume_ray.self.light_object = OBJECT_NONE;
volume_ray.self.light_prim = PRIM_NONE;
/* Store to avoid global fetches on every intersection step. */
const uint volume_stack_size = kernel_data.volume_stack_size;
@@ -68,7 +71,7 @@ ccl_device void integrator_volume_stack_update_for_subsurface(KernelGlobals kg,
volume_stack_enter_exit(kg, state, stack_sd);
/* Move ray forward. */
volume_ray.P = ray_offset(stack_sd->P, -stack_sd->Ng);
volume_ray.P = stack_sd->P;
if (volume_ray.t != FLT_MAX) {
volume_ray.D = normalize_len(to_P - volume_ray.P, &volume_ray.t);
}
@@ -91,6 +94,10 @@ ccl_device void integrator_volume_stack_init(KernelGlobals kg, IntegratorState s
* fewest hits. */
volume_ray.D = make_float3(0.0f, 0.0f, 1.0f);
volume_ray.t = FLT_MAX;
volume_ray.self.object = OBJECT_NONE;
volume_ray.self.prim = PRIM_NONE;
volume_ray.self.light_object = OBJECT_NONE;
volume_ray.self.light_prim = PRIM_NONE;
int stack_index = 0, enclosed_index = 0;
@@ -203,7 +210,7 @@ ccl_device void integrator_volume_stack_init(KernelGlobals kg, IntegratorState s
}
/* Move ray forward. */
volume_ray.P = ray_offset(stack_sd->P, -stack_sd->Ng);
volume_ray.P = stack_sd->P;
++step;
}
#endif

Some files were not shown because too many files have changed in this diff Show More