1
1

Compare commits

...

549 Commits

Author SHA1 Message Date
8d16e5ecab Correct numpy hash 2021-10-11 11:15:33 +02:00
f6ed41ea14 Fix typo 2021-10-11 11:15:04 +02:00
7c9733e7e4 Remove numpy patch, as it no longer applies; the option it tries to disable seems to have been removed from numpy. 2021-10-11 11:14:56 +02:00
530134a002 Bump requests, certifi, urllib, idna, cython, and numpy packages. Replace chardet with charset-normalizer (dependency change of requests) 2021-10-11 11:01:36 +02:00
973ee18ecb Bump Python to 3.9.7 and add zstandard package
These changes will be committed in two separate consecutive commits.
It's easier to review & build as a whole, hence the single diff.

----------------------

*Bump Python 3.9.2 → 3.9.7*

If we're going to add a Python package to Blender, this usually means
rebuilding all of Python, so we might just as well bump it to the
latest 3.9 release.

----------------------

*Bundle the `zstandard` Python package*

This package allows Python scripts to handle compressed blend files.
This is for example needed by #blender_asset_tracer to send files to a
Flamenco render farm.

This change includes a new `WITH_PYTHON_INSTALL_ZSTANDARD` build-time
option, to control whether to actually install the package. For this
the already-existing approach for Requests was copied. I'm not too
happy with the way Python packages and their dependents (Audaspace &
Mantaflow) are handled, but that's for a different cleanup commit.

Differential Revision: https://developer.blender.org/D12777
2021-10-11 10:17:12 +02:00
cefcc1e922 Deps: bump Python 3.9.2 → 3.9.7 2021-10-11 10:17:12 +02:00
7afde7cd22 Cleanup: asset catalogs, alphabetically order forward declarations
No functional changes.
2021-10-08 15:28:00 +02:00
092424dae3 install_deps: Fix OIIO depending on (system...) openVDB. 2021-10-08 14:52:06 +02:00
2aca08fc1c UI: Support tooltips for superimposed icons
In a couple of places in the UI, we show superimposed icons on buttons
to execute an operation (called "Extra Icons" internally). Hovering them
would show the tooltip of the underlying button, which is misleading and
confusing.
There are cases where it's not obvious what an icon does, so a tooltip
would be quite useful here. It's likely we are going to use superimposed
icons in more places in the future, e.g. see D11890.

The extra icon basically acts as an override for the button in the
tooltip code.

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

Reviewed by: Campbell Barton
2021-10-08 14:18:10 +02:00
86643a4e73 Py doc: document msgbus subscriptions clearing on blendfile load
Document that `bpy.msgbus.subscribe_rna()`-registered messagebus
subscriptions will be cleared whenever a new blend file is loaded.

Passing `options={'PERSISTENT'}` has no influence on this behaviour.
2021-10-08 14:06:30 +02:00
04ad42d83b UI/Assets: Disable undo for tree item buttons
Disables undo for:
* The tree row collapsing - which doesn't make sense to undo, isn't
  supported by the undo system, and just triggers the confirmation
  prompt when closing the file.
* Renaming items - While this may make sense in some cases, users of the
  tree-view API can explicitly do an undo push. For asset catalogs it's
  not supported.
2021-10-08 12:35:19 +02:00
5da58f48ae Cleanup: asset catalogs, move functions to their siblings
Moved function definitions around so that all members of a class are
next to each other. Previously some functions of one class were sitting
between functions of another class.

No functional changes.
2021-10-08 12:34:58 +02:00
482806c816 VSE: Implement the bounding box (xform) tool in the seq preview window
Make the "xform" tool/gizmo available for strip transformations in the
sequencer preview window.

Because of the amount of hacks needed to make the gizmo work nicely with
multiple strips at the same time, it was decided to only show the
translate gizmo when multiple strips are selected.

This is because the transforms with multiple strips would appear buggy
because of our lack of shearing support in the transform system.
There is also currently no way to properly sync the gizmo drawing with
the transform when using multiple strips.

Reviewed By: Richard Antalik, Campbell Barton

Differential Revision: http://developer.blender.org/D12729
2021-10-08 12:14:45 +02:00
a3e2cc0bb7 Asset Catalogs: Fix unit test on Windows
Force native slashes before comparing paths; on Windows mixing
separators caused a unit test to fail.

No functional changes.
2021-10-08 11:32:22 +02:00
bd65d3ce97 Cleanup: Explicit specifier for single argument constructor 2021-10-08 10:01:20 +02:00
3284b5bbde Cleanup: Else after return in Cycles 2021-10-08 10:01:20 +02:00
6c11733dfb Fix T91190: Remove gaps operator not working
Caused by mistake in f49d438ced - `SEQ_query_all_strips()` is not
meant to be recursive.
2021-10-08 09:30:07 +02:00
741fb0d6c9 Sequencer: hide gizmos & cursor during scrubbing & playback
This was distracting prevented easily viewing an animation.
2021-10-08 18:06:50 +11:00
415098abc3 Fix crash switching scenes with sequencer gizmos displayed 2021-10-08 17:24:45 +11:00
ebe216f532 Sequencer: add option to toggle gizmos
Use shortcut matching the 3D view & popover in the header
2021-10-08 17:07:56 +11:00
de07bf2b13 Cleanup: spelling 2021-10-08 13:23:19 +11:00
8f4697e570 Sequencer: only show the 2D cursor with overlays enabled
Also hide when displaying scopes.
2021-10-08 13:20:19 +11:00
2f9fab716d Cleanup: remove deprecated SEQ_DRAW_SEQUENCE value
While drawing cleared this value (as part of temporary fix from 2009),
this was still being checked until recently.

Remove this value in versioning code.

Also clear unused text space flag.
2021-10-08 13:15:19 +11:00
f9f88f50cb Fix sequencer preview/strip checks
- Drawing annotations used a deprecated value to detect
  if drawing was supported.
- ED_space_sequencer_check_show_strip was checking the preview
  image type (which doesn't impact strip display).

Signed-off-by: Campbell Barton <ideasman42@gmail.com>
2021-10-08 13:15:19 +11:00
29e496e768 Cleanup: remove redundant cursor copy, print 2021-10-08 11:57:42 +11:00
23791db145 Fix Cycles random walk SSS differences between CPU and GPU
The Embree logic did not match the GPU.
2021-10-07 21:35:24 +02:00
4ee97f129a Cleanup: remove unnecessary data from LocalIntersection 2021-10-07 21:35:24 +02:00
9708b1f317 Cleanup: Rename enum values
This makes the diff for adding a new version of the attribute transfer
node slightly smaller.
2021-10-07 14:00:11 -05:00
e9daca77d6 Fix: Missing field markers for curve fillet node inputs 2021-10-07 13:44:06 -05:00
0cd3d46246 Nodes: Move texture nodes to C++
Move texture nodes to C++ and use new socket declaration

Brick, Checker, Image, Magic and Wave

Differential Revision: https://developer.blender.org/D12778
2021-10-07 19:19:20 +01:00
ba4e5399fc Fix screenshot editor showing status text in the editor
This caused problems calling screenshot from menu-search
which included the status text in the screenshot.

Now the status text is shown in the global status bar
for any operators called from a screen context.
2021-10-08 04:01:59 +11:00
d04d27b406 Sequencer: 2D cursor for the preview & transform
- Use 2D cursor in the preview space using shortcuts
  matching the UV editor and 3D view.
- Add Cursor tool, cursor transform.
- Support for cursor and bound-box pivot.
- Add pivot pie menu.
2021-10-08 03:27:55 +11:00
919e513fa8 User Interface: Remove the green background when inside a node group
The current background color and parent nodetrees is too distracting and noisy.
It drastically affect the readability of the nested node-trees.

Other techniques (better bread crumbs) can be used instead to indicate
to users that they are inside a node group.

---

The background drawing was introduced in 4638e5f99a as part of the
Python Nodes branch merge. This made its debut in Blender 2.67
(30/May/2021).

At the time the color used for the background was a light gray. Over the
years the color changed to the current dark green, aggravating the
problem further.

Before that, the (expanded) nodegroup already had the partially
transparent background, mingling with the other nodes. The Python Nodes
branch brought this concept with its changes, and would always draw up
to two levels up in the background (the parent nodetree, and its parent
nodetree).

To read the original inspiration for all the changes introduced then:
https://code.blender.org/2012/01/improving-node-group-interface-editing/

Differential Revision: https://developer.blender.org/D12780
2021-10-07 17:35:40 +02:00
cc6a3509a0 Asset Catalogs: change rules for saving catalog definition files
Change the rules for determining where to save a new catalog definition
file (CDF).

Old situation (T91681): if a `blender_assets.cats.txt` file already
exists in the same directory as the blend file, write to that. If not,
see if the blend file is contained in an asset library, and write to its
top-level CDF.

The new situation swaps the rules: first see if the blend file is
contained in an asset library, and if so write to its top-level CDF. If
not, write a CDF next to the blend file.

As before, any pre-existing CDF is not just bluntly overwritten, but
merged with the in-memory catalogs.
2021-10-07 17:04:47 +02:00
1de922f88c Cleanup: asset catalog tests, move teardown function
Move `AssetCatalogTest::TearDown` close to the corresponding `SetUp`
function, so that it's easier to find.

No functional changes.
2021-10-07 17:04:47 +02:00
1b79b4dd30 Fix sequencer preview poll function
sequencer_view_preview_poll returned true even when in the
"Sequence" view.

Now check the preview is visible, also check the region
is expected type so preview actions aren't possible for mixed
sequence/preview display.
2021-10-08 01:58:32 +11:00
c7b237e7d1 Asset Browser: Move Asset Library selector to navigation bar
The menu to select the active Asset Library is now in the left bar (so called
"Source List", although I'd prefer "Navigation-Bar").

This has some benefits:
* All Asset Library navigation is in the left sidebar now, giving nice grouping
  and a top-to-bottom & left-to-right flow of the layout. The header is focused
  on view set-up now.
* Catalogs are stored inside the asset library. Makes sense to have them right
  under that.
* Less content in the header allows for less wide Asset Browsers without
  extensive scrolling.
* This location gives more space to add options or operators for Asset
  Libraries.

Main downside I see is that the side-bar needs to be opened to change
libraries, which takes quite some space. In practice there shouldn't be need to
do this often though.
2021-10-07 16:29:02 +02:00
9f9e2dd25d Cleanup: clang-tidy 2021-10-08 01:25:23 +11:00
0d4c53ecfe Fix wrong tile size calculated in Cycles
Was causing extra overscan pixels, and was confusing multiple workers
check after fix T91994.
2021-10-07 16:21:28 +02:00
0f58cc1594 Cleanup: make format 2021-10-07 16:11:40 +02:00
719c319055 Fix Cycles long start on scene without volumes
The state template iteration had difficult time dealing with 0-sized
arrays, causing iteration for until integer overflows.
2021-10-07 15:54:56 +02:00
c0a5b13b5e Asset Browser: Rework layout & behavior of catalog tree-view
This reworks how tree rows are constructed in the layout and how they
behave in return.

* To open or collapse a row, the triangle/chevron icon has to be clicked
  now. The previous behavior of allowing to do it on the entire row, but
  only if the item was active already, was just too unusual and felt
  weird.
* Reduce margin between chevron icon and the row label.
* Indent child items without chevron some more, otherwise they feel like
  a row on the same level as their parent, just without chevron.
* Fix renaming button taking entire row width. Respect indentation now.
* Fix double-clicking to rename toggling collapsed state on each click.

Some hacks/special-handling was needed so tree-rows always highlight
while the mouse is hovering them, even if the mouse is actually hovering
another button inside the row.
2021-10-07 15:30:59 +02:00
13a28d9e6f Fix proxy to override code being called on undos. 2021-10-07 15:20:54 +02:00
123255be6b Fix T91994: Cycles crash when rendering on multiple devices
The overscan change from D12599 lacked proper handling of window
when slicing buffer for multiple devices.
2021-10-07 15:07:25 +02:00
7fc11744e6 Revert commit, turns out this isn't a bug? 2021-10-07 04:11:49 -07:00
87a36cba1a UI: Fix alignment of buttons in Grease Pencil tool settings
Small fix reviewed on blender.chat by the Grease Pencil team.
2021-10-07 11:44:29 +02:00
00bd631c7c Fix mask expand not properly supporting
both inverse and keep mask modes being on
at the same time.
2021-10-07 02:27:09 -07:00
eadbacdbb0 Fix T91670: Strip text position is incorrect
Use `sseq->timeline_overlay.flag` instead of `sseq->flag`.
Caused oversight in 7cb65e4581.
2021-10-07 06:35:16 +02:00
70cc80ea1c Cleanup: Move VSE disk cache code into own file
No functional changes.
2021-10-07 03:04:34 +02:00
439c9b0b84 Cleanup: VSE iterator semantics
Use `BLI_gset_ensure_p_ex()` instead of `BLI_gset_insert()` after
checking `BLI_gset_lookup()`.
2021-10-07 00:38:33 +02:00
877ba6b251 Fix T91972: Meta changes length when adding strip
`SequencesMeta.new_movie()` API function caused meta strip to change
length. Similar issue has been fixed in transform code by checking
if `MetaStack` exists. `MetaStack` is not used when changing data in
python.

Provide `seqbase` to `SEQ_time_update_sequence()` so the function can
check if change happens inside of meta strip.

This patch also merges `seq_time_update_sequence_bounds()` into
`SEQ_time_update_sequence()`. This is because same issue applies for
both functions and it is confusing to have more time update
functions.re if this will lead anywhere.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D12763
2021-10-07 00:10:37 +02:00
306e9bff46 Fix VSE pan property text printing
Move text into separate label.
2021-10-07 00:04:26 +02:00
04857cc8ef Cycles: fully decouple triangle and curve primitive storage from BVH2
Previously the storage here was optimized to avoid indirections in BVH2
traversal. This helps improve performance a bit, but makes performance
and memory usage of Embree and OptiX BVHs a bit worse also. It also adds
code complexity in other parts of the code.

Now decouple triangle and curve primitive storage from BVH2.
* Reduced peak memory usage on all devices
* Bit better performance for OptiX and Embree
* Bit worse performance for CUDA
* Simplified code:
** Intersection.prim/object now matches ShaderData.prim/object
** No more offset manipulation for mesh displacement before a BVH is built
** Remove primitive packing code and flags for Embree and OptiX
** Curve segments are now stored in a KernelCurve struct
* Also happens to fix a bug in baking with incorrect prim/object

Fixes T91968, T91770, T91902

Differential Revision: https://developer.blender.org/D12766
2021-10-06 17:52:04 +02:00
0fd0b0643a Build: search for hipcc in HIP_ROOT_DIR/bin 2021-10-06 17:44:25 +02:00
8a6f224e26 Fix logic error when trying to find hovered item
Was just comparing this item's and the parent item's names. But if an item has
no parents, only its own name has to match for the check to return true. Make
sure that the number of parents also matches.
2021-10-06 16:55:51 +02:00
bbfa6a92cf Fix T91987: Linking overrides does not apply overrides rules.
Just a matter of calling `BKE_lib_override_library_main_update` in
`library_link_end`.
2021-10-06 16:53:20 +02:00
b7dc0346aa BMain: Add utils to check if a Main is empty or not.
Mostly intended for debug code (asserts).
2021-10-06 16:53:20 +02:00
0194e54fd3 Fix compilation error with MSVC
MSVC does not support variable size array definition.
Use maximum possible stack, similar to the GPU case.

Not expected to have user-measurable difference.
2021-10-06 16:51:07 +02:00
75fbf6f17e Asset Browser: Show catalog add & delete icons on mouse hover (only)
Now the icons to add or delete catalogs are only shown when mouse hovering a
catalog item in the tree. This is convenient for quick creation of catalogs,
and doesn't require activating a catalog to edit it first.

Determining if a tree item is hovered isn't trivial actually. The UI tree-view
code has to find the matching tree-row button in the previous layout to do so,
since the new layout isn't calculated yet.
2021-10-06 16:36:20 +02:00
536109b4ec Fix possibly wrong matching of tree-view item buttons
The UI code to ensure consistent button state over redraws was just comparing
the name of the item, ignoring the parent names. So with multiple items of the
same name, there might have been glitches (didn't see any myself though).

There's a leftover to-do though, we don't check yet if the matched buttons are
actually from the same tree. Added TODO comment.
2021-10-06 16:36:20 +02:00
2012d541ae Asset Browser: Always show icon to add catalog next to "All" item
Feedback was that it's unclear sometimes how to add a new item and that some
people expect a button to add a new item next to the "All" item.
2021-10-06 16:36:20 +02:00
Jacob Lewallen
12c66854bd Pass correct array size to BKE_object_material_remap_calc
This was patch D12460 from jlewallen and fixes T91339 and T90818.
2021-10-06 10:26:15 -04:00
c6275da852 Fix T91922: Cycles artifacts with high volume nested level
Make volume stack allocated conditionally, potentially based on the
actual nested level of objects in the scene.

Currently the nested level is estimated by number of volume objects.
This is a non-expensive check which is probably enough in practice
to get almost perfect memory usage and performance.

The conditional allocation is a bit tricky.

For the CPU we declare and define maximum possible volume stack,
because there are only that many integrator states on the CPU.

On the GPU we declare outer SoA to have all volume stack elements,
but only allocate actually needed ones. The actually used volume
stack size is passed as a pre-processor, which seems to be easiest
and fastest for the GPU state copy.

There seems to be no speed regression in the demo files on RTX6000.

Note that scenes with high nested level of volume will now be slower
but correct.

Differential Revision: https://developer.blender.org/D12759
2021-10-06 15:46:32 +02:00
e41dddd29a Gizmo: remove wmGizmoGroup.use_fallback_keymap
This ended up being a copy of:
`toolsettings->workspace_tool_type == SCE_WORKSPACE_TOOL_FALLBACK`
requiring boiler plate assignment in gizmos refresh callbacks.

Remove this struct member and check `toolsettings->workspace_tool_type`
directly, since so far there has been no advantage in gizmo-groups
being able to control this themselves.
2021-10-07 00:08:23 +11:00
cda20a7af8 Keymap: ignore the fallback keymap when "Active Tool" is set
Resolve regression in c9d9bfa84a,
which added support for tools to be tagged as using a fallback too.

In these cases the "Active Tool" setting was ignored and the fallback
tool would be used (the spin tool would box select for example).
2021-10-07 00:06:45 +11:00
539575b585 Assets: Support Renaming Catalogs in the UI
Catalogs can now be renamed by double clicking them in the Asset
Browser. This is mostly done through the tree-view API, the asset
specific code is very little.

There is some polish left to be done here, e.g. the double click
currently also collapses/uncollapses and activates the clicked item. And
the rename button takes the full width of the row. But addressing these
is better done as part of some other behavioral changes that are planned
anyway.
2021-10-06 14:25:26 +02:00
335f40ebfa Tests: include device type in benchmark graph labels 2021-10-06 14:21:26 +02:00
03f8c1abd0 Build: add ccache support for CUDA kernels on Linux 2021-10-06 14:21:26 +02:00
18c6314e26 Cleanup: don't detect duplicate intersections in Embree
It's unclear why this code was added in the first place, but it seems
unnecessary, it can be restored if we find this breaks something.

The Embree docs mention that the same primitive may be hit multiple times, but
my understanding is that about e.g. curves where both the frontside and backside
may be hit. However those hits would be at different distances.

The context for this change is that we want to add an optimization where we
can immediately update throughput for transparent shadows instead of recording
intersections, and avoid duplicate would require extra work. However there is
an Embree example that does something similar without worrying about duplicate
hits either.
2021-10-06 14:21:11 +02:00
3c4537cd38 Cleanup: Improve readability & comments in UI tree-view header 2021-10-06 13:08:45 +02:00
ac9ec52e9e UI: Draw tree-views (e.g. asset catalogs) in a box
Makes things look more appealing visually. Plus it's a way to visually
group the tree rows together, which can be important if there are more
widgets surrounding the tree.
2021-10-06 13:08:45 +02:00
4ab8212e1a Fix errors in 68dc970219
Swapped preview/timeline keymap and incorrect center measurement.
2021-10-06 21:42:09 +11:00
9ed19db539 Fix handling of overrides during append.
Liboverride references need a special handling during append, since
those pointers should never be made local, nor reampped to newly
localized data. And liboverride references should never be directly made
local either, to ensure their liboverride usages remain pointing to
linked data and not local one.

Issue was reported by the studio, and also probably as part of T91892.
2021-10-06 11:43:42 +02:00
b5ea3d2c09 Fix possible use-after-free when cancelling temporary rename button
If a renaming button was removed via `UI_but_active_only_ex()` and that
button was placed using the layout system, the button was still in the
layout.
So far this didn't cause issues, because all cases where the button may
be removed were not using the layout system.
2021-10-06 11:24:24 +02:00
Mikhail Matrosov
ca0450feef Fix T91064: Cycles low poly meshes having black edges when shade smoothed
Fixes:{T91064}

Caused by {rBcd118c5581f482afc8554ff88b5b6f3b552b1682}

- Applies `ensure_valid_reflection()` to the normal input on all BSDFs for CPU and GPU.
- This doesn't affect hair.
- Removes `ensure_valid_reflection()` from the output of Bump Map and Normal Map nodes for CPU/GPU as it is not needed.
- The fix doesn't touch OSL.

Reviewed By: brecht, leesonw

Maniphest Tasks: T91064

Differential Revision: https://developer.blender.org/D12403
2021-10-06 10:25:09 +02:00
85267ec1ae Correct error in 68dc970219
Included invalid keyword argument.
2021-10-06 18:12:01 +11:00
68dc970219 Sequencer: improvements to preview selection
- Support toggle/deselect/deselect_all options
  (matching 3D viewport object selection).
- Support legacy selection behavior.
- Support selecting by the center in preview views (holding Ctrl).
2021-10-06 18:01:27 +11:00
82f0e4948c UI: Boolean rename "Self" to "Self Intersection"
Better to be more explicit here, also this matches the recent Boolean Node.
2021-10-06 00:00:07 -04:00
ce66075d00 UI: add sequencer preview context menu
This is mostly a place-holder since many items
have not yet been implemented.
2021-10-06 14:54:05 +11:00
c73a550e90 UI: rename sequencer "Select" to "Tweak"
This matches the tweak tool elsewhere.

Match names since this name is shown prominently
in the fall back tool selector.
2021-10-06 14:54:05 +11:00
876b250499 Keymap: fallback tool support for the sequencer
Note that sample is no longer in the sequencer preview keymap,
it is still accessible as a tool.

This conflicted with click-drag to transform.
2021-10-06 14:54:05 +11:00
ba95cf6234 Keymap: remove selection from the common sequencer map
Needed for further changes as selection behaves differently
in the preview region.
2021-10-06 14:54:05 +11:00
8e2a21e862 Keymap: show sequencer tools in key-map editor
Re-order common sequencer key-map to be at the top level
(shared by preview and sequence view).

Without this sequencer tools would be displayed at different levels
in the hierarchy which is confusing and doesn't represent the separation
between "Sequencer" and "SequencerPreview" key-maps.
2021-10-06 14:54:05 +11:00
9161993e02 Sequencer: use pass-through for preview select
Needed for select-drag action as done in the 3D view and UV editor.
2021-10-06 14:54:05 +11:00
0e590f9078 Fix sequencer sample poll function
Sequencer poll was succeeding outside of a preview region.

This meant it couldn't be used in tool key maps which are currently
shared between preview & sequencer regions.
2021-10-06 14:54:05 +11:00
df8f507f41 Cleanup: spelling in comments 2021-10-06 14:54:05 +11:00
bf35dba7fb Nodes: Composite: Fix wrong socket type for color ramp node 2021-10-05 23:28:24 -04:00
b534806ecb VSE: Reduce memory footprint when using thumbnails
Free strip `anim` data immediately after rendering. This doesn't affect
rendering performance, because each new loop would have to seek to start
of strip. Also strips are now freed anyway, but after rendering loop
ends.

With SF edit file, thumbnail rendering used around 60GB of memory.
Now it uses few hundreds MB (depends on movie file resolution, codec,
etc.)

Freeing of strips caused UI to be unresponsive for brief period. This
issue is not removed, but is more spread out so it is less noticable.
2021-10-06 05:07:51 +02:00
0d68d7baa3 Cleanup: clang-format, correct doxy groups 2021-10-06 13:23:13 +11:00
8113b8391a Cleanup: VSE: Move thumbnail drawing to own file
No functional changes.
2021-10-06 04:21:01 +02:00
76de3ac4ce Cleanup: Remove data duplication from various lookup tables in Cycles
This effectively undoes some of the following commit:
rB4537e8558468c71a03bf53f59c60f888b3412de2

The tables in question were duplicated 5-6 times into the blender
executable due to the headers being used in multiple translation units.
This contributes ~6.3kb worth of duplicate data into the binary.

Some further details are in the below revision.

Differential Revision: https://developer.blender.org/D12724
2021-10-05 19:09:01 -07:00
11d31addf8 Cleanup: missing verb in comment 2021-10-06 02:42:18 +02:00
c148eba16f Fix crash when reading non standard Alembic velocity attribute type
Some software may export velocity as a different type than 3D vectors
(e.g. as colors or flat arrays or floats), so we need to explicitely
check for this.

A more robust attribute handling system allowing us to cope with other
software idiosyncrasies is on the way, so this fix will do for now.
2021-10-06 02:42:18 +02:00
b93e947306 Cleanup: rename BKE_font.h -> BKE_vfont.h
Match API naming prefix (BKE_vfont_*) and DNA_vfont_types.h.
2021-10-06 11:18:16 +11:00
dcac86f4f1 Cleanup: remove unused flag argument 2021-10-06 10:55:54 +11:00
fd592538d9 Cleanup: move BLI_vfontdata.h to BKE_vfontdata.h
This didn't belong on blenlib since it uses DNA data types
and included a bad-level call to BKE_curve.h.

It also meant linking in blenlib would depend on the freetype library,
noticeable for thumbnail extraction (see D6408).
2021-10-06 10:55:34 +11:00
26dac33ce1 Cleanup: simplify ED_imbuf_sample_poll
Access the space data directly from the area.

Also remove redundant NULL check.
2021-10-06 09:29:09 +11:00
6d2b486e43 Cleanup: spelling in comments 2021-10-06 09:28:00 +11:00
7b5835c793 Fix: Add missing function node declaration for RGB and Float Curve nodes 2021-10-05 22:38:41 +01:00
432d5bc692 Cleanup: Remove unused DerivedMesh functions
The long term goal is completely removing DerivedMesh, and these
functions are making some refactoring of mesh normals (T91186) more
complicated. They are not used anywhere.
2021-10-05 13:16:50 -05:00
16e7a7b5b1 Cleanup: Clang tidy 2021-10-05 13:15:31 -05:00
88c02bf826 VSE: Free animation strip data if they are not visible
Previously we would only free animation strip data when doing final
renders. If not doing a final render or simply just playing back videos
in the VSE, we would not free decoders or non VSE cache data from the
strips.

This would lead to memory usage exploding in complex VSE scenes.

Now we instead use the dumb apporach of freeing everything that is not
currently visible.
2021-10-05 18:53:58 +02:00
0a1a173e57 Cleanup: Make anim_getnew in the VSE less confusing
It was using dummy image buffers to indicate if an animation container
could be initialized or not.

Use booleans instead.
2021-10-05 18:53:58 +02:00
6eefcd7d78 GPencil: Remove unused spacetype check in Paint operator
The Paint operator only works in SPACE_VIEW3D and this is checked in the poll mtehod, so it's not logic check again.

These checkings were part of the old grease pencil but it was not removed.
2021-10-05 17:11:21 +02:00
11be9edae2 Fix missing proper 'make local' call for liboverrides from outliner.
Also includes minor improvements to
`BKE_lib_override_library_make_local` itself.

This is a complement to rB37458798fa02c.
2021-10-05 17:07:06 +02:00
c11585a82f Add missing "CUDA_ERROR_UNSUPPORTED_PTX_VERSION" to CUEW
This is required for Cycles to report a meaningful error message when it fails to load a PTX module
created with a newer CUDA toolkit version than the driver supports.

Ref T91879
2021-10-05 16:36:33 +02:00
6e268a749f Fix adaptive sampling artifacts on tile boundaries
Implement an overscan support for tiles, so that adaptive sampling can
rely on the pixels neighbourhood.

Differential Revision: https://developer.blender.org/D12599
2021-10-05 16:19:14 +02:00
758f3f7456 Fix T91940: Asset Browser catalogs continuously redraw
Issue was that the `on_activate()` callback of tree-items were
continuously called, because the active-state was queried before we
fully reconstructed the tree and its state from the previous redraw.
Such issues could happen in more places, so I've refactored the API a
bit to reflect the requirements for state queries, and include some
sanity checks.
The actual fix for the issue is to delay the state change until the tree
is fully reconstructed, by letting the tree-items pass a callback to
check if they should be active.
2021-10-05 16:10:27 +02:00
dbe3981b0a Cleanup: Better way to pass activate callbacks to Tree-View items
The `ui::BasicTreeViewItem` took a function-like object to execute on
item activation via the constructor. This was mainly intended to be used
with lambdas. However, it's confusing to just have this lambda there,
with no indication of what it's for (activation).
Instead, assign the function-like object via an explicit `on_activate()`
function.
2021-10-05 16:10:27 +02:00
9a0850c8c2 Cycles: Fix wrong GPU state calculation
Currently was only used for logging, but better to fix the size so
that it matches reality.

The issue was caused by decoupling number of shadow intersections
and using much higher number for CPU. This caused the total state
on GPU to be logged as 10s of gigabytes instead of 100s of megabytes.

Differential Revision: https://developer.blender.org/D12755
2021-10-05 16:09:31 +02:00
b1e6e63c22 Cleanup: Geometry Nodes dashed lines
No functional change, just cleaning up the shader code a bit.

Part of this is removing dead code (the discard was never called), and
part is shuffling mix/max around based on feedback by Sybren Stüvel.
2021-10-05 15:38:09 +02:00
55b8fc718a Cycles: improve detection of HIP compiler for buildbot
And fix various broken things in the HIP kernel compilation.
2021-10-05 13:47:50 +02:00
71cf9f4b3f Fix T91955: Cycles crash with denoising on non-available device
For example, crash when attempting to use OptiX denoiser on systems
without OptiX-capable device.

Perform check that scene update happened without errors.

Note that `et_error` makes progress to cancel, so the code was
simplified a bit.
2021-10-05 10:52:35 +02:00
b6ad0735a6 Fix T86379: When using "Append" not handling properly RigidBody constraints
This was simply never handled apparently.

Also fixes a regression from recent append refactor that prevented RB
objects to to properly handled too (since we instantiate loose objects
in append step now, we need to handle RigidBody ones after that
instantiation stage, otherwise nothing will happen since loose objects
won't be in any scene).
2021-10-05 10:48:10 +02:00
7df6f66ea2 Silenced compilation warning when compiling using ASAN. 2021-10-05 10:36:45 +02:00
9824df49c0 Fix memory leak when running test cases.
Issue is that test cases re-uses draw manager. The new
`DRWRegisteredDrawEngine` struct is only freed when a
valid opengl context was found. what isn't the case
when running test cases.

Also made sure that re-using draw manager would use re-inited
values.
2021-10-05 10:36:45 +02:00
7a66a9f22e Cleanup: remove unused parameter 2021-10-05 16:54:25 +09:00
1d49293b80 DRW: Move buffer & temp textures & framebuffer management to DrawManager
This is a necessary step for EEVEE's new arch. This moves more data
to the draw manager. This makes it easier to have the render or draw
engines manage their own data.

This makes more sense and cleans-up what the GPUViewport holds

Also rewrites the Texture pool manager to be in C++.

This also move the DefaultFramebuffer/TextureList and the engine related
data to a new `DRWViewData` struct. This struct manages the per view
(as in stereo view) engine data.

There is a bit of cleanup in the way the draw manager is setup.
We now use a temporary DRWData instead of creating a dummy viewport.

Development: fclem, jbakker

Differential Revision: https://developer.blender.org/D11966
2021-10-05 09:39:54 +02:00
08511b1c3d XR: Add runtime window area for XR events
This adds an offscreen View3D window area for the VR view in order to
execute XR events/operators in the proper context. The area is created
as runtime data before XR events are dispatched and set as the active
area during XR event handling.

Since the area is runtime-only, it will not be saved in files and since
the area is offscreen, it will not interfere with regular window areas.
The area is removed with the rest of the XR runtime data on exit, file
read, or when stopping the VR session.

Note: This also adds internal types (EVT_DATA_XR, EVT_XR_ACTION) and
structs (wmXrActionData) for XR events.

Reviewed By: Severin

Differential Revision: https://developer.blender.org/D12472
2021-10-05 16:05:12 +09:00
300403a38b Fix syntax error in caac532565 2021-10-05 17:41:23 +11:00
caac532565 Cleanup: add Params.select_tweak_event
Convenience, use for tool key-maps to avoid overly verbose expressions.
2021-10-05 16:35:05 +11:00
Erik Abrahamsson
1b22650fbf Geometry Nodes: Rename "String Join" node to "Join Strings"
Rename the "String Join" node to "Join Strings" to
go with the verb first naming convention.

Differential Revision: https://developer.blender.org/D12678
2021-10-04 23:54:21 -05:00
2b66b372bc Cleanup: use doxygen sections 2021-10-05 11:10:25 +11:00
2dace5f3ef Cleanup: use 3D dot product (not 4D) when comparing pose-bone axes
Also use more meaningful variable name.
2021-10-05 11:09:31 +11:00
92c449776d Cleanup: quiet shadow warning, trailign space 2021-10-05 10:59:48 +11:00
18959c502d Fix field type in curve resample node 2021-10-04 15:40:09 -05:00
c38d2513c5 Fix T91725: Waveforms are not displayed
Use `sseq->timeline_overlay.flag` for `SEQ_TIMELINE_ALL_WAVEFORMS`
instead of `sseq->flag`.
2021-10-04 22:17:05 +02:00
d1ade756a9 Fix T91920: Missing decorate buttons in sound panel
Add back decorate buttons, move mono and display waveforms to bottom as
they were before.
2021-10-04 22:10:17 +02:00
655ce5dc3e Cleanup: Use LISTBASE_FOREACH macro 2021-10-04 21:57:39 +02:00
c8d59b60b5 Make keyframe inserts/removals less verbose when called from python.
Following operators now only report messages back when they are called via their invoke-methods:

- ANIM_OT_keyframe_insert
- ANIM_OT_keyframe_insert_by_name
- ANIM_OT_keyframe_insert_menu
- ANIM_OT_keyframe_delete
- ANIM_OT_keyframe_clear_v3d
- ANIM_OT_keyframe_delete_v3d

Also removed the attribute confirm_success from the following operators:

- ANIM_OT_keyframe_insert
- ANIM_OT_keyframe_insert_by_name
- ANIM_OT_keyframe_insert_menu
- ANIM_OT_keyframe_delete
- ANIM_OT_keyframe_delete_by_name

Note: addons/scripts possibly need to be updated if they use the above operators AND set the "confirm_success" attribute

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D12697
2021-10-04 21:23:44 +02:00
3391a2ef1d Assets: Show all assets indirectly nested inside the active catalog
The asset catalog design was always that the active catalog would also
display all assets of its child catalogs (or grand-childs, etc.). This
is one of the main characteristics that differentiates catalogs from
usual directories.

Sybren prepared this on the asset catalog backend side with
56ce51d1f7. This integrates it into the Asset Browser backend and the
UI.
2021-10-04 20:24:25 +02:00
ffa20de050 Cleanup: Remove unused variable and include 2021-10-04 13:03:13 -05:00
65b5023df4 Fix: Geometry Nodes Handle Type Selection Fix
Fix the selection logic on the Handle Type Selection node to work
as intended:

(Left is Selected AND Left is ChosenType)
OR
(Right is Selected AND Right is ChosenType)
2021-10-04 12:47:35 -05:00
076d797bda Geometry Nodes: Curve Trim Node Update
This update allows the Trim Curve node to use float field inputs
for the start and end inputs. These fields are evaluated on the
spline domain.

Differential Revision: https://developer.blender.org/D12744
2021-10-04 12:01:29 -05:00
301ee97b93 Fix: Unable to select left and right in set handle type node
The "enum" RNA flag was missing.
2021-10-04 11:10:08 -05:00
f2c896a9ad GPencil: Simplify code removing extra function
The function was not doing anything and only was calling another function.
2021-10-04 17:08:16 +02:00
2b6f2072f1 UI Tree-View API: Enforce active item to be un-collapsed
Makes sure that the active item of a tree never has collapsed parent
items, which can be confusing if it happens. E.g. for the asset catalogs
UI, the active catalog decides which assets are visible. Having it
hidden while being the main factor deciding which assets are visible is
quite confusing.

I think it makes sense to have this at the UI Tree-View level, rather
than doing it manually in the asset catalog code for example. Seems like
something you'd commonly want. We can make it optional in the API if
needed.

Renamed the `set_active()` function to make clear that it is more than a
mere setter.
2021-10-04 17:03:12 +02:00
4fd7ce321d GPencil: Remove unused flag
This flag was used in older versions, but now is not used anymore.
2021-10-04 16:43:07 +02:00
0bc4056455 Nodes: Revert some socket declarations to previos API
See T91826, there is a bug in the code where both `.` and `_` are used as a seperator for `BLI_uniquename_cb`.

This resulted in some nodes becoming disconnected on file load.
Until this is resolved, the chnages are reverted to prevent data loss.
2021-10-04 10:35:11 -04:00
4a3464050c Assets: Support dragging assets on "Unassigned" catalog
Dragging assets onto the "Unassigned" catalog tree item will effectively
move the assets out of any catalog. Technically this means unsetting the
Catalog-ID stored in the asset metadata, or more precisely setting the
UUID to be all zeros.
2021-10-04 16:17:09 +02:00
b536605e78 Cleanup: Use static function for asset catalog tree-view helper 2021-10-04 15:29:39 +02:00
4882208633 Cleanup: Separate interface & implementation for asset catalog tree-view
Should make the code a bit more organized and help getting an overview
of the interfaces more quickly.
2021-10-04 15:29:39 +02:00
cc636db8f2 Fix T91823: Regression not showing idblocks when recursion is set to Blend file
Introduced by fc7beac8d6. During code review it wasn't clear why this
branch was needed, so we removed it. Now it is clear why it is needed
so we added it back and added a comment why the branch is needed.

Patch provided by @Severin.
2021-10-04 15:25:40 +02:00
f806bd8261 Fix T91861: Black environment behind shadow catcher
Always sample background pass behind shadow catcher (if the pass
exists, of course), regardless of whether shadow catcher will be
used as approximate or accurate.

Allows to combine accurate shadows into an environment map.

Differential Revision: https://developer.blender.org/D12747
2021-10-04 15:07:32 +02:00
fc4886a314 Fix T91894: Cycles baking normal maps of transformed objects not working 2021-10-04 13:58:37 +02:00
326bd76d3b Fix T89759: baking normals does not take into account mirror modifier 2021-10-04 13:58:37 +02:00
a80a2f07b7 Fix T90815: wrong Cycles OSL normal map render after recent optimization 2021-10-04 13:58:37 +02:00
76238af213 Fix Cycles render time pass being available in UI, but it was removed
This previously only work for CPU rendering, and isn't that practical to get
working in the new architecture.
2021-10-04 13:58:37 +02:00
8ca7250982 Fix T91911: error in image dithering code after recent changes
Thanks to Patrik Olsson for spotting this.
2021-10-04 13:58:37 +02:00
dc4c2815a6 Cleanup: Reverting submodules hash
This partially reverts commit e62ce9e08e.
2021-10-04 12:42:07 +02:00
Simon Lenz
e62ce9e08e Fix camera border bug in passepartout render view
{F10761402}

With active viewport render from camera view, the camera border shows up, even when passepartout and overlays are disabled.

By moving the line-drawing code to the passepartout section, it is effectively disabled when passepartout is off.

Reviewed By: sebastian_k

Differential Revision: https://developer.blender.org/D12745
2021-10-04 12:21:40 +02:00
23d9953c80 I18n tools: Fix issue when extracting messages on release builds.
This was also affecting prototype of buildbot-driven UI messages
extraction...
2021-10-04 12:17:50 +02:00
ce6a24976a Cleanup: Redundant space at the end of comment 2021-10-04 12:02:14 +02:00
f2b86471ea Fix session uuid ghash comparison return value
Because of legacy reasons (C string compare function returning 0 when
strings are equal), the ghash compare function is expected to return
false when hashes are equal.
2021-10-04 11:55:09 +02:00
37003cbbc1 Fix T91867: Error reading tiles with Persistent Data ON 2021-10-04 11:54:11 +02:00
87a3cb3bff Cleanup: Neighbour -> Neighbor. and other minor UI messages fixes.
Blender English should use 'American' variants, not 'British' variants.
2021-10-04 11:14:57 +02:00
8c55333a8e Cleanup: tag unused parameters as such. 2021-10-04 09:43:40 +02:00
fc6228bd85 Fix T91873: Crash when opening properties panel
This patch fixes a crash that was recently introduced by rB5cebcb415e76.
The reason were missing poll functions in the UI and operator.

Reviewed By: ISS

Maniphest Tasks: T91873

Differential Revision: https://developer.blender.org/D12736
2021-10-04 08:15:03 +02:00
93e92ac126 Cleanup: remove unused assignments 2021-10-04 13:15:15 +11:00
357acd1d50 Cleanup: pass arguments as const 2021-10-04 13:15:15 +11:00
e43fcc014a Cleanup: remove redundant assignment 2021-10-04 13:15:15 +11:00
3c3669894f Cleanup: use system includes 2021-10-04 13:14:58 +11:00
6e48a51af7 check_cppcheck: use quiet output
Without this, each cppcheck invocation included all defines/includes
flooding the console with unhelpful information.

Also remove nonexistent directory to exclude.
2021-10-04 13:12:37 +11:00
606271966e check_cppcheck: use '--cppcheck-build-dir'
Use a temporary directory for faster performance.
2021-10-04 13:12:36 +11:00
e0e7a5522f project_source_info: queue_processes() now waits for jobs to finish
queue_processes() - used for some of the "make check_*" utilities,
wasn't waiting for all jobs to finish before returning.

This conflicted with running cleanup operations.
2021-10-04 13:12:35 +11:00
e7274dedc4 Fix possible NULL pointer deference
The pointer was referenced before being checked.
2021-10-04 13:12:34 +11:00
cc8fa3ee90 Fix T91904: Assert when loading empty CurveProfile
Somehow, the file from T71329 has an empty curve profile. While that may
be a problem in itself, it's reasonable to avoid asserts or crashes when
loading or drawing such a CurveProfile. This commit just makes sure the
table always has a single vertex, and adds some checks in drawing code.
2021-10-03 20:28:31 -05:00
dfdc9c6219 Cleanup: Make more functions static
This simplifies the surface of the API for a CurveProfile.
2021-10-03 19:52:59 -05:00
b6195f6664 Cleanup: Replace macro with function 2021-10-03 18:54:52 -05:00
272a38e0c2 Cleanup: Make function static 2021-10-03 18:31:56 -05:00
c9af025936 Cleanup: Add doxygen sections, rearrange functions 2021-10-03 18:23:58 -05:00
1e5cfebf66 Fix key-map with fall-back tool on RMB select
Regression in bffda4185d.
2021-10-04 09:28:33 +11:00
57272d598d Cleanup: rename eRegionType -> eRegion_Type
Match eSpace_Type.
2021-10-04 09:28:33 +11:00
ee79bde54d Keymap: print more verbose output for --debug-handlers
Include the short-cut text and the operator properties to make it easier
to track down the key-map item source that matched the event.
2021-10-04 09:28:33 +11:00
c4dca65228 Asset Browser: Support dragging assets into catalogs
With this it is possible to select any number of assets in the Asset
Browser and drag them into catalogs. The assets will be moved to that
catalog then. However, this will only work in the "Current File" asset
library, since that is the only library that allows changing assets,
which is what's done here.

While dragging assets over the tree row, a tooltip is shown explaining
what's going to happen.

In preparation to this, the new UI tree-view API was already extended
with custom drop support, see 4ee2d9df42.

----

Changes here to the `wmDrag` code were needed to support dragging multiple
assets. Some of it is considered temporary because a) a proper #AssetHandle
design should replace some ugly parts of this patch and b) the multi-item
support in `wmDrag` isn't that great yet. The entire API will have to be
written anyway (see D4071).

Maniphest Tasks: T91573

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

Reviewed by: Sybren Stüvel
2021-10-03 23:58:20 +02:00
3b1a243039 Cleanup: Rename file-list function to better match what it's doing 2021-10-03 23:18:04 +02:00
2305f270c5 Geometry Nodes: Handle Type Selection Node Update
This node creates a boolean field selection of bezier spline points
that have a handle of the given type on the selected 'side' of the
contol point. This is evaluated on the point domain.

Differential Revision: https://developer.blender.org/D12559
2021-10-03 15:01:30 -05:00
adc084a3e9 Cleanup: Move curveprofile.c to C++ 2021-10-03 14:40:08 -05:00
ae86584404 Geometry Nodes: Points to Volume Fields fixes
A few items when OpenVDB is not enabled.
  - Cleanup a compiler warning
  - Add a node warning message
  - Return an empty geometry set
2021-10-03 13:43:51 -05:00
98fe05fb5b Fix T91810 Bevel not working well with certain unbeveled edge positions.
A previous commit, c56526d8b6, which sometimes didn't drop offsets
into 'in plane' faces, as a fix to T71329, was overly aggressive.
If all the intermediate edges are in the same plane then it is fine
to just put the meeting point on the plane of the start and end edges.
2021-10-03 11:30:40 -04:00
1833ebea31 Cleanup: move as_span method out of header
This method does not have to be in a header and results in a relatively
large number of symbols to be generated (42).
2021-10-03 17:07:26 +02:00
bf354cde96 Cleanup: move special methods of geometry set out of header
This reduces the compile time, because fewer symbols have to be generated
in translation units using geometry sets.
2021-10-03 16:58:33 +02:00
64d07ffcc3 Cleanup: move methods out of field classes
This makes it easier to scan through the classes and simplifies
testing the compile time impact of having these methods in the header.
2021-10-03 16:47:54 +02:00
17e2d54a3d Cleanup: use extern templates for typed output attribute
This is very similar to rBa812fe8ceb75fd2b.
This time the number of symbols decreases further from 1335 to 928.
Compile time of the distribute node decreases from ~2.4s to ~2.3s.
2021-10-03 16:30:14 +02:00
a812fe8ceb Nodes: use extern templates for socket declarations
The new socket declaration api generates a surprising amount
of symbols in each translation unit where it is used. This resulted
in a measurable compile time increase.

This commit reduces the number of symbols that are generated in
each translation unit significantly. For example, in
`node_geo_distribute_points_on_faces.cc` the number of symbols
decreased from 1930 to 1335. In my tests, this results in a 5-20%
compile time speedup when this and similar files are compiled
in isolation (measured by executing the command in `compile_commands.json`).

Compiling the distribute points on faces node sped up from ~2.65s to ~2.4s.
2021-10-03 16:05:19 +02:00
2f52f5683c Cleanup: move more method definitions out of their class
This makes it easier to test the impact of moving them out
of the header later.
2021-10-03 15:24:21 +02:00
06c3bac23b Cleanup: move more methods out of classes 2021-10-03 15:14:03 +02:00
fb34cdc7da Geometry Nodes: Points to Volume Fields Update
This update of the Points to Volume node allows a field to populate the
radius input of the node and removes the implicit realization of
instances.

Differential Revision: https://developer.blender.org/D12531
2021-10-03 08:03:46 -05:00
0998856c92 Cleanup: use movable output attribute instead of optional
This simplifies the code a bit and improves compile times a bit.
2021-10-03 15:01:02 +02:00
8fc97a871f Cleanup: make typed output attribute movable
This comes at a small performance cost due to an additional
memory allocation, but that is not significant currently.
2021-10-03 14:49:15 +02:00
5d5a753d96 Cleanup: move AttributeIDRef and OutputAttribute methods out of class
This makes the classes easier to read and simplifies testing
the compile time impact of defining these methods in the header.
2021-10-03 14:39:17 +02:00
e1e75bd62c Cleanup: move resource scope method definitions out of class 2021-10-03 14:23:26 +02:00
a8d6a86981 Cleanup: move StringRef method definitions out of class
This makes the classes more appealing to look at and makes
it easier to see what different methods are available.
2021-10-03 14:10:26 +02:00
c206fa9627 Cleanup: add nolint comment to move semantic test 2021-10-03 14:03:53 +02:00
f2da98d816 Cleanup: remove unused functions 2021-10-03 13:44:44 +02:00
d3afe0c126 Geometry Nodes: Resample Curve Fields Update
This update of the Resample Curve node allows a field to populate the
count or length input of the node depending on the current mode. The
field is evaluated on the spline domain.

Differential Revision: https://developer.blender.org/D12735
2021-10-02 21:45:51 -05:00
e863e05697 Data Transfer: Remove unnecessary noisy error message
I've seen requests to remove this or complaints about this error message
quite frequently. In lots of production files it's just always going off.
It's not an actionable warning, and since "slow" is relative, it isn't
always even correct.

Differential Revision: https://developer.blender.org/D12694
2021-10-02 20:33:15 -05:00
b57b4dfab1 Cleanup: clang-format 2021-10-03 12:13:29 +11:00
f49dff97d4 Cleanup: spelling in strings 2021-10-03 12:13:29 +11:00
74f45ed9c5 Cleanup: spelling in comments 2021-10-03 12:13:29 +11:00
Jarrett Johnson
c5c94e3eae Geometry Nodes: Add Rotate Euler Node
This commit introduces the Rotate Euler function node which modifies
an input euler rotation. The node replaces the "Point Rotate" node.

Addresses T91375.

Differential Revision: https://developer.blender.org/D12531
2021-10-02 20:04:45 -05:00
34cf33eb12 Geometry Nodes: Switch Node Fields Update
This update of the Switch node allows for field compatible types
to be switched through the node. This includes the following:

Float, Int, Bool, String, Vector, and Color

The remaining types are processed with the orginal code:

Geometry, Object, Collection, Texture, and Material

Because the old types require a diffent "switch" socket than the
field types, versioning for old files is included to move links
of those types to a new switch socket. Once fields of other types
are supported, this node can be updated to support them as well.

Differential Revision: https://developer.blender.org/D12642
2021-10-02 17:34:47 -05:00
Leon Leno
54927caf4f Geometry Nodes: Add side and fill segments to Cone/Cylinder nodes
This commit extends the 'Cone' and 'Cylinder' mesh primitive nodes,
with two inputs to control the segments along the side and in the fill.
This makes the nodes more flexible and brings them more in line with
the improved cube node.

Differential Revision: https://developer.blender.org/D12463
2021-10-02 17:29:25 -05:00
12e8c78353 Fix T91888: Pivot point settings shown in timeline
Added to timeline by accident in f9e0981976.
2021-10-01 23:26:59 +02:00
1476d35870 Geometry Nodes: Set Handle Type Node Field Update
This update of the Set Handle Type node allows for a bool field to be
used as the selection of the affected control point handles for
bezier splines. If no bezier splines are provided a info message is
shown.

Differential Revision: https://developer.blender.org/D12526
2021-10-01 14:22:24 -05:00
1fb364491b Geometry Nodes: Set Spline Type Node Field Update
This update of the Set Spline Type node allows for a bool field to be
used as the selection of the affected splines.

Differential Revision: https://developer.blender.org/D12522
2021-10-01 11:59:29 -05:00
eacdc0ab4a VSE: Draw active strips with a different color in the preview window 2021-10-01 18:03:18 +02:00
dc30a9087c Geometry Nodes: Spline Length Input Node
The Spline Length Input node provides a field containing the
length of the current evaluated spline to the Point and Spline
domains.

Differential Revision: https://developer.blender.org/D12706
2021-10-01 09:58:49 -05:00
9e456ca695 Asset Browser: expose current catalog ID in RNA
Add read-only access to the active catalog ID via
`context.space_data.params.catalog_id` in the Asset Browser context.

The UUID is exposed as string to Python.
2021-10-01 16:47:16 +02:00
aae96176e8 Geometry Nodes: Curve Subdivide Node with Fields
The curve subdivide node can now take an int field to specify the
number of subdivisions to make at each curve segment.

Reviewed by: Hans Goudey
Differential Revision: https://developer.blender.org/D12534
2021-10-01 09:43:04 -05:00
e1952c541a Cleanup: unused function declaration
This should have been removed during the recent velocity attribute
refactor.
2021-10-01 16:41:50 +02:00
Johan Walles
fb820496f5 Tracking: Sort motion tracking tracks by start and end frames
Enable sorting motion tracking tracks by start / end times.

Help identifying what cases reconstructed camera jumps, based
on information about whether any track starts/ends at the frame.

Based on revision eb0eb54d96.

{F10563305}

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D12621
2021-10-01 16:29:38 +02:00
f497e471f8 Asset Catalogs: always have an Asset Catalog Tree available
Always create an `AssetCatalogTree` in the `AssetCatalogService`. This
ensures that newly-created catalogs are immediately visible in the UI
(because they insert themselves into an already-existing tree).
2021-10-01 16:15:50 +02:00
3be4cb5b27 Cleanup: Asset Catalog Test, fix clang-tidy warnings
No functional changes.
2021-10-01 15:24:04 +02:00
56ce51d1f7 Asset Catalogs: add catalog filter for the asset browser
Given an "active catalog" (i.e. the one selected in the UI), construct
an `AssetCatalogFilter` instance. This filter can determine whether an
asset should be shown or not. It returns `true` when The asset's catalog
ID is:

- the active catalog,
- an alias of the active catalog (so different UUID that maps to the
  same path),
- a sub-catalog of the active catalog.

Not yet hooked up to the UI.
2021-10-01 15:22:05 +02:00
1c7ce7e0b4 Cleanup: asset catalogs, make function const
Declare `AssetCatalogService::find_catalog()` as `const`, as it's not
requiring modification off the service object.

No functional changes.
2021-10-01 15:22:05 +02:00
271210126e Fix T91834: Appending objects with shape keys into new file is broken.
Recent append refactor 'broke' this, we need special recursive care and
handling of those nasty shpae keys... again.
2021-10-01 14:49:04 +02:00
f9acf21063 Python API Docs: add an example of Bone.convert_local_to_pose usage.
The use case for this method is quite obscure and difficult to
understand without an example. Despite how big looks, this is
actually the simplest example that makes sense.
2021-10-01 15:47:30 +03:00
bdc66c9569 GPU: set 'GL_PACK_ALIGNMENT' 1 as default
This fixes T91828.

The current value of `GL_PACK_ALIGNMENT` may result in crash in the `gpu` module if the buffer is not aligned.

Differential Revision: https://developer.blender.org/D12720
2021-10-01 09:11:37 -03:00
eb3a8fb4e8 Fix T91872: incorrect socket inspection on group nodes
This bug was introduced in rBef45399f3be0955ba8.
2021-10-01 13:21:03 +02:00
798e593002 Fix T87189: Copy/pasting IDs does not handle properly instantiation.
Copy/Paste uses its own code path for ID linking, which was not setting
`LIB_TAG_DOIT` for proper instantiation later on.

Would be nice the make this logic closer to the rest of the link/append
code at some point, but for now this fix will do.
2021-10-01 12:21:08 +02:00
21c29480c3 Fix paste code linking 'direct' IDs with 'INDIRECT' flag.
No idea why this was done that way (it originate from initial paste
commit, rB12b642062c6f).

But the IDs 'selected' as direct paste in `BLO_library_link_copypaste`
should be 'directly' linked, it's similar case to actual append of
selected IDs by the user.

Related to T87189.
2021-10-01 12:21:08 +02:00
928d644895 Append: Fix appended objects potentially auto-instantiated in more than one collection.
Related to T87189.
2021-10-01 12:21:08 +02:00
af0b7925db Fix T87536: incorrect socket types in reroute nodes
This refactors and fixes the code that propagates socket types
through reroute nodes. In my tests it is faster than the previous
code. The difference becomes larger the more reroute nodes
there are, because the old code had O(n^2) runtime, while the
new code runs in linear time.

Differential Revision: https://developer.blender.org/D12716
2021-10-01 11:42:00 +02:00
7843cd63d8 Fix T91839: incorrect active vertex group index
Differential Revision: https://developer.blender.org/D12712
2021-10-01 11:36:10 +02:00
ae4b45145c Cleanup: Asset Catalog Paths, move default constructor to header file
No functional changes.
2021-10-01 10:58:33 +02:00
2e6c6426d3 Asset Catalogs: test that missing catalogs are created once
Add asset catalogs test, to ensure missing catalogs are only created once,
and not for every originally defined catalog.

No functional changes to Blender (the code was already doing the right
thing).
2021-10-01 10:58:16 +02:00
bdb7d262aa Cleanup: clang-tidy warnings 2021-10-01 16:20:31 +10:00
b559fb178e Gizmo: hide 2D gizmos while transforming
Hide gizmos in the sequencer & UV editor while transforming.
2021-10-01 16:19:12 +10:00
4485dc483c Cleanup: use C-style comments, nullptr for C++
Minor changes extracted from D6408
2021-10-01 10:45:09 +10:00
Vitor Boschi
3a59ddb292 Fix: Incorrect warning in curve to mesh node with instances
The node was setting a warning when used with instances on input,
even though it worked fine.

Differential Revision: https://developer.blender.org/D12718
2021-09-30 18:27:58 -05:00
66fe1c79f3 Compositor: Fix Composite node using alpha when "Use Alpha" is off
Alpha input was not receiving the final composite canvas 
as preferred causing a Translate operation being inserted 
for centering. This resulted in a transparent background.
The issue only affects Full Frame mode.
2021-09-30 23:56:53 +02:00
e2df5c8a56 Compositor: Fix Flip node not flipping translation on Full Frame
To match tiled implementation, flip center should not be translated
when canvas has offset. Instead the canvas offset needs to be flipped.
2021-09-30 23:56:53 +02:00
f3274bfa70 Compositor: Fix Dilate/Erode node crash with Step option
It was writing the buffer out of bounds.
Only "Full Frame" mode was affected.
2021-09-30 23:56:53 +02:00
4569d9c0c3 Compositor: Fix Movie Distortion node rendering an empty image
Input area of interest calculation was incorrect because `m_margin`
was uninitialized.
Only "Full Frame" mode was affected.
2021-09-30 23:10:27 +02:00
Pratik Borhade
33dc584b37 Fix T91285: Bad tooltip for VSE Slip operator
This patch is created to change the tooltip for Slip Strip Contents
As per the present info, only active strip will be affected.
But in reality selected strips can be trimmed with this operator.

Word Trim changed to Slip in tooltip

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D12450
2021-09-30 21:11:09 +02:00
Josef Raschen
213554f24a VSE: Add ASC CDL color correction method
Add Offset/Slope/Power controls to the color balance modifier. This is
already available in compositor.

Reviewed By: sergey, ISS

Differential Revision: https://developer.blender.org/D12575
2021-09-30 21:09:47 +02:00
8d60ac2bb0 Cleanup: Fix unused variable warning 2021-09-30 14:01:56 -05:00
Brecht Van Lommel
1a134c4c30 Cycles: refactor API for render output
* Add OutputDriver, replacing function callbacks in Session.
* Add PathTraceTile, replacing tile access methods in Session.
* Add more detailed comments about how this driver should be implemented.
* Add OIIOOutputDriver for Cycles standalone to output an image.

Differential Revision: https://developer.blender.org/D12627
2021-09-30 20:53:27 +02:00
a754e35198 Cycles: refactor API for GPU display
* Split GPUDisplay into two classes. PathTraceDisplay to implement the Cycles side,
  and DisplayDriver to implement the host application side. The DisplayDriver is now
  a fully abstract base class, embedded in the PathTraceDisplay.
* Move copy_pixels_to_texture implementation out of the host side into the Cycles side,
  since it can be implemented in terms of the texture buffer mapping.
* Move definition of DeviceGraphicsInteropDestination into display driver header, so
  that we do not need to expose private device headers in the public API.
* Add more detailed comments about how the DisplayDriver should be implemented.

The "driver" terminology might not be obvious, but is also used in other renderers.

Differential Revision: https://developer.blender.org/D12626
2021-09-30 20:48:08 +02:00
ac582056e2 Geometry Nodes: Swap order of geometry proximity inputs
"Target" is the most important, so it goes at the top.
2021-09-30 13:41:55 -05:00
Charlie Jolly
be70827e6f Nodes: Add Float Curve for GN and Shader nodes.
Replacement for float curve in legacy Attribute Curve Map node.

Float Curve defaults to [0.0-1.0] range.

Reviewed By: JacquesLucke, brecht

Differential Revision: https://developer.blender.org/D12683
2021-09-30 19:24:40 +01:00
827e30bd15 Geometry Nodes: Change default for mesh to points node
While "Vertices" may be less useful since mesh vertices are already
points, the output is more easily understandable, so it's a better
default.
2021-09-30 11:53:48 -05:00
6cff1d6480 Fix T91734: Crash snapping mesh if a beveled curve is present
`BKE_mesh_boundbox_get` cannot be called for objects of type Curve.

The BoundBox however does not match the object seen in the scene.
This will be dealt with in another commit.
2021-09-30 02:48:02 -03:00
dd3391dd99 Asset Catalogs: create missing parent catalogs
For every known catalog, ensure its parent catalog also exists. This
ensures that assets can be assigned to parent catalogs, even when they
didn't exist in the Catalog Definition File yet.
2021-09-30 17:34:58 +02:00
4389067929 Fix possible use-after-free in drag-drop handling logic
Would happen when there were multiple drag items in parallel. There was
a listbase constructed with twice the same item, even though that item
would be deleted after it was handled the first time.
2021-09-30 16:39:09 +02:00
4ee2d9df42 UI: Support easy dropping into/onto rows in new tree-view API
Adds an easy way to add drop support for tree-view rows.

Most of the work is handled by the tree-view UI code. The tree items can
simply override a few functions (`can_drop()`, `on_drop()`,
`drop_tooltip()`) to implement their custom drop behavior.

While dragging over a tree-view item that can be dropped into/onto, the
item can show a custom and dynamic tooltip explaining what's gonna
happen on drop.

This isn't used yet, but will soon be for asset catalogs.

See documentation here:
https://wiki.blender.org/wiki/Source/Interface/Views#Further_Customizations
2021-09-30 16:39:09 +02:00
42ce88f15c Cleanup: remove CatalogPath alias
The `CatalogPath` name was an alias for `std::string`, so that it could
be easily switched over to something else. This happened in the previous
commit (switched to `AssetCatalogPath`), so the alias is no longer
necessary.

This commit removes the `CatalogPath` alias.

No functional changes.
2021-09-30 16:34:30 +02:00
628fab696c Asset Catalog: introduce AssetCatalogPath class
So far we have used `std::string` for asset catalog paths. Some
operations are better described on a dedicated class for this, though.
This commits switches catalog paths from using `std::string` to a
dedicated `blender::bke::AssetCatalogPath` class.

The `using CatalogPath = AssetCatalogPath` alias is still there, and
will be removed in a following cleanup commit.

New `AssetCatalogPath` code reviewed by @severin in D12710.
2021-09-30 16:29:14 +02:00
5d42ea0369 GPencil: Change default template for better contrast in header
Patch created by Pablo Vazquez

This change darkens the header area a bit to create more contrast with the texts.

Differential Revision: https://developer.blender.org/D12711
2021-09-30 16:14:44 +02:00
d754d85845 Fix RigidBodyWorld copy using NO_MAIN instead of COW flag for cache handling.
We only want to share caches in case of CoW copying for the depsgraph,
not for regular `NO_MAIN` data.
2021-09-30 16:00:29 +02:00
1a72744ddc Fix T90246: Full Copy'ing a scene confuses physics in the original scene.
Handling of RigidBody data in duplicate of scenes/collections was very
wrong. This commit:
 - Add handling of duplication of RB collections when fully duplicating
   a scene.
 - Fix Object duplication trying to add duplicated RB objects to
   matching RBW collections.

While the later behavior is desired when only duplicated objects, when
duplicating their collections and/or scenes it is actually very bad, as
it would add back new object duplicates to old (RBW) collections.
2021-09-30 16:00:29 +02:00
779ea49af7 Cleanup: move node_common.c to c++
Buildbot compiled without problems.
2021-09-30 15:44:08 +02:00
07c5d02a11 Asset Browser: Support activating catalogs in the "Current File" library
If the "Current File" asset library is selected in the Asset Browser,
now asssets are filtered based on the active asset catalog. Previously
it would just show all assets. This was marked as a TODO in the code
already.

Maniphest Task: https://developer.blender.org/T91820
2021-09-30 15:23:13 +02:00
3453b22b1e Fix: Curve to Mesh node outputs original curve
It should only output the new mesh (and potentially instances
that are processed separately).
2021-09-30 13:33:21 +02:00
9628ef4135 Fix: wrong field input deduplication with Material Selection node 2021-09-30 12:51:09 +02:00
80d7cac22d Fix T91773: improve numerical stability in Curve Spiral node 2021-09-30 12:33:34 +02:00
ae0f944a57 Fix Cycles viewport flickering
Caused by a lack of synchronization between update process which sets
clear flag and the draw code checking the flag outside of a lock.
2021-09-30 11:44:53 +02:00
5f632f9f6e Fix color width regression in 66e24ce35b
Color buttons were drawing single icon width.
2021-09-30 17:45:09 +10:00
af13168a3f Cleanup: remove unused SpaceImage.curtile 2021-09-30 17:32:48 +10:00
e9dac3eab8 Cleanup: reduce Sequence size by 8 bytes
Also use int8_t for color tag.
2021-09-30 17:32:46 +10:00
fdcae48663 Cleanup: isolate UDIM parameters into a struct
Passing multiple UDIM arguments into the packing function
is awkward especially since the caller may not be using UDIM.

Use an argument to store UDIM packing parameters which can be NULL,
which operates without any UDIM support.

Add a function that extracts these parameters out of the image space
allowing for multiple functions to take UDIM parameters in the future.
2021-09-30 17:32:45 +10:00
2c2516bfc9 Fix(unreported): LineArt curve objects garbled result.
This is caused by line art loading curve objects twice from curve and converted mesh instances (when instance option is on). Now only load mesh when instance option is on.
2021-09-30 13:30:10 +08:00
66e24ce35b Fix menu width regression in c7d94a7827
Icon only popup buttons needed to be adjusted too,
add an uiTextIconPadFactor.icon_only to support this.
2021-09-30 12:43:52 +10:00
84dcf12ceb UI: Increase Area Resize Edge Hit Size
This patch increases the size of the Area BORDERPADDING a bit to make
it easier to hit the edges when initiating area resizing.

See D11925 for details and examples.

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

Reviewed by Campbell Barton
2021-09-29 15:05:58 -07:00
81f552e9ad Geometry Nodes: Expose Bezier handle positions as an attribute
This commit exposes left and right bezier handles as an attribute.
Interaction basically works like edit mode. If you move an aligned
handle, it also moves the opposite handle of the control point.
The difference is that you can't edit "Auto" or "Vector" handles,
you have to first use the "Set Handle Type" node. That gives the handle
types a bit more meaning in the node tree-- changing them in edit mod
is more like a "UI override".

The attributes are named `handle_start` and `handle_end`,
which is the same name used in the curve RNA API.

A new virtual array implementation is added which handles the case of
splines that don't have these attributes, and it also calls two new
functions on `BezierSpline` to set the handle position accounting
for aligned handles.

The virtual arrays and attribute providers will be refactored
(probably templated) in the future, as a next step after the last
built-in curve attribute provider has landed.

Differential Revision: https://developer.blender.org/D12005
2021-09-29 15:29:29 -05:00
cd03f5b6e5 Add RNA path funcs for VolumeRender & VolumeDisplay
Without proper RNA paths, Alt-click editing properties on multiple
selected objects doesn not work (as well as the 'Copy To Selected'
operator).

Fixes T91806.

Maniphest Tasks: T91806

Differential Revision: https://developer.blender.org/D12700
2021-09-29 21:39:56 +02:00
0cddbcf1d7 Fix T91803: Freestyle rendering as pass broken after recent changes 2021-09-29 21:14:37 +02:00
a2e321aa6d Cleanup: Compositor: Migrate most converter nodes to new socket builder
This migrates most nodes except for the switch view node.
This node requires dynamic sockets so its implementation will be more involved.
2021-09-29 14:48:30 -04:00
d3d021601d Nodes: Fix Split View missing identifier
Mistake from rB84251acfcc4534059d6ccd6682f8e37d529b9063
2021-09-29 14:48:30 -04:00
19785cb022 Fix Cycles CPU performance regression after recent change for intersections size
This struct is much bigger now, and does not actually need to be fully zero
initialized.
2021-09-29 20:25:16 +02:00
Himanshi Kalra
22c61e8060 Tests: Disable tests for non-compiled libraries
This diff disables tests for Boolean, subdivision surface and volume
when GMP, Opensubdiv and Openvdb are not compiled respectively.
It also changes the existing file structure and adds sub-folders for
boolean and subdivison tests. The volume folder only has one test and
is as unchanged structure-wise.

Reviewed By: JacquesLucke, LazyDodo

Differential Revision: https://developer.blender.org/D12448
2021-09-29 23:52:52 +05:30
6f23e4484d Fix non-finite curve normal causing Cycles to crash
Similar to the previous change in the area: need to avoid ray
point and direction becoming a non-finite value.

Use the view direction when the geometrical normal can not be
calculated.

Collaboration and sanity inspiration with Brecht!

Differential Revision: https://developer.blender.org/D12703
2021-09-29 19:49:59 +02:00
1d478851f8 GPencil: Avoid double depsgraph tag
The eval data is updated at the end of the function and this call just adds a calculation not used.
2021-09-29 19:21:54 +02:00
214baf5422 Assets: Enable recursive reading for the asset view template as well
This makes asset view templates, e.g. as used by the Pose Library add-on
use recursive asset loading, see

Also works around an issue that made assets not show up at all anymore
since fc7beac8d6. I'm creating a separate report for that regression,
but in the Asset Browser and Viewer it shouldn't be apparent currently.
2021-09-29 18:51:10 +02:00
45a312fd8f Fix build failure on Windows + wrong buffer size
Was using `NAME_MAX` which is defined in `limits.h`, which again may be
implicitly included by the compiler. Intend was to use the Blender
define `MAX_NAME`.
2021-09-29 17:49:42 +02:00
9d9f205dc4 Asset Browser: Initial Asset Catalog UI
The Asset Browser now displays a tree with asset catalogs in the left
sidebar.
This replaces the asset categories. It uses the new UI tree-view API
(https://wiki.blender.org/wiki/Source/Interface/Views#Tree-View).
Buttons are displayed for adding and removing of catalogs. Parent items
can be collapsed, but the collapsed/uncollapsed state is not stored in
files yet.
Note that edits to catalogs (e.g. new or removed catalogs) are only
written to the asset library's catalog definition files when saving a
.blend.

In the "Current File" asset library, we try to show asset catalogs from
a parent asset library, or if that fails, from the directory the file is
stored in. See adaf4f56e1.

There are plenty of TODOs and smaller glitches to be fixed still. Plus a
UI polishing pass should be done.

Important missing UI features:
* Dragging assets into catalogs (WIP, close to being ready).
* Renaming catalogs
* Proper handling of catalogs in the "Current File" asset library
  (currently not working well).

The "Current File" asset library is especially limited still. Since this
is the only place where you can assign assets to a catalog, this makes
the catalogs very cumbersome in general. To assign an asset to a
catalog, one has to manually copy the Catalog ID (a random hash like
number) to the asset metadata through a temporary UI in the Asset
Browser Sidebar. These limitations should be addressed over the next few
days, they are high priority.

Differential Revision: https://developer.blender.org/D12670
2021-09-29 17:15:23 +02:00
df9120b365 Fix T89864: Adding an asset referencing other objects adds it to scene but only adds data-blocks of referenced objects.
Link/append code needs proper access to scene/view3d data to handle
collections/objects instantiation.

Note that this is a temporary hack more than a proper fix, which would require
a deeper redesign of drag&drop code.

Also note that this will not handle 'properly' (i.e. as user would
expect it) cases like implicitely appended parent objects, in that only
the explicitely appended object will be dropped to the nes location, the
others will remain at their original coordinates.

Differential Revision: https://developer.blender.org/D12696
2021-09-29 17:10:42 +02:00
6aac892fad Cleanup: Enforce C linkage for internal File Browser header
This will be used by C++ code in the upcoming asset catalog UI commit.
2021-09-29 16:59:48 +02:00
367775ac6a Fix Cycles use of uninitialized value in volume stack intersection on CPU
Could cause an actual bug but probability is low in practice.
2021-09-29 16:37:32 +02:00
4d4113adc2 Cycles: record large number of transparent shadow intersections on CPU
So we can do fewer intersection calls, only on the GPU do we need to save
memory and do this in small steps.

Ref T87836
2021-09-29 16:37:32 +02:00
fe070fe33b Fix Cycles crash in certain hair configurations
The issue was caused by hair shader setup setting normal to a non
finite value, which then gets used to create a ray with non-finite
direction, making BVH traversal to run out of stack memory.

Happens with 150_0040_A.lighting.blend frame 112 of the Sprites
project.

Differential Revision: https://developer.blender.org/D12692
2021-09-29 16:14:23 +02:00
901fa96b7f Keymap: New preference to open folders on single click in file browser
Introduce a new keymap preference to navigate into folders by clicking on them once instead of twice.
Makes browsing folders faster albeit non-standard, so keeping this off by default for now.

Does not affect Industry Compatible or other keymaps.

It is still the possible to right-click to open context menu, hold Ctrl or Shift to select multiple items:

{F10651030, size=full}

----

Keymap preference:

{F10652759, size=full}

Part of T91537

Reviewed By: fsiddi, campbellbarton

Differential Revision: https://developer.blender.org/D12667
2021-09-29 15:57:57 +02:00
1f4545dc9c Cleanup: else-after-return 2021-09-29 15:48:16 +02:00
b80ed8396d Fix T89164: Sculpt "Smooth" brush crash with zero pressure
Caused by {rB3e5431fdf439}

Issue is that sculpting could start with using `SCULPT_smooth` and
(because of the Pressure sensitivity dropping to zero) code would switch
to `SCULPT_enhance_details_brush` at strength zero.
Issue with this though is that this can be in the middle or end of a
stroke and the necessary `ss->cache->detail_directions` are only
initialized for the first brush step (see
`SCULPT_stroke_is_first_brush_step` in `SCULPT_enhance_details_brush`).
With these missing, it could only go downhill from there.

Suggest to prevent the "mode-flip" from `SCULPT_smooth` to
`SCULPT_enhance_details_brush` (happening solely because of pressure
strength) by changing the condition.
Now do `SCULPT_enhance_details_brush` only if strength is **below** zero
and `SCULPT_smooth` else (flipping from enhance_details to regular smooth
is fine).

If inverting the brush in the middle of the stroke will be supported at
some point, the codepath of `smooth` would have to inform the cache that
invert changed and detail_directions would have to be initialized then
(even if not at the start of the stroke).

Maniphest Tasks: T89164

Differential Revision: https://developer.blender.org/D12676
2021-09-29 15:07:45 +02:00
c33a005297 Texts in Outliner dont activate
Texts in Outliner dont activate on selecting (Text Editor did not change
to selected text) which is a bit inconsistent to other ID types.

ref T90862

Maniphest Tasks: T90862

Differential Revision: https://developer.blender.org/D12412
2021-09-29 15:07:13 +02:00
ef29bf9023 Assets: Expose option to reuse data-block data when appending
With 794c2828af & f48a4aa0f9 it's possible to reuse possibly
expensive, nested data of a data-block when appending. E.g. the
texture of a material, or the mesh of an object. Without this it's easy
to bloat memory and the file size. Duplicated textures also cause
unnecessary shader recompilations.

The feature was intended to be the new default behavior for the Asset
Browser, but it wasn't actually added to the UI yet. This patch adds a
new import type option to the Asset Browser. So from the menu in the
header, you can now choose between:

* Link
* Append
* Append (Reuse Data)

The latter is the new default.

Maniphest Task: https://developer.blender.org/T91741

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

Reviewed by: Sybren Stüvel, Bastien Montagne
2021-09-29 15:02:38 +02:00
Falk David
5cebcb415e VSE: Add color tags to strips
This patch adds color tags to VSE strips, an overlay option to toggle the colors
on and off, a section in the theme settings to define the 9 possible colors and
two ways of changing the color tag through the UI. You can change the color
through the right-click context menu, or in the strip side panel next to the
strip name.

Color tags are defined in user preferences and they can be disabled in overlay
settings.

Reviewed By: campbellbarton, ISS

Differential Revision: https://developer.blender.org/D12405
2021-09-29 14:34:01 +02:00
ffb9577ac9 Cycles: Ensure finite displacement and background evaluation
Avoids possible numerical issues in the path tracing kernel, which
is most important for displacement as non-finite values in BVH can
lead to infinite node recursion during traversal.

Differential Revision: https://developer.blender.org/D12690
2021-09-29 14:06:10 +02:00
731325a022 Cycles: Make sure GPU transfer is finished prior display update
Noticed while looking into flickering issues in viewport.

Doesn't seem to solve the flicker issue for me, but is something
what is supposed to be happening anyway.

Differential Revision: https://developer.blender.org/D12673
2021-09-29 14:05:51 +02:00
adaf4f56e1 Support loading catalogs in the Current File asset library
When the Asset Browser shows the "Current File" asset library, now it
also attempts to load an asset catalog definition file from location of
the current .blend file. This happens as follows:
* First, see if the file is inside of an asset library that is "mounted" in the
  Preferences. Load the catalogs from there if so.
* Otherwise, if the file is saved, load the catalogs from the directory the
  file is saved in.
* If the file is not saved, no catalogs will be loaded.

Unit tests are being worked on in D12689.

Creating catalogs from the "Current File" asset library still doesn't work, as
the asset catalog service doesn't construct an in-memory catalog definition
file in that case yet.

Differential Revision: https://developer.blender.org/D12675
2021-09-29 13:18:44 +02:00
Gaia Clary
78b9a8c7b9 Add an option to silence bpy.ops.anim.keyframe_delete_v3d when used in Addons
The issues:

1.) When we want to remove keyframes from a range of frames in an
action,
then we can use bpy.ops.anim.keyframe_delete_v3d to remove the keys
frame by frame. However, whenever the operator hits a frame with no
keyframes, then it generates an error. While when it hits a frame
with keyframes, then it reports the numbner of removed keys.

This creates a lot of unnecessary noise in the Blender console.

2.) Furthermore a related issue is that WM_event_add_notifier() is
called also when no frames where removed. This seems to significantly
slow down the removal of keyframes in a range of frames at least
when i use vscode for debugging.

A proposal for improvement:
This patch adds an attribute 'confirm_success' which controls
if the operator reports back what it did (or did not) while
executing. Silent mode would then be called like this:

bpy.ops.anim.keyframe_delete_v3d(confirm_success=False)

Note: confirm_success is True by default so this patchj does not
change the behavior of Blender, it only gives the option to scripts.

3.) Personal note:
I have chosen the attribute name to be equal as it is used
in other related operators. However i rather would rename the
attribute to "verbose" (preferred) or "with_confirm". But i let this
to be decided by the reviewers. Thanks for your time to review!

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D12629
2021-09-29 13:09:17 +02:00
6351c73b75 Fix T88954: Rearranging of modifiers for linked objects no longer works.
There would be no modifier set in context in drag and drop case, in that
case try to get active modifier from active object instead.
2021-09-29 12:53:57 +02:00
0c32e3b312 Fix T91756: String to Curve node produces NaN when size is zero 2021-09-29 12:40:36 +02:00
4cf4bb2664 UI: swap tool and regular header
Swap the tool-header and header order so the tool-header
so the header is always next to the window edge.

Note that files saved in 3.0 will have overlapping headers when opened
in any version of Blender before this commit.

Reviewed By: Severin, fsiddi

Maniphest Tasks: T91536

Ref D12631
2021-09-29 20:03:47 +10:00
eabb134840 Fix T91802: vertex color layer name collides with itself
Vertex colors are already included in `mesh.attributes`. So they don't
have to be added to the collision checks separately.
2021-09-29 11:01:17 +02:00
24a965bb16 Fix T91767: crash when instancing geometry coming from modifier
The issue was that the `GeometrySet` that comes from the modifier does
not have full ownership of the mesh for legacy reasons to avoid copies.
Calling `ensure_owns_direct_data` makes sure that the geometry set
actually owns the geometry so that it can be instanced.
2021-09-29 10:55:32 +02:00
f51bef75f4 Geometry Nodes: instance on points in instances
For consistency with other nodes, we also want to process
all instances in the Points input independently. This allows
for more efficient instancing of many objects but also leads
to nested instancing. All instances are processed in their
local space, so that instances don't have to be realized.

Differential Revision: https://developer.blender.org/D12660
2021-09-29 10:10:12 +02:00
8cbec0beb2 Fix/bypass doversion for wire new colors
Some cases were not covered by the original doversion in
4a0ddeb62b. For now we make it always change the wire color regardless
of whether it was changed before or not.

This do a subversion bump.
2021-09-29 09:58:55 +02:00
Siddhartha Jejurkar
a285299ebb UV: Pack to closest/active UDIM
Implements T78397
Extends the functionality of pack islands operator to allow packing UVs
to either the closest or active UDIM tile.
This provides 2 new options for packing UVs :

* Closest UDIM: Selected UVs will be packed to the UDIM tile they were
  placed on. If not present on a valid UDIM tile, the UVs will be packed
  to the closest UDIM in UV space
* Active UDIM: Selected UVs will be packed to the active UDIM image tile
  In case, no image is present in the UV editor, then UVs will be packed
  to the tile on the UDIM grid where the 2D cursor is located.

Reviewed By: campbellbarton

Maniphest Tasks: T78397

Ref D12680
2021-09-29 17:53:09 +10:00
Siddhartha Jejurkar
bf06f76be6 UV Editor: Grid and snapping improvements
Implements T89789, T89792, custom grid (described as dynamic grid in
T78389) and UV grid snapping (T78391)
Replaces the default UV editor grid with 2 new types of grid :

* Custom grid: Allows the user to create an NxN grid, where the value
  of N is specified by the user.
* Subdividing grid: Subdivides the UV editor grid when the user
  zooms in the viewport and vice versa when zooming out.

UV snapping improvements :
* Increment snapping: Increment values for snapping are calculated based
  on which grid type is being used in the UV editor
  (subdividing or custom). In general the increment value is equal to
  the distance between 2 visible grid lines.
* Absolute grid snap: New toggle added to increment snapping option in
  the UV editor, allows UV grid snapping during translation.

Reviewed By: campbellbarton

Ref D12684
2021-09-29 17:48:35 +10:00
008ae26712 Fix T91237: Wrong Editors could sync animation 'Visible Range'
This was reported for the Outliner.

It was possible to set 'show_locked_time' on any space (via python, not
sure if there are other ways to achieve this).
Navigating in an animation editor obviously ruined the layout in certain
Editors that are not made for this.

Now restrict syncing to editors that support it well (the ones that have
this setting exposed in their menus) and prevent setting this in RNA.

Maniphest Tasks: T91237

Differential Revision: https://developer.blender.org/D12512
2021-09-29 09:12:47 +02:00
eddc3f5bc8 Cleanup: Add constructor for AttributeFieldInput 2021-09-28 23:19:33 -05:00
756c22bb41 Cleanup: Compositor: Migrate color nodes to new socket builder 2021-09-29 00:09:41 -04:00
d1220f795f UI: Update Levels Nodes
- Instead of making the enum expanded leave it in menu form.
- Use full words instead of letters.

Differential Revision: https://developer.blender.org/D12686
2021-09-28 21:36:15 -04:00
8e40bb2dea Nodes: Fix compositor viewer nodes having wrong alpha channel
Default should be black image with an alpha value of 1.
2021-09-28 20:33:42 -04:00
84251acfcc Cleanup: Compositor: Migrate most output nodes to new socket builder
This migrates most nodes except for the file output node.
This node requires dynamic sockets so its implementation will be more involved.
2021-09-28 20:13:42 -04:00
e81533b25e Cleanup: Simplify compositor Z Combine operation conversion 2021-09-28 18:46:10 -04:00
f0f70729b1 Fix: Knife undo with no cut segments left
Now if a user presses the knife tool undo key when there are no more cut segments to undo, the operator exits. Previously, it did nothing.
2021-09-28 23:09:54 +01:00
7f5d62dfc6 Cleanup: Make format 2021-09-28 18:03:33 -04:00
4a48482247 Cleanup: Compositor: Migrate most input nodes to new socket builder
This migrates most nodes except for the image/render layer nodes.
These nodes require dynamic sockets so their implementation will be more involved.
2021-09-28 18:00:14 -04:00
960b21e1d7 Cleanup: sort cmake file lists 2021-09-29 07:30:34 +10:00
6dceaafe5a Cleanup: trailing space, newlines at EOF 2021-09-29 07:30:34 +10:00
b524153d61 Cleanup: use C comments for plain text 2021-09-29 07:30:34 +10:00
79290f5160 Cleanup: spelling in comments 2021-09-29 07:29:15 +10:00
efe3a13b55 Cleanup: Removed redundant if macro 2021-09-28 21:57:42 +01:00
9f0a3a99ab Geometry Nodes: Fields version of attribute proximity node
Add a fields-aware implementation of the attribute proximity node.
The Source position is an implicit position field, but can be
connected with a position input node with alterations before use.
The target input and mode function the same as the original node.

Patch by Johnny Matthews with edits from Hans Goudey (@HooglyBoogly).

Differential Revision: https://developer.blender.org/D12635
2021-09-28 15:21:36 -05:00
283d76a70d Compositor: Full frame Glare node
Part of T88150.
2021-09-28 22:00:17 +02:00
0830211c95 Cleanup: Remove XRange and YRange in Compositor
Mostly unused and originally meant for areas with positive values.
With canvas compositing areas position may be negative.
2021-09-28 22:00:17 +02:00
f84fb12f5d Compositor: Add support for canvas compositing
This commit adds functionality for operations that require pixel
translation or resizing on "Full Frame" mode, allowing to adjust
their canvas. It fixes most cropping issues in translate, scale,
rotate and transform nodes by adjusting their canvas to the result,
instead of the input canvas.

Operations output buffer is still always on (0,0) position for
easier image algorithm implementation, even when the
canvas is not.

Current limitations (will be addressed on bcon2):
- Displayed translation in Viewer node is limited to 6000px.
- When scaling up the canvas size is limited to the
 scene resolution size x 1.5 . From that point it crops.

If none of these limitations are hit, the Viewer node displays
the full input with any translation.

Differential Revision: https://developer.blender.org/D12466
2021-09-28 22:00:17 +02:00
76377f0176 Compositor: Replace resolution concept by canvas
This is a code refactor in preparation of supporting canvas
compositing. See {D12466}.

No functional changes, all canvases are at (0,0) position matching
tiled implementation.

Differential Revision: https://developer.blender.org/D12465
2021-09-28 22:00:16 +02:00
2ecd963d87 Fix error in previous commit
`v_other` -> `v_step`
2021-09-28 16:57:49 -03:00
5cdb2aadfc Fix flag wrongly set in 'BM_face_split_edgenet_connect_islands'
Sometimes the `use_partial_connect` option could trigger the assert:
```
BLI_assert(!BM_elem_flag_test(l_iter->v, VERT_NOT_IN_STACK));
```

This can happen when `v_delimit->e` is not part of edgenet, so `v_other` will not have the flag.
2021-09-28 16:54:23 -03:00
Aaron Carlisle
c7a7c3f5e5 Cleanup: convert compositor nodes to c++
- Many cleanups of to use list base
- Some variable changes

These change is needed to migrate to the new socket builder API

Reviewed By: manzanilla

Differential Revision: https://developer.blender.org/D12366
2021-09-28 15:30:23 -04:00
87e315c237 Cleanup: Sort node types alphabetically 2021-09-28 14:20:29 -05:00
Johnny Matthews
85aac0ef6a Geometry Nodes: Field version of curve reverse node
The updated version has a selection input as a field
and does not realize instances implicitly.

Differential Revision: https://developer.blender.org/D12506
2021-09-28 13:53:20 -05:00
cc653c9b02 Fix potential render tests error with invalid utf-8 characters
In general should not happen, but better to report the actual error instead
of the Python test code failing.
2021-09-28 20:50:38 +02:00
95fca22bfe Geometry Nodes: Remove experimental option for fields
This enables fields as the official workflow for geometry nodes.
While many features are converted to use fields rather than the old
attribute workflow, many are not yet converted. In that case, the
unconverted nodes are still accessible with an experimental option.
In the coming weeks the rest of the nodes will be converted.

Differential Revision: https://developer.blender.org/D12672
2021-09-28 13:22:52 -05:00
86ec9d79ec Fix build without Cycles HIP device 2021-09-28 20:00:55 +02:00
e45ffce5fa Geometry Nodes: Use factor slider for distribution density factor
Though the factor isn't so useful to adjust by itself, and is mostly
useful when used with a field connected, the slider from 0 to 1 can
help to make it clear that it's just used as a multiplier for the max
density after distribution.

Differential Revision: https://developer.blender.org/D12654
2021-09-28 12:44:50 -05:00
Erik Abrahamsson
faedfd5740 Fix VS2017 compile error in String to Curves node
Because of a bug in VS2017 codecvt is replaced with Blender
BLI functions to convert from UTF8 to UTF32.

Differential Revision: https://developer.blender.org/D12655
2021-09-28 12:37:56 -05:00
Brian Savery
044a77352f Cycles: add HIP device support for AMD GPUs
NOTE: this feature is not ready for user testing, and not yet enabled in daily
builds. It is being merged now for easier collaboration on development.

HIP is a heterogenous compute interface allowing C++ code to be executed on
GPUs similar to CUDA. It is intended to bring back AMD GPU rendering support
on Windows and Linux.

https://github.com/ROCm-Developer-Tools/HIP.

As of the time of writing, it should compile and run on Linux with existing
HIP compilers and driver runtimes. Publicly available compilers and drivers
for Windows will come later.

See task T91571 for more details on the current status and work remaining
to be done.

Credits:

Sayak Biswas (AMD)
Arya Rafii (AMD)
Brian Savery (AMD)

Differential Revision: https://developer.blender.org/D12578
2021-09-28 19:18:55 +02:00
262b211856 Geometry Nodes: Mesh Point Cloud Conversion Nodes
This commit adds nodes to do direct conversion between meshes and point
clouds in geometry nodes. The conversion from mesh to points is helpful
to instance once per face, or once per edge, which was previously only
possibly with ugly work-arounds. Fields can be evaluated on the mesh
to pass them to the points with the attribute capture node.

The other conversion, point cloud to mesh vertices, is a bit less
obvious, though it is still a common request from users. It's helpful
for flexibility when passing data around, better visualization in the
viewport (and in the future, cycles), and the simplicity of points.

This is a step towards T91754, where point clouds are currently
combined with meshes when outputing to the next modifier after geometry
nodes. Since we're removing the implicit behavior for realizing
instances, it feels natural to use an explicit node to convert points
to vertices too.

Differential Revision: https://developer.blender.org/D12657
2021-09-28 12:14:13 -05:00
797064544e Geometry Nodes: Only show attribute toggle for field inputs
Change the toggle to switch between an attribute and a single value to
only display for inputs that are fields, as determined statically by
the field inferencing added in rB61f3d4eb7c7db7. This means the field
inferencing must be calculated on file load, since it's used in the UI.

Differential Revision: https://developer.blender.org/D12623
2021-09-28 12:05:42 -05:00
44e4f077a9 Geometry Nodes: Run nodes once on unique instance data
As described in T91672, often it can be much more efficient to run each
node only on the unique geometry of the instances, rather than realizing
all instances and potentially processing redundant data. Sometimes the
performance difference can be completely smooth vs. completely unusable.

Geometry nodes used to hide that choice from users by always realizing
instances, but recently we have decided to expose it. So this commit
makes nodes run once per unique reference in the entire tree of nested
instances in their input geometries, continuing the work started in
rB0559971ab377 and rBf94164d89629f0d2. For the old behavior, a realize
instances node can be added before the nodes, which is done in the
versioning code.

Differential Revision: https://developer.blender.org/D12656
2021-09-28 11:36:28 -05:00
b32b38b380 Fix T89400: Possible to delete objects used by overrides of collections.
This should not be allowed in general, added some initial call to check
when user is allowed to delete a data to search for mandatory override
usages...
2021-09-28 18:30:33 +02:00
f35ea668a1 Geometry Nodes: Move more nodes to legacy
- Curve to Points: Needs output sockets
- Curve Endpoitns: Needs the same output sockets
- Edge Split: Should have a selection input instead
- Subdivision Surface: Should not use "crease" implicitly
All new versions of these nodes should also not implicitly
realize instances.
2021-09-28 11:03:12 -05:00
e694165123 VSE: fix versioning code to the new maximum zoom level (128)
Since we bumped the number of channels to 128, I forgot to doversion the
editors. So new files (new editors) would have this right, but not
existing files.

Fixup to: 8fecc2a852
2021-09-28 17:58:41 +02:00
6ee2f2da96 Cleanup: asset catalog, remove obsolete TODO
No functional changes.
2021-09-28 17:47:34 +02:00
10d926cd4a Cleanup: asset catalogs, move file header definition to constant
Define the standard catalog definition file header in a constant,
separating it from the function that writes the entire file.

No functional changes.
2021-09-28 17:47:34 +02:00
3acf3e9e2f Geometry Nodes: don't realize instances in Instance on Points node
Part of T91672.
2021-09-28 17:46:32 +02:00
330a04d7c7 Fix T91393: Duplicating an action with python crashes Blender.
Own mistake when making NLA overridable, instead of assuming things
about the ID owner of the animation data being processed, properly
return and use the one found by `ED_actedit_animdata_from_context`.
2021-09-28 17:41:40 +02:00
53fa4801a0 Fix: Fluid/Cloth/DynamicPaint: Only share pointcaches in CoW case.
Particle copying code was already properly sharing pointcache between
orig data and its copy only when `LIB_ID_COPY_SET_COPIED_ON_WRITE` is
set, do the same for the other point cache users.

Using `LIB_ID_CREATE_NO_MAIN` here is waaaaaaay to much wide scope for
such a dangerous/advanced behavior, that kind of things has to be
strictly restricted in scope.
2021-09-28 17:41:40 +02:00
34ba6968b2 Cleanup: asset catalog service, remove obsolete write_to_disk function
Remove `AssetCatalogService::write_to_disk()` function. It has been
superseded by `write_to_disk_on_blendfile_save()`; the handful of test
functions that called the old function have been adjusted to use the
new one.

No functional changes to Blender itself.
2021-09-28 17:32:58 +02:00
f17ca53cdd Fix wrong update with shadow catcher and transparent film
This change fixes an issue when scene has a shadow catcher and film is
configured to be transparent. Starting viewport render and making the
background non-transparent will cause bad memory access (wrong render
and possibly crash).

Film passes depends on transparency of background, so check for this.

Demo file: F10650585

Differential Revision: https://developer.blender.org/D12666
2021-09-28 17:06:16 +02:00
640c4ace0b Cycles: Disable tile-level denoising
Only do denoising on the full-frame result. Saves render time.

Can re-consider in the future when/if we'll want to support
denoising during rendering (similar to viewport) to allow artists
to stop rendering when they see image to be good enough. Until
there is a design for that workflow stick to a more time efficient
rendering.

Differential Revision: https://developer.blender.org/D12662
2021-09-28 17:05:47 +02:00
ff7e67afd5 Geometry Nodes: Dashed lines for function flow
Use dashes to represent the function flow (while keeping continuous
lines for the data-flow).

It is important to tell both flows apart (the data and the function
 flow). The sockets help with that, the noodles help this further.

The "data flow" is evaluated at every single node. A user can inspect
the output sockets of those nodes and have a glimpse at their values.

The "function flow" (nodes) however is only evaluated in the geometry
nodes. The noodles are not transporting data in the same sense of the
"data flow". All that can be inspected are the attributes the functions
depend on.

Having this clearly communicated should help users to inspect the
nodetrees, read and understand the different flows in the same tree.

---

Known limitations:

At the moment the dash lines are not equidistant:

* It would be nice to get the "uv.x" to be resampled for the bezier curve
so the dashes are equally distributed in the curve.

* Using distance between the P3 and P0 instead of the real bezier curve
length seems to be fine.

---

Full disclaimer:

Changes with that much of a visual impact tend to be controversial. So
far the main feedback is that dashed lines can be associated to broken
link, and that there are better ways to represent the flows (or
different information that should be visually represented).

I'm fully aware of that. However dashed lines are already used in the
viewport and outliner to indicate (hierarchical) relation. Besides,
other approaches (double-lines, having the data flow to be more
distinct, ...) didn't pan out in the end (or didn't look as good as
this).

---

Impact in other editors:

The compositor uses mostly a "data flow" nodetree, so no change is
expected there.

The shader nodetree is one that could but doesn't have to change its
visual language.

The shader nodetree uses mostly "function flow" with some "data flow" nodes.
One can argue that it should be adapted to follow the
same pattern as geometry nodes (with the new noodles and the diamond
sockets). Oh the other hand, a shader nodetree has a single context.
When a node depends on the "UV", there is only one UV at a time for the
entire nodetree. So it can also be treated as a psedo "data flow"
nodetree if we want to avoid too many changes in other parts of Blender.

Differential Revision: https://developer.blender.org/D12602
2021-09-28 17:03:03 +02:00
728ae33f37 Cycles: Improve handling of tile file error
Expose them to the interface, and stop rendering as soon as possible.

Differential Revision: https://developer.blender.org/D12617
2021-09-28 16:58:27 +02:00
52a702468a Asset Catalog Service: add function to change catalog path
Add `AssetCatalogService::update_catalog_path()` to change the catalog
path of the given catalog, and also change the path of all the catalogs
contained within the given catalog.

Rebuilds the tree structure for the UI, but does not save the new catalog
definitions to disk.

No user-facing changes, just backend preparation for UI work.
2021-09-28 16:09:12 +02:00
d2004326a1 Geometry Nodes: remove empty mesh component in distribute node output 2021-09-28 15:52:31 +02:00
3e78c9e5bb Fix T91766: NLA Editor - Segmentation fault on strip resize
NLA and Dope Sheet use a specific transform operation to scale.

Unlike the conventional resize operation, `TIME_SCALE` operates on `td->val`.

This is a bit outside the convention of transform operators.

The expected thing in this case would be to work in `td->loc` and use the conventional resize operator.

But for now, to fix the problem, use `td->loc` in the `TIME_SCALE` operation.

This commit also brings a cleanup in the style of some comments and removing unnecessary `memset`.
2021-09-28 10:24:02 -03:00
3674347849 Assets: Clear Asset operator variants for clearing/setting Fake User
The Clear Asset operator (`ASSET_OT_clear`) now clears the Fake User.
This makes it symmetrical with the Mark Asset (`ASSET_OT_mark`)
operator, which sets Fake User to ensure assets are always saved to
disk.

Clear Asset now also has a `set_fake_user` boolean option, which allows
users to Clear Asset and set Fake User in one go.

The asset browser now shows these options in the context menu:
- Clear Asset: also clears Fake User. This makes it possible to actually
  remove assets from the blend file without leaving the Asset Browser.
- Clear Asset (Set Fake User): keeps the Fake User bit set. This makes
  it possible to "hide" the asset from the asset browser, without
  loosing the actual data.

Internally, the `ED_asset_clear_id(id)` function now always clears the
Fake User bit. If it was intended that this bit was kept set, it's up to
the caller to explicitly call `id_fake_user_set(id)` afterwards.

Manifest Task: T90844

Reviewed By: Severin

Differential Revision: https://developer.blender.org/D12663
2021-09-28 15:04:55 +02:00
73b2ecb297 Cleanup: typo in comment
Noticed by @david_black in D12392, thx!
2021-09-28 14:37:06 +02:00
Vitor Boschi da Silva
9490db1ad2 Cleanup: remove unused variable
As the title says

Reviewed By: lichtwerk, campbellbarton

Differential Revision: https://developer.blender.org/D12665
2021-09-28 14:29:02 +02:00
6a745e54f6 Cleanup: remove incorrect assert
The method works perfectly fine when `resource` is empty.
2021-09-28 13:32:22 +02:00
5d160dec3b Geometry Nodes: move legacy nodes to separate folder
Previously, we were moving them one by one. It's a lot easier
to just move all files at the same time.
2021-09-28 11:31:46 +02:00
b3431a8846 Fix Drivers Editor showing playhead on the X Axis
Currently the Drivers Editor shows this (the blue thing can be dragged
to change frame):
{F10647661}

But the Drivers Editors X axis is the output of the driver [which can be
further tweaked by the curve] not time(frame).
So it seems better to not mix them here, it is just confusing to have
two different units on one axis.
Especially since what we really want to look at in X (the drivers output
value) can be in a totally unrelated range compared to frames, so e.g.
we might be interested in a drivers range from 0.0 to 1.0 and a
framerange of 100 to 200, so putting this on one axis just does not make
sense. Better to use a separate timeline for this.

Note 2.79 also did not do this.

Maniphest Tasks: T91157

Differential Revision: https://developer.blender.org/D12392
2021-09-28 11:14:44 +02:00
6f29801f1b Fix Drivers Editor not hiding vertical part of cursor
When "Show Cursor" is unchecked, the Drivers Editor would still display
the vertical line representing the cursor x.

Probably overseen in {rB65072499c65a} (historically the vertical line
could represent either the current frame of the cursor X in drawing, but
this is now much more separate).

There is no point in seeing part of the cursor in the Drivers Editor if
this is disabled.

Also correct outdated comments.

ref. T91157

Maniphest Tasks: T91157

Differential Revision: https://developer.blender.org/D12391
2021-09-28 11:14:44 +02:00
b91946780c Path util: BLI_path_contains() case-insensitive on Windows
Make `BLI_path_contains()` case-insensitive on Windows. This behaviour
is dependent on the platform Blender is running on, like the rest of
BLI_path, and not on the style of paths (Windows-style paths will be
treated case-sensitively when Blender is running on Linux/macOS).
2021-09-28 11:05:45 +02:00
741fa8180c Fix T91679: Crash when saving bordered render as multilayer exr
The related issue which is fixed by this change is the missing noisy
image pass when denoising and border render is used,

Need to allocate passes after the passes has been copied from the
original render result.
2021-09-28 10:49:01 +02:00
e5ff9f3615 Cleanup: Move VSE channels check into own util function
Differential Revision: https://developer.blender.org/D12661
2021-09-28 10:44:39 +02:00
a64782b133 VSE: Implement sanity check for files with more channels than supported
This is a follow up to 8fecc2a852.

This makes sure future .blend files that have more channels than the
limit won't break Blender.

It can be backported to LTS.

This is part of https://developer.blender.org/D12645

Differential Revision: https://developer.blender.org/D12648
2021-09-28 10:23:13 +02:00
7cd43a9d28 Fix: field inferencing fails when there are undefined nodes 2021-09-28 10:19:16 +02:00
def8fd6330 Cleanup: support moving InstanceReference 2021-09-28 10:17:49 +02:00
e7b9423623 Geometry Nodes: multi-threading when modifying multiple geometry sets
Differential Revision: https://developer.blender.org/D12652
2021-09-28 10:17:00 +02:00
c7d94a7827 UI: avoid excessive padding for labels in headers
Labels in headers reserved space for an icon even when no icon was used.

This is caused by the shared function ui_text_icon_width adding 1.5x
a buttons X-units width the the width of the string.

Menu buttons detected this and subtracted the extra padding.

Instead of adding the same workaround for labels,
add ui_text_icon_width_ex that takes a padding argument.

Add presets for 'default', 'compact' and 'none' to avoid duplicating
padding values.

This allows removal of hard-coded label scaling for the add-object tool.
2021-09-28 14:36:52 +10:00
986d60490c Asset Browser: Allow World assets to be drag/dropped onto the viewport
While World data has always been able to be marked as an asset, there
was no way to actually use them from the asset browser. This change
allows users to drag-drop world assets onto the Viewport and have them
appended/linked to their scene.

Differential Revision: https://developer.blender.org/D12566
2021-09-27 21:00:17 -07:00
c53ffda8a4 Cleanup: Fix incorrect comments 2021-09-27 13:29:53 -05:00
f94164d896 Geometry Nodes: Do not realize instances in the material assign node
Only run the node once for every unique geometry set in the input's
instance heirarchy. This can massively improve performance when
there are many instances, but it will mean that the result is the same
for every instance. For the previous behavior, a "Realize Instances"
node can be used before this one.

This node can be changed without versioning since the old material
assign node was already deprecated and replaced.
2021-09-27 13:22:44 -05:00
5d70a4d7ee Geometry Nodes: Move output attribute names to a subpanel
In a sub-panel it will be clearer that they are outputs, since they
just look like more inputs now. Unfortunately it is not possible to
make sub-panels display conditionally currently, so the output
sub-panel will always be visible whether or not it is empty.

Differential Revision: https://developer.blender.org/D12653
2021-09-27 13:04:58 -05:00
e6aabcae14 Fix part of T91516: Cycles not rendering geometry nodes instances
Part of the fix is by Jacques. This fixes the most obvious case, but it's
still not clear how to deal with non-mesh geometry instances or how to handle
motion blur for such instances.
2021-09-27 19:49:43 +02:00
50b7253257 Cleanup: fix (harmless) uninitialized variable usage 2021-09-27 19:49:43 +02:00
8da23fd5aa Constraints: change default Stretch To rotation type to Swing.
As also explained in D6134, in most case of Stretch To usage in
rigs, it is desirable to use swing rotation, either via the old
method of pairing the constraint with Damped Track, or via the
Swing rotation type introduced in 2.82. This is for instance true
for all usages of the constraint in Rigify.

The reason can be understood by realizing that unlike order-
dependent euler rotations, swing is not biased to an axis, and
isn't affected by gimbal lock effects at merely 90 degrees
of rotation (it has only one singularity at 180 degrees).

Thus it makes sense to change the default for newly created
constraints to the Swing mode. This has no backward compatibility
concerns except for old tutorials and rig generation scripts.

Differential Revision: https://developer.blender.org/D12643
2021-09-27 20:45:03 +03:00
8967bcb755 Update RNA to user manual url mappings 2021-09-27 13:42:41 -04:00
847d355cab File/Asset Browser: Don't deselect other items when dragging
Basically this enables the select-tweaking behavior as per the
guidelines:
https://wiki.blender.org/wiki/Human_Interface_Guidelines/Selection#Select-tweaking.

We use this in most other other editors that allow selecting and
dragging multiple items. But besides the consistency improvement, this
is important if we want to support dragging multiple assets (or files)
in future. We want to support this at least for dragging multiple assets
into an asset catalog for the upcoming asset catalog UI.
2021-09-27 18:52:16 +02:00
c76ccd85be Cleanup: incorrect null check in asset library
Found by clang tidy (P2439).
2021-09-27 18:42:19 +02:00
11bfbc3337 Fix: Incorrect node socket name after recent refactor
Caused by rBc99cb814520480379
2021-09-27 11:21:33 -05:00
c75c08a737 Geometry Nodes: Distribute points once per instance reference
With this commit, the distribute points on faces node runs only
once for every unique mesh in its input. That means if there are
100 instances of the same mesh, it will only run once.

This basically reverts rB84a4f2ae68d408301. The optimization there
didn't end up being worth it in the end, since it complicates code
quite a lot. It's also incompatible with this method of dealing with
instances, and it breaks field evaluation for instances, where we would
have to make sure to handle each instance transform properly otherwise,
evaluating the field separately for every instance.

Differential Revision: https://developer.blender.org/D12630
2021-09-27 11:16:25 -05:00
efa9667c09 Cleanup: Asset catalogs, fix clang-tidy warning
Change `auto &catalog` to `const auto &catalog`.

No functional changes.
2021-09-27 18:14:44 +02:00
10061ee18a Asset Catalogs: write catalogs to disk when saving the blend file
The Asset Catalog Definition File is now saved whenever the blend file
is saved. The location of the CDF depends on where the blend file is
saved, and whether previously a CDF was already loaded, according to the
following rules. The first matching rule wins:

1. Already loaded a CDF from disk? -> Always write to that file.
2. The directory containing the blend file has a
   `blender_assets.cats.txt` file? -> Merge with & write to that file.
3. The directory containing the blend file is part of an asset library,
   as per the user's preferences? -> Merge with & write to
   `${ASSET_LIBRARY_ROOT}/blender_assets.cats.txt`
4. Create a new file `blender_assets.cats.txt` next to the blend file.
2021-09-27 18:14:21 +02:00
90aa0a5256 BKE Preferences: find asset library containing a path
Add `BKE_preferences_asset_library_containing_path(&U, some_path)` that
finds the asset library that contains the given path.

This is a simple linear search, returning the first asset library that
matches. There is no smartness when it comes to nested asset libraries
(like returning the library with the best-matching path), although this
could be a useful feature to add later.
2021-09-27 18:10:47 +02:00
aafbe111fc BLI Path: add function BLI_path_contains()
Add function `BLI_path_contains(container, containee)` that returns true
if and only `container` contains `containee`.

Paths are normalised and converted to native path separators before
comparing. Relative paths are *not* made absolute, to simplify the
function call; if this is necessary the caller has to do this conversion
first.
2021-09-27 18:10:47 +02:00
6578db57cd Fix T91691: Selecting "Remove unused slots" in Materials panel removes slots that are assigned to particle systems/hair.
`BKE_object_material_slot_used` would only check obdata usages, but
particle settings can also (weirdly enough) use objects' material slots.

So now, as its name suggests, `BKE_object_material_slot_used` does take
an object as parameter, and also checks for potential slot usage from
psys in the object.
2021-09-27 18:09:20 +02:00
824733ea47 Assets: Additions/fixes to the catalog system in preparation for the UI
* Fixes missing update of the catalog tree when adding catalogs.
* Adds iterators for the catalogs, needed for UI code.
* Store catalog ID in the catalog tree items, needed for UI code.
* Other smaller API additions for the UI.
* Improve comments and smaller cleanups.

New functions are covered with unit tests.

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

Reviewed by: Sybren Stüvel
2021-09-27 17:49:31 +02:00
5bea5e25d5 Fix T91728: Cycles render artifacts with motion blur and object attributes 2021-09-27 17:40:03 +02:00
0559971ab3 Geometry Nodes: add utility to process all instances separately
This adds a new `GeometrySet::modify_geometry_sets` method that can be
used to update each sub-geometry-set separately without making any
instances real.

Differential Revision: https://developer.blender.org/D12650
2021-09-27 17:35:45 +02:00
2189dfd6e2 Cycles: Rework OptiX visibility flags handling
Before the visibility test against the visibility flags was performed in an any-hit program in OptiX
(called `__anyhit__kernel_optix_visibility_test`), which was using the `__prim_visibility` array.
This is not entirely correct however, since `__prim_visibility` is filled with the merged visibility
flags of all objects that reference that primitive, so if one object uses different visibility flags
than another object, but they both are instances of the same geometry, they would appear the same
way. The reason that the any-hit program was used rather than the OptiX instance visibility mask is
that the latter is currently limited to 8 bits only, which is not sufficient to contain all Cycles
visibility flags (12 bits).

To mostly fix the problem with multiple instances and different visibility flags, I changed things to
use the OptiX instance visibility mask for a subset of the Cycles visibility flags (`PATH_RAY_CAMERA`
to `PATH_RAY_VOLUME_SCATTER`, which fit into 8 bits) and only fall back to the visibility test any-hit
program if that isn't enough (e.g. the ray visibility mask exceeds 8 bits or when using the built-in
curves from OptiX, since the any-hit program is then also used to skip the curve endcaps).

This may also improve performance in some cases, since by default OptiX can now perform the normal
scene intersection trace calls entirely on RT cores without having to jump back to the SM on every
hit to execute the any-hit program.

Fixes T89801

Differential Revision: https://developer.blender.org/D12604
2021-09-27 17:12:43 +02:00
7270ba011c Fix two issues with recent new Append code.
* ID pointer returned by `wm_file_link_append_datablock_ex` was
  improperly extracted from `WMLinkAppendDataItem` before append step.

* Code deleting linked IDs when their local matching version was re-used
  did not properly clear `LIB_TAG_DOIT` beforehand.
2021-09-27 16:36:07 +02:00
4a0ddeb62b Nodes: Change wire color to increase contrast
If the theme used by the user did not touch the wire or the wire outline
colors this will update them as well.

This was supposed to be a part of a bigger UI theme change for 3.0. But
it was expedited because of the recent change in line thickness for the
noodles (2bd0205215).

Theme change by Pablo Vazquez.

Differential Revision: https://developer.blender.org/D12649
2021-09-27 16:09:40 +02:00
3d2ce25afd Geometry Nodes: support creating new attributes in modifier
This patch allows passing a field to the modifier as output. In the
modifier, the user can choose an attribute name. The attribute
will be filled with values computed by the field. This only works
for realized mesh/curve/point data. As mentioned in T91376, the
output domain is selected in the node group itself. We might want
to add this functionality to the modifier later as well, but not now.

Differential Revision: https://developer.blender.org/D12644
2021-09-27 15:39:47 +02:00
43167a2c25 Fix T90570: Constraint validity not updated with library overrides.
For some reason was assuming setting a property in RNA would call its
update callback if any, but this actually needs to be done separately.

So add this call to `rna_property_override_operation_apply`.
2021-09-27 15:33:58 +02:00
5949d598bc RNA: Make is clear that Scene parameter of update callback may be NULL.
There are cases where there is no way to ensure we do have/know about an
active scene. Further more, this should not be required to perform
'real' updates on data, only to perform additional special handling in
current scene (mostly related to editing tools, UI, etc.).

This pointer is actually almost never used in practice, and half of its current
 usages are fairly close to abuse of the system (like calls to
`ED_gpencil_tag_scene_gpencil` or `BKE_rigidbody_cache_reset`).

This commit ensures that the few places using this 'active scene' pointer are
safely handling the `NULL` case, and clearly document the fact that a
NULL scene pointer is valid.
2021-09-27 15:33:58 +02:00
b077f0684e RNA: Fix bad usages of scene pointer in Update callbacks.
Scene passed to the update callback is the active scene it //may// not
be that actual ID owner of the affected data (although in practice it
should always be currently).
2021-09-27 15:33:58 +02:00
a6b53ef994 Cycles: print name of kernels on errors in CUDA queue, for debugging 2021-09-27 15:24:12 +02:00
2bd0205215 Geometry Nodes: make field links thinner than other links
This makes it easier to spot which links contain fields and which
contain data. Actually, the patch makes all other links a bit thicker.
However, with soon-to-be-implemented theme changes, the
perceived thickness will be the same as before.

This is part of T91563.

Differential Revision: https://developer.blender.org/D12646
2021-09-27 15:10:28 +02:00
8fecc2a852 Increase VSE strip channels limit from 32 to 128
The original limit dates back from 2002 when Blender went open source.
After that many years some productions (e.g., Sprite Fright) are already
experiencing limitations for complex edits.

The future plans is to support an initial shorter (2?) number of
channels with support to "unlimited" channels.

Finally, I'm bumping the minimum file requirement since files with more
than 32 channels won't work well in old Blender versions.

In a future commit I will implement a sanitization so that we only read (and write)
128 channels. Making sure future changes of this number won't corrupt Blender.

Differential Revision: https://developer.blender.org/D12645
2021-09-27 14:58:03 +02:00
Peter Fog
0419c74ae8 VSE: Clamp resulting frame in multiply mode
The clamp added will ensure immediate speed direction change on
changing to/from positive/negative speed factor when using the Speed
effect strip's Multiply mode.

Reviewed By: ISS, sergey

Differential Revision: https://developer.blender.org/D12462
2021-09-27 14:41:56 +02:00
4a562f5077 Fix T91714: Cycles direct/indirect clamp distinction not working correctly 2021-09-27 14:25:22 +02:00
2a0db195c9 Fix viewport roll working wrong
Mistake in own {rB69893ef27c91}.
Was mixing screen on region coordinates.
2021-09-27 14:19:38 +02:00
e87783a5ec Cleanup: spelling in comments 2021-09-27 21:04:34 +10:00
95af9317f0 Cleanup: remove unnecessary use of MEM_SAFE_FREE macro 2021-09-27 21:04:34 +10:00
2c2e1b3d61 Fix T81922: Pose bones F-Curves hidden for unselected objects
Whilst in pose-mode, the selection filter only includes other objects in
pose-mode instead of the object selection.

This makes sense as the selection of the pose bones what the user as
acting on in the 3D view.
The object selection only makes sense to use in object mode.

Reviewed By: sybren

Maniphest Tasks: T81922

Ref D12494
2021-09-27 21:04:34 +10:00
32ffb858d6 Keymap: resolve conflict with use_alt_cursor/Ctrl-LMB to add/extrude
While the option allows tools be be activated on press instead of tweak,
this meant box-select was catching Ctrl-LMB which is also used for
add/extrude in edit mode.

Resolve this by always using tweak for selection tools,
only supporting activation on press for other tools.

Note that this doesn't impact the default configuration.
2021-09-27 21:04:34 +10:00
c618075541 Cleanup: make format 2021-09-27 12:43:54 +02:00
a13b9d20b5 Cleanup: Move asset library remove function next to add function
Better to keep such related operations close together in code.
2021-09-27 12:32:21 +02:00
d90f542b04 Cleanup: Remove function declaration without definition
There is no function definition for this declaration. Instead there is
`BKE_preferences_asset_library_remove()`.
2021-09-27 12:31:06 +02:00
5d5504d8a4 3DView: ability to cancel out of viewport roll
This adds the ability to cancel out of the roll using ESC or RMB
(which is not common for viewops -- but makes sense in the case of roll
I think). This resets the view as well as potential locked cameras to
the original orientations (but does not remove potential autokeys --
which no transform does on cancel btw.)

Maniphest Tasks: T89883

Differential Revision: https://developer.blender.org/D12582
2021-09-27 11:54:25 +02:00
69893ef27c 3DView: Use "real" angle for viewport roll
Since its introduction in {rB5c569d227b64}, the view roll was based on
horizontal movement only. Using a "real" angle not only feels more
natural but also has the benefit of getting more precission the further
away from the center you are (just like regular rotation, brush/stencil
rotation etc.). A similar thing has already been implemented in the
Grease Pencil Tools Addon, now make the blender standard roll the same.

Since this is not using the transform system, we are still lacking a
line in the viewport (this could be added but since this is always based
on the center of the view we dont necessarily need this), as well as the
additional Shift-extra-precission behavior.

Fixes T89883

Maniphest Tasks: T89883

Differential Revision: https://developer.blender.org/D12582
2021-09-27 11:53:26 +02:00
8dcddbcc07 Fix T91711: Blender 3.0 - The Rain demo scene breaks (Proxy to Override auto conversion).
Proxy conversion is a fairly particular case of liboverride creation, in
which remapping all local usages of linked data probably makes more
sense, rather than only doing so whitin the overridden 'group' of IDs.
2021-09-27 11:11:43 +02:00
30ef197c7b Kernel: allow unregistering BKE callback functions
Introduce `BKE_callback_remove()`, which undoes the effect of
`BKE_callback_add()`. It also respects `funcstore->alloc` by freeing the
removed `funcstore` when needed.

This allows for shorter-lived objects in memory to unregister their
callbacks at the end of their lifespan.

`BKE_callback_global_finalize()` has been adjusted so that the
responsibility "remove a callback" is given to one function only.

Reviewed by: campbellbarton

Differential Revision: https://developer.blender.org/D12625
2021-09-27 10:57:23 +02:00
617954c143 Geometry Nodes: new Instance on Points node
This adds a new Instance on Points node that is a replacement
for the old Point Instance node. Contrary to the old node,
it does not have a mode to instance objects or collections
directly. Instead, the node has to be used with an Object/
Collection Info to achieve the same effect.

Rotation and scale of the instances can be adjusted in the node
directly or can be controlled with a field to get some variation
between instances.

The node supports placing different instances on different points.
The user has control over which instance is placed on which point
using an Instance Index input. If that functionality is used, the
Instance Geometry has to contain multiple instances that can are
instanced separately.

Differential Revision: https://developer.blender.org/D12478
2021-09-27 10:17:17 +02:00
547f7d23ca Geometry Nodes: support outputting collection children as instances
This adds two new input sockets to the Collection Info node:
* `Separate Children`: When turned off, the entire collection is output as a single
  collection instance (same behavior as before). When turned on, each child of
  the collection is output as a separate instance (children can be objects and collections).
  Toggling this input should not change the visual transforms of the output geometry.
* `Reset Children`: Only used when `Separate Children` is on. When used, the transforms
  of the instances are reset to the origin. This is useful when one wants to e.g. instance
  the collection children separately in the upcoming instancing node.

Part of D12478.
2021-09-27 10:17:17 +02:00
William Leeson
f3ace5aa80 Fixes T91632 by stopping the sample correlation between dimensions which was causing rendering artifacts on simple scenes.
Fix T91632: Stops the sample correlation between dimensions which was causing rendering artefacts on simple scenes.

This is done by increasing the amount of jitter the Cranley Patterson Rotation is allowed to add. Also, it uses the y dimension of the of the sample table for 1D sampling which causes further decorrelation between dimensions. As an additional measure the x and y dimensions are swapped randomly to provide further decorrelation.

Maniphest Tasks: T91632

Differential Revision: https://developer.blender.org/D12610
2021-09-27 09:54:37 +02:00
fe49904646 Fix: wrong socket shape in Vector input node 2021-09-27 09:34:17 +02:00
ddb0dc2527 Fix knife tool missing refresh changing the lock axes 2021-09-27 16:28:01 +10:00
10a26d583d Fix knife tool using an invalid event value check
The events value was checked without checking the expected modal state.
2021-09-27 16:28:01 +10:00
Lasse Foster
037e66999a FIX: T91697 Eevee Generated texture coordinates completly missing
This patch fixes Eevee-regression https://developer.blender.org/T91697

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D12634
2021-09-27 08:07:23 +02:00
d2dda0e8b9 Fix T91694: VSE crashes when creating new scene
Crash happened due to NULL dereference. Add NULL checks.
2021-09-27 06:58:07 +02:00
Peter Fog
ad3e5d2bf5 VSE: Expose Zoom to Fit in all display modes
Zoom to Fit is working in all display modes, but was only exposed in
Image mode. This patch exposes it in all Image modes.

Reviewed By: ISS

Differential Revision: https://developer.blender.org/D12632
2021-09-27 04:40:05 +02:00
f9e0981976 Fix T91666: Missing pivot point in VSE
Add pivot point setting for combined timeline and preview mode.
2021-09-27 04:20:37 +02:00
d046a1f2fa Functions: fail early when multi-function throws an exception
Multi-functions are not allowed to throw exceptions that are not
caught in the same multi-function. Previously, it was difficult to
backtrack a crash to a previously thrown exception.
2021-09-26 23:28:14 +02:00
1cd8a438bb Cleanup: simplify field evaluation 2021-09-26 23:28:14 +02:00
88a2b054da Fix T91732: crash in Set Position node on empty mesh 2021-09-26 23:28:14 +02:00
93b36fad68 Knife: Expose XYZ axis locking in modal keymap
A small quality of life improvement that will allow users to change the keys used for axis locking.
2021-09-26 22:18:24 +01:00
80f7bc6d8e LineArt: Smooth tolerance value for chaining.
smooth out jaggy lines with a given threshold. For each point in a stroke, the ones with in a given distance of its previous segment will be removed,
thus "zig-zag" artefacts can be cleaned up.

Reviewed By: Antonio Vazquez (antoniov)

Differential Revision: https://developer.blender.org/D12050
2021-09-26 19:43:12 +08:00
505422220d Cleanup: use override/final for derived classes.
This will help detecting missing API changes. Those keywords were added
on classes which did not already use them. Also added missing
`accepts_object_type()` on NURBS reader.
2021-09-25 09:31:00 +02:00
43394e41a8 Fix Alembic point cloud streaming.
Point clouds are not imported and read anymore. This was caused by an
API change in rB128eb6cbe928e58dfee1c64f340fd8d663134c26 which was not
applied to `AbcPointsReader`. It did not cause a compile error as the
base class as a default implementation for this method.
2021-09-25 09:31:00 +02:00
ab09844be8 Cleanup: typos in code and comments.
No functional changes.
2021-09-25 09:31:00 +02:00
a3027fb094 Fix T91662: VSE Image overlay is drawn for backdrop
Don't draw image overlay in timeline, image manipulation only works in
preview.
2021-09-24 21:18:03 +02:00
b314d3e787 Fix T91639: Cycles crash rendering high resolution images with multiple passes
We were writing large 2048x2048 tiles into EXR files, which appears to cause
integer overflow inside the OpenEXR library when there are multiple passes. Now
use smaller tiles in the image file, while still rendering large tiles.

This adds the requirement that the render tile size must be a multiple of 128
or be smaller than 128, this is adjusted automatically.
2021-09-24 21:08:14 +02:00
2dd3968335 Geometry Nodes: Add versioning and legacy warning for random float node 2021-09-24 14:06:41 -05:00
Johnny Matthews
536f9eb82e Geometry Nodes: Random Value Node
This node replaces the deprecated Attribute Randomize node, populating
a vector, float, integer or boolean field with random values. Vector,
float, and integer have min/max settings, which are also field aware.
The boolean type has a probability value for controlling what portion
of the output should be true. All four types have a field seed input
which is implicitly driven by the index, otherwise, all values would
be the same "random" value.

The Random Float node is now deprecated like other nodes, since it is
redundant with this node.

Differential Revision: https://developer.blender.org/D12603
2021-09-24 14:03:42 -05:00
c87e6b23be Assets: Read catalogs immediately when loading a library
Until now, the asset catalogs would only show up after all assets from
the library were loaded. Now the catalogs are read first, which makes
them appear pretty much immediately. This makes the UI more responsive
and feel less heavy.

I added a dedicated file-list type for asset libraries now. While not
necessarily needed, I prefer that so asset library specific stuff can be
handled in there.
2021-09-24 20:17:04 +02:00
Erik Abrahamsson
be16794ba1 Geometry Nodes: String to Curves Node
This commit adds a node that generates a text paragraph as curve
instances. The inputs on the node control the overall shape of the
paragraph, and other nodes can be used to move the individual instances
afterwards. To output more than one line, the "Special Characters" node
can be used.

The node outputs instances instead of real geometry so that it doesn't
have to duplicate work for every character afterwards. This is much
more efficient, because all of the curve evaluation and nodes like fill
curve don't have to repeat the same calculation for every instance of
the same character.

In the future, the instances component will support attributes, and the
node can output attribute fields like "Word Index" and "Line Index".

Differential Revision: https://developer.blender.org/D11522
2021-09-24 12:41:49 -05:00
Erik Abrahamsson
5c0017e85a Geometry Nodes: Special string characters node
This patch adds a new node called "Special Characters" with two string
outputs: "Line Break" and "Tab". This is necessary because the newline
character cannot be easily typed with a keyboard, but is necessary for
the string to curve node.

Differential Revision: https://developer.blender.org/D12620
2021-09-24 11:00:21 -05:00
bdb8ee9717 Fix Cycles memory leak in baking, after recent changes 2021-09-24 17:46:34 +02:00
Johnny Matthews
ef45399f3b Nodes: initial support for socket tooltips
This adds initial limited support for socket tooltips. It's limited
in a couple of ways for now:
* Only works when hovering over the socket shape, not when hovering
  over the value in the socket.
* Only works for built-in nodes that already use the new node
  declaration system. This can later be extended to support pynodes.

Those limitations are well worth it for now, given that the
implementation is quite simple and the impact on usability is quite
large. More complex updates to the layout system, that would allow
showing socket tooltips in the nodes, can be done later. With the
current implementation we can at least start writing tooltips for
geometry nodes now.

This commit already adds tooltips for the Cylinder node as an example.

Differential Revision: https://developer.blender.org/D12607
2021-09-24 17:13:40 +02:00
4a2c63f4bd Nodes: hide socket value when input is a field implicitly 2021-09-24 16:42:20 +02:00
90b410fe74 Fix: field evaluation crash when the domain size is zero 2021-09-24 16:42:20 +02:00
25d4de92fa Cleanup: UUID, add some documenting comments
No functional changes.
2021-09-24 16:34:25 +02:00
c0db8e3b41 Fix T91660: Cycles remaining render time does not take into account time limit 2021-09-24 16:34:15 +02:00
585998987a Cycles: some steps towards getting standalone compiling again
Render output and display still need to be rewritten to work with the new
system.
2021-09-24 16:34:14 +02:00
ab8f24811d Cleanup: remove unused device code and includes 2021-09-24 16:34:14 +02:00
9cf593f305 GPencil: Reorganize list of modifiers
As we have a now a new `Modify` column, we move some modifers to this column.
2021-09-24 16:27:58 +02:00
45e432b894 GPencil: Change Proximity distance properties to distance type
This keep consistency with mesh modifer.
2021-09-24 16:16:40 +02:00
ede14b3856 GPencil: Invert weight in Weight Proximity modifier
In meshes modifer the Lowest is 0 and Highest is 1.0 and this was working inverted for grease pencil. Now, it works equals to meshes modifier.

Also changed the tooltip to keep consistency with meshes modifier.
2021-09-24 16:16:40 +02:00
95ec6e4dd3 Geometry Nodes: make index field more reusable
Some inputs will be the index field implicitly, so we want this
class to be available outside of `node_geo_input_index.cc`.
2021-09-24 16:03:07 +02:00
1a1c546124 Fix T91240: Object duplication was duplicating its action twice.
Weird that this was not reported before, this was creating a lot of
extra actions everytime...
2021-09-24 15:25:49 +02:00
e1e380ba38 Asset Catalogs: write catalogs sorted by path & UUID
When writing asset catalog definition files, order the catalogs by
(path, UUID). This ensures that every write produces the same file, playing
nice with versioning / synchronisation systems.
2021-09-24 14:42:48 +02:00
ab9644382d UUID: add less-than operator
Add `operator<` to C++ class to allow lexicographic ordering of UUIDs.

This will be necessary when writing asset catalogs to disk in a predictable
(i.e. ordered) manner.
2021-09-24 14:42:48 +02:00
2b9ca0f112 Codestyle: Add brackets around body of if statements. 2021-09-24 13:38:03 +02:00
7e904139a3 Nodes: make dot in socket shape circular
Previously, it was a diamond shape when the overall
shape was a diamond.
2021-09-24 13:33:28 +02:00
2b5733ff01 Fix T91192: Context.copy() crashes on file load
The `ui_list` lookup from 87c1c8112f
didn't account for the region being unset.
2021-09-24 21:10:02 +10:00
dfe01628b0 Cleanup: old-style-declaration warning 2021-09-24 21:10:01 +10:00
e8c6e32348 Asset Catalogs: fix trailing slash test case
The "path with trailing slash" test catalog was using the same path as
another catalog, which meant it was ignored after doing the path
cleanup. It's now different in the test file in SVN, so it'll actually
show up in the test.
2021-09-24 12:53:14 +02:00
59387aabe8 LibOverride: deprecate Proxies: Remove 'Make Proxy' operator. 2021-09-24 12:40:04 +02:00
501b0190d6 LibOverride: Deprecate Proxies: Add auto-conversion on file load.
This commit also add an experimental userPreferences to prevent proxies
conversions on file load, and reporting for amount of coverted proxies
(and possible issues).

Note that potentially linked proxies from other libraries are not
hamdled here (this feature seems to be broken anyway in master
currently?).
2021-09-24 12:40:04 +02:00
cdcdd2c479 LibOverride: Add utils to convert all proxies to overrides. 2021-09-24 12:40:03 +02:00
e7ae2840a5 Geometry Nodes: new Distribute Points on Faces node
This adds a replacement for the deprecated Point Distribute node.

Arguments for the name change can be found in T91155.
Descriptions of the sockets are available in D12536.

Thanks to Jarrett Johnson for the initial patch!

Differential Revision: https://developer.blender.org/D12536
2021-09-24 11:50:02 +02:00
d8a5b768f0 BLI: expose more noise hash functions in header
This is a follow up of the previous commit.
These functions are useful for other areas of Blender as well.
2021-09-24 11:24:15 +02:00
bc27bafa54 BLI: make noise hash functions available in header 2021-09-24 10:55:23 +02:00
7ca48a3814 Fix: incorrect socket shape for noise texture input 2021-09-24 10:55:23 +02:00
f8a0e102cf Weightpaint Gradient tool: expose falloff to the UI
By default, we'll always get a falloff like this from the tool:
{F10559413}

But in the context of using vertexgroups in modifiers/modeling, a choice
on how the gradient falloff of the Weightpaint Gradient tool is shaped
would be desirable:
"real" linear:
{F10559416}
Custom:
{F10559421}
{F10559428}

The way the Weightpaint gradient tool works is a bit outside the usual
tools that use brushes [even though it creates a brush on the fly in
`WPGradient_userData`].
However, it does not have an entry in `eBrushWeightPaintTool` and adding
one there does not play nice for the same reasons (not "really" being
integrated in the brush-based tools).

So in order to expose the brush curve in the UI, we would have to do one
of the following:
- [1] try to use `VIEW3D_PT_tools_brush_falloff`, for this to work:
-- make all kinds of exception in python super classes [`FalloffPanel`,
`BrushPanel`, `UnifiedPaintPanel`, ... -- including making real entries
in `eBrushWeightPaintTool`] to get a proper tool mode and...
-- .. to also make sure Falloff Shape and Front-Face Falloff are not
available [which the tool seems to just not support in its current form]
- [2] just have a simple, contained panel for this tool alone

This patch implements [2] and adds it as part of the ToolDef (could also
be done in `VIEW3D_HT_tool_header`, but again, I think this is nice to
keep separate from the usual tools)
{F10559482}
{F10559485}

Testfile:
{F10559442}

Fixes T91636

Maniphest Tasks: T91636

Differential Revision: https://developer.blender.org/D12614
2021-09-24 10:52:12 +02:00
3ac342dc6d Cleanup: clang format 2021-09-24 10:45:36 +02:00
9a45a4c525 Cleanup: asset catalogs, fix clang-tidy warning
Remove unnecessary call to `std::string::c_str()`.

No functional changes.
2021-09-24 10:29:52 +02:00
e161f39660 Cleanup: clang-tidy 2021-09-24 10:25:16 +02:00
Jeroen Bakker
fc7beac8d6 FileBrowser: Reduce Overhead Browsing Libraries.
When Browsing libraries the asset files were opened multiple times.
once to determine the needed groups to query and once for each
group to query the items in the group. For file browsing this makes sense
but for asset browsing this can be reduced.

This patch will load the asset files recursively and only opens them once.
Another change is that only the assets are requested and not filtered out
later in the process.

This patch is needed to simplify the library indexing. Where
we need access to the full library content.

## The numbers ##

Benchmarked by adding scenes of the spring open movie to the default
asset library. Refreshing the asset library would recursively load all the files
there.

| **8bc27c508a** | Processed 317 'directories/libraries' | 7.573986s |
| **Patch** | Processed 42 'directories/libraries' | 0.821013s |

{F10442811}

Reviewed By: mont29, Severin

Maniphest Tasks: T91406

Differential Revision: https://developer.blender.org/D12499
2021-09-24 08:41:40 +02:00
Jeroen Bakker
6a88f83d67 Hair Info Length Attribute
Goal is to add the length attribute to the Hair Info node, for better control over color gradients or similar along the hair.

Reviewed By: #eevee_viewport, brecht

Differential Revision: https://developer.blender.org/D10481
2021-09-24 07:44:22 +02:00
0f764ade1a Fix T91661: Vector rotate output socket diconnects on file load
An incorrect name was used in the socket declaration refactor.
2021-09-23 23:56:15 -05:00
0e039749e3 Fix: Incorrect field visualization for some shader nodes
These need to be tagged as function nodes in their declaration.
2021-09-23 22:23:14 -05:00
bc65c7d0e5 Cleanup: spelling in comments 2021-09-24 11:31:23 +10:00
599d96e8f9 UI: keymap preference tweaks
- Expose option to use shortcuts to activate tools as an enum.
- "Emulate 3 Button Mouse" now disables preferences
  that depend on Alt-LMB.
2021-09-24 11:07:01 +10:00
bffda4185d Cleanup: group convenience assignments in the keymap 2021-09-24 11:07:01 +10:00
26141664f0 Fix: Curve fill node doesn't fill real geometry with instances
A misplaced return in the middle of the function made it so
the node didn't fill real geometry.
2021-09-23 17:45:41 -05:00
f7608276e3 Audaspace: port bugfix from upstream.
Fixes T91615: Instant crash when dragging video file into video editor sequencer
2021-09-23 23:27:49 +02:00
61f3d4eb7c Geometry Nodes: Initial socket visualization for fields.
This implements the update logic for the vizualization of which
sockets pass data or constants directly, and which pass functions.
The socket shapes may still have to be updated. That should be
done separately, because it might be a bit more involved, because
socket shapes are currently linked to keyframe shapes. Currently
the circle and diamond shapes are used with the following meanings:

 - Input Sockets:
    - Circle: Required to be a single value.
    - Diamond: This input supports fields.
 - Output Sockets:
    - Circle: This output is a single value.
    - Diamond: This output may be a field.

Connecting a field to a circle input socket is an error, since a
field cannot be converted to a single value. If the socket shape
is a diamond with a dot in the middle, it means it is currently
a single value, but could be a field.

In addition to socket shapes, the intention is to draw node links
differently based on the field status. However, the exact method for
conveying that isn't decided yet.

Differential Revision: https://developer.blender.org/D12584
2021-09-23 15:21:31 -05:00
c1b925f7ff Fix build error caused by typo 2021-09-23 15:20:57 -05:00
1bdaf0ebec Fix T91638: image editor Open Cached Render not loading some passes
Previously this was only loading built-in render passes. Now instead of trying
to load the scene render passes, load whatever passes exist in the cache file.
2021-09-23 20:45:42 +02:00
Charlie Jolly
7fb2b50e5d Fix: Build issue with MSVC
header for std::function was not included

reported/fixed by Charlie on chat
2021-09-23 12:33:27 -06:00
fc2255135e Paint: prevent RenderResults and Viewers where unappropriate
Using a RenderResult (or a Viewer) was never really working (think you
cant get a real ImBuff from these) -- cannot use it as a clone, stencil
or canvas [Single Image paint texture slot].

In the case of using it as a 2D paint clone image this would also crash
[due to the Image Editor drawing refactor in 2.91].

Now [in the spirit of T73182 / D11179], prevent using these where
unappropriate by using rna pointer polling functions.

Also add a security check for the 2D paint clone image crash in case a
stencil ImBuff cannot be provided for some reason, but generally old
files are now patched in do_versions_after_linking_300 (thx @brecht!).

Fixes T91625.

Maniphest Tasks: T91625

Differential Revision: https://developer.blender.org/D12609
2021-09-23 20:11:45 +02:00
b8a30c7664 Cleanup: Use const in previously committed function 2021-09-23 19:39:26 +02:00
323fd80aad UI: Tree-View API for easy creation of tree UIs
This follows three main targets:

* Make creation of new tree UIs easy.
* Groundwork to generalize tree UIs (so e.g. Outliner, animation
  channels, asset catalogs and spreadsheet data-sets don't have to
  re-implement basic tree UI code) or even other data-view UIs.
* Better separate data and UI state. E.g. with this, tree-item selection
  or the open/collapsed state can be stored on the UI level, rather than
  in data. (Asset Catalogs need this, storing UI state info in them is
  not an option.)

In addition, the design should be well testable and could even be
exposed to Python.

Note that things will likely change in master still. E.g. the actually
resulting UI isn't very nice visually yet.

The design is documented here:
https://wiki.blender.org/wiki/Source/Interface/Views

Differential Revision: https://developer.blender.org/D12573
2021-09-23 19:33:54 +02:00
eb0eb54d96 Fix D12533: Simplify curve object to mesh conversion
This patch simplifies the curve object to mesh conversion
used by the object convert operator and exporters.

The existing code had a convoluted model of ownership, and did quite
a bit of unnecessary work. It also assumed that curve objects always
evaluated to a mesh, which is not the case anymore.

Now the code checks if the object it receives is evaluated. If so,
it can simply return a copy of the evaluated mesh (or convert the
evaluated curve wire edges to a mesh if there was no evaluated mesh).
If the object isn't evaluated, it uses a temporary copy of the object
with modifiers removed to create the mesh in the same way.

This follows up on the recent changes to curve evaluation,
namely that the result is always either a mesh or a wire curve.

Differential Revision: https://developer.blender.org/D12533
2021-09-23 11:41:46 -05:00
ed541de29d Fix T91626: Cycles sss behind fully transparent object renders differently 2021-09-23 18:32:30 +02:00
354c3eee40 Cycles: improve Auto Tile option description
Ref T91645
2021-09-23 18:32:30 +02:00
0a8a726014 bUUID: make it explicit the default constructor produces the nil value
The implicit default constructor zeroes all plain data fields, and now
this behaviour is explicit & tested for in a unit test.
2021-09-23 18:27:19 +02:00
18a4dc869d Cleanup: UUID, fix clang-tidy warnings
Use explicit `uint32_t` instead of `uint`, add a missing end-of-namespace
comment, and change `auto` to `const auto *`.

No functional changes.
2021-09-23 18:27:19 +02:00
502543e46b Geometry Nodes: remove old method to iterate over attributes
The previous commit added a new method to the same in a better way.
2021-09-23 17:59:44 +02:00
38af29df5c Geometry Nodes: simplify looping over attributes in geometry set
This adds three new methods:
* `InstancesComponent::foreach_reference_as_geometry(...)`
* `GeometrySet::attribute_foreach(...)`
* `GeometrySet::gather_attributes_for_propagation(...)`

The goal is that these iteration primitives can be used in places
where we use more specialized iterators currently.

Differential Revision: https://developer.blender.org/D12613
2021-09-23 17:59:44 +02:00
105115da9f UUID: add != operator for comparing UUIDs
Make it possible to unit test with `EXPECT_NE(uuid1, uuid2)`.
2021-09-23 17:58:20 +02:00
bd63944a73 UUID: place C++ code in correct namespace
Put the `bUUID` class in the `blender` namespace, instead of the
`blender::bke` namespace.

As a result, some C++ code now correctly uses the C++ class, where
previously it would use the C struct and use implicit casting where
necessary. As a result, support for initializer lists had to be
explicitly coded and in another place an explicit `::bUUID` was
necessary to avoid ambiguity.
2021-09-23 17:58:20 +02:00
942fc9f467 Cleanup: bUUID, document the constructors
No functional changes.
2021-09-23 17:58:20 +02:00
93997f9d0a Cleanup: asset catalogs, correct assertion message
There is no such thing as a "relative path" when it comes to asset catalog
paths (they're always absolute).

No functional changes.
2021-09-23 17:58:20 +02:00
d7f803f522 Fix T91641: crash rendering with 16k environment map in Cycles
Protect against integer overflow.
2021-09-23 17:48:16 +02:00
6279efbb78 Fix Cycles compiler warning on GCC 11
For shadow rays there are no closures, leave out the closure merging code
there to avoid warnings about accessing closure memory that does not exist.
2021-09-23 17:48:16 +02:00
d0493796a6 Cleanup: Remove hardcoded values and rename keyframe shape shaders
No functional change.

The shader is complicated by itself, having hardcoded values makes it
even more cryptic.

I also renamed the shader because the shader is not for the keyfarme diamond only,
but for all the keyframe shapes.

Differential Revision: https://developer.blender.org/D12615
2021-09-23 17:41:11 +02:00
f11bcb5a80 Fix T91557: Texture Paint Stencil doesnt use assigned UV Layer
Choosing a UV layer would actually affect the overlay in the viewport
and also painting with the mask brush was in that UV space, but the
resulting stencil mask was always applied with the active UV (not the
explicitly selected stencil UV -- the one one is looking at in the
viewport!) to painting.

This has been like that as far as I have checked back (at least 2.79b),
I am surprised this has not come up before, but it does not seem to make
sense at all...

Now use the UV specified for the stencil layer when applying the mask for
painting, so it corresponds to the stencil mask one is looking at in the
viewport.

Maniphest Tasks: T91557

Differential Revision: https://developer.blender.org/D12583
2021-09-23 16:56:03 +02:00
490425d56e Asset Catalogs: explicit version number in catalog definition files
Declare the current format used for asset catalog definition files as
version 1, and write that to the files. Files without that version number
will be rejected.

This makes it much easier to move to different versions later, with the
opportunity to do versioning on file load.

The version is not associated with any version of Blender, but a separate
integer that's simply incremented when a non-backward-compatible change
happens.
2021-09-23 16:06:25 +02:00
aa2493e2e7 Fix unused variable warning in release builds
The variable is only used in debug builds.
2021-09-23 15:04:41 +02:00
Sybren A. Stüvel
9b12b23d0b Assets: add Asset Catalog system
Catalogs work like directories on disk (without hard-/symlinks), in that
an asset is only contained in one catalog.

See T90066 for design considerations.

#### Known Limitations

Only a single catalog definition file (CDF), is supported, at
`${ASSET_LIBRARY_ROOT}/blender_assets.cats.txt`. In the future this is
to be expanded to support arbitrary CDFs (like one per blend file, one
per subdirectory, etc.).

The current implementation is based on the asset browser, which in
practice means that the asset browser owns the `AssetCatalogService`
instance for the selected asset library. In the future these instances
will be accessible via a less UI-bound asset system.

The UI is still very rudimentary, only showing the catalog ID for the
currently selected asset. Most notably, the loaded catalogs are not
shown yet. The UI is being implemented and will be merged soon.

#### Catalog Identifiers

Catalogs are internally identified by UUID. In older designs this was a
human-readable name, which has the problem that it has to be kept in
sync with its semantics (so when renaming a catalog from X to Y, the
UUID can be kept the same).

Since UUIDs don't communicate any human-readable information, the
mapping from catalog UUID to its path (stored in the Catalog Definition
File, CDF) is critical for understanding which asset is stored in which
human-readable catalog. To make this less critical, and to allow manual
data reconstruction after a CDF is lost/corrupted, each catalog also has
a "simple name" that's stored along with the UUID. This is also stored
on each asset, next to the catalog UUID.

#### Writing to Disk

Before saving asset catalogs to disk, the to-be-overwritten file gets
inspected. Any new catalogs that are found thre are loaded to memory
before writing the catalogs back to disk:

- Changed catalog path: in-memory data wins
- Catalogs deleted on disk: they are recreated based on in-memory data
- Catalogs deleted in memory: deleted on disk as well
- New catalogs on disk: are loaded and thus survive the overwriting

#### Tree Design

This implements the initial tree structure to load catalogs into. See
T90608, and the basic design in T90066.

Reviewed By: Severin

Maniphest Tasks: T91552

Differential Revision: https://developer.blender.org/D12589
2021-09-23 15:00:45 +02:00
222fd1abf0 Asset Browser: Disable metadata editing for external asset libraries
Buttons to edit asset metadata are now disabled for assets from an
external library (i.e. assets not stored in the current .blend file).
Their tooltips explain why they are disabled.

Had to do some RNA trickery to disable the metadata properties at RNA
level, not at UI script level.
The basic idea is:
* Local data-block assets set the data-block as owning ID for the asset
  metadata RNA pointer now.
* That way we can use the owner ID to see where the metadata belongs to
  and decide if it's editable that way.
* Additionaly, some Python operators needed better polling so they show
  as grayed out, and don't just fail.

One important thing: Custom properties of the metadata can still be
edited. The edits won't be saved however. Would be nice to disable that,
but it's currently not supported on BPY/IDProperty/RNA level.

Addresses T82943.

Differential Revision: https://developer.blender.org/D12127
2021-09-23 14:46:13 +02:00
059d01d42e Fileops: call BLI_path_slash_native() in BLI_dir_create_recursive()
Make the Windows version of `BLI_dir_create_recursive()` call
`BLI_path_slash_native()` before it tries to handle the path. This
should make it possible to call it with non-native path separators.

This change was provided by our Windows platform maintainer @LazyDodo in
P2414, so I assume he agrees with this change.
2021-09-23 14:42:14 +02:00
83975965a7 Keymap: RMB select option to place cursor on Alt-LMB
This allows most tools to activate on press, removing a small but
noticeable distance between the initial press and detection of a drag
event.

Gizmo tweak no longer actives when Alt is held, to avoid conflicting
with cursor placement.

This has the advantage that the gizmo doesn't get in the way when Alt
is used for activating tools or placing the cursor.
2021-09-23 22:10:56 +10:00
88692baace WM: gestures now activate immediately on mouse press
Some gestures were activating immediately on tweak events,
extend this to mouse-press and click-drag.

Without this change, box-select for example wouldn't be automatically
activated on mouse-press.
2021-09-23 22:08:02 +10:00
b659d1a560 Cleanup: spelling in comments 2021-09-23 22:08:02 +10:00
d431b91995 Cleanup: assign variable for LMB select 2021-09-23 22:06:47 +10:00
4d2ca33a8a LibLink: Modify WM API to link/append one ID to take flag parameter.
There is no reason to lock behavior into a specific configuration in
those calls, make them properly configurable like the rest of the
link/append code.

This also enable users of those functions to activate 'ID reuse'
behavior.
2021-09-23 13:48:41 +02:00
aadb7ef071 Geometry Nodes: add utility to print an attribute id. 2021-09-23 13:46:26 +02:00
e86cf55667 Fix T91629: Crash in "Open Cached Render" function 2021-09-23 13:03:36 +02:00
f48a4aa0f9 LibLink Append: Expose 'reuse ID' through new BLO flag, and add basic tests.
Option is now available to append operator, alsthough hidden and
disabled by default.
2021-09-23 12:56:05 +02:00
cb173d05dc LibLink Append: Fix 'reused ID' case keeping linked data around.
When we re-use a local ID, we need to delete the matching linked data.
2021-09-23 12:54:23 +02:00
6f53988e7a Cleanup: proper handling of LIB_TAG_DOIT in append code. 2021-09-23 12:46:51 +02:00
ce96a75c2c Cleanup: eBLOLibLinkFlags: Add 'space' between APPEND flags and INSTANCE ones. 2021-09-23 12:45:40 +02:00
3558ae3b6c Cleanup: Silence unused var warning in release builds. 2021-09-23 12:30:07 +02:00
b63f777950 Add missing GPencil IDTYPE_FLAGS_APPEND_IS_REUSABLE flag.
Forgot that one in rB794c2828af60.

Noted by Antonio Vazquez (@antoniov), thanks.
2021-09-23 11:28:39 +02:00
b801e86f8b Append: Reuse local data: remove limitation on directly selected data.
in asset context, when user drag & drop a material several time, they
would still expect to re-use existing one instead of getting new copies
of it, even if this material is directly appended (and not an indirect
dependency of an object e.g.).
2021-09-23 11:15:58 +02:00
3042994c91 Link/Append: Refactor flags.
Flags controlling link/append code are split between two enums, one in
`DNA_space_types.h` and one in `BLO_readfile.h`.

This commit:
 - Moves flags exclusively used in WM and BLO code to `eBLOLibLinkFlags`
   in `BLO_readfile.h`. Flags in `eFileSel_Params_Flag` from
   `DNA_space_types.h` are now only the ones effectively used by the
   file browser editor code too.
 - Fixes some internal utils in `readfile.c` still taking `short` flag
   parameter instead of proper `int` one.

NOTE: there are a few other flags that could probably be moved to
`eBLOLibLinkFlags` (at the very least `FILE_LINK`, probably also
`FILE_AUTOSELECT` and `FILE_ACTIVE_COLLECTION`), since those are not
effectively used by the file browser, and control linking/appending
behavior, not filebrowser behavior.

However for now think it's safer to not touch that.
2021-09-23 11:01:00 +02:00
12924ed573 Fix last Cycles tile highlighted while file from disk is being processed 2021-09-23 10:41:06 +02:00
a351023bd5 Fix default surface resolution U/V mis-match
The resolution for surfaces was 12 for U, 4 for V,
where both should have been set to 4.

Regression in 9a076dd95a
2021-09-23 15:54:32 +10:00
754d56dcc1 Cleanup: spelling in comments 2021-09-23 15:42:44 +10:00
bf948b2cef Custom Properties: Rewrite edit operator, improve UX
This commit changes the custom property edit operator to make editing
different properties types more obvious and expose more of the data,
made more easily possible by the recent UI data refactor.

Previously, the operator guessed the type you wanted based on what you
wrote in a text box. That was problematic, you couldn't make a string
property with a value of `1234`, and you had to know about the Python
syntax for lists in order to create an array property. It was also slow
and error prone; it was too easy to make a typo.

Improvements compared to the old operator:
 - A type drop-down to choose between the property types.
 - Step and precision values are exposed.
 - Buttons that have the correct type based on the property.
 - String properties no longer display min, max, etc. buttons.
 - Generally works in more cases. The old operator tended to break.
 - Choose array length with a slider.
 - Easy to choose to use python evaluation when necessary.
 - Code is commented, split up, and much easier to understand.

The custom property's value is purposefully not exposed, since the Edit
operator is for changing the property's metadata now, rather than the
value itself. Though in the "Python" mode the value is still available.

More improvements are possible in the future, like exposing different
subtypes, and improving the UI of the custom properties panel.

Differential Revision: https://developer.blender.org/D12435
2021-09-22 21:57:33 -05:00
6e77afe6ec Applying patch D12600, GSOC Knife Tools branch
This adds constrained angle mode improvements,
snapping to global and local orientation,
visible distance and angle measurements,
undo capability,
x-ray mode,
multi-object edit mode.

See https://developer.blender.org/D12600 for more details.

Note: this project moved some of the default keymappings
around a bit, as discussed with users in the thread
https://devtalk.blender.org/t/gsoc-2021-knife-tool-improvements-feedback/19047
We'll change the manual documentation in the next couple of days.
2021-09-22 21:23:44 -04:00
a78d3c5261 Fix: T91602 ffmpeg crash
Issue caused by our patch in rB1af722b81912
we replaced an array with a memory allocation
but we forgot to update the assert which now
used an invalid method to calculate the array
size.

SVN libs will have to be updated before
T91602 will be fixed for end users.
2021-09-22 17:29:23 -06:00
79bcc19240 Cleanup: Move more shader nodes to socket declaration API
I had to add `no_muted_links` to the declaration API. The name could
change there, but I think it's more obvious than "internal"
2021-09-22 17:34:09 -05:00
6fb4c8f040 Fix: Incorrect socket names after previous commit 2021-09-22 16:58:29 -05:00
c99cb81452 Cleanup: Use new node socket declaration API for some shader nodes
This converts socket declarations for most shader nodes that had already
been converted to C++, but skips those that needed a special flag.
2021-09-22 14:39:09 -05:00
bd01f4761c GPencil: Fix compiler warnings 2021-09-22 21:17:04 +02:00
ee49991999 Cleanup: Silence missing switch case warning 2021-09-22 12:00:21 -07:00
6611f2cb74 Fix T91607: GPencil Tint modifier "apply" removes the effect 2021-09-22 20:07:35 +02:00
f893dea586 BLI: support initializing empty FunctionRef with nullptr
This may sometimes be desired because it is more explicitely
shows that the `FunctionRef` will be empty.
2021-09-22 19:55:44 +02:00
02bde2c1d5 Cleanup: add using declarations 2021-09-22 19:45:47 +02:00
a28ec92088 BLI: avoid warning when copying empty StringRef 2021-09-22 19:45:18 +02:00
188de4bc31 BLI: initialize MutableSpan in default constructor 2021-09-22 19:44:58 +02:00
bd1c4a781f Geometry Nodes: fix evaluating field to span 2021-09-22 18:45:11 +02:00
3180c6b4a7 Cleanup: Themes: Remove invalid theme option
`font_kerning_style` was removed in rBa1e91fbef3dc9a5d5c8456cd9a887aac1bdb652c
2021-09-22 12:33:12 -04:00
e1a0983b3c Fix T91608: Cycles crash with tile size 0 2021-09-22 18:12:46 +02:00
4068b6b5a7 Fix T91598: Decreasing sample count causes viewport to reset
Differential Revision: https://developer.blender.org/D12601
2021-09-22 18:09:06 +02:00
Chandrapal Singh
5033310e8a UI: Add description for Batch rename
Added description for Batch rename which pop-ups when
hovering the mouse over "Batch rename" inside the edit menu.

Fixes T91390

Reviewed By: Blendify

Maniphest Tasks: T91390

Differential Revision: https://developer.blender.org/D12594
2021-09-22 11:35:29 -04:00
ac68b08c5b Fix T91592: Negative Cycles remaining render time
For the default startup was showing -14:-08.-48 as a remaining time.

Was an integer overflow when specifying total number of pixel-samples.
2021-09-22 17:30:00 +02:00
bc1e675bb9 Fix T91603: Cycles crash when volume becomes visible
Making object which uses volume shader invisible will mark the shader
as not having a volume, forcing re-compilation of the shader to bring
it back to a consistent state.

The compilation is happening as part of scene update, which needs to
know kernel features. So there is a feedback loop.

Use more relaxed way of knowing whether there is a volume in the
shader for the kernel features, which doesn't require shader to be
compiled first.

Solves issues from the report, but potentially causes extra memory
allocated if the volume part of graph is fully optimized out. This
downside is solvable, but would need to split scene update into two
steps (the one which requires on kernel, and the one which does not).
It will be an interesting project to tackle, but for a bug fix is
better to use simpler solution.
2021-09-22 17:10:06 +02:00
1eba32c3e9 Fix T91576: Cycles attribute node with name N for smooth normal no longer working
There was an optimization to remove duplicate storage of normals as attributes
when using normal maps. However for named attributes like this we still need to
store the attribute.

Don't request normal attribute from the normal map node now, instead of skipping it
in the geometry code.
2021-09-22 17:05:31 +02:00
4762a9b09f GPencil: Fix unreported missing material panel for new Scene
When a new scene is created, the paint pointers are not available before using them, so the python panel exits because the pointer was None.

Now, the pointer is checked in order to display the materials panel as expected.
2021-09-22 17:05:21 +02:00
794c2828af Initial implementation of local ID re-use when appending.
This commit adds to ID struct a new optional 'weak reference' to a
linked ID (in the form of a blend file library path and full ID name).

This can then be used on next append to try to find a matching local ID
instead of re-making the linked data local again.

Ref. T90545

NOTE: ID re-use will be disabled for regular append for the time being
(3.0 release), and only used for assets. Therefore, this commit should
not change anything user-wise.

Differential Revision: https://developer.blender.org/D12545
2021-09-22 16:55:39 +02:00
707bcd5693 Cleanup: make format 2021-09-22 16:55:09 +02:00
dilithjay
0d350e0193 Geometry Nodes: Curve Fillet Node
This node can be used to fillet splines at control points to
create a circular arc.
The implementation roughly follows T89227's design.

The node works in two main modes: Bezier and Poly
* Bezier: Creates a circular arc at vertices by changing
handle lengths (applicable only for Bezier splines).
* Poly: Creates a circular arc by creating vertices (as
many as defined by the Count fields input) along
the arc (applicable for all spline types).

In both modes, the radius of the created arc is defined
by the Radius fields input.
The Limit Radius attribute can be enabled to prevent
overlapping when the defined radius exceeds the maximum
possible radius for a given point.

Reviewed By: Hans Goudey

Differential Revision: https://developer.blender.org/D12115
2021-09-22 20:11:12 +05:30
204b01a254 Fix T91590: Cycles specular baking not using smooth normal 2021-09-22 16:08:45 +02:00
e57ce464c2 Fix T91600: Cycles viewport not updaing on metaball changes 2021-09-22 16:08:45 +02:00
53e7c64be7 Fix T91597: Cycles volume scatter visibility on lights not working 2021-09-22 16:08:45 +02:00
368b56c9a1 GPencil: Split Weight modifier in two to make more consistent
The old modifier had two modes, but it is better to keep separated as meshes.

The UI has changed to be more consistent, including a new column type of modifiers.

Note: The logic has not changed with the previous version of the modifier, just is a split on two modifiers..

Reviewed By: mendio, pablovazquez

Differential Revision: https://developer.blender.org/D12586
2021-09-22 15:54:34 +02:00
1165 changed files with 40829 additions and 14156 deletions

View File

@@ -180,6 +180,7 @@ ForEachMacros:
- CTX_DATA_BEGIN_WITH_ID
- DEG_OBJECT_ITER_BEGIN
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN
- DRW_ENABLED_ENGINE_ITER
- DRIVER_TARGETS_LOOPER_BEGIN
- DRIVER_TARGETS_USED_LOOPER_BEGIN
- FOREACH_BASE_IN_EDIT_MODE_BEGIN

View File

@@ -388,6 +388,10 @@ if(WITH_PYTHON_INSTALL)
set(PYTHON_REQUESTS_PATH "" CACHE PATH "Path to python site-packages or dist-packages containing 'requests' module")
mark_as_advanced(PYTHON_REQUESTS_PATH)
endif()
option(WITH_PYTHON_INSTALL_ZSTANDARD "Copy zstandard into the blender install folder" ON)
set(PYTHON_ZSTANDARD_PATH "" CACHE PATH "Path to python site-packages or dist-packages containing 'zstandard' module")
mark_as_advanced(PYTHON_ZSTANDARD_PATH)
endif()
option(WITH_CPU_SIMD "Enable SIMD instruction if they're detected on the host machine" ON)
@@ -406,6 +410,7 @@ mark_as_advanced(WITH_CYCLES_CUDA_BUILD_SERIAL)
set(CYCLES_TEST_DEVICES CPU CACHE STRING "Run regression tests on the specified device types (CPU CUDA OPTIX)" )
set(CYCLES_CUDA_BINARIES_ARCH sm_30 sm_35 sm_37 sm_50 sm_52 sm_60 sm_61 sm_70 sm_75 sm_86 compute_75 CACHE STRING "CUDA architectures to build binaries for")
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
option(WITH_CYCLES_HIP_BINARIES "Build Cycles HIP binaries" OFF)
unset(PLATFORM_DEFAULT)
option(WITH_CYCLES_LOGGING "Build Cycles with logging support" ON)
option(WITH_CYCLES_DEBUG_NAN "Build Cycles with additional asserts for detecting NaNs and invalid values" OFF)
@@ -419,6 +424,8 @@ mark_as_advanced(WITH_CYCLES_NATIVE_ONLY)
option(WITH_CYCLES_DEVICE_CUDA "Enable Cycles CUDA compute support" ON)
option(WITH_CYCLES_DEVICE_OPTIX "Enable Cycles OptiX support" ON)
option(WITH_CYCLES_DEVICE_HIP "Enable Cycles HIP support" OFF)
mark_as_advanced(WITH_CYCLES_DEVICE_HIP)
mark_as_advanced(WITH_CYCLES_DEVICE_CUDA)
option(WITH_CUDA_DYNLOAD "Dynamically load CUDA libraries at runtime" ON)
@@ -821,6 +828,11 @@ if(NOT WITH_CUDA_DYNLOAD)
endif()
endif()
if(WITH_CYCLES_DEVICE_HIP)
# Currently HIP must be dynamically loaded, this may change in future toolkits
set(WITH_HIP_DYNLOAD ON)
endif()
#-----------------------------------------------------------------------------
# Check check if submodules are cloned
@@ -1716,6 +1728,12 @@ if(WITH_PYTHON)
elseif(WITH_PYTHON_INSTALL_REQUESTS)
find_python_package(requests "")
endif()
if(WIN32 OR APPLE)
# pass, we have this in lib/python/site-packages
elseif(WITH_PYTHON_INSTALL_ZSTANDARD)
find_python_package(zstandard "")
endif()
endif()
# Select C++17 as the standard for C++ projects.
@@ -1850,6 +1868,9 @@ elseif(WITH_CYCLES_STANDALONE)
if(WITH_CUDA_DYNLOAD)
add_subdirectory(extern/cuew)
endif()
if(WITH_HIP_DYNLOAD)
add_subdirectory(extern/hipew)
endif()
if(NOT WITH_SYSTEM_GLEW)
add_subdirectory(extern/glew)
endif()
@@ -1984,6 +2005,7 @@ if(FIRST_RUN)
endif()
info_cfg_option(WITH_PYTHON_INSTALL)
info_cfg_option(WITH_PYTHON_INSTALL_NUMPY)
info_cfg_option(WITH_PYTHON_INSTALL_ZSTANDARD)
info_cfg_option(WITH_PYTHON_MODULE)
info_cfg_option(WITH_PYTHON_SAFETY)

View File

@@ -38,7 +38,6 @@ ExternalProject_Add(external_numpy
PREFIX ${BUILD_DIR}/numpy
PATCH_COMMAND ${NUMPY_PATCH}
CONFIGURE_COMMAND ""
PATCH_COMMAND COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/numpy/src/external_numpy < ${PATCH_DIR}/numpy.diff
LOG_BUILD 1
BUILD_COMMAND ${PYTHON_BINARY} ${BUILD_DIR}/numpy/src/external_numpy/setup.py build ${NUMPY_BUILD_OPTION} install --old-and-unmanageable
INSTALL_COMMAND ""

View File

@@ -25,7 +25,7 @@ ExternalProject_Add(external_python_site_packages
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} chardet==${CHARDET_VERSION} urllib3==${URLLIB3_VERSION} certifi==${CERTIFI_VERSION} requests==${REQUESTS_VERSION} --no-binary :all:
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:
)
if(USE_PIP_NUMPY)

View File

@@ -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.2)
set(PYTHON_VERSION 3.9.7)
set(PYTHON_SHORT_VERSION 3.9)
set(PYTHON_SHORT_VERSION_NO_DOTS 39)
set(PYTHON_URI https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tar.xz)
set(PYTHON_HASH f0dc9000312abeb16de4eccce9a870ab)
set(PYTHON_HASH fddb060b483bc01850a3f412eea1d954)
set(PYTHON_HASH_TYPE MD5)
set(PYTHON_FILE Python-${PYTHON_VERSION}.tar.xz)
@@ -215,17 +215,18 @@ set(NANOVDB_HASH e7b9e863ec2f3b04ead171dec2322807)
set(NANOVDB_HASH_TYPE MD5)
set(NANOVDB_FILE nano-vdb-${NANOVDB_GIT_UID}.tar.gz)
set(IDNA_VERSION 2.10)
set(CHARDET_VERSION 4.0.0)
set(URLLIB3_VERSION 1.26.3)
set(CERTIFI_VERSION 2020.12.5)
set(REQUESTS_VERSION 2.25.1)
set(CYTHON_VERSION 0.29.21)
set(IDNA_VERSION 3.2)
set(CHARSET_NORMALIZER_VERSION 2.0.6)
set(URLLIB3_VERSION 1.26.7)
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(NUMPY_VERSION 1.19.5)
set(NUMPY_SHORT_VERSION 1.19)
set(NUMPY_VERSION 1.21.2)
set(NUMPY_SHORT_VERSION 1.21)
set(NUMPY_URI https://github.com/numpy/numpy/releases/download/v${NUMPY_VERSION}/numpy-${NUMPY_VERSION}.zip)
set(NUMPY_HASH f6a1b48717c552bbc18f1adc3cc1fe0e)
set(NUMPY_HASH 5638d5dae3ca387be562912312db842e)
set(NUMPY_HASH_TYPE MD5)
set(NUMPY_FILE numpy-${NUMPY_VERSION}.zip)

View File

@@ -379,7 +379,7 @@ USE_CXX11=true
CLANG_FORMAT_VERSION_MIN="6.0"
CLANG_FORMAT_VERSION_MAX="10.0"
PYTHON_VERSION="3.9.2"
PYTHON_VERSION="3.9.7"
PYTHON_VERSION_SHORT="3.9"
PYTHON_VERSION_MIN="3.7"
PYTHON_VERSION_MAX="3.11"
@@ -389,24 +389,24 @@ PYTHON_FORCE_REBUILD=false
PYTHON_SKIP=false
# Additional Python modules.
PYTHON_IDNA_VERSION="2.9"
PYTHON_IDNA_VERSION="3.2"
PYTHON_IDNA_VERSION_MIN="2.0"
PYTHON_IDNA_VERSION_MAX="3.0"
PYTHON_IDNA_VERSION_MAX="3.2"
PYTHON_IDNA_NAME="idna"
PYTHON_CHARDET_VERSION="3.0.4"
PYTHON_CHARDET_VERSION_MIN="3.0"
PYTHON_CHARDET_VERSION_MAX="5.0"
PYTHON_CHARDET_NAME="chardet"
PYTHON_CHARSET_NORMALIZER_VERSION="2.0.6"
PYTHON_CHARSET_NORMALIZER_VERSION_MIN="2.0.6"
PYTHON_CHARSET_NORMALIZER_VERSION_MAX="2.1.0" # requests uses `charset_normalizer~=2.0.0`
PYTHON_CHARSET_NORMALIZER_NAME="charset-normalizer"
PYTHON_URLLIB3_VERSION="1.25.9"
PYTHON_URLLIB3_VERSION="1.26.7"
PYTHON_URLLIB3_VERSION_MIN="1.0"
PYTHON_URLLIB3_VERSION_MAX="2.0"
PYTHON_URLLIB3_NAME="urllib3"
PYTHON_CERTIFI_VERSION="2020.4.5.2"
PYTHON_CERTIFI_VERSION_MIN="2020.0"
PYTHON_CERTIFI_VERSION_MAX="2021.0"
PYTHON_CERTIFI_VERSION="2021.10.8"
PYTHON_CERTIFI_VERSION_MIN="2021.0"
PYTHON_CERTIFI_VERSION_MAX="2023.0"
PYTHON_CERTIFI_NAME="certifi"
PYTHON_REQUESTS_VERSION="2.23.0"
@@ -414,7 +414,12 @@ PYTHON_REQUESTS_VERSION_MIN="2.0"
PYTHON_REQUESTS_VERSION_MAX="3.0"
PYTHON_REQUESTS_NAME="requests"
PYTHON_NUMPY_VERSION="1.19.5"
PYTHON_ZSTANDARD_VERSION="0.15.2"
PYTHON_ZSTANDARD_VERSION_MIN="0.15.2"
PYTHON_ZSTANDARD_VERSION_MAX="0.16.0"
PYTHON_ZSTANDARD_NAME="zstandard"
PYTHON_NUMPY_VERSION="1.21.2"
PYTHON_NUMPY_VERSION_MIN="1.14"
PYTHON_NUMPY_VERSION_MAX="2.0"
PYTHON_NUMPY_NAME="numpy"
@@ -422,20 +427,22 @@ PYTHON_NUMPY_NAME="numpy"
# As package-ready parameters (only used with distro packages).
PYTHON_MODULES_PACKAGES=(
"$PYTHON_IDNA_NAME $PYTHON_IDNA_VERSION_MIN $PYTHON_IDNA_VERSION_MAX"
"$PYTHON_CHARDET_NAME $PYTHON_CHARDET_VERSION_MIN $PYTHON_CHARDET_VERSION_MAX"
"$PYTHON_CHARSET_NORMALIZER_NAME $PYTHON_CHARSET_NORMALIZER_VERSION_MIN $PYTHON_CHARSET_NORMALIZER_VERSION_MAX"
"$PYTHON_URLLIB3_NAME $PYTHON_URLLIB3_VERSION_MIN $PYTHON_URLLIB3_VERSION_MAX"
"$PYTHON_CERTIFI_NAME $PYTHON_CERTIFI_VERSION_MIN $PYTHON_CERTIFI_VERSION_MAX"
"$PYTHON_REQUESTS_NAME $PYTHON_REQUESTS_VERSION_MIN $PYTHON_REQUESTS_VERSION_MAX"
"$PYTHON_ZSTANDARD_NAME $PYTHON_ZSTANDARD_VERSION_MIN $PYTHON_ZSTANDARD_VERSION_MAX"
"$PYTHON_NUMPY_NAME $PYTHON_NUMPY_VERSION_MIN $PYTHON_NUMPY_VERSION_MAX"
)
# As pip-ready parameters (only used when building python).
PYTHON_MODULES_PIP=(
"$PYTHON_IDNA_NAME==$PYTHON_IDNA_VERSION"
"$PYTHON_CHARDET_NAME==$PYTHON_CHARDET_VERSION"
"$PYTHON_CHARSET_NORMALIZER_NAME==$PYTHON_CHARSET_NORMALIZER_VERSION"
"$PYTHON_URLLIB3_NAME==$PYTHON_URLLIB3_VERSION"
"$PYTHON_CERTIFI_NAME==$PYTHON_CERTIFI_VERSION"
"$PYTHON_REQUESTS_NAME==$PYTHON_REQUESTS_VERSION"
"$PYTHON_ZSTANDARD_NAME==$PYTHON_ZSTANDARD_VERSION"
"$PYTHON_NUMPY_NAME==$PYTHON_NUMPY_VERSION"
)
@@ -1141,10 +1148,11 @@ You may also want to build them yourself (optional ones are [between brackets]):
* Python $PYTHON_VERSION (from $PYTHON_SOURCE).
** [IDNA $PYTHON_IDNA_VERSION] (use pip).
** [Chardet $PYTHON_CHARDET_VERSION] (use pip).
** [Chardet $PYTHON_CHARSET_NORMALIZER_VERSION] (use pip).
** [Urllib3 $PYTHON_URLLIB3_VERSION] (use pip).
** [Certifi $PYTHON_CERTIFI_VERSION] (use pip).
** [Requests $PYTHON_REQUESTS_VERSION] (use pip).
** [ZStandard $PYTHON_ZSTANDARD_VERSION] (use pip).
** [NumPy $PYTHON_NUMPY_VERSION] (use pip).
* Boost $BOOST_VERSION (from $BOOST_SOURCE, modules: $BOOST_BUILD_MODULES).
* TBB $TBB_VERSION (from $TBB_SOURCE).
@@ -2013,7 +2021,7 @@ compile_OIIO() {
fi
# To be changed each time we make edits that would modify the compiled result!
oiio_magic=17
oiio_magic=18
_init_oiio
# Force having own builds for the dependencies.
@@ -2088,6 +2096,7 @@ compile_OIIO() {
cmake_d="$cmake_d -D USE_PYTHON=OFF"
cmake_d="$cmake_d -D USE_FFMPEG=OFF"
cmake_d="$cmake_d -D USE_OPENCV=OFF"
cmake_d="$cmake_d -D USE_OPENVDB=OFF"
cmake_d="$cmake_d -D BUILD_TESTING=OFF"
cmake_d="$cmake_d -D OIIO_BUILD_TESTS=OFF"
cmake_d="$cmake_d -D OIIO_BUILD_TOOLS=OFF"

View File

@@ -70,16 +70,18 @@
}
--- a/libavcodec/rl.c
+++ b/libavcodec/rl.c
@@ -71,7 +71,7 @@ av_cold void ff_rl_init(RLTable *rl,
@@ -71,17 +71,19 @@
av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size)
{
int i, q;
- VLC_TYPE table[1500][2] = {{0}};
+ VLC_TYPE (*table)[2] = av_calloc(sizeof(VLC_TYPE), 1500 * 2);
VLC vlc = { .table = table, .table_allocated = static_size };
av_assert0(static_size <= FF_ARRAY_ELEMS(table));
- av_assert0(static_size <= FF_ARRAY_ELEMS(table));
+ av_assert0(static_size < 1500);
init_vlc(&vlc, 9, rl->n + 1, &rl->table_vlc[0][1], 4, 2, &rl->table_vlc[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC);
@@ -80,8 +80,10 @@ av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size)
for (q = 0; q < 32; q++) {
int qmul = q * 2;
int qadd = (q - 1) | 1;
@@ -91,7 +93,7 @@
if (q == 0) {
qmul = 1;
@@ -113,4 +115,5 @@ av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size)
@@ -113,4 +115,5 @@
rl->rl_vlc[q][i].run = run;
}
}

View File

@@ -1,27 +0,0 @@
diff --git a/numpy/distutils/system_info.py b/numpy/distutils/system_info.py
index ba2b1f4..b10f7df 100644
--- a/numpy/distutils/system_info.py
+++ b/numpy/distutils/system_info.py
@@ -2164,8 +2164,8 @@ class accelerate_info(system_info):
'accelerate' in libraries):
if intel:
args.extend(['-msse3'])
- else:
- args.extend(['-faltivec'])
+# else:
+# args.extend(['-faltivec'])
args.extend([
'-I/System/Library/Frameworks/vecLib.framework/Headers'])
link_args.extend(['-Wl,-framework', '-Wl,Accelerate'])
@@ -2174,8 +2174,8 @@ class accelerate_info(system_info):
'veclib' in libraries):
if intel:
args.extend(['-msse3'])
- else:
- args.extend(['-faltivec'])
+# else:
+# args.extend(['-faltivec'])
args.extend([
'-I/System/Library/Frameworks/vecLib.framework/Headers'])
link_args.extend(['-Wl,-framework', '-Wl,vecLib'])

View File

@@ -0,0 +1,81 @@
# - Find HIP compiler
#
# This module defines
# HIP_HIPCC_EXECUTABLE, the full path to the hipcc executable
# HIP_VERSION, the HIP compiler version
#
# HIP_FOUND, if the HIP toolkit is found.
#=============================================================================
# Copyright 2021 Blender Foundation.
#
# Distributed under the OSI-approved BSD 3-Clause License,
# see accompanying file BSD-3-Clause-license.txt for details.
#=============================================================================
# If HIP_ROOT_DIR was defined in the environment, use it.
if(NOT HIP_ROOT_DIR AND NOT $ENV{HIP_ROOT_DIR} STREQUAL "")
set(HIP_ROOT_DIR $ENV{HIP_ROOT_DIR})
endif()
set(_hip_SEARCH_DIRS
${HIP_ROOT_DIR}
)
find_program(HIP_HIPCC_EXECUTABLE
NAMES
hipcc
HINTS
${_hip_SEARCH_DIRS}
PATH_SUFFIXES
bin
)
if(HIP_HIPCC_EXECUTABLE AND NOT EXISTS ${HIP_HIPCC_EXECUTABLE})
message(WARNING "Cached or directly specified hipcc executable does not exist.")
set(HIP_FOUND FALSE)
elseif(HIP_HIPCC_EXECUTABLE)
set(HIP_FOUND TRUE)
set(HIP_VERSION_MAJOR 0)
set(HIP_VERSION_MINOR 0)
set(HIP_VERSION_PATCH 0)
# Get version from the output.
execute_process(COMMAND ${HIP_HIPCC_EXECUTABLE} --version
OUTPUT_VARIABLE HIP_VERSION_RAW
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
# Parse parts.
if(HIP_VERSION_RAW MATCHES "HIP version: .*")
# Strip the HIP prefix and get list of individual version components.
string(REGEX REPLACE
".*HIP version: ([.0-9]+).*" "\\1"
HIP_SEMANTIC_VERSION "${HIP_VERSION_RAW}")
string(REPLACE "." ";" HIP_VERSION_PARTS "${HIP_SEMANTIC_VERSION}")
list(LENGTH HIP_VERSION_PARTS NUM_HIP_VERSION_PARTS)
# Extract components into corresponding variables.
if(NUM_HIP_VERSION_PARTS GREATER 0)
list(GET HIP_VERSION_PARTS 0 HIP_VERSION_MAJOR)
endif()
if(NUM_HIP_VERSION_PARTS GREATER 1)
list(GET HIP_VERSION_PARTS 1 HIP_VERSION_MINOR)
endif()
if(NUM_HIP_VERSION_PARTS GREATER 2)
list(GET HIP_VERSION_PARTS 2 HIP_VERSION_PATCH)
endif()
# Unset temp variables.
unset(NUM_HIP_VERSION_PARTS)
unset(HIP_SEMANTIC_VERSION)
unset(HIP_VERSION_PARTS)
endif()
# Construct full semantic version.
set(HIP_VERSION "${HIP_VERSION_MAJOR}.${HIP_VERSION_MINOR}.${HIP_VERSION_PATCH}")
unset(HIP_VERSION_RAW)
else()
set(HIP_FOUND FALSE)
endif()

View File

@@ -24,6 +24,7 @@ import project_source_info
import subprocess
import sys
import os
import tempfile
from typing import (
Any,
@@ -35,7 +36,6 @@ USE_QUIET = (os.environ.get("QUIET", None) is not None)
CHECKER_IGNORE_PREFIX = [
"extern",
"intern/moto",
]
CHECKER_BIN = "cppcheck"
@@ -47,13 +47,19 @@ CHECKER_ARGS = [
"--max-configs=1", # speeds up execution
# "--check-config", # when includes are missing
"--enable=all", # if you want sixty hundred pedantic suggestions
# Quiet output, otherwise all defines/includes are printed (overly verbose).
# Only enable this for troubleshooting (if defines are not set as expected for example).
"--quiet",
# NOTE: `--cppcheck-build-dir=<dir>` is added later as a temporary directory.
]
if USE_QUIET:
CHECKER_ARGS.append("--quiet")
def main() -> None:
def cppcheck() -> None:
source_info = project_source_info.build_info(ignore_prefix_list=CHECKER_IGNORE_PREFIX)
source_defines = project_source_info.build_defines_as_args()
@@ -78,7 +84,10 @@ def main() -> None:
percent_str = "[" + ("%.2f]" % percent).rjust(7) + " %:"
sys.stdout.flush()
sys.stdout.write("%s " % percent_str)
sys.stdout.write("%s %s\n" % (
percent_str,
os.path.relpath(c, project_source_info.SOURCE_DIR)
))
return subprocess.Popen(cmd)
@@ -90,5 +99,11 @@ def main() -> None:
print("Finished!")
def main() -> None:
with tempfile.TemporaryDirectory() as temp_dir:
CHECKER_ARGS.append("--cppcheck-build-dir=" + temp_dir)
cppcheck()
if __name__ == "__main__":
main()

View File

@@ -243,7 +243,9 @@ def build_defines_as_args() -> List[str]:
# use this module.
def queue_processes(
process_funcs: Sequence[Tuple[Callable[..., subprocess.Popen[Any]], Tuple[Any, ...]]],
*,
job_total: int =-1,
sleep: float = 0.1,
) -> None:
""" Takes a list of function arg pairs, each function must return a process
"""
@@ -271,14 +273,20 @@ def queue_processes(
if len(processes) <= job_total:
break
else:
time.sleep(0.1)
time.sleep(sleep)
sys.stdout.flush()
sys.stderr.flush()
processes.append(func(*args))
# Don't return until all jobs have finished.
while 1:
processes[:] = [p for p in processes if p.poll() is None]
if not processes:
break
time.sleep(sleep)
def main() -> None:
if not os.path.exists(join(CMAKE_DIR, "CMakeCache.txt")):

View File

@@ -0,0 +1,40 @@
"""
This method enables conversions between Local and Pose space for bones in
the middle of updating the armature without having to update dependencies
after each change, by manually carrying updated matrices in a recursive walk.
"""
def set_pose_matrices(obj, matrix_map):
"Assign pose space matrices of all bones at once, ignoring constraints."
def rec(pbone, parent_matrix):
matrix = matrix_map[pbone.name]
## Instead of:
# pbone.matrix = matrix
# bpy.context.view_layer.update()
# Compute and assign local matrix, using the new parent matrix
if pbone.parent:
pbone.matrix_basis = pbone.bone.convert_local_to_pose(
matrix,
pbone.bone.matrix_local,
parent_matrix=parent_matrix,
parent_matrix_local=pbone.parent.bone.matrix_local,
invert=True
)
else:
pbone.matrix_basis = pbone.bone.convert_local_to_pose(
matrix,
pbone.bone.matrix_local,
invert=True
)
# Recursively process children, passing the new matrix through
for child in pbone.children:
rec(child, matrix)
# Scan all bone trees from their roots
for pbone in obj.pose.bones:
if not pbone.parent:
rec(pbone, None)

View File

@@ -1101,6 +1101,7 @@ context_type_map = {
"scene": ("Scene", False),
"sculpt_object": ("Object", False),
"selectable_objects": ("Object", True),
"selected_asset_files": ("FileSelectEntry", True),
"selected_bones": ("EditBone", True),
"selected_editable_bones": ("EditBone", True),
"selected_editable_fcurves": ("FCurve", True),

View File

@@ -67,9 +67,12 @@ endif()
if(WITH_CYCLES OR WITH_COMPOSITOR OR WITH_OPENSUBDIV)
add_subdirectory(clew)
if(WITH_CUDA_DYNLOAD)
if((WITH_CYCLES_DEVICE_CUDA OR WITH_CYCLES_DEVICE_OPTIX) AND WITH_CUDA_DYNLOAD)
add_subdirectory(cuew)
endif()
if(WITH_CYCLES_DEVICE_HIP AND WITH_HIP_DYNLOAD)
add_subdirectory(hipew)
endif()
endif()
if(WITH_GHOST_X11 AND WITH_GHOST_XDND)

View File

@@ -102,26 +102,30 @@ AUD_API int AUD_Sound_getFileStreams(AUD_Sound* sound, AUD_StreamInfo **stream_i
if(file)
{
auto streams = file->queryStreams();
size_t size = sizeof(AUD_StreamInfo) * streams.size();
if(!size)
try
{
auto streams = file->queryStreams();
size_t size = sizeof(AUD_StreamInfo) * streams.size();
if(!size)
{
*stream_infos = nullptr;
return 0;
}
*stream_infos = reinterpret_cast<AUD_StreamInfo*>(std::malloc(size));
std::memcpy(*stream_infos, streams.data(), size);
return streams.size();
}
catch(Exception&)
{
*stream_infos = nullptr;
return 0;
}
*stream_infos = reinterpret_cast<AUD_StreamInfo*>(std::malloc(size));
std::memcpy(*stream_infos, streams.data(), size);
return streams.size();
}
else
{
*stream_infos = nullptr;
return 0;
}
*stream_infos = nullptr;
return 0;
}
AUD_API sample_t* AUD_Sound_data(AUD_Sound* sound, int* length, AUD_Specs* specs)

View File

@@ -609,6 +609,7 @@ typedef enum cudaError_enum {
CUDA_ERROR_INVALID_GRAPHICS_CONTEXT = 219,
CUDA_ERROR_NVLINK_UNCORRECTABLE = 220,
CUDA_ERROR_JIT_COMPILER_NOT_FOUND = 221,
CUDA_ERROR_UNSUPPORTED_PTX_VERSION = 222,
CUDA_ERROR_INVALID_SOURCE = 300,
CUDA_ERROR_FILE_NOT_FOUND = 301,
CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND = 302,

View File

@@ -736,6 +736,7 @@ const char *cuewErrorString(CUresult result) {
case CUDA_ERROR_INVALID_GRAPHICS_CONTEXT: return "Invalid graphics context";
case CUDA_ERROR_NVLINK_UNCORRECTABLE: return "Nvlink uncorrectable";
case CUDA_ERROR_JIT_COMPILER_NOT_FOUND: return "Jit compiler not found";
case CUDA_ERROR_UNSUPPORTED_PTX_VERSION: return "Unsupported PTX version";
case CUDA_ERROR_INVALID_SOURCE: return "Invalid source";
case CUDA_ERROR_FILE_NOT_FOUND: return "File not found";
case CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND: return "Link to a shared object failed to resolve";

39
extern/hipew/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,39 @@
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# The Original Code is Copyright (C) 2021, Blender Foundation
# All rights reserved.
# ***** END GPL LICENSE BLOCK *****
set(INC
.
include
)
set(INC_SYS
)
set(SRC
src/hipew.c
include/hipew.h
)
set(LIB
)
blender_add_lib(extern_hipew "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")

1207
extern/hipew/include/hipew.h vendored Normal file

File diff suppressed because it is too large Load Diff

533
extern/hipew/src/hipew.c vendored Normal file
View File

@@ -0,0 +1,533 @@
/*
* Copyright 2011-2021 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
*/
#ifdef _MSC_VER
# if _MSC_VER < 1900
# define snprintf _snprintf
# endif
# define popen _popen
# define pclose _pclose
# define _CRT_SECURE_NO_WARNINGS
#endif
#include <hipew.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#ifdef _WIN32
# define WIN32_LEAN_AND_MEAN
# define VC_EXTRALEAN
# include <windows.h>
/* Utility macros. */
typedef HMODULE DynamicLibrary;
# define dynamic_library_open(path) LoadLibraryA(path)
# define dynamic_library_close(lib) FreeLibrary(lib)
# define dynamic_library_find(lib, symbol) GetProcAddress(lib, symbol)
#else
# include <dlfcn.h>
typedef void* DynamicLibrary;
# define dynamic_library_open(path) dlopen(path, RTLD_NOW)
# define dynamic_library_close(lib) dlclose(lib)
# define dynamic_library_find(lib, symbol) dlsym(lib, symbol)
#endif
#define _LIBRARY_FIND_CHECKED(lib, name) \
name = (t##name *)dynamic_library_find(lib, #name); \
assert(name);
#define _LIBRARY_FIND(lib, name) \
name = (t##name *)dynamic_library_find(lib, #name);
#define HIP_LIBRARY_FIND_CHECKED(name) \
_LIBRARY_FIND_CHECKED(hip_lib, name)
#define HIP_LIBRARY_FIND(name) _LIBRARY_FIND(hip_lib, name)
static DynamicLibrary hip_lib;
/* Function definitions. */
thipGetErrorName *hipGetErrorName;
thipInit *hipInit;
thipDriverGetVersion *hipDriverGetVersion;
thipGetDevice *hipGetDevice;
thipGetDeviceCount *hipGetDeviceCount;
thipDeviceGetName *hipDeviceGetName;
thipDeviceGetAttribute *hipDeviceGetAttribute;
thipDeviceComputeCapability *hipDeviceComputeCapability;
thipDevicePrimaryCtxRetain *hipDevicePrimaryCtxRetain;
thipDevicePrimaryCtxRelease *hipDevicePrimaryCtxRelease;
thipDevicePrimaryCtxSetFlags *hipDevicePrimaryCtxSetFlags;
thipDevicePrimaryCtxGetState *hipDevicePrimaryCtxGetState;
thipDevicePrimaryCtxReset *hipDevicePrimaryCtxReset;
thipCtxCreate *hipCtxCreate;
thipCtxDestroy *hipCtxDestroy;
thipCtxPushCurrent *hipCtxPushCurrent;
thipCtxPopCurrent *hipCtxPopCurrent;
thipCtxSetCurrent *hipCtxSetCurrent;
thipCtxGetCurrent *hipCtxGetCurrent;
thipCtxGetDevice *hipCtxGetDevice;
thipCtxGetFlags *hipCtxGetFlags;
thipCtxSynchronize *hipCtxSynchronize;
thipDeviceSynchronize *hipDeviceSynchronize;
thipCtxGetCacheConfig *hipCtxGetCacheConfig;
thipCtxSetCacheConfig *hipCtxSetCacheConfig;
thipCtxGetSharedMemConfig *hipCtxGetSharedMemConfig;
thipCtxSetSharedMemConfig *hipCtxSetSharedMemConfig;
thipCtxGetApiVersion *hipCtxGetApiVersion;
thipModuleLoad *hipModuleLoad;
thipModuleLoadData *hipModuleLoadData;
thipModuleLoadDataEx *hipModuleLoadDataEx;
thipModuleUnload *hipModuleUnload;
thipModuleGetFunction *hipModuleGetFunction;
thipModuleGetGlobal *hipModuleGetGlobal;
thipModuleGetTexRef *hipModuleGetTexRef;
thipMemGetInfo *hipMemGetInfo;
thipMalloc *hipMalloc;
thipMemAllocPitch *hipMemAllocPitch;
thipFree *hipFree;
thipMemGetAddressRange *hipMemGetAddressRange;
thipHostMalloc *hipHostMalloc;
thipHostFree *hipHostFree;
thipHostGetDevicePointer *hipHostGetDevicePointer;
thipHostGetFlags *hipHostGetFlags;
thipMallocManaged *hipMallocManaged;
thipDeviceGetByPCIBusId *hipDeviceGetByPCIBusId;
thipDeviceGetPCIBusId *hipDeviceGetPCIBusId;
thipMemcpyPeer *hipMemcpyPeer;
thipMemcpyHtoD *hipMemcpyHtoD;
thipMemcpyDtoH *hipMemcpyDtoH;
thipMemcpyDtoD *hipMemcpyDtoD;
thipDrvMemcpy2DUnaligned *hipDrvMemcpy2DUnaligned;
thipMemcpyParam2D *hipMemcpyParam2D;
thipDrvMemcpy3D *hipDrvMemcpy3D;
thipMemcpyHtoDAsync *hipMemcpyHtoDAsync;
thipMemcpyDtoHAsync *hipMemcpyDtoHAsync;
thipMemcpyParam2DAsync *hipMemcpyParam2DAsync;
thipDrvMemcpy3DAsync *hipDrvMemcpy3DAsync;
thipMemsetD8 *hipMemsetD8;
thipMemsetD16 *hipMemsetD16;
thipMemsetD32 *hipMemsetD32;
thipMemsetD8Async *hipMemsetD8Async;
thipMemsetD16Async *hipMemsetD16Async;
thipMemsetD32Async *hipMemsetD32Async;
thipArrayCreate *hipArrayCreate;
thipArrayDestroy *hipArrayDestroy;
thipArray3DCreate *hipArray3DCreate;
thipStreamCreateWithFlags *hipStreamCreateWithFlags;
thipStreamCreateWithPriority *hipStreamCreateWithPriority;
thipStreamGetPriority *hipStreamGetPriority;
thipStreamGetFlags *hipStreamGetFlags;
thipStreamWaitEvent *hipStreamWaitEvent;
thipStreamAddCallback *hipStreamAddCallback;
thipStreamQuery *hipStreamQuery;
thipStreamSynchronize *hipStreamSynchronize;
thipStreamDestroy *hipStreamDestroy;
thipEventCreateWithFlags *hipEventCreateWithFlags;
thipEventRecord *hipEventRecord;
thipEventQuery *hipEventQuery;
thipEventSynchronize *hipEventSynchronize;
thipEventDestroy *hipEventDestroy;
thipEventElapsedTime *hipEventElapsedTime;
thipFuncGetAttribute *hipFuncGetAttribute;
thipFuncSetCacheConfig *hipFuncSetCacheConfig;
thipModuleLaunchKernel *hipModuleLaunchKernel;
thipDrvOccupancyMaxActiveBlocksPerMultiprocessor *hipDrvOccupancyMaxActiveBlocksPerMultiprocessor;
thipDrvOccupancyMaxActiveBlocksPerMultiprocessorWithFlags *hipDrvOccupancyMaxActiveBlocksPerMultiprocessorWithFlags;
thipModuleOccupancyMaxPotentialBlockSize *hipModuleOccupancyMaxPotentialBlockSize;
thipTexRefSetArray *hipTexRefSetArray;
thipTexRefSetAddress *hipTexRefSetAddress;
thipTexRefSetAddress2D *hipTexRefSetAddress2D;
thipTexRefSetFormat *hipTexRefSetFormat;
thipTexRefSetAddressMode *hipTexRefSetAddressMode;
thipTexRefSetFilterMode *hipTexRefSetFilterMode;
thipTexRefSetFlags *hipTexRefSetFlags;
thipTexRefGetAddress *hipTexRefGetAddress;
thipTexRefGetArray *hipTexRefGetArray;
thipTexRefGetAddressMode *hipTexRefGetAddressMode;
thipTexObjectCreate *hipTexObjectCreate;
thipTexObjectDestroy *hipTexObjectDestroy;
thipDeviceCanAccessPeer *hipDeviceCanAccessPeer;
thipCtxEnablePeerAccess *hipCtxEnablePeerAccess;
thipCtxDisablePeerAccess *hipCtxDisablePeerAccess;
thipDeviceGetP2PAttribute *hipDeviceGetP2PAttribute;
thipGraphicsUnregisterResource *hipGraphicsUnregisterResource;
thipGraphicsMapResources *hipGraphicsMapResources;
thipGraphicsUnmapResources *hipGraphicsUnmapResources;
thipGraphicsResourceGetMappedPointer *hipGraphicsResourceGetMappedPointer;
thipGraphicsGLRegisterBuffer *hipGraphicsGLRegisterBuffer;
thipGLGetDevices *hipGLGetDevices;
static DynamicLibrary dynamic_library_open_find(const char **paths) {
int i = 0;
while (paths[i] != NULL) {
DynamicLibrary lib = dynamic_library_open(paths[i]);
if (lib != NULL) {
return lib;
}
++i;
}
return NULL;
}
/* Implementation function. */
static void hipewHipExit(void) {
if (hip_lib != NULL) {
/* Ignore errors. */
dynamic_library_close(hip_lib);
hip_lib = NULL;
}
}
static int hipewHipInit(void) {
/* Library paths. */
#ifdef _WIN32
/* Expected in c:/windows/system or similar, no path needed. */
const char *hip_paths[] = {"amdhip64.dll", NULL};
#elif defined(__APPLE__)
/* Default installation path. */
const char *hip_paths[] = {"", NULL};
#else
const char *hip_paths[] = {"/opt/rocm/hip/lib/libamdhip64.so", NULL};
#endif
static int initialized = 0;
static int result = 0;
int error, driver_version;
if (initialized) {
return result;
}
initialized = 1;
error = atexit(hipewHipExit);
if (error) {
result = HIPEW_ERROR_ATEXIT_FAILED;
return result;
}
/* Load library. */
hip_lib = dynamic_library_open_find(hip_paths);
if (hip_lib == NULL) {
result = HIPEW_ERROR_OPEN_FAILED;
return result;
}
/* Fetch all function pointers. */
HIP_LIBRARY_FIND_CHECKED(hipGetErrorName);
HIP_LIBRARY_FIND_CHECKED(hipInit);
HIP_LIBRARY_FIND_CHECKED(hipDriverGetVersion);
HIP_LIBRARY_FIND_CHECKED(hipGetDevice);
HIP_LIBRARY_FIND_CHECKED(hipGetDeviceCount);
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetName);
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetAttribute);
HIP_LIBRARY_FIND_CHECKED(hipDeviceComputeCapability);
HIP_LIBRARY_FIND_CHECKED(hipDevicePrimaryCtxRetain);
HIP_LIBRARY_FIND_CHECKED(hipDevicePrimaryCtxRelease);
HIP_LIBRARY_FIND_CHECKED(hipDevicePrimaryCtxSetFlags);
HIP_LIBRARY_FIND_CHECKED(hipDevicePrimaryCtxGetState);
HIP_LIBRARY_FIND_CHECKED(hipDevicePrimaryCtxReset);
HIP_LIBRARY_FIND_CHECKED(hipCtxCreate);
HIP_LIBRARY_FIND_CHECKED(hipCtxDestroy);
HIP_LIBRARY_FIND_CHECKED(hipCtxPushCurrent);
HIP_LIBRARY_FIND_CHECKED(hipCtxPopCurrent);
HIP_LIBRARY_FIND_CHECKED(hipCtxSetCurrent);
HIP_LIBRARY_FIND_CHECKED(hipCtxGetCurrent);
HIP_LIBRARY_FIND_CHECKED(hipCtxGetDevice);
HIP_LIBRARY_FIND_CHECKED(hipCtxGetFlags);
HIP_LIBRARY_FIND_CHECKED(hipCtxSynchronize);
HIP_LIBRARY_FIND_CHECKED(hipDeviceSynchronize);
HIP_LIBRARY_FIND_CHECKED(hipCtxGetCacheConfig);
HIP_LIBRARY_FIND_CHECKED(hipCtxSetCacheConfig);
HIP_LIBRARY_FIND_CHECKED(hipCtxGetSharedMemConfig);
HIP_LIBRARY_FIND_CHECKED(hipCtxSetSharedMemConfig);
HIP_LIBRARY_FIND_CHECKED(hipCtxGetApiVersion);
HIP_LIBRARY_FIND_CHECKED(hipModuleLoad);
HIP_LIBRARY_FIND_CHECKED(hipModuleLoadData);
HIP_LIBRARY_FIND_CHECKED(hipModuleLoadDataEx);
HIP_LIBRARY_FIND_CHECKED(hipModuleUnload);
HIP_LIBRARY_FIND_CHECKED(hipModuleGetFunction);
HIP_LIBRARY_FIND_CHECKED(hipModuleGetGlobal);
HIP_LIBRARY_FIND_CHECKED(hipModuleGetTexRef);
HIP_LIBRARY_FIND_CHECKED(hipMemGetInfo);
HIP_LIBRARY_FIND_CHECKED(hipMalloc);
HIP_LIBRARY_FIND_CHECKED(hipMemAllocPitch);
HIP_LIBRARY_FIND_CHECKED(hipFree);
HIP_LIBRARY_FIND_CHECKED(hipMemGetAddressRange);
HIP_LIBRARY_FIND_CHECKED(hipHostMalloc);
HIP_LIBRARY_FIND_CHECKED(hipHostFree);
HIP_LIBRARY_FIND_CHECKED(hipHostGetDevicePointer);
HIP_LIBRARY_FIND_CHECKED(hipHostGetFlags);
HIP_LIBRARY_FIND_CHECKED(hipMallocManaged);
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetByPCIBusId);
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetPCIBusId);
HIP_LIBRARY_FIND_CHECKED(hipMemcpyPeer);
HIP_LIBRARY_FIND_CHECKED(hipMemcpyHtoD);
HIP_LIBRARY_FIND_CHECKED(hipMemcpyDtoH);
HIP_LIBRARY_FIND_CHECKED(hipMemcpyDtoD);
HIP_LIBRARY_FIND_CHECKED(hipMemcpyParam2D);
HIP_LIBRARY_FIND_CHECKED(hipDrvMemcpy3D);
HIP_LIBRARY_FIND_CHECKED(hipMemcpyHtoDAsync);
HIP_LIBRARY_FIND_CHECKED(hipMemcpyDtoHAsync);
HIP_LIBRARY_FIND_CHECKED(hipDrvMemcpy2DUnaligned);
HIP_LIBRARY_FIND_CHECKED(hipMemcpyParam2DAsync);
HIP_LIBRARY_FIND_CHECKED(hipDrvMemcpy3DAsync);
HIP_LIBRARY_FIND_CHECKED(hipMemsetD8);
HIP_LIBRARY_FIND_CHECKED(hipMemsetD16);
HIP_LIBRARY_FIND_CHECKED(hipMemsetD32);
HIP_LIBRARY_FIND_CHECKED(hipMemsetD8Async);
HIP_LIBRARY_FIND_CHECKED(hipMemsetD16Async);
HIP_LIBRARY_FIND_CHECKED(hipMemsetD32Async);
HIP_LIBRARY_FIND_CHECKED(hipArrayCreate);
HIP_LIBRARY_FIND_CHECKED(hipArrayDestroy);
HIP_LIBRARY_FIND_CHECKED(hipArray3DCreate);
HIP_LIBRARY_FIND_CHECKED(hipStreamCreateWithFlags);
HIP_LIBRARY_FIND_CHECKED(hipStreamCreateWithPriority);
HIP_LIBRARY_FIND_CHECKED(hipStreamGetPriority);
HIP_LIBRARY_FIND_CHECKED(hipStreamGetFlags);
HIP_LIBRARY_FIND_CHECKED(hipStreamWaitEvent);
HIP_LIBRARY_FIND_CHECKED(hipStreamAddCallback);
HIP_LIBRARY_FIND_CHECKED(hipStreamQuery);
HIP_LIBRARY_FIND_CHECKED(hipStreamSynchronize);
HIP_LIBRARY_FIND_CHECKED(hipStreamDestroy);
HIP_LIBRARY_FIND_CHECKED(hipEventCreateWithFlags);
HIP_LIBRARY_FIND_CHECKED(hipEventRecord);
HIP_LIBRARY_FIND_CHECKED(hipEventQuery);
HIP_LIBRARY_FIND_CHECKED(hipEventSynchronize);
HIP_LIBRARY_FIND_CHECKED(hipEventDestroy);
HIP_LIBRARY_FIND_CHECKED(hipEventElapsedTime);
HIP_LIBRARY_FIND_CHECKED(hipFuncGetAttribute);
HIP_LIBRARY_FIND_CHECKED(hipFuncSetCacheConfig);
HIP_LIBRARY_FIND_CHECKED(hipModuleLaunchKernel);
HIP_LIBRARY_FIND_CHECKED(hipModuleOccupancyMaxPotentialBlockSize);
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetArray);
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetAddress);
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetAddress2D);
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetFormat);
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetAddressMode);
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetFilterMode);
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetFlags);
HIP_LIBRARY_FIND_CHECKED(hipTexRefGetAddress);
HIP_LIBRARY_FIND_CHECKED(hipTexRefGetAddressMode);
HIP_LIBRARY_FIND_CHECKED(hipTexObjectCreate);
HIP_LIBRARY_FIND_CHECKED(hipTexObjectDestroy);
HIP_LIBRARY_FIND_CHECKED(hipDeviceCanAccessPeer);
HIP_LIBRARY_FIND_CHECKED(hipCtxEnablePeerAccess);
HIP_LIBRARY_FIND_CHECKED(hipCtxDisablePeerAccess);
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetP2PAttribute);
#ifdef _WIN32
HIP_LIBRARY_FIND_CHECKED(hipGraphicsUnregisterResource);
HIP_LIBRARY_FIND_CHECKED(hipGraphicsMapResources);
HIP_LIBRARY_FIND_CHECKED(hipGraphicsUnmapResources);
HIP_LIBRARY_FIND_CHECKED(hipGraphicsResourceGetMappedPointer);
HIP_LIBRARY_FIND_CHECKED(hipGraphicsGLRegisterBuffer);
HIP_LIBRARY_FIND_CHECKED(hipGLGetDevices);
#endif
result = HIPEW_SUCCESS;
return result;
}
int hipewInit(hipuint32_t flags) {
int result = HIPEW_SUCCESS;
if (flags & HIPEW_INIT_HIP) {
result = hipewHipInit();
if (result != HIPEW_SUCCESS) {
return result;
}
}
return result;
}
const char *hipewErrorString(hipError_t result) {
switch (result) {
case hipSuccess: return "No errors";
case hipErrorInvalidValue: return "Invalid value";
case hipErrorOutOfMemory: return "Out of memory";
case hipErrorNotInitialized: return "Driver not initialized";
case hipErrorDeinitialized: return "Driver deinitialized";
case hipErrorProfilerDisabled: return "Profiler disabled";
case hipErrorProfilerNotInitialized: return "Profiler not initialized";
case hipErrorProfilerAlreadyStarted: return "Profiler already started";
case hipErrorProfilerAlreadyStopped: return "Profiler already stopped";
case hipErrorNoDevice: return "No HIP-capable device available";
case hipErrorInvalidDevice: return "Invalid device";
case hipErrorInvalidImage: return "Invalid kernel image";
case hipErrorInvalidContext: return "Invalid context";
case hipErrorContextAlreadyCurrent: return "Context already current";
case hipErrorMapFailed: return "Map failed";
case hipErrorUnmapFailed: return "Unmap failed";
case hipErrorArrayIsMapped: return "Array is mapped";
case hipErrorAlreadyMapped: return "Already mapped";
case hipErrorNoBinaryForGpu: return "No binary for GPU";
case hipErrorAlreadyAcquired: return "Already acquired";
case hipErrorNotMapped: return "Not mapped";
case hipErrorNotMappedAsArray: return "Mapped resource not available for access as an array";
case hipErrorNotMappedAsPointer: return "Mapped resource not available for access as a pointer";
case hipErrorECCNotCorrectable: return "Uncorrectable ECC error detected";
case hipErrorUnsupportedLimit: return "hipLimit_t not supported by device";
case hipErrorContextAlreadyInUse: return "Context already in use";
case hipErrorPeerAccessUnsupported: return "Peer access unsupported";
case hipErrorInvalidKernelFile: return "Invalid ptx";
case hipErrorInvalidGraphicsContext: return "Invalid graphics context";
case hipErrorInvalidSource: return "Invalid source";
case hipErrorFileNotFound: return "File not found";
case hipErrorSharedObjectSymbolNotFound: return "Link to a shared object failed to resolve";
case hipErrorSharedObjectInitFailed: return "Shared object initialization failed";
case hipErrorOperatingSystem: return "Operating system";
case hipErrorInvalidHandle: return "Invalid handle";
case hipErrorNotFound: return "Not found";
case hipErrorNotReady: return "HIP not ready";
case hipErrorIllegalAddress: return "Illegal address";
case hipErrorLaunchOutOfResources: return "Launch exceeded resources";
case hipErrorLaunchTimeOut: return "Launch exceeded timeout";
case hipErrorPeerAccessAlreadyEnabled: return "Peer access already enabled";
case hipErrorPeerAccessNotEnabled: return "Peer access not enabled";
case hipErrorSetOnActiveProcess: return "Primary context active";
case hipErrorAssert: return "Assert";
case hipErrorHostMemoryAlreadyRegistered: return "Host memory already registered";
case hipErrorHostMemoryNotRegistered: return "Host memory not registered";
case hipErrorLaunchFailure: return "Launch failed";
case hipErrorCooperativeLaunchTooLarge: return "Cooperative launch too large";
case hipErrorNotSupported: return "Not supported";
case hipErrorUnknown: return "Unknown error";
default: return "Unknown HIP error value";
}
}
static void path_join(const char *path1,
const char *path2,
int maxlen,
char *result) {
#if defined(WIN32) || defined(_WIN32)
const char separator = '\\';
#else
const char separator = '/';
#endif
int n = snprintf(result, maxlen, "%s%c%s", path1, separator, path2);
if (n != -1 && n < maxlen) {
result[n] = '\0';
}
else {
result[maxlen - 1] = '\0';
}
}
static int path_exists(const char *path) {
struct stat st;
if (stat(path, &st)) {
return 0;
}
return 1;
}
const char *hipewCompilerPath(void) {
#ifdef _WIN32
const char *hipPath = getenv("HIP_ROCCLR_HOME");
const char *windowsCommand = "perl ";
const char *executable = "bin/hipcc";
static char hipcc[65536];
static char finalCommand[65536];
if(hipPath) {
path_join(hipPath, executable, sizeof(hipcc), hipcc);
if(path_exists(hipcc)) {
snprintf(finalCommand, sizeof(hipcc), "%s %s", windowsCommand, hipcc);
return finalCommand;
} else {
printf("Could not find hipcc. Make sure HIP_ROCCLR_HOME points to the directory holding /bin/hipcc");
}
}
#else
const char *hipPath = "opt/rocm/hip/bin";
const char *executable = "hipcc";
static char hipcc[65536];
if(hipPath) {
path_join(hipPath, executable, sizeof(hipcc), hipcc);
if(path_exists(hipcc)){
return hipcc;
}
}
#endif
{
#ifdef _WIN32
FILE *handle = popen("where hipcc", "r");
#else
FILE *handle = popen("which hipcc", "r");
#endif
if (handle) {
char buffer[4096] = {0};
int len = fread(buffer, 1, sizeof(buffer) - 1, handle);
buffer[len] = '\0';
pclose(handle);
if (buffer[0]) {
return "hipcc";
}
}
}
return NULL;
}
int hipewCompilerVersion(void) {
const char *path = hipewCompilerPath();
const char *marker = "Hip compilation tools, release ";
FILE *pipe;
int major, minor;
char *versionstr;
char buf[128];
char output[65536] = "\0";
char command[65536] = "\0";
if (path == NULL) {
return 0;
}
/* get --version output */
strcat(command, "\"");
strncat(command, path, sizeof(command) - 1);
strncat(command, "\" --version", sizeof(command) - strlen(path) - 1);
pipe = popen(command, "r");
if (!pipe) {
fprintf(stderr, "HIP: failed to run compiler to retrieve version");
return 0;
}
while (!feof(pipe)) {
if (fgets(buf, sizeof(buf), pipe) != NULL) {
strncat(output, buf, sizeof(output) - strlen(output) - 1);
}
}
pclose(pipe);
return 40;
}

View File

@@ -574,6 +574,8 @@ Dbl2 AreaDiag::area(Dbl2 p1, Dbl2 p2, int left)
Dbl2 d = p2 - p1;
if (d.x == 0.0)
return Dbl2(0.0, 1.0);
if (d.y == 0.0)
return Dbl2(1.0, 0.0);
double x1 = (double)(1 + left);
double x2 = x1 + 1.0;

View File

@@ -2,4 +2,5 @@ Project: TinyGLTF
URL: https://github.com/syoyo/tinygltf
License: MIT
Upstream version: 2.5.0, 19a41d20ec0
Local modifications: None
Local modifications:
* Silence "enum value not handled in switch" warnings due to JSON dependency.

View File

@@ -3201,6 +3201,7 @@ static bool ParseJsonAsValue(Value *ret, const json &o) {
val = Value(o.get<double>());
break;
case json::value_t::null:
case json::value_t::binary:
case json::value_t::discarded:
// default:
break;

View File

@@ -297,6 +297,7 @@ endif()
if(WITH_CYCLES_STANDALONE)
set(WITH_CYCLES_DEVICE_CUDA TRUE)
set(WITH_CYCLES_DEVICE_HIP TRUE)
endif()
# TODO(sergey): Consider removing it, only causes confusion in interface.
set(WITH_CYCLES_DEVICE_MULTI TRUE)

View File

@@ -64,6 +64,8 @@ if(WITH_CYCLES_STANDALONE)
cycles_standalone.cpp
cycles_xml.cpp
cycles_xml.h
oiio_output_driver.cpp
oiio_output_driver.h
)
add_executable(cycles ${SRC} ${INC} ${INC_SYS})
unset(SRC)
@@ -73,7 +75,7 @@ if(WITH_CYCLES_STANDALONE)
if(APPLE)
if(WITH_OPENCOLORIO)
set_property(TARGET cycles APPEND_STRING PROPERTY LINK_FLAGS " -framework IOKit")
set_property(TARGET cycles APPEND_STRING PROPERTY LINK_FLAGS " -framework IOKit -framework Carbon")
endif()
if(WITH_OPENIMAGEDENOISE AND "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
# OpenImageDenoise uses BNNS from the Accelerate framework.

View File

@@ -36,6 +36,9 @@
#include "util/util_unique_ptr.h"
#include "util/util_version.h"
#include "app/cycles_xml.h"
#include "app/oiio_output_driver.h"
#ifdef WITH_CYCLES_STANDALONE_GUI
# include "util/util_view.h"
#endif
@@ -53,7 +56,8 @@ struct Options {
SessionParams session_params;
bool quiet;
bool show_help, interactive, pause;
string output_path;
string output_filepath;
string output_pass;
} options;
static void session_print(const string &str)
@@ -89,30 +93,6 @@ static void session_print_status()
session_print(status);
}
static bool write_render(const uchar *pixels, int w, int h, int channels)
{
string msg = string_printf("Writing image %s", options.output_path.c_str());
session_print(msg);
unique_ptr<ImageOutput> out = unique_ptr<ImageOutput>(ImageOutput::create(options.output_path));
if (!out) {
return false;
}
ImageSpec spec(w, h, channels, TypeDesc::UINT8);
if (!out->open(options.output_path, spec)) {
return false;
}
/* conversion for different top/bottom convention */
out->write_image(
TypeDesc::UINT8, pixels + (h - 1) * w * channels, AutoStride, -w * channels, AutoStride);
out->close();
return true;
}
static BufferParams &session_buffer_params()
{
static BufferParams buffer_params;
@@ -147,9 +127,14 @@ static void scene_init()
static void session_init()
{
options.session_params.write_render_cb = write_render;
options.output_pass = "combined";
options.session = new Session(options.session_params, options.scene_params);
if (!options.output_filepath.empty()) {
options.session->set_output_driver(make_unique<OIIOOutputDriver>(
options.output_filepath, options.output_pass, session_print));
}
if (options.session_params.background && !options.quiet)
options.session->progress.set_update_callback(function_bind(&session_print_status));
#ifdef WITH_CYCLES_STANDALONE_GUI
@@ -160,7 +145,12 @@ static void session_init()
/* load scene */
scene_init();
options.session->reset(session_buffer_params(), options.session_params.samples);
/* add pass for output. */
Pass *pass = options.scene->create_node<Pass>();
pass->set_name(ustring(options.output_pass.c_str()));
pass->set_type(PASS_COMBINED);
options.session->reset(options.session_params, session_buffer_params());
options.session->start();
}
@@ -222,9 +212,7 @@ static void display_info(Progress &progress)
static void display()
{
static DeviceDrawParams draw_params = DeviceDrawParams();
options.session->draw(session_buffer_params(), draw_params);
options.session->draw();
display_info(options.session->progress);
}
@@ -254,7 +242,7 @@ static void motion(int x, int y, int button)
options.session->scene->camera->need_flags_update = true;
options.session->scene->camera->need_device_update = true;
options.session->reset(session_buffer_params(), options.session_params.samples);
options.session->reset(options.session_params, session_buffer_params());
}
}
@@ -271,7 +259,7 @@ static void resize(int width, int height)
options.session->scene->camera->need_flags_update = true;
options.session->scene->camera->need_device_update = true;
options.session->reset(session_buffer_params(), options.session_params.samples);
options.session->reset(options.session_params, session_buffer_params());
}
}
@@ -283,7 +271,7 @@ static void keyboard(unsigned char key)
/* Reset */
else if (key == 'r')
options.session->reset(session_buffer_params(), options.session_params.samples);
options.session->reset(options.session_params, session_buffer_params());
/* Cancel */
else if (key == 27) // escape
@@ -320,7 +308,7 @@ static void keyboard(unsigned char key)
options.session->scene->camera->need_flags_update = true;
options.session->scene->camera->need_device_update = true;
options.session->reset(session_buffer_params(), options.session_params.samples);
options.session->reset(options.session_params, session_buffer_params());
}
/* Set Max Bounces */
@@ -346,7 +334,7 @@ static void keyboard(unsigned char key)
options.session->scene->integrator->set_max_bounce(bounce);
options.session->reset(session_buffer_params(), options.session_params.samples);
options.session->reset(options.session_params, session_buffer_params());
}
}
#endif
@@ -361,11 +349,13 @@ static int files_parse(int argc, const char *argv[])
static void options_parse(int argc, const char **argv)
{
options.width = 0;
options.height = 0;
options.width = 1024;
options.height = 512;
options.filepath = "";
options.session = NULL;
options.quiet = false;
options.session_params.use_auto_tile = false;
options.session_params.tile_size = 0;
/* device names */
string device_names = "";
@@ -411,7 +401,7 @@ static void options_parse(int argc, const char **argv)
&options.session_params.samples,
"Number of samples to render",
"--output %s",
&options.output_path,
&options.output_filepath,
"File path to write output image",
"--threads %d",
&options.session_params.threads,
@@ -422,12 +412,9 @@ static void options_parse(int argc, const char **argv)
"--height %d",
&options.height,
"Window height in pixel",
"--tile-width %d",
&options.session_params.tile_size.x,
"Tile width in pixels",
"--tile-height %d",
&options.session_params.tile_size.y,
"Tile height in pixels",
"--tile-size %d",
&options.session_params.tile_size,
"Tile size in pixels",
"--list-devices",
&list,
"List information about all available devices",
@@ -489,8 +476,9 @@ static void options_parse(int argc, const char **argv)
options.session_params.background = true;
#endif
/* Use progressive rendering */
options.session_params.progressive = true;
if (options.session_params.tile_size > 0) {
options.session_params.use_auto_tile = true;
}
/* find matching device */
DeviceType device_type = Device::type_from_string(devicename.c_str());

View File

@@ -333,6 +333,7 @@ static void xml_read_shader_graph(XMLReadState &state, Shader *shader, xml_node
}
snode = (ShaderNode *)node_type->create(node_type);
snode->set_owner(graph);
}
xml_read_node(graph_reader, snode, node);

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2021 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/oiio_output_driver.h"
CCL_NAMESPACE_BEGIN
OIIOOutputDriver::OIIOOutputDriver(const string_view filepath,
const string_view pass,
LogFunction log)
: filepath_(filepath), pass_(pass), log_(log)
{
}
OIIOOutputDriver::~OIIOOutputDriver()
{
}
void OIIOOutputDriver::write_render_tile(const Tile &tile)
{
/* Only write the full buffer, no intermediate tiles. */
if (!(tile.size == tile.full_size)) {
return;
}
log_(string_printf("Writing image %s", filepath_.c_str()));
unique_ptr<ImageOutput> image_output(ImageOutput::create(filepath_));
if (image_output == nullptr) {
log_("Failed to create image file");
return;
}
const int width = tile.size.x;
const int height = tile.size.y;
ImageSpec spec(width, height, 4, TypeDesc::FLOAT);
if (!image_output->open(filepath_, spec)) {
log_("Failed to create image file");
return;
}
vector<float> pixels(width * height * 4);
if (!tile.get_pass_pixels(pass_, 4, pixels.data())) {
log_("Failed to read render pass pixels");
return;
}
/* Manipulate offset and stride to convert from bottom-up to top-down convention. */
image_output->write_image(TypeDesc::FLOAT,
pixels.data() + (height - 1) * width * 4,
AutoStride,
-width * 4 * sizeof(float),
AutoStride);
image_output->close();
}
CCL_NAMESPACE_END

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2021 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 "render/output_driver.h"
#include "util/util_function.h"
#include "util/util_image.h"
#include "util/util_string.h"
#include "util/util_unique_ptr.h"
#include "util/util_vector.h"
CCL_NAMESPACE_BEGIN
class OIIOOutputDriver : public OutputDriver {
public:
typedef function<void(const string &)> LogFunction;
OIIOOutputDriver(const string_view filepath, const string_view pass, LogFunction log);
virtual ~OIIOOutputDriver();
void write_render_tile(const Tile &tile) override;
protected:
string filepath_;
string pass_;
LogFunction log_;
};
CCL_NAMESPACE_END

View File

@@ -31,13 +31,14 @@ set(INC_SYS
set(SRC
blender_camera.cpp
blender_device.cpp
blender_display_driver.cpp
blender_image.cpp
blender_geometry.cpp
blender_gpu_display.cpp
blender_light.cpp
blender_mesh.cpp
blender_object.cpp
blender_object_cull.cpp
blender_output_driver.cpp
blender_particles.cpp
blender_curves.cpp
blender_logging.cpp
@@ -51,10 +52,11 @@ set(SRC
CCL_api.h
blender_device.h
blender_gpu_display.h
blender_display_driver.h
blender_id_map.h
blender_image.h
blender_object_cull.h
blender_output_driver.h
blender_sync.h
blender_session.h
blender_texture.h
@@ -95,6 +97,9 @@ set(ADDON_FILES
add_definitions(${GL_DEFINITIONS})
if(WITH_CYCLES_DEVICE_HIP)
add_definitions(-DWITH_HIP)
endif()
if(WITH_MOD_FLUID)
add_definitions(-DWITH_FLUID)
endif()

View File

@@ -28,7 +28,7 @@ def _configure_argument_parser():
action='store_true')
parser.add_argument("--cycles-device",
help="Set the device to use for Cycles, overriding user preferences and the scene setting."
"Valid options are 'CPU', 'CUDA' or 'OPTIX'."
"Valid options are 'CPU', 'CUDA', 'OPTIX', or 'HIP'"
"Additionally, you can append '+CPU' to any GPU type for hybrid rendering.",
default=None)
return parser
@@ -211,7 +211,6 @@ def list_render_passes(scene, srl):
if crl.use_pass_shadow_catcher: yield ("Shadow Catcher", "RGB", 'COLOR')
# Debug passes.
if crl.pass_debug_render_time: yield ("Debug Render Time", "X", 'VALUE')
if crl.pass_debug_sample_count: yield ("Debug Sample Count", "X", 'VALUE')
# Cryptomatte passes.

View File

@@ -111,6 +111,7 @@ enum_device_type = (
('CPU', "CPU", "CPU", 0),
('CUDA', "CUDA", "CUDA", 1),
('OPTIX', "OptiX", "OptiX", 3),
("HIP", "HIP", "HIP", 4)
)
enum_texture_limit = (
@@ -123,7 +124,7 @@ enum_texture_limit = (
('4096', "4096", "Limit texture size to 4096 pixels", 6),
('8192', "8192", "Limit texture size to 8192 pixels", 7),
)
# NOTE: Identifiers are expected to be an upper case version of identifiers from `Pass::get_type_enum()`
enum_view3d_shading_render_pass = (
('', "General", ""),
@@ -739,14 +740,14 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
use_auto_tile: BoolProperty(
name="Auto Tiles",
description="Automatically split image into tiles",
description="Automatically render high resolution images in tiles to reduce memory usage, using the specified tile size. Tiles are cached to disk while rendering to save memory",
default=True,
)
tile_size: IntProperty(
name="Tile Size",
default=2048,
description="",
min=0, max=16384,
min=8, max=16384,
)
# Various fine-tuning debug flags
@@ -1196,12 +1197,6 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
pass_debug_render_time: BoolProperty(
name="Debug Render Time",
description="Render time in milliseconds per sample and pixel",
default=False,
update=update_render_passes,
)
pass_debug_sample_count: BoolProperty(
name="Debug Sample Count",
description="Number of samples/camera rays per pixel",
@@ -1266,12 +1261,16 @@ class CyclesPreferences(bpy.types.AddonPreferences):
def get_device_types(self, context):
import _cycles
has_cuda, has_optix = _cycles.get_device_types()
has_cuda, has_optix, has_hip = _cycles.get_device_types()
list = [('NONE', "None", "Don't use compute device", 0)]
if has_cuda:
list.append(('CUDA', "CUDA", "Use CUDA for GPU acceleration", 1))
if has_optix:
list.append(('OPTIX', "OptiX", "Use OptiX for GPU acceleration", 3))
if has_hip:
list.append(('HIP', "HIP", "Use HIP for GPU acceleration", 4))
return list
compute_device_type: EnumProperty(
@@ -1296,7 +1295,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
def update_device_entries(self, device_list):
for device in device_list:
if not device[1] in {'CUDA', 'OPTIX', 'CPU'}:
if not device[1] in {'CUDA', 'OPTIX', 'CPU', 'HIP'}:
continue
# Try to find existing Device entry
entry = self.find_existing_device_entry(device)
@@ -1330,7 +1329,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
elif entry.type == 'CPU':
cpu_devices.append(entry)
# Extend all GPU devices with CPU.
if compute_device_type != 'CPU':
if compute_device_type != 'CPU' and compute_device_type != 'HIP':
devices.extend(cpu_devices)
return devices
@@ -1340,7 +1339,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
import _cycles
# Ensure `self.devices` is not re-allocated when the second call to
# get_devices_for_type is made, freeing items from the first list.
for device_type in ('CUDA', 'OPTIX', 'OPENCL'):
for device_type in ('CUDA', 'OPTIX', 'HIP'):
self.update_device_entries(_cycles.available_devices(device_type))
# Deprecated: use refresh_devices instead.

View File

@@ -99,6 +99,11 @@ def use_cuda(context):
return (get_device_type(context) == 'CUDA' and cscene.device == 'GPU')
def use_hip(context):
cscene = context.scene.cycles
return (get_device_type(context) == 'HIP' and cscene.device == 'GPU')
def use_optix(context):
cscene = context.scene.cycles
@@ -613,8 +618,8 @@ class CYCLES_RENDER_PT_performance_threads(CyclesButtonsPanel, Panel):
sub.prop(rd, "threads")
class CYCLES_RENDER_PT_performance_tiles(CyclesButtonsPanel, Panel):
bl_label = "Tiles"
class CYCLES_RENDER_PT_performance_memory(CyclesButtonsPanel, Panel):
bl_label = "Memory"
bl_parent_id = "CYCLES_RENDER_PT_performance"
def draw(self, context):
@@ -787,7 +792,6 @@ class CYCLES_RENDER_PT_passes_data(CyclesButtonsPanel, Panel):
col.prop(view_layer, "use_pass_material_index")
col = layout.column(heading="Debug", align=True)
col.prop(cycles_view_layer, "pass_debug_render_time", text="Render Time")
col.prop(cycles_view_layer, "pass_debug_sample_count", text="Sample Count")
layout.prop(view_layer, "pass_alpha_threshold")
@@ -2107,7 +2111,7 @@ classes = (
CYCLES_RENDER_PT_film_transparency,
CYCLES_RENDER_PT_performance,
CYCLES_RENDER_PT_performance_threads,
CYCLES_RENDER_PT_performance_tiles,
CYCLES_RENDER_PT_performance_memory,
CYCLES_RENDER_PT_performance_acceleration_structure,
CYCLES_RENDER_PT_performance_final_render,
CYCLES_RENDER_PT_performance_viewport,

View File

@@ -927,6 +927,9 @@ BufferParams BlenderSync::get_buffer_params(
params.height = height;
}
params.window_width = params.width;
params.window_height = params.height;
return params;
}

View File

@@ -283,10 +283,13 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
return;
Attribute *attr_intercept = NULL;
Attribute *attr_length = NULL;
Attribute *attr_random = NULL;
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT))
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT);
if (hair->need_attribute(scene, ATTR_STD_CURVE_LENGTH))
attr_length = hair->attributes.add(ATTR_STD_CURVE_LENGTH);
if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM))
attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM);
@@ -336,6 +339,10 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
num_curve_keys++;
}
if (attr_length != NULL) {
attr_length->add(CData->curve_length[curve]);
}
if (attr_random != NULL) {
attr_random->add(hash_uint2_to_float(num_curves, 0));
}
@@ -657,11 +664,15 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
/* Add requested attributes. */
Attribute *attr_intercept = NULL;
Attribute *attr_length = NULL;
Attribute *attr_random = NULL;
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) {
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT);
}
if (hair->need_attribute(scene, ATTR_STD_CURVE_LENGTH)) {
attr_length = hair->attributes.add(ATTR_STD_CURVE_LENGTH);
}
if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) {
attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM);
}
@@ -714,6 +725,10 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
}
}
if (attr_length) {
attr_length->add(length);
}
/* Random number per curve. */
if (attr_random != NULL) {
attr_random->add(hash_uint2_to_float(b_curve.index(), 0));

View File

@@ -26,6 +26,7 @@ enum ComputeDevice {
COMPUTE_DEVICE_CPU = 0,
COMPUTE_DEVICE_CUDA = 1,
COMPUTE_DEVICE_OPTIX = 3,
COMPUTE_DEVICE_HIP = 4,
COMPUTE_DEVICE_NUM
};
@@ -81,6 +82,9 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
else if (compute_device == COMPUTE_DEVICE_OPTIX) {
mask |= DEVICE_MASK_OPTIX;
}
else if (compute_device == COMPUTE_DEVICE_HIP) {
mask |= DEVICE_MASK_HIP;
}
vector<DeviceInfo> devices = Device::available_devices(mask);
/* Match device preferences and available devices. */

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "blender/blender_gpu_display.h"
#include "blender/blender_display_driver.h"
#include "device/device.h"
#include "util/util_logging.h"
@@ -273,17 +273,17 @@ uint BlenderDisplaySpaceShader::get_shader_program()
}
/* --------------------------------------------------------------------
* BlenderGPUDisplay.
* BlenderDisplayDriver.
*/
BlenderGPUDisplay::BlenderGPUDisplay(BL::RenderEngine &b_engine, BL::Scene &b_scene)
BlenderDisplayDriver::BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene)
: b_engine_(b_engine), display_shader_(BlenderDisplayShader::create(b_engine, b_scene))
{
/* Create context while on the main thread. */
gl_context_create();
}
BlenderGPUDisplay::~BlenderGPUDisplay()
BlenderDisplayDriver::~BlenderDisplayDriver()
{
gl_resources_destroy();
}
@@ -292,19 +292,18 @@ BlenderGPUDisplay::~BlenderGPUDisplay()
* Update procedure.
*/
bool BlenderGPUDisplay::do_update_begin(const GPUDisplayParams &params,
bool BlenderDisplayDriver::update_begin(const Params &params,
int texture_width,
int texture_height)
{
/* Note that it's the responsibility of BlenderGPUDisplay to ensure updating and drawing
/* Note that it's the responsibility of BlenderDisplayDriver 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 at the GPU display level, because that would cause lock
* inversion. */
* This locking is not performed on the Cycles side, because that would cause lock inversion. */
if (!gl_context_enable()) {
return false;
}
@@ -361,7 +360,7 @@ bool BlenderGPUDisplay::do_update_begin(const GPUDisplayParams &params,
return true;
}
void BlenderGPUDisplay::do_update_end()
void BlenderDisplayDriver::update_end()
{
gl_upload_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
@@ -369,54 +368,18 @@ void BlenderGPUDisplay::do_update_end()
gl_context_disable();
}
/* --------------------------------------------------------------------
* Texture update from CPU buffer.
*/
void BlenderGPUDisplay::do_copy_pixels_to_texture(
const half4 *rgba_pixels, int texture_x, int texture_y, int pixels_width, int pixels_height)
{
/* This call copies pixels to a Pixel Buffer Object (PBO) which is much cheaper from CPU time
* point of view than to copy data directly to the OpenGL texture.
*
* The possible downside of this approach is that it might require a higher peak memory when
* doing partial updates of the texture (although, in practice even partial updates might peak
* with a full-frame buffer stored on the CPU if the GPU is currently occupied). */
half4 *mapped_rgba_pixels = map_texture_buffer();
if (!mapped_rgba_pixels) {
return;
}
if (texture_x == 0 && texture_y == 0 && pixels_width == texture_.width &&
pixels_height == texture_.height) {
const size_t size_in_bytes = sizeof(half4) * texture_.width * texture_.height;
memcpy(mapped_rgba_pixels, rgba_pixels, size_in_bytes);
}
else {
const half4 *rgba_row = rgba_pixels;
half4 *mapped_rgba_row = mapped_rgba_pixels + texture_y * texture_.width + texture_x;
for (int y = 0; y < pixels_height;
++y, rgba_row += pixels_width, mapped_rgba_row += texture_.width) {
memcpy(mapped_rgba_row, rgba_row, sizeof(half4) * pixels_width);
}
}
unmap_texture_buffer();
}
/* --------------------------------------------------------------------
* Texture buffer mapping.
*/
half4 *BlenderGPUDisplay::do_map_texture_buffer()
half4 *BlenderDisplayDriver::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 BlenderGPUDisplay pixel buffer object.";
LOG(ERROR) << "Error mapping BlenderDisplayDriver pixel buffer object.";
}
if (texture_.need_clear) {
@@ -431,7 +394,7 @@ half4 *BlenderGPUDisplay::do_map_texture_buffer()
return mapped_rgba_pixels;
}
void BlenderGPUDisplay::do_unmap_texture_buffer()
void BlenderDisplayDriver::unmap_texture_buffer()
{
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
@@ -442,9 +405,9 @@ void BlenderGPUDisplay::do_unmap_texture_buffer()
* Graphics interoperability.
*/
DeviceGraphicsInteropDestination BlenderGPUDisplay::do_graphics_interop_get()
BlenderDisplayDriver::GraphicsInterop BlenderDisplayDriver::graphics_interop_get()
{
DeviceGraphicsInteropDestination interop_dst;
GraphicsInterop interop_dst;
interop_dst.buffer_width = texture_.buffer_width;
interop_dst.buffer_height = texture_.buffer_height;
@@ -456,12 +419,12 @@ DeviceGraphicsInteropDestination BlenderGPUDisplay::do_graphics_interop_get()
return interop_dst;
}
void BlenderGPUDisplay::graphics_interop_activate()
void BlenderDisplayDriver::graphics_interop_activate()
{
gl_context_enable();
}
void BlenderGPUDisplay::graphics_interop_deactivate()
void BlenderDisplayDriver::graphics_interop_deactivate()
{
gl_context_disable();
}
@@ -470,27 +433,21 @@ void BlenderGPUDisplay::graphics_interop_deactivate()
* Drawing.
*/
void BlenderGPUDisplay::clear()
void BlenderDisplayDriver::clear()
{
texture_.need_clear = true;
}
void BlenderGPUDisplay::set_zoom(float zoom_x, float zoom_y)
void BlenderDisplayDriver::set_zoom(float zoom_x, float zoom_y)
{
zoom_ = make_float2(zoom_x, zoom_y);
}
void BlenderGPUDisplay::do_draw(const GPUDisplayParams &params)
void BlenderDisplayDriver::draw(const Params &params)
{
/* See do_update_begin() for why no locking is required here. */
const bool transparent = true; // TODO(sergey): Derive this from Film.
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;
}
@@ -499,6 +456,16 @@ void BlenderGPUDisplay::do_draw(const GPUDisplayParams &params)
gl_context_mutex_.lock();
}
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.
* Watch out for the lock though so that the clear happening during update is properly
* synchronized here. */
gl_context_mutex_.unlock();
return;
}
if (gl_upload_sync_) {
glWaitSync((GLsync)gl_upload_sync_, 0, GL_TIMEOUT_IGNORED);
}
@@ -524,7 +491,7 @@ void BlenderGPUDisplay::do_draw(const GPUDisplayParams &params)
const float zoomed_width = params.size.x * zoom_.x;
const float zoomed_height = params.size.y * zoom_.y;
if (texture_.width != params.size.x || texture_.height != params.size.y) {
/* Resolution divider is different from 1, force enarest interpolation. */
/* Resolution divider is different from 1, force nearest interpolation. */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
else if (zoomed_width - params.size.x > 0.5f || zoomed_height - params.size.y > 0.5f) {
@@ -580,7 +547,7 @@ void BlenderGPUDisplay::do_draw(const GPUDisplayParams &params)
}
}
void BlenderGPUDisplay::gl_context_create()
void BlenderDisplayDriver::gl_context_create()
{
/* When rendering in viewport there is no render context available via engine.
* Check whether own context is to be created here.
@@ -609,7 +576,7 @@ void BlenderGPUDisplay::gl_context_create()
}
}
bool BlenderGPUDisplay::gl_context_enable()
bool BlenderDisplayDriver::gl_context_enable()
{
if (use_gl_context_) {
if (!gl_context_) {
@@ -624,7 +591,7 @@ bool BlenderGPUDisplay::gl_context_enable()
return true;
}
void BlenderGPUDisplay::gl_context_disable()
void BlenderDisplayDriver::gl_context_disable()
{
if (use_gl_context_) {
if (gl_context_) {
@@ -637,7 +604,7 @@ void BlenderGPUDisplay::gl_context_disable()
RE_engine_render_context_disable(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
}
void BlenderGPUDisplay::gl_context_dispose()
void BlenderDisplayDriver::gl_context_dispose()
{
if (gl_context_) {
const bool drw_state = DRW_opengl_context_release();
@@ -649,7 +616,7 @@ void BlenderGPUDisplay::gl_context_dispose()
}
}
bool BlenderGPUDisplay::gl_draw_resources_ensure()
bool BlenderDisplayDriver::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
@@ -676,7 +643,7 @@ bool BlenderGPUDisplay::gl_draw_resources_ensure()
return true;
}
void BlenderGPUDisplay::gl_resources_destroy()
void BlenderDisplayDriver::gl_resources_destroy()
{
gl_context_enable();
@@ -699,7 +666,7 @@ void BlenderGPUDisplay::gl_resources_destroy()
gl_context_dispose();
}
bool BlenderGPUDisplay::gl_texture_resources_ensure()
bool BlenderDisplayDriver::gl_texture_resources_ensure()
{
if (texture_.creation_attempted) {
return texture_.is_created;
@@ -736,7 +703,7 @@ bool BlenderGPUDisplay::gl_texture_resources_ensure()
return true;
}
void BlenderGPUDisplay::texture_update_if_needed()
void BlenderDisplayDriver::texture_update_if_needed()
{
if (!texture_.need_update) {
return;
@@ -750,7 +717,7 @@ void BlenderGPUDisplay::texture_update_if_needed()
texture_.need_update = false;
}
void BlenderGPUDisplay::vertex_buffer_update(const GPUDisplayParams &params)
void BlenderDisplayDriver::vertex_buffer_update(const Params &params)
{
/* Invalidate old contents - avoids stalling if the buffer is still waiting in queue to be
* rendered. */
@@ -763,23 +730,23 @@ void BlenderGPUDisplay::vertex_buffer_update(const GPUDisplayParams &params)
vpointer[0] = 0.0f;
vpointer[1] = 0.0f;
vpointer[2] = params.offset.x;
vpointer[3] = params.offset.y;
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.offset.x;
vpointer[7] = params.offset.y;
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.offset.x;
vpointer[11] = (float)params.size.y + params.offset.y;
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.offset.x;
vpointer[15] = (float)params.size.y + params.offset.y;
vpointer[14] = params.full_offset.x;
vpointer[15] = (float)params.size.y + params.full_offset.y;
glUnmapBuffer(GL_ARRAY_BUFFER);
}

View File

@@ -22,12 +22,14 @@
#include "RNA_blender_cpp.h"
#include "render/gpu_display.h"
#include "render/display_driver.h"
#include "util/util_thread.h"
#include "util/util_unique_ptr.h"
CCL_NAMESPACE_BEGIN
/* Base class of shader used for GPU display rendering. */
/* Base class of shader used for display driver rendering. */
class BlenderDisplayShader {
public:
static constexpr const char *position_attribute_name = "pos";
@@ -96,11 +98,11 @@ class BlenderDisplaySpaceShader : public BlenderDisplayShader {
uint shader_program_ = 0;
};
/* GPU display implementation which is specific for Blender viewport integration. */
class BlenderGPUDisplay : public GPUDisplay {
/* Display driver implementation which is specific for Blender viewport integration. */
class BlenderDisplayDriver : public DisplayDriver {
public:
BlenderGPUDisplay(BL::RenderEngine &b_engine, BL::Scene &b_scene);
~BlenderGPUDisplay();
BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene);
~BlenderDisplayDriver();
virtual void graphics_interop_activate() override;
virtual void graphics_interop_deactivate() override;
@@ -110,22 +112,15 @@ class BlenderGPUDisplay : public GPUDisplay {
void set_zoom(float zoom_x, float zoom_y);
protected:
virtual bool do_update_begin(const GPUDisplayParams &params,
int texture_width,
int texture_height) override;
virtual void do_update_end() override;
virtual bool update_begin(const Params &params, int texture_width, int texture_height) override;
virtual void update_end() override;
virtual void do_copy_pixels_to_texture(const half4 *rgba_pixels,
int texture_x,
int texture_y,
int pixels_width,
int pixels_height) override;
virtual void do_draw(const GPUDisplayParams &params) override;
virtual half4 *map_texture_buffer() override;
virtual void unmap_texture_buffer() override;
virtual half4 *do_map_texture_buffer() override;
virtual void do_unmap_texture_buffer() override;
virtual GraphicsInterop graphics_interop_get() override;
virtual DeviceGraphicsInteropDestination do_graphics_interop_get() override;
virtual void draw(const Params &params) override;
/* Helper function which allocates new GPU context. */
void gl_context_create();
@@ -152,13 +147,13 @@ class BlenderGPUDisplay : public GPUDisplay {
* This buffer is used to render texture in the viewport.
*
* NOTE: The buffer needs to be bound. */
void vertex_buffer_update(const GPUDisplayParams &params);
void vertex_buffer_update(const Params &params);
BL::RenderEngine b_engine_;
/* OpenGL context which is used the render engine doesn't have its own. */
void *gl_context_ = nullptr;
/* The when Blender RenderEngine side context is not available and the GPUDisplay is to create
/* The when Blender RenderEngine side context is not available and the DisplayDriver is to create
* its own context. */
bool use_gl_context_ = false;
/* Mutex used to guard the `gl_context_`. */

View File

@@ -80,7 +80,11 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
{
/* Test if we can instance or if the object is modified. */
Geometry::Type geom_type = determine_geom_type(b_ob_info, use_particle_hair);
GeometryKey key(b_ob_info.object_data, geom_type);
BL::ID b_key_id = (b_ob_info.is_real_object_data() &&
BKE_object_is_modified(b_ob_info.real_object)) ?
b_ob_info.real_object :
b_ob_info.object_data;
GeometryKey key(b_key_id.ptr.data, geom_type);
/* Find shader indices. */
array<Node *> used_shaders = find_used_shaders(b_ob_info.iter_object);
@@ -110,7 +114,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
}
else {
/* Test if we need to update existing geometry. */
sync = geometry_map.update(geom, b_ob_info.object_data);
sync = geometry_map.update(geom, b_key_id);
}
if (!sync) {

View File

@@ -0,0 +1,126 @@
/*
* Copyright 2021 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 "blender/blender_output_driver.h"
CCL_NAMESPACE_BEGIN
BlenderOutputDriver::BlenderOutputDriver(BL::RenderEngine &b_engine) : b_engine_(b_engine)
{
}
BlenderOutputDriver::~BlenderOutputDriver()
{
}
bool BlenderOutputDriver::read_render_tile(const Tile &tile)
{
/* Get render result. */
BL::RenderResult b_rr = b_engine_.begin_result(tile.offset.x,
tile.offset.y,
tile.size.x,
tile.size.y,
tile.layer.c_str(),
tile.view.c_str());
/* Can happen if the intersected rectangle gives 0 width or height. */
if (b_rr.ptr.data == NULL) {
return false;
}
BL::RenderResult::layers_iterator b_single_rlay;
b_rr.layers.begin(b_single_rlay);
/* layer will be missing if it was disabled in the UI */
if (b_single_rlay == b_rr.layers.end()) {
return false;
}
BL::RenderLayer b_rlay = *b_single_rlay;
vector<float> pixels(tile.size.x * tile.size.y * 4);
/* Copy each pass.
* TODO:copy only the required ones for better performance? */
for (BL::RenderPass &b_pass : b_rlay.passes) {
tile.set_pass_pixels(b_pass.name(), b_pass.channels(), (float *)b_pass.rect());
}
b_engine_.end_result(b_rr, false, false, false);
return true;
}
bool BlenderOutputDriver::update_render_tile(const Tile &tile)
{
/* Use final write for preview renders, otherwise render result wouldn't be be updated
* quickly on Blender side. For all other cases we use the display driver. */
if (b_engine_.is_preview()) {
write_render_tile(tile);
return true;
}
/* Don't highlight full-frame tile. */
if (!(tile.size == tile.full_size)) {
b_engine_.tile_highlight_clear_all();
b_engine_.tile_highlight_set(tile.offset.x, tile.offset.y, tile.size.x, tile.size.y, true);
}
return false;
}
void BlenderOutputDriver::write_render_tile(const Tile &tile)
{
b_engine_.tile_highlight_clear_all();
/* Get render result. */
BL::RenderResult b_rr = b_engine_.begin_result(tile.offset.x,
tile.offset.y,
tile.size.x,
tile.size.y,
tile.layer.c_str(),
tile.view.c_str());
/* Can happen if the intersected rectangle gives 0 width or height. */
if (b_rr.ptr.data == NULL) {
return;
}
BL::RenderResult::layers_iterator b_single_rlay;
b_rr.layers.begin(b_single_rlay);
/* Layer will be missing if it was disabled in the UI. */
if (b_single_rlay == b_rr.layers.end()) {
return;
}
BL::RenderLayer b_rlay = *b_single_rlay;
vector<float> pixels(tile.size.x * tile.size.y * 4);
/* Copy each pass. */
for (BL::RenderPass &b_pass : b_rlay.passes) {
if (!tile.get_pass_pixels(b_pass.name(), b_pass.channels(), &pixels[0])) {
memset(&pixels[0], 0, pixels.size() * sizeof(float));
}
b_pass.rect(&pixels[0]);
}
b_engine_.end_result(b_rr, true, false, true);
}
CCL_NAMESPACE_END

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2021 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 "MEM_guardedalloc.h"
#include "RNA_blender_cpp.h"
#include "render/output_driver.h"
CCL_NAMESPACE_BEGIN
class BlenderOutputDriver : public OutputDriver {
public:
explicit BlenderOutputDriver(BL::RenderEngine &b_engine);
~BlenderOutputDriver();
virtual void write_render_tile(const Tile &tile) override;
virtual bool update_render_tile(const Tile &tile) override;
virtual bool read_render_tile(const Tile &tile) override;
protected:
BL::RenderEngine b_engine_;
};
CCL_NAMESPACE_END

View File

@@ -911,14 +911,16 @@ static PyObject *enable_print_stats_func(PyObject * /*self*/, PyObject * /*args*
static PyObject *get_device_types_func(PyObject * /*self*/, PyObject * /*args*/)
{
vector<DeviceType> device_types = Device::available_types();
bool has_cuda = false, has_optix = false;
bool has_cuda = false, has_optix = false, has_hip = false;
foreach (DeviceType device_type, device_types) {
has_cuda |= (device_type == DEVICE_CUDA);
has_optix |= (device_type == DEVICE_OPTIX);
has_hip |= (device_type == DEVICE_HIP);
}
PyObject *list = PyTuple_New(2);
PyObject *list = PyTuple_New(3);
PyTuple_SET_ITEM(list, 0, PyBool_FromLong(has_cuda));
PyTuple_SET_ITEM(list, 1, PyBool_FromLong(has_optix));
PyTuple_SET_ITEM(list, 2, PyBool_FromLong(has_hip));
return list;
}
@@ -944,6 +946,9 @@ static PyObject *set_device_override_func(PyObject * /*self*/, PyObject *arg)
else if (override == "OPTIX") {
BlenderSession::device_override = DEVICE_MASK_OPTIX;
}
else if (override == "HIP") {
BlenderSession::device_override = DEVICE_MASK_HIP;
}
else {
printf("\nError: %s is not a valid Cycles device.\n", override.c_str());
Py_RETURN_FALSE;

View File

@@ -42,7 +42,8 @@
#include "util/util_progress.h"
#include "util/util_time.h"
#include "blender/blender_gpu_display.h"
#include "blender/blender_display_driver.h"
#include "blender/blender_output_driver.h"
#include "blender/blender_session.h"
#include "blender/blender_sync.h"
#include "blender/blender_util.h"
@@ -71,7 +72,8 @@ BlenderSession::BlenderSession(BL::RenderEngine &b_engine,
width(0),
height(0),
preview_osl(preview_osl),
python_thread_state(NULL)
python_thread_state(NULL),
use_developer_ui(false)
{
/* offline render */
background = true;
@@ -156,11 +158,13 @@ void BlenderSession::create_session()
b_v3d, b_rv3d, scene->camera, width, height);
session->reset(session_params, buffer_params);
/* Create GPU display. */
/* Create GPU display.
* TODO(sergey): Investigate whether DisplayDriver can be used for the preview as well. */
if (!b_engine.is_preview() && !headless) {
unique_ptr<BlenderGPUDisplay> gpu_display = make_unique<BlenderGPUDisplay>(b_engine, b_scene);
gpu_display_ = gpu_display.get();
session->set_gpu_display(move(gpu_display));
unique_ptr<BlenderDisplayDriver> display_driver = make_unique<BlenderDisplayDriver>(b_engine,
b_scene);
display_driver_ = display_driver.get();
session->set_display_driver(move(display_driver));
}
/* Viewport and preview (as in, material preview) does not do tiled rendering, so can inform
@@ -277,94 +281,6 @@ void BlenderSession::free_session()
session = nullptr;
}
void BlenderSession::read_render_tile()
{
const int2 tile_offset = session->get_render_tile_offset();
const int2 tile_size = session->get_render_tile_size();
/* get render result */
BL::RenderResult b_rr = b_engine.begin_result(tile_offset.x,
tile_offset.y,
tile_size.x,
tile_size.y,
b_rlay_name.c_str(),
b_rview_name.c_str());
/* can happen if the intersected rectangle gives 0 width or height */
if (b_rr.ptr.data == NULL) {
return;
}
BL::RenderResult::layers_iterator b_single_rlay;
b_rr.layers.begin(b_single_rlay);
/* layer will be missing if it was disabled in the UI */
if (b_single_rlay == b_rr.layers.end())
return;
BL::RenderLayer b_rlay = *b_single_rlay;
vector<float> pixels(tile_size.x * tile_size.y * 4);
/* Copy each pass.
* TODO:copy only the required ones for better performance? */
for (BL::RenderPass &b_pass : b_rlay.passes) {
session->set_render_tile_pixels(b_pass.name(), b_pass.channels(), (float *)b_pass.rect());
}
}
void BlenderSession::write_render_tile()
{
const int2 tile_offset = session->get_render_tile_offset();
const int2 tile_size = session->get_render_tile_size();
const string_view render_layer_name = session->get_render_tile_layer();
const string_view render_view_name = session->get_render_tile_view();
b_engine.tile_highlight_clear_all();
/* get render result */
BL::RenderResult b_rr = b_engine.begin_result(tile_offset.x,
tile_offset.y,
tile_size.x,
tile_size.y,
render_layer_name.c_str(),
render_view_name.c_str());
/* can happen if the intersected rectangle gives 0 width or height */
if (b_rr.ptr.data == NULL) {
return;
}
BL::RenderResult::layers_iterator b_single_rlay;
b_rr.layers.begin(b_single_rlay);
/* layer will be missing if it was disabled in the UI */
if (b_single_rlay == b_rr.layers.end()) {
return;
}
BL::RenderLayer b_rlay = *b_single_rlay;
write_render_result(b_rlay);
b_engine.end_result(b_rr, true, false, true);
}
void BlenderSession::update_render_tile()
{
if (!session->has_multiple_render_tiles()) {
/* Don't highlight full-frame tile. */
return;
}
const int2 tile_offset = session->get_render_tile_offset();
const int2 tile_size = session->get_render_tile_size();
b_engine.tile_highlight_clear_all();
b_engine.tile_highlight_set(tile_offset.x, tile_offset.y, tile_size.x, tile_size.y, true);
}
void BlenderSession::full_buffer_written(string_view filename)
{
full_buffer_files_.emplace_back(filename);
@@ -438,18 +354,8 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
return;
}
/* set callback to write out render results */
session->write_render_tile_cb = [&]() { write_render_tile(); };
/* Use final write for preview renders, otherwise render result wouldn't be be updated on Blender
* side. */
/* TODO(sergey): Investigate whether GPUDisplay can be used for the preview as well. */
if (b_engine.is_preview()) {
session->update_render_tile_cb = [&]() { write_render_tile(); };
}
else {
session->update_render_tile_cb = [&]() { update_render_tile(); };
}
/* Create driver to write out render results. */
session->set_output_driver(make_unique<BlenderOutputDriver>(b_engine));
session->full_buffer_written_cb = [&](string_view filename) { full_buffer_written(filename); };
@@ -557,6 +463,11 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
/* free result without merging */
b_engine.end_result(b_rr, true, false, false);
/* When tiled rendering is used there will be no "write" done for the tile. Forcefully clear
* highlighted tiles now, so that the highlight will be removed while processing full frame from
* file. */
b_engine.tile_highlight_clear_all();
double total_time, render_time;
session->progress.get_time(total_time, render_time);
VLOG(1) << "Total render time: " << total_time;
@@ -581,13 +492,22 @@ void BlenderSession::render_frame_finish()
for (string_view filename : full_buffer_files_) {
session->process_full_buffer_from_disk(filename);
if (check_and_report_session_error()) {
break;
}
}
for (string_view filename : full_buffer_files_) {
path_remove(filename);
}
/* clear callback */
session->write_render_tile_cb = function_null;
session->update_render_tile_cb = function_null;
/* Clear driver. */
session->set_output_driver(nullptr);
session->full_buffer_written_cb = function_null;
/* All the files are handled.
* Clear the list so that this session can be re-used by Persistent Data. */
full_buffer_files_.clear();
}
static PassType bake_type_to_pass(const string &bake_type_str, const int bake_filter)
@@ -692,9 +612,8 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
pass->set_type(bake_type_to_pass(bake_type, bake_filter));
pass->set_include_albedo((bake_filter & BL::BakeSettings::pass_filter_COLOR));
session->read_render_tile_cb = [&]() { read_render_tile(); };
session->write_render_tile_cb = [&]() { write_render_tile(); };
session->set_gpu_display(nullptr);
session->set_display_driver(nullptr);
session->set_output_driver(make_unique<BlenderOutputDriver>(b_engine));
if (!session->progress.get_cancel()) {
/* Sync scene. */
@@ -737,43 +656,7 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
session->wait();
}
session->read_render_tile_cb = function_null;
session->write_render_tile_cb = function_null;
}
void BlenderSession::write_render_result(BL::RenderLayer &b_rlay)
{
if (!session->copy_render_tile_from_device()) {
return;
}
const int2 tile_size = session->get_render_tile_size();
vector<float> pixels(tile_size.x * tile_size.y * 4);
/* Copy each pass. */
for (BL::RenderPass &b_pass : b_rlay.passes) {
if (!session->get_render_tile_pixels(b_pass.name(), b_pass.channels(), &pixels[0])) {
memset(&pixels[0], 0, pixels.size() * sizeof(float));
}
b_pass.rect(&pixels[0]);
}
}
void BlenderSession::update_render_result(BL::RenderLayer &b_rlay)
{
if (!session->copy_render_tile_from_device()) {
return;
}
const int2 tile_size = session->get_render_tile_size();
vector<float> pixels(tile_size.x * tile_size.y * 4);
/* Copy combined pass. */
BL::RenderPass b_combined_pass(b_rlay.passes.find_by_name("Combined", b_rview_name.c_str()));
if (session->get_render_tile_pixels("Combined", b_combined_pass.channels(), &pixels[0])) {
b_combined_pass.rect(&pixels[0]);
}
session->set_output_driver(nullptr);
}
void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
@@ -881,7 +764,7 @@ void BlenderSession::draw(BL::SpaceImageEditor &space_image)
}
BL::Array<float, 2> zoom = space_image.zoom();
gpu_display_->set_zoom(zoom[0], zoom[1]);
display_driver_->set_zoom(zoom[0], zoom[1]);
session->draw();
}
@@ -988,8 +871,9 @@ void BlenderSession::update_status_progress()
get_status(status, substatus);
get_progress(progress, total_time, render_time);
if (progress > 0)
remaining_time = (1.0 - (double)progress) * (render_time / (double)progress);
if (progress > 0) {
remaining_time = session->get_estimated_remaining_time();
}
if (background) {
if (scene)
@@ -1027,20 +911,27 @@ void BlenderSession::update_status_progress()
last_progress = progress;
}
if (session->progress.get_error()) {
string error = session->progress.get_error_message();
if (error != last_error) {
/* TODO(sergey): Currently C++ RNA API doesn't let us to
* use mnemonic name for the variable. Would be nice to
* have this figured out.
*
* For until then, 1 << 5 means RPT_ERROR.
*/
b_engine.report(1 << 5, error.c_str());
b_engine.error_set(error.c_str());
last_error = error;
}
check_and_report_session_error();
}
bool BlenderSession::check_and_report_session_error()
{
if (!session->progress.get_error()) {
return false;
}
const string error = session->progress.get_error_message();
if (error != last_error) {
/* TODO(sergey): Currently C++ RNA API doesn't let us to use mnemonic name for the variable.
* Would be nice to have this figured out.
*
* For until then, 1 << 5 means RPT_ERROR. */
b_engine.report(1 << 5, error.c_str());
b_engine.error_set(error.c_str());
last_error = error;
}
return true;
}
void BlenderSession::tag_update()

View File

@@ -29,7 +29,7 @@
CCL_NAMESPACE_BEGIN
class BlenderGPUDisplay;
class BlenderDisplayDriver;
class BlenderSync;
class ImageMetaData;
class Scene;
@@ -70,20 +70,7 @@ class BlenderSession {
const int bake_width,
const int bake_height);
void write_render_result(BL::RenderLayer &b_rlay);
void write_render_tile();
void update_render_tile();
void full_buffer_written(string_view filename);
/* update functions are used to update display buffer only after sample was rendered
* only needed for better visual feedback */
void update_render_result(BL::RenderLayer &b_rlay);
/* read functions for baking input */
void read_render_tile();
/* interactive updates */
void synchronize(BL::Depsgraph &b_depsgraph);
@@ -110,8 +97,7 @@ class BlenderSession {
BL::RenderSettings b_render;
BL::Depsgraph b_depsgraph;
/* NOTE: Blender's scene might become invalid after call
* free_blender_memory_if_possible().
*/
* #free_blender_memory_if_possible(). */
BL::Scene b_scene;
BL::SpaceView3D b_v3d;
BL::RegionView3D b_rv3d;
@@ -147,6 +133,11 @@ class BlenderSession {
protected:
void stamp_view_layer_metadata(Scene *scene, const string &view_layer_name);
/* Check whether session error happened.
* If so, it is reported to the render engine and true is returned.
* Otherwise false is returned. */
bool check_and_report_session_error();
void builtin_images_load();
/* Is used after each render layer synchronization is done with the goal
@@ -160,8 +151,8 @@ class BlenderSession {
int last_pass_index = -1;
} draw_state_;
/* NOTE: The BlenderSession references the GPU display. */
BlenderGPUDisplay *gpu_display_ = nullptr;
/* NOTE: The BlenderSession references the display driver. */
BlenderDisplayDriver *display_driver_ = nullptr;
vector<string> full_buffer_files_;
};

View File

@@ -279,7 +279,7 @@ static ShaderNode *add_node(Scene *scene,
array<float3> curve_mapping_curves;
float min_x, max_x;
curvemapping_color_to_array(mapping, curve_mapping_curves, RAMP_TABLE_SIZE, true);
curvemapping_minmax(mapping, true, &min_x, &max_x);
curvemapping_minmax(mapping, 4, &min_x, &max_x);
curves->set_min_x(min_x);
curves->set_max_x(max_x);
curves->set_curves(curve_mapping_curves);
@@ -292,12 +292,25 @@ static ShaderNode *add_node(Scene *scene,
array<float3> curve_mapping_curves;
float min_x, max_x;
curvemapping_color_to_array(mapping, curve_mapping_curves, RAMP_TABLE_SIZE, false);
curvemapping_minmax(mapping, false, &min_x, &max_x);
curvemapping_minmax(mapping, 3, &min_x, &max_x);
curves->set_min_x(min_x);
curves->set_max_x(max_x);
curves->set_curves(curve_mapping_curves);
node = curves;
}
else if (b_node.is_a(&RNA_ShaderNodeFloatCurve)) {
BL::ShaderNodeFloatCurve b_curve_node(b_node);
BL::CurveMapping mapping(b_curve_node.mapping());
FloatCurveNode *curve = graph->create_node<FloatCurveNode>();
array<float> curve_mapping_curve;
float min_x, max_x;
curvemapping_float_to_array(mapping, curve_mapping_curve, RAMP_TABLE_SIZE);
curvemapping_minmax(mapping, 1, &min_x, &max_x);
curve->set_min_x(min_x);
curve->set_max_x(max_x);
curve->set_curve(curve_mapping_curve);
node = curve;
}
else if (b_node.is_a(&RNA_ShaderNodeValToRGB)) {
RGBRampNode *ramp = graph->create_node<RGBRampNode>();
BL::ShaderNodeValToRGB b_ramp_node(b_node);

View File

@@ -545,8 +545,6 @@ static PassType get_blender_pass_type(BL::RenderPass &b_pass)
MAP_PASS("Shadow Catcher", PASS_SHADOW_CATCHER);
MAP_PASS("Noisy Shadow Catcher", PASS_SHADOW_CATCHER);
MAP_PASS("Debug Render Time", PASS_RENDER_TIME);
MAP_PASS("AdaptiveAuxBuffer", PASS_ADAPTIVE_AUX_BUFFER);
MAP_PASS("Debug Sample Count", PASS_SAMPLE_COUNT);
@@ -604,10 +602,6 @@ void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_v
PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles");
/* Debug passes. */
if (get_boolean(crl, "pass_debug_render_time")) {
b_engine.add_pass("Debug Render Time", 1, "X", b_view_layer.name().c_str());
pass_add(scene, PASS_RENDER_TIME, "Debug Render Time");
}
if (get_boolean(crl, "pass_debug_sample_count")) {
b_engine.add_pass("Debug Sample Count", 1, "X", b_view_layer.name().c_str());
pass_add(scene, PASS_SAMPLE_COUNT, "Debug Sample Count");
@@ -855,7 +849,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
if (background) {
params.use_auto_tile = RNA_boolean_get(&cscene, "use_auto_tile");
params.tile_size = get_int(cscene, "tile_size");
params.tile_size = max(get_int(cscene, "tile_size"), 8);
}
else {
params.use_auto_tile = false;

View File

@@ -90,26 +90,27 @@ static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/,
}
#endif
BL::Mesh mesh(PointerRNA_NULL);
if (b_ob_info.object_data.is_a(&RNA_Mesh)) {
/* TODO: calc_undeformed is not used. */
mesh = BL::Mesh(b_ob_info.object_data);
BL::Mesh mesh = (b_ob_info.object_data.is_a(&RNA_Mesh)) ? BL::Mesh(b_ob_info.object_data) :
BL::Mesh(PointerRNA_NULL);
/* Make a copy to split faces if we use autosmooth, otherwise not needed.
* Also in edit mode do we need to make a copy, to ensure data layers like
* UV are not empty. */
if (mesh.is_editmode() ||
(mesh.use_auto_smooth() && subdivision_type == Mesh::SUBDIVISION_NONE)) {
if (b_ob_info.is_real_object_data()) {
if (mesh) {
/* Make a copy to split faces if we use autosmooth, otherwise not needed.
* Also in edit mode do we need to make a copy, to ensure data layers like
* UV are not empty. */
if (mesh.is_editmode() ||
(mesh.use_auto_smooth() && subdivision_type == Mesh::SUBDIVISION_NONE)) {
BL::Depsgraph depsgraph(PointerRNA_NULL);
mesh = b_ob_info.real_object.to_mesh(false, depsgraph);
}
}
else {
BL::Depsgraph depsgraph(PointerRNA_NULL);
assert(b_ob_info.is_real_object_data());
mesh = b_ob_info.real_object.to_mesh(false, depsgraph);
}
}
else {
BL::Depsgraph depsgraph(PointerRNA_NULL);
if (b_ob_info.is_real_object_data()) {
mesh = b_ob_info.real_object.to_mesh(false, depsgraph);
}
/* TODO: what to do about non-mesh geometry instances? */
}
#if 0
@@ -170,12 +171,11 @@ static inline void curvemap_minmax_curve(/*const*/ BL::CurveMap &curve, float *m
}
static inline void curvemapping_minmax(/*const*/ BL::CurveMapping &cumap,
bool rgb_curve,
int num_curves,
float *min_x,
float *max_x)
{
// const int num_curves = cumap.curves.length(); /* Gives linking error so far. */
const int num_curves = rgb_curve ? 4 : 3;
*min_x = FLT_MAX;
*max_x = -FLT_MAX;
for (int i = 0; i < num_curves; ++i) {
@@ -195,6 +195,28 @@ static inline void curvemapping_to_array(BL::CurveMapping &cumap, array<float> &
}
}
static inline void curvemapping_float_to_array(BL::CurveMapping &cumap,
array<float> &data,
int size)
{
float min = 0.0f, max = 1.0f;
curvemapping_minmax(cumap, 1, &min, &max);
const float range = max - min;
cumap.update();
BL::CurveMap map = cumap.curves[0];
data.resize(size);
for (int i = 0; i < size; i++) {
float t = min + (float)i / (float)(size - 1) * range;
data[i] = cumap.evaluate(map, t);
}
}
static inline void curvemapping_color_to_array(BL::CurveMapping &cumap,
array<float3> &data,
int size,
@@ -213,7 +235,8 @@ static inline void curvemapping_color_to_array(BL::CurveMapping &cumap,
*
* There might be some better estimations here tho.
*/
curvemapping_minmax(cumap, rgb_curve, &min_x, &max_x);
const int num_curves = rgb_curve ? 4 : 3;
curvemapping_minmax(cumap, num_curves, &min_x, &max_x);
const float range_x = max_x - min_x;

View File

@@ -50,10 +50,6 @@ struct PackedBVH {
array<int4> leaf_nodes;
/* object index to BVH node index mapping for instances */
array<int> object_node;
/* Mapping from primitive index to index in triangle array. */
array<uint> prim_tri_index;
/* Continuous storage of triangle vertices. */
array<float4> prim_tri_verts;
/* primitive type - triangle or strand */
array<int> prim_type;
/* visibility visibilitys for primitives */

View File

@@ -439,61 +439,20 @@ void BVH2::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility
/* Triangles */
void BVH2::pack_triangle(int idx, float4 tri_verts[3])
{
int tob = pack.prim_object[idx];
assert(tob >= 0 && tob < objects.size());
const Mesh *mesh = static_cast<const Mesh *>(objects[tob]->get_geometry());
int tidx = pack.prim_index[idx];
Mesh::Triangle t = mesh->get_triangle(tidx);
const float3 *vpos = &mesh->verts[0];
float3 v0 = vpos[t.v[0]];
float3 v1 = vpos[t.v[1]];
float3 v2 = vpos[t.v[2]];
tri_verts[0] = float3_to_float4(v0);
tri_verts[1] = float3_to_float4(v1);
tri_verts[2] = float3_to_float4(v2);
}
void BVH2::pack_primitives()
{
const size_t tidx_size = pack.prim_index.size();
size_t num_prim_triangles = 0;
/* Count number of triangles primitives in BVH. */
for (unsigned int i = 0; i < tidx_size; i++) {
if ((pack.prim_index[i] != -1)) {
if ((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
++num_prim_triangles;
}
}
}
/* Reserve size for arrays. */
pack.prim_tri_index.clear();
pack.prim_tri_index.resize(tidx_size);
pack.prim_tri_verts.clear();
pack.prim_tri_verts.resize(num_prim_triangles * 3);
pack.prim_visibility.clear();
pack.prim_visibility.resize(tidx_size);
/* Fill in all the arrays. */
size_t prim_triangle_index = 0;
for (unsigned int i = 0; i < tidx_size; i++) {
if (pack.prim_index[i] != -1) {
int tob = pack.prim_object[i];
Object *ob = objects[tob];
if ((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
pack_triangle(i, (float4 *)&pack.prim_tri_verts[3 * prim_triangle_index]);
pack.prim_tri_index[i] = 3 * prim_triangle_index;
++prim_triangle_index;
}
else {
pack.prim_tri_index[i] = -1;
}
pack.prim_visibility[i] = ob->visibility_for_tracing();
}
else {
pack.prim_tri_index[i] = -1;
pack.prim_visibility[i] = 0;
}
}
@@ -522,10 +481,8 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
/* reserve */
size_t prim_index_size = pack.prim_index.size();
size_t prim_tri_verts_size = pack.prim_tri_verts.size();
size_t pack_prim_index_offset = prim_index_size;
size_t pack_prim_tri_verts_offset = prim_tri_verts_size;
size_t pack_nodes_offset = nodes_size;
size_t pack_leaf_nodes_offset = leaf_nodes_size;
size_t object_offset = 0;
@@ -535,7 +492,6 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
if (geom->need_build_bvh(params.bvh_layout)) {
prim_index_size += bvh->pack.prim_index.size();
prim_tri_verts_size += bvh->pack.prim_tri_verts.size();
nodes_size += bvh->pack.nodes.size();
leaf_nodes_size += bvh->pack.leaf_nodes.size();
}
@@ -545,8 +501,6 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
pack.prim_type.resize(prim_index_size);
pack.prim_object.resize(prim_index_size);
pack.prim_visibility.resize(prim_index_size);
pack.prim_tri_verts.resize(prim_tri_verts_size);
pack.prim_tri_index.resize(prim_index_size);
pack.nodes.resize(nodes_size);
pack.leaf_nodes.resize(leaf_nodes_size);
pack.object_node.resize(objects.size());
@@ -559,8 +513,6 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
int *pack_prim_type = (pack.prim_type.size()) ? &pack.prim_type[0] : NULL;
int *pack_prim_object = (pack.prim_object.size()) ? &pack.prim_object[0] : NULL;
uint *pack_prim_visibility = (pack.prim_visibility.size()) ? &pack.prim_visibility[0] : NULL;
float4 *pack_prim_tri_verts = (pack.prim_tri_verts.size()) ? &pack.prim_tri_verts[0] : NULL;
uint *pack_prim_tri_index = (pack.prim_tri_index.size()) ? &pack.prim_tri_index[0] : NULL;
int4 *pack_nodes = (pack.nodes.size()) ? &pack.nodes[0] : NULL;
int4 *pack_leaf_nodes = (pack.leaf_nodes.size()) ? &pack.leaf_nodes[0] : NULL;
float2 *pack_prim_time = (pack.prim_time.size()) ? &pack.prim_time[0] : NULL;
@@ -609,18 +561,14 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
int *bvh_prim_index = &bvh->pack.prim_index[0];
int *bvh_prim_type = &bvh->pack.prim_type[0];
uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0];
uint *bvh_prim_tri_index = &bvh->pack.prim_tri_index[0];
float2 *bvh_prim_time = bvh->pack.prim_time.size() ? &bvh->pack.prim_time[0] : NULL;
for (size_t i = 0; i < bvh_prim_index_size; i++) {
if (bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + geom_prim_offset;
pack_prim_tri_index[pack_prim_index_offset] = -1;
}
else {
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + geom_prim_offset;
pack_prim_tri_index[pack_prim_index_offset] = bvh_prim_tri_index[i] +
pack_prim_tri_verts_offset;
}
pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
@@ -633,15 +581,6 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
}
}
/* Merge triangle vertices data. */
if (bvh->pack.prim_tri_verts.size()) {
const size_t prim_tri_size = bvh->pack.prim_tri_verts.size();
memcpy(pack_prim_tri_verts + pack_prim_tri_verts_offset,
&bvh->pack.prim_tri_verts[0],
prim_tri_size * sizeof(float4));
pack_prim_tri_verts_offset += prim_tri_size;
}
/* merge nodes */
if (bvh->pack.leaf_nodes.size()) {
int4 *leaf_nodes_offset = &bvh->pack.leaf_nodes[0];

View File

@@ -67,8 +67,12 @@ BVHBuild::~BVHBuild()
/* Adding References */
void BVHBuild::add_reference_triangles(BoundBox &root, BoundBox &center, Mesh *mesh, int i)
void BVHBuild::add_reference_triangles(BoundBox &root,
BoundBox &center,
Mesh *mesh,
int object_index)
{
const PrimitiveType primitive_type = mesh->primitive_type();
const Attribute *attr_mP = NULL;
if (mesh->has_motion_blur()) {
attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
@@ -81,7 +85,7 @@ void BVHBuild::add_reference_triangles(BoundBox &root, BoundBox &center, Mesh *m
BoundBox bounds = BoundBox::empty;
t.bounds_grow(verts, bounds);
if (bounds.valid() && t.valid(verts)) {
references.push_back(BVHReference(bounds, j, i, PRIMITIVE_TRIANGLE));
references.push_back(BVHReference(bounds, j, object_index, primitive_type));
root.grow(bounds);
center.grow(bounds.center2());
}
@@ -101,7 +105,7 @@ void BVHBuild::add_reference_triangles(BoundBox &root, BoundBox &center, Mesh *m
t.bounds_grow(vert_steps + step * num_verts, bounds);
}
if (bounds.valid()) {
references.push_back(BVHReference(bounds, j, i, PRIMITIVE_MOTION_TRIANGLE));
references.push_back(BVHReference(bounds, j, object_index, primitive_type));
root.grow(bounds);
center.grow(bounds.center2());
}
@@ -140,7 +144,7 @@ void BVHBuild::add_reference_triangles(BoundBox &root, BoundBox &center, Mesh *m
if (bounds.valid()) {
const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1;
references.push_back(
BVHReference(bounds, j, i, PRIMITIVE_MOTION_TRIANGLE, prev_time, curr_time));
BVHReference(bounds, j, object_index, primitive_type, prev_time, curr_time));
root.grow(bounds);
center.grow(bounds.center2());
}
@@ -153,18 +157,14 @@ void BVHBuild::add_reference_triangles(BoundBox &root, BoundBox &center, Mesh *m
}
}
void BVHBuild::add_reference_curves(BoundBox &root, BoundBox &center, Hair *hair, int i)
void BVHBuild::add_reference_curves(BoundBox &root, BoundBox &center, Hair *hair, int object_index)
{
const Attribute *curve_attr_mP = NULL;
if (hair->has_motion_blur()) {
curve_attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
}
const PrimitiveType primitive_type =
(curve_attr_mP != NULL) ?
((hair->curve_shape == CURVE_RIBBON) ? PRIMITIVE_MOTION_CURVE_RIBBON :
PRIMITIVE_MOTION_CURVE_THICK) :
((hair->curve_shape == CURVE_RIBBON) ? PRIMITIVE_CURVE_RIBBON : PRIMITIVE_CURVE_THICK);
const PrimitiveType primitive_type = hair->primitive_type();
const size_t num_curves = hair->num_curves();
for (uint j = 0; j < num_curves; j++) {
@@ -177,7 +177,7 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox &center, Hair *hair
curve.bounds_grow(k, &hair->get_curve_keys()[0], curve_radius, bounds);
if (bounds.valid()) {
int packed_type = PRIMITIVE_PACK_SEGMENT(primitive_type, k);
references.push_back(BVHReference(bounds, j, i, packed_type));
references.push_back(BVHReference(bounds, j, object_index, packed_type));
root.grow(bounds);
center.grow(bounds.center2());
}
@@ -198,7 +198,7 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox &center, Hair *hair
}
if (bounds.valid()) {
int packed_type = PRIMITIVE_PACK_SEGMENT(primitive_type, k);
references.push_back(BVHReference(bounds, j, i, packed_type));
references.push_back(BVHReference(bounds, j, object_index, packed_type));
root.grow(bounds);
center.grow(bounds.center2());
}
@@ -254,7 +254,8 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox &center, Hair *hair
if (bounds.valid()) {
const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1;
int packed_type = PRIMITIVE_PACK_SEGMENT(primitive_type, k);
references.push_back(BVHReference(bounds, j, i, packed_type, prev_time, curr_time));
references.push_back(
BVHReference(bounds, j, object_index, packed_type, prev_time, curr_time));
root.grow(bounds);
center.grow(bounds.center2());
}
@@ -268,15 +269,18 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox &center, Hair *hair
}
}
void BVHBuild::add_reference_geometry(BoundBox &root, BoundBox &center, Geometry *geom, int i)
void BVHBuild::add_reference_geometry(BoundBox &root,
BoundBox &center,
Geometry *geom,
int object_index)
{
if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
Mesh *mesh = static_cast<Mesh *>(geom);
add_reference_triangles(root, center, mesh, i);
add_reference_triangles(root, center, mesh, object_index);
}
else if (geom->geometry_type == Geometry::HAIR) {
Hair *hair = static_cast<Hair *>(geom);
add_reference_curves(root, center, hair, i);
add_reference_curves(root, center, hair, object_index);
}
}

View File

@@ -89,20 +89,9 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
/* Test if we need to record this transparent intersection. */
if (ctx->num_hits < ctx->max_hits || ray->tfar < ctx->max_t) {
/* Skip already recorded intersections. */
int num_recorded_hits = min(ctx->num_hits, ctx->max_hits);
for (int i = 0; i < num_recorded_hits; ++i) {
if (current_isect.object == ctx->isect_s[i].object &&
current_isect.prim == ctx->isect_s[i].prim && current_isect.t == ctx->isect_s[i].t) {
/* This intersection was already recorded, skip it. */
*args->valid = 0;
return;
}
}
/* If maximum number of hits was reached, replace the intersection with the
* highest distance. We want to find the N closest intersections. */
const int num_recorded_hits = min(ctx->num_hits, ctx->max_hits);
int isect_index = num_recorded_hits;
if (num_recorded_hits + 1 >= ctx->max_hits) {
float max_t = ctx->isect_s[0].t;
@@ -147,10 +136,7 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
}
else {
kernel_embree_convert_hit(kg, ray, hit, &current_isect);
int object = (current_isect.object == OBJECT_NONE) ?
kernel_tex_fetch(__prim_object, current_isect.prim) :
current_isect.object;
if (ctx->local_object_id != object) {
if (ctx->local_object_id != current_isect.object) {
/* This tells Embree to continue tracing. */
*args->valid = 0;
break;
@@ -169,41 +155,49 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
break;
}
/* See triangle_intersect_subsurface() for the native equivalent. */
for (int i = min(ctx->max_hits, ctx->local_isect->num_hits) - 1; i >= 0; --i) {
if (ctx->local_isect->hits[i].t == ray->tfar) {
/* This tells Embree to continue tracing. */
*args->valid = 0;
break;
}
}
LocalIntersection *local_isect = ctx->local_isect;
int hit_idx = 0;
if (ctx->lcg_state) {
/* See triangle_intersect_subsurface() for the native equivalent. */
for (int i = min(ctx->max_hits, local_isect->num_hits) - 1; i >= 0; --i) {
if (local_isect->hits[i].t == ray->tfar) {
/* This tells Embree to continue tracing. */
*args->valid = 0;
return;
}
}
++ctx->local_isect->num_hits;
if (ctx->local_isect->num_hits <= ctx->max_hits) {
hit_idx = ctx->local_isect->num_hits - 1;
local_isect->num_hits++;
if (local_isect->num_hits <= ctx->max_hits) {
hit_idx = local_isect->num_hits - 1;
}
else {
/* reservoir sampling: if we are at the maximum number of
* hits, randomly replace element or skip it */
hit_idx = lcg_step_uint(ctx->lcg_state) % ctx->local_isect->num_hits;
hit_idx = lcg_step_uint(ctx->lcg_state) % local_isect->num_hits;
if (hit_idx >= ctx->max_hits) {
/* This tells Embree to continue tracing. */
*args->valid = 0;
break;
return;
}
}
}
else {
ctx->local_isect->num_hits = 1;
/* Record closest intersection only. */
if (local_isect->num_hits && current_isect.t > local_isect->hits[0].t) {
*args->valid = 0;
return;
}
local_isect->num_hits = 1;
}
/* record intersection */
ctx->local_isect->hits[hit_idx] = current_isect;
ctx->local_isect->Ng[hit_idx] = normalize(make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z));
local_isect->hits[hit_idx] = current_isect;
local_isect->Ng[hit_idx] = normalize(make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z));
/* This tells Embree to continue tracing. */
*args->valid = 0;
break;
@@ -213,21 +207,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);
for (size_t i = 0; i < ctx->max_hits; ++i) {
if (current_isect.object == ctx->isect_s[i].object &&
current_isect.prim == ctx->isect_s[i].prim && current_isect.t == ctx->isect_s[i].t) {
/* This intersection was already recorded, skip it. */
*args->valid = 0;
break;
}
}
Intersection *isect = &ctx->isect_s[ctx->num_hits];
++ctx->num_hits;
*isect = current_isect;
/* Only primitives from volume object. */
uint tri_object = (isect->object == OBJECT_NONE) ?
kernel_tex_fetch(__prim_object, isect->prim) :
isect->object;
uint tri_object = isect->object;
int object_flag = kernel_tex_fetch(__object_flag, tri_object);
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
--ctx->num_hits;
@@ -249,7 +233,7 @@ static void rtc_filter_func_thick_curve(const RTCFilterFunctionNArguments *args)
const RTCRay *ray = (RTCRay *)args->ray;
RTCHit *hit = (RTCHit *)args->hit;
/* Always ignore backfacing intersections. */
/* Always ignore back-facing intersections. */
if (dot(make_float3(ray->dir_x, ray->dir_y, ray->dir_z),
make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z)) > 0.0f) {
*args->valid = 0;
@@ -262,7 +246,7 @@ static void rtc_filter_occluded_func_thick_curve(const RTCFilterFunctionNArgumen
const RTCRay *ray = (RTCRay *)args->ray;
RTCHit *hit = (RTCHit *)args->hit;
/* Always ignore backfacing intersections. */
/* Always ignore back-facing intersections. */
if (dot(make_float3(ray->dir_x, ray->dir_y, ray->dir_z),
make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z)) > 0.0f) {
*args->valid = 0;
@@ -456,7 +440,7 @@ void BVHEmbree::add_instance(Object *ob, int i)
void BVHEmbree::add_triangles(const Object *ob, const Mesh *mesh, int i)
{
size_t prim_offset = mesh->optix_prim_offset;
size_t prim_offset = mesh->prim_offset;
const Attribute *attr_mP = NULL;
size_t num_motion_steps = 1;
@@ -625,7 +609,7 @@ void BVHEmbree::set_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair, c
void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i)
{
size_t prim_offset = hair->optix_prim_offset;
size_t prim_offset = hair->curve_segment_offset;
const Attribute *attr_mP = NULL;
size_t num_motion_steps = 1;
@@ -702,7 +686,7 @@ void BVHEmbree::refit(Progress &progress)
if (mesh->num_triangles() > 0) {
RTCGeometry geom = rtcGetGeometry(scene, geom_id);
set_tri_vertex_buffer(geom, mesh, true);
rtcSetGeometryUserData(geom, (void *)mesh->optix_prim_offset);
rtcSetGeometryUserData(geom, (void *)mesh->prim_offset);
rtcCommitGeometry(geom);
}
}
@@ -711,7 +695,7 @@ void BVHEmbree::refit(Progress &progress)
if (hair->num_curves() > 0) {
RTCGeometry geom = rtcGetGeometry(scene, geom_id + 1);
set_curve_vertex_buffer(geom, hair, true);
rtcSetGeometryUserData(geom, (void *)hair->optix_prim_offset);
rtcSetGeometryUserData(geom, (void *)hair->curve_segment_offset);
rtcCommitGeometry(geom);
}
}

View File

@@ -521,7 +521,7 @@ endif()
if(WITH_CYCLES_CUDA_BINARIES OR NOT WITH_CUDA_DYNLOAD)
find_package(CUDA) # Try to auto locate CUDA toolkit
if(CUDA_FOUND)
message(STATUS "CUDA nvcc = ${CUDA_NVCC_EXECUTABLE}")
message(STATUS "Found CUDA ${CUDA_NVCC_EXECUTABLE} (${CUDA_VERSION})")
else()
message(STATUS "CUDA compiler not found, disabling WITH_CYCLES_CUDA_BINARIES")
set(WITH_CYCLES_CUDA_BINARIES OFF)
@@ -532,4 +532,23 @@ if(WITH_CYCLES_CUDA_BINARIES OR NOT WITH_CUDA_DYNLOAD)
endif()
endif()
###########################################################################
# HIP
###########################################################################
if(WITH_CYCLES_HIP_BINARIES AND WITH_CYCLES_DEVICE_HIP)
find_package(HIP)
if(HIP_FOUND)
message(STATUS "Found HIP ${HIP_HIPCC_EXECUTABLE} (${HIP_VERSION})")
else()
message(STATUS "HIP compiler not found, disabling WITH_CYCLES_HIP_BINARIES")
set(WITH_CYCLES_HIP_BINARIES OFF)
endif()
endif()
if(NOT WITH_HIP_DYNLOAD)
set(WITH_HIP_DYNLOAD ON)
endif()
unset(_cycles_lib_dir)

View File

@@ -156,10 +156,16 @@ macro(cycles_target_link_libraries target)
${PLATFORM_LINKLIBS}
)
if(WITH_CUDA_DYNLOAD)
target_link_libraries(${target} extern_cuew)
else()
target_link_libraries(${target} ${CUDA_CUDA_LIBRARY})
if(WITH_CYCLES_DEVICE_CUDA OR WITH_CYCLES_DEVICE_OPTIX)
if(WITH_CUDA_DYNLOAD)
target_link_libraries(${target} extern_cuew)
else()
target_link_libraries(${target} ${CUDA_CUDA_LIBRARY})
endif()
endif()
if(WITH_CYCLES_DEVICE_HIP AND WITH_HIP_DYNLOAD)
target_link_libraries(${target} extern_hipew)
endif()
if(CYCLES_STANDALONE_REPOSITORY)

View File

@@ -22,16 +22,25 @@ set(INC_SYS
../../../extern/clew/include
)
if(WITH_CUDA_DYNLOAD)
if(WITH_CYCLES_DEVICE_OPTIX OR WITH_CYCLES_DEVICE_CUDA)
if(WITH_CUDA_DYNLOAD)
list(APPEND INC
../../../extern/cuew/include
)
add_definitions(-DWITH_CUDA_DYNLOAD)
else()
list(APPEND INC_SYS
${CUDA_TOOLKIT_INCLUDE}
)
add_definitions(-DCYCLES_CUDA_NVCC_EXECUTABLE="${CUDA_NVCC_EXECUTABLE}")
endif()
endif()
if(WITH_CYCLES_DEVICE_HIP AND WITH_HIP_DYNLOAD)
list(APPEND INC
../../../extern/cuew/include
../../../extern/hipew/include
)
add_definitions(-DWITH_CUDA_DYNLOAD)
else()
list(APPEND INC_SYS
${CUDA_TOOLKIT_INCLUDE}
)
add_definitions(-DCYCLES_CUDA_NVCC_EXECUTABLE="${CUDA_NVCC_EXECUTABLE}")
add_definitions(-DWITH_HIP_DYNLOAD)
endif()
set(SRC
@@ -70,6 +79,21 @@ set(SRC_CUDA
cuda/util.h
)
set(SRC_HIP
hip/device.cpp
hip/device.h
hip/device_impl.cpp
hip/device_impl.h
hip/graphics_interop.cpp
hip/graphics_interop.h
hip/kernel.cpp
hip/kernel.h
hip/queue.cpp
hip/queue.h
hip/util.cpp
hip/util.h
)
set(SRC_DUMMY
dummy/device.cpp
dummy/device.h
@@ -105,13 +129,21 @@ set(LIB
${CYCLES_GL_LIBRARIES}
)
if(WITH_CUDA_DYNLOAD)
if(WITH_CYCLES_DEVICE_OPTIX OR WITH_CYCLES_DEVICE_CUDA)
if(WITH_CUDA_DYNLOAD)
list(APPEND LIB
extern_cuew
)
else()
list(APPEND LIB
${CUDA_CUDA_LIBRARY}
)
endif()
endif()
if(WITH_CYCLES_DEVICE_HIP AND WITH_HIP_DYNLOAD)
list(APPEND LIB
extern_cuew
)
else()
list(APPEND LIB
${CUDA_CUDA_LIBRARY}
extern_hipew
)
endif()
@@ -120,6 +152,9 @@ add_definitions(${GL_DEFINITIONS})
if(WITH_CYCLES_DEVICE_CUDA)
add_definitions(-DWITH_CUDA)
endif()
if(WITH_CYCLES_DEVICE_HIP)
add_definitions(-DWITH_HIP)
endif()
if(WITH_CYCLES_DEVICE_OPTIX)
add_definitions(-DWITH_OPTIX)
endif()
@@ -140,6 +175,7 @@ cycles_add_library(cycles_device "${LIB}"
${SRC}
${SRC_CPU}
${SRC_CUDA}
${SRC_HIP}
${SRC_DUMMY}
${SRC_MULTI}
${SRC_OPTIX}

View File

@@ -54,7 +54,6 @@
#include "util/util_function.h"
#include "util/util_logging.h"
#include "util/util_map.h"
#include "util/util_opengl.h"
#include "util/util_openimagedenoise.h"
#include "util/util_optimization.h"
#include "util/util_progress.h"
@@ -170,7 +169,7 @@ void CPUDevice::mem_copy_to(device_memory &mem)
}
void CPUDevice::mem_copy_from(
device_memory & /*mem*/, int /*y*/, int /*w*/, int /*h*/, int /*elem*/)
device_memory & /*mem*/, size_t /*y*/, size_t /*w*/, size_t /*h*/, size_t /*elem*/)
{
/* no-op */
}
@@ -204,7 +203,7 @@ void CPUDevice::mem_free(device_memory &mem)
}
}
device_ptr CPUDevice::mem_alloc_sub_ptr(device_memory &mem, int offset, int /*size*/)
device_ptr CPUDevice::mem_alloc_sub_ptr(device_memory &mem, size_t offset, size_t /*size*/)
{
return (device_ptr)(((char *)mem.device_pointer) + mem.memory_elements_size(offset));
}
@@ -298,154 +297,6 @@ void CPUDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
Device::build_bvh(bvh, progress, refit);
}
#if 0
void CPUDevice::render(DeviceTask &task, RenderTile &tile, KernelGlobals *kg)
{
const bool use_coverage = kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE;
scoped_timer timer(&tile.buffers->render_time);
Coverage coverage(kg, tile);
if (use_coverage) {
coverage.init_path_trace();
}
float *render_buffer = (float *)tile.buffer;
int start_sample = tile.start_sample;
int end_sample = tile.start_sample + tile.num_samples;
/* Needed for Embree. */
SIMD_SET_FLUSH_TO_ZERO;
for (int sample = start_sample; sample < end_sample; sample++) {
if (task.get_cancel() || TaskPool::canceled()) {
if (task.need_finish_queue == false)
break;
}
if (tile.stealing_state == RenderTile::CAN_BE_STOLEN && task.get_tile_stolen()) {
tile.stealing_state = RenderTile::WAS_STOLEN;
break;
}
if (tile.task == RenderTile::PATH_TRACE) {
for (int y = tile.y; y < tile.y + tile.h; y++) {
for (int x = tile.x; x < tile.x + tile.w; x++) {
if (use_coverage) {
coverage.init_pixel(x, y);
}
kernels.path_trace(kg, render_buffer, sample, x, y, tile.offset, tile.stride);
}
}
}
else {
for (int y = tile.y; y < tile.y + tile.h; y++) {
for (int x = tile.x; x < tile.x + tile.w; x++) {
kernels.bake(kg, render_buffer, sample, x, y, tile.offset, tile.stride);
}
}
}
tile.sample = sample + 1;
if (task.adaptive_sampling.use && task.adaptive_sampling.need_filter(sample)) {
const bool stop = adaptive_sampling_filter(kg, tile, sample);
if (stop) {
const int num_progress_samples = end_sample - sample;
tile.sample = end_sample;
task.update_progress(&tile, tile.w * tile.h * num_progress_samples);
break;
}
}
task.update_progress(&tile, tile.w * tile.h);
}
if (use_coverage) {
coverage.finalize();
}
if (task.adaptive_sampling.use && (tile.stealing_state != RenderTile::WAS_STOLEN)) {
adaptive_sampling_post(tile, kg);
}
}
void CPUDevice::thread_render(DeviceTask &task)
{
if (TaskPool::canceled()) {
if (task.need_finish_queue == false)
return;
}
/* allocate buffer for kernel globals */
CPUKernelThreadGlobals kg(kernel_globals, get_cpu_osl_memory());
profiler.add_state(&kg.profiler);
/* NLM denoiser. */
DenoisingTask *denoising = NULL;
/* OpenImageDenoise: we can only denoise with one thread at a time, so to
* avoid waiting with mutex locks in the denoiser, we let only a single
* thread acquire denoising tiles. */
uint tile_types = task.tile_types;
bool hold_denoise_lock = false;
if ((tile_types & RenderTile::DENOISE) && task.denoising.type == DENOISER_OPENIMAGEDENOISE) {
if (!oidn_task_lock.try_lock()) {
tile_types &= ~RenderTile::DENOISE;
hold_denoise_lock = true;
}
}
RenderTile tile;
while (task.acquire_tile(this, tile, tile_types)) {
if (tile.task == RenderTile::PATH_TRACE) {
render(task, tile, &kg);
}
else if (tile.task == RenderTile::BAKE) {
render(task, tile, &kg);
}
else if (tile.task == RenderTile::DENOISE) {
denoise_openimagedenoise(task, tile);
task.update_progress(&tile, tile.w * tile.h);
}
task.release_tile(tile);
if (TaskPool::canceled()) {
if (task.need_finish_queue == false)
break;
}
}
if (hold_denoise_lock) {
oidn_task_lock.unlock();
}
profiler.remove_state(&kg.profiler);
delete denoising;
}
void CPUDevice::thread_denoise(DeviceTask &task)
{
RenderTile tile;
tile.x = task.x;
tile.y = task.y;
tile.w = task.w;
tile.h = task.h;
tile.buffer = task.buffer;
tile.sample = task.sample + task.num_samples;
tile.num_samples = task.num_samples;
tile.start_sample = task.sample;
tile.offset = task.offset;
tile.stride = task.stride;
tile.buffers = task.buffers;
denoise_openimagedenoise(task, tile);
task.update_progress(&tile, tile.w * tile.h);
}
#endif
const CPUKernels *CPUDevice::get_cpu_kernels() const
{
return &kernels;

View File

@@ -72,10 +72,13 @@ class CPUDevice : public Device {
virtual void mem_alloc(device_memory &mem) override;
virtual void mem_copy_to(device_memory &mem) override;
virtual void mem_copy_from(device_memory &mem, int y, int w, int h, int elem) override;
virtual void mem_copy_from(
device_memory &mem, size_t y, size_t w, size_t h, size_t elem) override;
virtual void mem_zero(device_memory &mem) override;
virtual void mem_free(device_memory &mem) override;
virtual device_ptr mem_alloc_sub_ptr(device_memory &mem, int offset, int /*size*/) override;
virtual device_ptr mem_alloc_sub_ptr(device_memory &mem,
size_t offset,
size_t /*size*/) override;
virtual void const_copy_to(const char *name, void *host, size_t size) override;

View File

@@ -31,7 +31,6 @@
# include "util/util_logging.h"
# include "util/util_map.h"
# include "util/util_md5.h"
# include "util/util_opengl.h"
# include "util/util_path.h"
# include "util/util_string.h"
# include "util/util_system.h"
@@ -837,7 +836,7 @@ void CUDADevice::mem_copy_to(device_memory &mem)
}
}
void CUDADevice::mem_copy_from(device_memory &mem, int y, int w, int h, int elem)
void CUDADevice::mem_copy_from(device_memory &mem, size_t y, size_t w, size_t h, size_t elem)
{
if (mem.type == MEM_TEXTURE || mem.type == MEM_GLOBAL) {
assert(!"mem_copy_from not supported for textures.");
@@ -891,7 +890,7 @@ void CUDADevice::mem_free(device_memory &mem)
}
}
device_ptr CUDADevice::mem_alloc_sub_ptr(device_memory &mem, int offset, int /*size*/)
device_ptr CUDADevice::mem_alloc_sub_ptr(device_memory &mem, size_t offset, size_t /*size*/)
{
return (device_ptr)(((char *)mem.device_pointer) + mem.memory_elements_size(offset));
}
@@ -1169,141 +1168,6 @@ void CUDADevice::tex_free(device_texture &mem)
}
}
# if 0
void CUDADevice::render(DeviceTask &task,
RenderTile &rtile,
device_vector<KernelWorkTile> &work_tiles)
{
scoped_timer timer(&rtile.buffers->render_time);
if (have_error())
return;
CUDAContextScope scope(this);
CUfunction cuRender;
/* Get kernel function. */
if (rtile.task == RenderTile::BAKE) {
cuda_assert(cuModuleGetFunction(&cuRender, cuModule, "kernel_cuda_bake"));
}
else {
cuda_assert(cuModuleGetFunction(&cuRender, cuModule, "kernel_cuda_path_trace"));
}
if (have_error()) {
return;
}
cuda_assert(cuFuncSetCacheConfig(cuRender, CU_FUNC_CACHE_PREFER_L1));
/* Allocate work tile. */
work_tiles.alloc(1);
KernelWorkTile *wtile = work_tiles.data();
wtile->x = rtile.x;
wtile->y = rtile.y;
wtile->w = rtile.w;
wtile->h = rtile.h;
wtile->offset = rtile.offset;
wtile->stride = rtile.stride;
wtile->buffer = (float *)(CUdeviceptr)rtile.buffer;
/* Prepare work size. More step samples render faster, but for now we
* remain conservative for GPUs connected to a display to avoid driver
* timeouts and display freezing. */
int min_blocks, num_threads_per_block;
cuda_assert(
cuOccupancyMaxPotentialBlockSize(&min_blocks, &num_threads_per_block, cuRender, NULL, 0, 0));
if (!info.display_device) {
min_blocks *= 8;
}
uint step_samples = divide_up(min_blocks * num_threads_per_block, wtile->w * wtile->h);
/* Render all samples. */
uint start_sample = rtile.start_sample;
uint end_sample = rtile.start_sample + rtile.num_samples;
for (int sample = start_sample; sample < end_sample;) {
/* Setup and copy work tile to device. */
wtile->start_sample = sample;
wtile->num_samples = step_samples;
if (task.adaptive_sampling.use) {
wtile->num_samples = task.adaptive_sampling.align_samples(sample, step_samples);
}
wtile->num_samples = min(wtile->num_samples, end_sample - sample);
work_tiles.copy_to_device();
CUdeviceptr d_work_tiles = (CUdeviceptr)work_tiles.device_pointer;
uint total_work_size = wtile->w * wtile->h * wtile->num_samples;
uint num_blocks = divide_up(total_work_size, num_threads_per_block);
/* Launch kernel. */
void *args[] = {&d_work_tiles, &total_work_size};
cuda_assert(
cuLaunchKernel(cuRender, num_blocks, 1, 1, num_threads_per_block, 1, 1, 0, 0, args, 0));
/* Run the adaptive sampling kernels at selected samples aligned to step samples. */
uint filter_sample = sample + wtile->num_samples - 1;
if (task.adaptive_sampling.use && task.adaptive_sampling.need_filter(filter_sample)) {
adaptive_sampling_filter(filter_sample, wtile, d_work_tiles);
}
cuda_assert(cuCtxSynchronize());
/* Update progress. */
sample += wtile->num_samples;
rtile.sample = sample;
task.update_progress(&rtile, rtile.w * rtile.h * wtile->num_samples);
if (task.get_cancel()) {
if (task.need_finish_queue == false)
break;
}
}
/* Finalize adaptive sampling. */
if (task.adaptive_sampling.use) {
CUdeviceptr d_work_tiles = (CUdeviceptr)work_tiles.device_pointer;
adaptive_sampling_post(rtile, wtile, d_work_tiles);
cuda_assert(cuCtxSynchronize());
task.update_progress(&rtile, rtile.w * rtile.h * wtile->num_samples);
}
}
void CUDADevice::thread_run(DeviceTask &task)
{
CUDAContextScope scope(this);
if (task.type == DeviceTask::RENDER) {
device_vector<KernelWorkTile> work_tiles(this, "work_tiles", MEM_READ_ONLY);
/* keep rendering tiles until done */
RenderTile tile;
DenoisingTask denoising(this, task);
while (task.acquire_tile(this, tile, task.tile_types)) {
if (tile.task == RenderTile::PATH_TRACE) {
render(task, tile, work_tiles);
}
else if (tile.task == RenderTile::BAKE) {
render(task, tile, work_tiles);
}
task.release_tile(tile);
if (task.get_cancel()) {
if (task.need_finish_queue == false)
break;
}
}
work_tiles.free();
}
}
# endif
unique_ptr<DeviceQueue> CUDADevice::gpu_queue_create()
{
return make_unique<CUDADeviceQueue>(this);

View File

@@ -26,7 +26,6 @@
# ifdef WITH_CUDA_DYNLOAD
# include "cuew.h"
# else
# include "util/util_opengl.h"
# include <cuda.h>
# include <cudaGL.h>
# endif
@@ -120,13 +119,13 @@ class CUDADevice : public Device {
void mem_copy_to(device_memory &mem) override;
void mem_copy_from(device_memory &mem, int y, int w, int h, int elem) override;
void mem_copy_from(device_memory &mem, size_t y, size_t w, size_t h, size_t elem) override;
void mem_zero(device_memory &mem) override;
void mem_free(device_memory &mem) override;
device_ptr mem_alloc_sub_ptr(device_memory &mem, int offset, int /*size*/) override;
device_ptr mem_alloc_sub_ptr(device_memory &mem, size_t offset, size_t /*size*/) override;
virtual void const_copy_to(const char *name, void *host, size_t size) override;

View File

@@ -37,14 +37,15 @@ CUDADeviceGraphicsInterop::~CUDADeviceGraphicsInterop()
}
}
void CUDADeviceGraphicsInterop::set_destination(
const DeviceGraphicsInteropDestination &destination)
void CUDADeviceGraphicsInterop::set_display_interop(
const DisplayDriver::GraphicsInterop &display_interop)
{
const int64_t new_buffer_area = int64_t(destination.buffer_width) * destination.buffer_height;
const int64_t new_buffer_area = int64_t(display_interop.buffer_width) *
display_interop.buffer_height;
need_clear_ = destination.need_clear;
need_clear_ = display_interop.need_clear;
if (opengl_pbo_id_ == destination.opengl_pbo_id && buffer_area_ == new_buffer_area) {
if (opengl_pbo_id_ == display_interop.opengl_pbo_id && buffer_area_ == new_buffer_area) {
return;
}
@@ -55,12 +56,12 @@ void CUDADeviceGraphicsInterop::set_destination(
}
const CUresult result = cuGraphicsGLRegisterBuffer(
&cu_graphics_resource_, destination.opengl_pbo_id, CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE);
&cu_graphics_resource_, display_interop.opengl_pbo_id, CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE);
if (result != CUDA_SUCCESS) {
LOG(ERROR) << "Error registering OpenGL buffer: " << cuewErrorString(result);
}
opengl_pbo_id_ = destination.opengl_pbo_id;
opengl_pbo_id_ = display_interop.opengl_pbo_id;
buffer_area_ = new_buffer_area;
}

View File

@@ -41,7 +41,7 @@ class CUDADeviceGraphicsInterop : public DeviceGraphicsInterop {
CUDADeviceGraphicsInterop &operator=(const CUDADeviceGraphicsInterop &other) = delete;
CUDADeviceGraphicsInterop &operator=(CUDADeviceGraphicsInterop &&other) = delete;
virtual void set_destination(const DeviceGraphicsInteropDestination &destination) override;
virtual void set_display_interop(const DisplayDriver::GraphicsInterop &display_interop) override;
virtual device_ptr map() override;
virtual void unmap() override;

View File

@@ -116,18 +116,18 @@ bool CUDADeviceQueue::enqueue(DeviceKernel kernel, const int work_size, void *ar
}
/* Launch kernel. */
cuda_device_assert(cuda_device_,
cuLaunchKernel(cuda_kernel.function,
num_blocks,
1,
1,
num_threads_per_block,
1,
1,
shared_mem_bytes,
cuda_stream_,
args,
0));
assert_success(cuLaunchKernel(cuda_kernel.function,
num_blocks,
1,
1,
num_threads_per_block,
1,
1,
shared_mem_bytes,
cuda_stream_,
args,
0),
"enqueue");
return !(cuda_device_->have_error());
}
@@ -139,7 +139,8 @@ bool CUDADeviceQueue::synchronize()
}
const CUDAContextScope scope(cuda_device_);
cuda_device_assert(cuda_device_, cuStreamSynchronize(cuda_stream_));
assert_success(cuStreamSynchronize(cuda_stream_), "synchronize");
debug_synchronize();
return !(cuda_device_->have_error());
@@ -162,9 +163,9 @@ void CUDADeviceQueue::zero_to_device(device_memory &mem)
assert(mem.device_pointer != 0);
const CUDAContextScope scope(cuda_device_);
cuda_device_assert(
cuda_device_,
cuMemsetD8Async((CUdeviceptr)mem.device_pointer, 0, mem.memory_size(), cuda_stream_));
assert_success(
cuMemsetD8Async((CUdeviceptr)mem.device_pointer, 0, mem.memory_size(), cuda_stream_),
"zero_to_device");
}
void CUDADeviceQueue::copy_to_device(device_memory &mem)
@@ -185,10 +186,10 @@ void CUDADeviceQueue::copy_to_device(device_memory &mem)
/* Copy memory to device. */
const CUDAContextScope scope(cuda_device_);
cuda_device_assert(
cuda_device_,
assert_success(
cuMemcpyHtoDAsync(
(CUdeviceptr)mem.device_pointer, mem.host_pointer, mem.memory_size(), cuda_stream_));
(CUdeviceptr)mem.device_pointer, mem.host_pointer, mem.memory_size(), cuda_stream_),
"copy_to_device");
}
void CUDADeviceQueue::copy_from_device(device_memory &mem)
@@ -204,10 +205,19 @@ void CUDADeviceQueue::copy_from_device(device_memory &mem)
/* Copy memory from device. */
const CUDAContextScope scope(cuda_device_);
cuda_device_assert(
cuda_device_,
assert_success(
cuMemcpyDtoHAsync(
mem.host_pointer, (CUdeviceptr)mem.device_pointer, mem.memory_size(), cuda_stream_));
mem.host_pointer, (CUdeviceptr)mem.device_pointer, mem.memory_size(), cuda_stream_),
"copy_from_device");
}
void CUDADeviceQueue::assert_success(CUresult result, const char *operation)
{
if (result != CUDA_SUCCESS) {
const char *name = cuewErrorString(result);
cuda_device_->set_error(string_printf(
"%s in CUDA queue %s (%s)", name, operation, debug_active_kernels().c_str()));
}
}
unique_ptr<DeviceGraphicsInterop> CUDADeviceQueue::graphics_interop_create()

View File

@@ -60,6 +60,8 @@ class CUDADeviceQueue : public DeviceQueue {
protected:
CUDADevice *cuda_device_;
CUstream cuda_stream_;
void assert_success(CUresult result, const char *operation);
};
CCL_NAMESPACE_END

View File

@@ -25,6 +25,7 @@
#include "device/cpu/device.h"
#include "device/cuda/device.h"
#include "device/dummy/device.h"
#include "device/hip/device.h"
#include "device/multi/device.h"
#include "device/optix/device.h"
@@ -32,7 +33,6 @@
#include "util/util_half.h"
#include "util/util_logging.h"
#include "util/util_math.h"
#include "util/util_opengl.h"
#include "util/util_string.h"
#include "util/util_system.h"
#include "util/util_time.h"
@@ -47,6 +47,7 @@ thread_mutex Device::device_mutex;
vector<DeviceInfo> Device::cuda_devices;
vector<DeviceInfo> Device::optix_devices;
vector<DeviceInfo> Device::cpu_devices;
vector<DeviceInfo> Device::hip_devices;
uint Device::devices_initialized_mask = 0;
/* Device */
@@ -97,6 +98,14 @@ Device *Device::create(const DeviceInfo &info, Stats &stats, Profiler &profiler)
device = device_optix_create(info, stats, profiler);
break;
#endif
#ifdef WITH_HIP
case DEVICE_HIP:
if (device_hip_init())
device = device_hip_create(info, stats, profiler);
break;
#endif
default:
break;
}
@@ -118,6 +127,8 @@ DeviceType Device::type_from_string(const char *name)
return DEVICE_OPTIX;
else if (strcmp(name, "MULTI") == 0)
return DEVICE_MULTI;
else if (strcmp(name, "HIP") == 0)
return DEVICE_HIP;
return DEVICE_NONE;
}
@@ -132,6 +143,8 @@ string Device::string_from_type(DeviceType type)
return "OPTIX";
else if (type == DEVICE_MULTI)
return "MULTI";
else if (type == DEVICE_HIP)
return "HIP";
return "";
}
@@ -146,6 +159,10 @@ vector<DeviceType> Device::available_types()
#ifdef WITH_OPTIX
types.push_back(DEVICE_OPTIX);
#endif
#ifdef WITH_HIP
types.push_back(DEVICE_HIP);
#endif
return types;
}
@@ -187,6 +204,20 @@ vector<DeviceInfo> Device::available_devices(uint mask)
}
#endif
#ifdef WITH_HIP
if (mask & DEVICE_MASK_HIP) {
if (!(devices_initialized_mask & DEVICE_MASK_HIP)) {
if (device_hip_init()) {
device_hip_info(hip_devices);
}
devices_initialized_mask |= DEVICE_MASK_HIP;
}
foreach (DeviceInfo &info, hip_devices) {
devices.push_back(info);
}
}
#endif
if (mask & DEVICE_MASK_CPU) {
if (!(devices_initialized_mask & DEVICE_MASK_CPU)) {
device_cpu_info(cpu_devices);
@@ -227,6 +258,15 @@ string Device::device_capabilities(uint mask)
}
#endif
#ifdef WITH_HIP
if (mask & DEVICE_MASK_HIP) {
if (device_hip_init()) {
capabilities += "\nHIP device capabilities:\n";
capabilities += device_hip_capabilities();
}
}
#endif
return capabilities;
}
@@ -315,6 +355,7 @@ void Device::free_memory()
devices_initialized_mask = 0;
cuda_devices.free_memory();
optix_devices.free_memory();
hip_devices.free_memory();
cpu_devices.free_memory();
}

View File

@@ -51,6 +51,7 @@ enum DeviceType {
DEVICE_CUDA,
DEVICE_MULTI,
DEVICE_OPTIX,
DEVICE_HIP,
DEVICE_DUMMY,
};
@@ -58,6 +59,7 @@ enum DeviceTypeMask {
DEVICE_MASK_CPU = (1 << DEVICE_CPU),
DEVICE_MASK_CUDA = (1 << DEVICE_CUDA),
DEVICE_MASK_OPTIX = (1 << DEVICE_OPTIX),
DEVICE_MASK_HIP = (1 << DEVICE_HIP),
DEVICE_MASK_ALL = ~0
};
@@ -119,7 +121,7 @@ class Device {
string error_msg;
virtual device_ptr mem_alloc_sub_ptr(device_memory & /*mem*/, int /*offset*/, int /*size*/)
virtual device_ptr mem_alloc_sub_ptr(device_memory & /*mem*/, size_t /*offset*/, size_t /*size*/)
{
/* Only required for devices that implement denoising. */
assert(false);
@@ -273,7 +275,7 @@ class Device {
virtual void mem_alloc(device_memory &mem) = 0;
virtual void mem_copy_to(device_memory &mem) = 0;
virtual void mem_copy_from(device_memory &mem, int y, int w, int h, int elem) = 0;
virtual void mem_copy_from(device_memory &mem, size_t y, size_t w, size_t h, size_t elem) = 0;
virtual void mem_zero(device_memory &mem) = 0;
virtual void mem_free(device_memory &mem) = 0;
@@ -284,6 +286,7 @@ class Device {
static vector<DeviceInfo> cuda_devices;
static vector<DeviceInfo> optix_devices;
static vector<DeviceInfo> cpu_devices;
static vector<DeviceInfo> hip_devices;
static uint devices_initialized_mask;
};

View File

@@ -16,25 +16,12 @@
#pragma once
#include "render/display_driver.h"
#include "util/util_types.h"
CCL_NAMESPACE_BEGIN
/* Information about interoperability destination.
* Is provided by the GPUDisplay. */
class DeviceGraphicsInteropDestination {
public:
/* Dimensions of the buffer, in pixels. */
int buffer_width = 0;
int buffer_height = 0;
/* OpenGL pixel buffer object. */
int opengl_pbo_id = 0;
/* Clear the entire destination before doing partial write to it. */
bool need_clear = false;
};
/* Device-side graphics interoperability support.
*
* Takes care of holding all the handlers needed by the device to implement interoperability with
@@ -46,7 +33,7 @@ class DeviceGraphicsInterop {
/* Update this device-side graphics interoperability object with the given destination resource
* information. */
virtual void set_destination(const DeviceGraphicsInteropDestination &destination) = 0;
virtual void set_display_interop(const DisplayDriver::GraphicsInterop &display_interop) = 0;
virtual device_ptr map() = 0;
virtual void unmap() = 0;

View File

@@ -136,7 +136,7 @@ void device_memory::device_copy_to()
}
}
void device_memory::device_copy_from(int y, int w, int h, int elem)
void device_memory::device_copy_from(size_t y, size_t w, size_t h, size_t elem)
{
assert(type != MEM_TEXTURE && type != MEM_READ_ONLY && type != MEM_GLOBAL);
device->mem_copy_from(*this, y, w, h, elem);
@@ -181,7 +181,7 @@ bool device_memory::is_resident(Device *sub_device) const
/* Device Sub Ptr */
device_sub_ptr::device_sub_ptr(device_memory &mem, int offset, int size) : device(mem.device)
device_sub_ptr::device_sub_ptr(device_memory &mem, size_t offset, size_t size) : device(mem.device)
{
ptr = device->mem_alloc_sub_ptr(mem, offset, size);
}

View File

@@ -81,154 +81,154 @@ static constexpr size_t datatype_size(DataType datatype)
template<typename T> struct device_type_traits {
static const DataType data_type = TYPE_UNKNOWN;
static const int num_elements_cpu = sizeof(T);
static const int num_elements_gpu = sizeof(T);
static const size_t num_elements_cpu = sizeof(T);
static const size_t num_elements_gpu = sizeof(T);
};
template<> struct device_type_traits<uchar> {
static const DataType data_type = TYPE_UCHAR;
static const int num_elements_cpu = 1;
static const int num_elements_gpu = 1;
static const size_t num_elements_cpu = 1;
static const size_t num_elements_gpu = 1;
static_assert(sizeof(uchar) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<uchar2> {
static const DataType data_type = TYPE_UCHAR;
static const int num_elements_cpu = 2;
static const int num_elements_gpu = 2;
static const size_t num_elements_cpu = 2;
static const size_t num_elements_gpu = 2;
static_assert(sizeof(uchar2) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<uchar3> {
static const DataType data_type = TYPE_UCHAR;
static const int num_elements_cpu = 3;
static const int num_elements_gpu = 3;
static const size_t num_elements_cpu = 3;
static const size_t num_elements_gpu = 3;
static_assert(sizeof(uchar3) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<uchar4> {
static const DataType data_type = TYPE_UCHAR;
static const int num_elements_cpu = 4;
static const int num_elements_gpu = 4;
static const size_t num_elements_cpu = 4;
static const size_t num_elements_gpu = 4;
static_assert(sizeof(uchar4) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<uint> {
static const DataType data_type = TYPE_UINT;
static const int num_elements_cpu = 1;
static const int num_elements_gpu = 1;
static const size_t num_elements_cpu = 1;
static const size_t num_elements_gpu = 1;
static_assert(sizeof(uint) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<uint2> {
static const DataType data_type = TYPE_UINT;
static const int num_elements_cpu = 2;
static const int num_elements_gpu = 2;
static const size_t num_elements_cpu = 2;
static const size_t num_elements_gpu = 2;
static_assert(sizeof(uint2) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<uint3> {
static const DataType data_type = TYPE_UINT;
static const int num_elements_cpu = 3;
static const int num_elements_gpu = 3;
static const size_t num_elements_cpu = 3;
static const size_t num_elements_gpu = 3;
static_assert(sizeof(uint3) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<uint4> {
static const DataType data_type = TYPE_UINT;
static const int num_elements_cpu = 4;
static const int num_elements_gpu = 4;
static const size_t num_elements_cpu = 4;
static const size_t num_elements_gpu = 4;
static_assert(sizeof(uint4) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<int> {
static const DataType data_type = TYPE_INT;
static const int num_elements_cpu = 1;
static const int num_elements_gpu = 1;
static const size_t num_elements_cpu = 1;
static const size_t num_elements_gpu = 1;
static_assert(sizeof(int) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<int2> {
static const DataType data_type = TYPE_INT;
static const int num_elements_cpu = 2;
static const int num_elements_gpu = 2;
static const size_t num_elements_cpu = 2;
static const size_t num_elements_gpu = 2;
static_assert(sizeof(int2) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<int3> {
static const DataType data_type = TYPE_INT;
static const int num_elements_cpu = 4;
static const int num_elements_gpu = 3;
static const size_t num_elements_cpu = 4;
static const size_t num_elements_gpu = 3;
static_assert(sizeof(int3) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<int4> {
static const DataType data_type = TYPE_INT;
static const int num_elements_cpu = 4;
static const int num_elements_gpu = 4;
static const size_t num_elements_cpu = 4;
static const size_t num_elements_gpu = 4;
static_assert(sizeof(int4) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<float> {
static const DataType data_type = TYPE_FLOAT;
static const int num_elements_cpu = 1;
static const int num_elements_gpu = 1;
static const size_t num_elements_cpu = 1;
static const size_t num_elements_gpu = 1;
static_assert(sizeof(float) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<float2> {
static const DataType data_type = TYPE_FLOAT;
static const int num_elements_cpu = 2;
static const int num_elements_gpu = 2;
static const size_t num_elements_cpu = 2;
static const size_t num_elements_gpu = 2;
static_assert(sizeof(float2) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<float3> {
static const DataType data_type = TYPE_FLOAT;
static const int num_elements_cpu = 4;
static const int num_elements_gpu = 3;
static const size_t num_elements_cpu = 4;
static const size_t num_elements_gpu = 3;
static_assert(sizeof(float3) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<float4> {
static const DataType data_type = TYPE_FLOAT;
static const int num_elements_cpu = 4;
static const int num_elements_gpu = 4;
static const size_t num_elements_cpu = 4;
static const size_t num_elements_gpu = 4;
static_assert(sizeof(float4) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<half> {
static const DataType data_type = TYPE_HALF;
static const int num_elements_cpu = 1;
static const int num_elements_gpu = 1;
static const size_t num_elements_cpu = 1;
static const size_t num_elements_gpu = 1;
static_assert(sizeof(half) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<ushort4> {
static const DataType data_type = TYPE_UINT16;
static const int num_elements_cpu = 4;
static const int num_elements_gpu = 4;
static const size_t num_elements_cpu = 4;
static const size_t num_elements_gpu = 4;
static_assert(sizeof(ushort4) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<uint16_t> {
static const DataType data_type = TYPE_UINT16;
static const int num_elements_cpu = 1;
static const int num_elements_gpu = 1;
static const size_t num_elements_cpu = 1;
static const size_t num_elements_gpu = 1;
static_assert(sizeof(uint16_t) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<half4> {
static const DataType data_type = TYPE_HALF;
static const int num_elements_cpu = 4;
static const int num_elements_gpu = 4;
static const size_t num_elements_cpu = 4;
static const size_t num_elements_gpu = 4;
static_assert(sizeof(half4) == num_elements_cpu * datatype_size(data_type));
};
template<> struct device_type_traits<uint64_t> {
static const DataType data_type = TYPE_UINT64;
static const int num_elements_cpu = 1;
static const int num_elements_gpu = 1;
static const size_t num_elements_cpu = 1;
static const size_t num_elements_gpu = 1;
static_assert(sizeof(uint64_t) == num_elements_cpu * datatype_size(data_type));
};
@@ -277,6 +277,7 @@ class device_memory {
protected:
friend class CUDADevice;
friend class OptiXDevice;
friend class HIPDevice;
/* Only create through subclasses. */
device_memory(Device *device, const char *name, MemoryType type);
@@ -296,7 +297,7 @@ class device_memory {
void device_alloc();
void device_free();
void device_copy_to();
void device_copy_from(int y, int w, int h, int elem);
void device_copy_from(size_t y, size_t w, size_t h, size_t elem);
void device_zero();
bool device_is_cpu();
@@ -565,7 +566,7 @@ template<typename T> class device_vector : public device_memory {
device_copy_from(0, data_width, (data_height == 0) ? 1 : data_height, sizeof(T));
}
void copy_from_device(int y, int w, int h)
void copy_from_device(size_t y, size_t w, size_t h)
{
device_copy_from(y, w, h, sizeof(T));
}
@@ -601,7 +602,7 @@ template<typename T> class device_vector : public device_memory {
class device_sub_ptr {
public:
device_sub_ptr(device_memory &mem, int offset, int size);
device_sub_ptr(device_memory &mem, size_t offset, size_t size);
~device_sub_ptr();
device_ptr operator*() const

View File

@@ -57,8 +57,9 @@ void DeviceQueue::debug_init_execution()
{
if (VLOG_IS_ON(3)) {
last_sync_time_ = time_dt();
last_kernels_enqueued_ = 0;
}
last_kernels_enqueued_ = 0;
}
void DeviceQueue::debug_enqueue(DeviceKernel kernel, const int work_size)
@@ -66,8 +67,9 @@ void DeviceQueue::debug_enqueue(DeviceKernel kernel, const int work_size)
if (VLOG_IS_ON(3)) {
VLOG(4) << "GPU queue launch " << device_kernel_as_string(kernel) << ", work_size "
<< work_size;
last_kernels_enqueued_ |= (uint64_t(1) << (uint64_t)kernel);
}
last_kernels_enqueued_ |= (uint64_t(1) << (uint64_t)kernel);
}
void DeviceQueue::debug_synchronize()
@@ -80,8 +82,14 @@ void DeviceQueue::debug_synchronize()
stats_kernel_time_[last_kernels_enqueued_] += elapsed_time;
last_sync_time_ = new_time;
last_kernels_enqueued_ = 0;
}
last_kernels_enqueued_ = 0;
}
string DeviceQueue::debug_active_kernels()
{
return device_kernel_mask_as_string(last_kernels_enqueued_);
}
CCL_NAMESPACE_END

View File

@@ -21,6 +21,7 @@
#include "device/device_graphics_interop.h"
#include "util/util_logging.h"
#include "util/util_map.h"
#include "util/util_string.h"
#include "util/util_unique_ptr.h"
CCL_NAMESPACE_BEGIN
@@ -101,6 +102,7 @@ class DeviceQueue {
void debug_init_execution();
void debug_enqueue(DeviceKernel kernel, const int work_size);
void debug_synchronize();
string debug_active_kernels();
/* Combination of kernels enqueued together sync last synchronize. */
DeviceKernelMask last_kernels_enqueued_;

View File

@@ -48,7 +48,7 @@ class DummyDevice : public Device {
{
}
virtual void mem_copy_from(device_memory &, int, int, int, int) override
virtual void mem_copy_from(device_memory &, size_t, size_t, size_t, size_t) override
{
}

View File

@@ -0,0 +1,276 @@
/*
* Copyright 2011-2021 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 "device/hip/device.h"
#include "util/util_logging.h"
#ifdef WITH_HIP
# include "device/device.h"
# include "device/hip/device_impl.h"
# include "util/util_string.h"
# include "util/util_windows.h"
#endif /* WITH_HIP */
CCL_NAMESPACE_BEGIN
bool device_hip_init()
{
#if !defined(WITH_HIP)
return false;
#elif defined(WITH_HIP_DYNLOAD)
static bool initialized = false;
static bool result = false;
if (initialized)
return result;
initialized = true;
int hipew_result = hipewInit(HIPEW_INIT_HIP);
if (hipew_result == HIPEW_SUCCESS) {
VLOG(1) << "HIPEW initialization succeeded";
if (HIPDevice::have_precompiled_kernels()) {
VLOG(1) << "Found precompiled kernels";
result = true;
}
else if (hipewCompilerPath() != NULL) {
VLOG(1) << "Found HIPCC " << hipewCompilerPath();
result = true;
}
else {
VLOG(1) << "Neither precompiled kernels nor HIPCC was found,"
<< " unable to use HIP";
}
}
else {
VLOG(1) << "HIPEW initialization failed: "
<< ((hipew_result == HIPEW_ERROR_ATEXIT_FAILED) ? "Error setting up atexit() handler" :
"Error opening the library");
}
return result;
#else /* WITH_HIP_DYNLOAD */
return true;
#endif /* WITH_HIP_DYNLOAD */
}
Device *device_hip_create(const DeviceInfo &info, Stats &stats, Profiler &profiler)
{
#ifdef WITH_HIP
return new HIPDevice(info, stats, profiler);
#else
(void)info;
(void)stats;
(void)profiler;
LOG(FATAL) << "Request to create HIP device without compiled-in support. Should never happen.";
return nullptr;
#endif
}
#ifdef WITH_HIP
static hipError_t device_hip_safe_init()
{
# ifdef _WIN32
__try {
return hipInit(0);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
/* Ignore crashes inside the HIP driver and hope we can
* survive even with corrupted HIP installs. */
fprintf(stderr, "Cycles HIP: driver crashed, continuing without HIP.\n");
}
return hipErrorNoDevice;
# else
return hipInit(0);
# endif
}
#endif /* WITH_HIP */
void device_hip_info(vector<DeviceInfo> &devices)
{
#ifdef WITH_HIP
hipError_t result = device_hip_safe_init();
if (result != hipSuccess) {
if (result != hipErrorNoDevice)
fprintf(stderr, "HIP hipInit: %s\n", hipewErrorString(result));
return;
}
int count = 0;
result = hipGetDeviceCount(&count);
if (result != hipSuccess) {
fprintf(stderr, "HIP hipGetDeviceCount: %s\n", hipewErrorString(result));
return;
}
vector<DeviceInfo> display_devices;
for (int num = 0; num < count; num++) {
char name[256];
result = hipDeviceGetName(name, 256, num);
if (result != hipSuccess) {
fprintf(stderr, "HIP :hipDeviceGetName: %s\n", hipewErrorString(result));
continue;
}
int major;
hipDeviceGetAttribute(&major, hipDeviceAttributeComputeCapabilityMajor, num);
// TODO : (Arya) What is the last major version we are supporting?
DeviceInfo info;
info.type = DEVICE_HIP;
info.description = string(name);
info.num = num;
info.has_half_images = (major >= 3);
info.has_nanovdb = true;
info.denoisers = 0;
info.has_gpu_queue = true;
/* Check if the device has P2P access to any other device in the system. */
for (int peer_num = 0; peer_num < count && !info.has_peer_memory; peer_num++) {
if (num != peer_num) {
int can_access = 0;
hipDeviceCanAccessPeer(&can_access, num, peer_num);
info.has_peer_memory = (can_access != 0);
}
}
int pci_location[3] = {0, 0, 0};
hipDeviceGetAttribute(&pci_location[0], hipDeviceAttributePciDomainID, num);
hipDeviceGetAttribute(&pci_location[1], hipDeviceAttributePciBusId, num);
hipDeviceGetAttribute(&pci_location[2], hipDeviceAttributePciDeviceId, num);
info.id = string_printf("HIP_%s_%04x:%02x:%02x",
name,
(unsigned int)pci_location[0],
(unsigned int)pci_location[1],
(unsigned int)pci_location[2]);
/* If device has a kernel timeout and no compute preemption, we assume
* it is connected to a display and will freeze the display while doing
* computations. */
int timeout_attr = 0, preempt_attr = 0;
hipDeviceGetAttribute(&timeout_attr, hipDeviceAttributeKernelExecTimeout, num);
if (timeout_attr && !preempt_attr) {
VLOG(1) << "Device is recognized as display.";
info.description += " (Display)";
info.display_device = true;
display_devices.push_back(info);
}
else {
VLOG(1) << "Device has compute preemption or is not used for display.";
devices.push_back(info);
}
VLOG(1) << "Added device \"" << name << "\" with id \"" << info.id << "\".";
}
if (!display_devices.empty())
devices.insert(devices.end(), display_devices.begin(), display_devices.end());
#else /* WITH_HIP */
(void)devices;
#endif /* WITH_HIP */
}
string device_hip_capabilities()
{
#ifdef WITH_HIP
hipError_t result = device_hip_safe_init();
if (result != hipSuccess) {
if (result != hipErrorNoDevice) {
return string("Error initializing HIP: ") + hipewErrorString(result);
}
return "No HIP device found\n";
}
int count;
result = hipGetDeviceCount(&count);
if (result != hipSuccess) {
return string("Error getting devices: ") + hipewErrorString(result);
}
string capabilities = "";
for (int num = 0; num < count; num++) {
char name[256];
if (hipDeviceGetName(name, 256, num) != hipSuccess) {
continue;
}
capabilities += string("\t") + name + "\n";
int value;
# define GET_ATTR(attr) \
{ \
if (hipDeviceGetAttribute(&value, hipDeviceAttribute##attr, num) == hipSuccess) { \
capabilities += string_printf("\t\thipDeviceAttribute" #attr "\t\t\t%d\n", value); \
} \
} \
(void)0
/* TODO(sergey): Strip all attributes which are not useful for us
* or does not depend on the driver.
*/
GET_ATTR(MaxThreadsPerBlock);
GET_ATTR(MaxBlockDimX);
GET_ATTR(MaxBlockDimY);
GET_ATTR(MaxBlockDimZ);
GET_ATTR(MaxGridDimX);
GET_ATTR(MaxGridDimY);
GET_ATTR(MaxGridDimZ);
GET_ATTR(MaxSharedMemoryPerBlock);
GET_ATTR(TotalConstantMemory);
GET_ATTR(WarpSize);
GET_ATTR(MaxPitch);
GET_ATTR(MaxRegistersPerBlock);
GET_ATTR(ClockRate);
GET_ATTR(TextureAlignment);
GET_ATTR(MultiprocessorCount);
GET_ATTR(KernelExecTimeout);
GET_ATTR(Integrated);
GET_ATTR(CanMapHostMemory);
GET_ATTR(ComputeMode);
GET_ATTR(MaxTexture1DWidth);
GET_ATTR(MaxTexture2DWidth);
GET_ATTR(MaxTexture2DHeight);
GET_ATTR(MaxTexture3DWidth);
GET_ATTR(MaxTexture3DHeight);
GET_ATTR(MaxTexture3DDepth);
GET_ATTR(ConcurrentKernels);
GET_ATTR(EccEnabled);
GET_ATTR(MemoryClockRate);
GET_ATTR(MemoryBusWidth);
GET_ATTR(L2CacheSize);
GET_ATTR(MaxThreadsPerMultiProcessor);
GET_ATTR(ComputeCapabilityMajor);
GET_ATTR(ComputeCapabilityMinor);
GET_ATTR(MaxSharedMemoryPerMultiprocessor);
GET_ATTR(ManagedMemory);
GET_ATTR(IsMultiGpuBoard);
# undef GET_ATTR
capabilities += "\n";
}
return capabilities;
#else /* WITH_HIP */
return "";
#endif /* WITH_HIP */
}
CCL_NAMESPACE_END

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2011-2021 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 "util/util_string.h"
#include "util/util_vector.h"
CCL_NAMESPACE_BEGIN
class Device;
class DeviceInfo;
class Profiler;
class Stats;
bool device_hip_init();
Device *device_hip_create(const DeviceInfo &info, Stats &stats, Profiler &profiler);
void device_hip_info(vector<DeviceInfo> &devices);
string device_hip_capabilities();
CCL_NAMESPACE_END

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,153 @@
/*
* Copyright 2011-2021 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.
*/
#ifdef WITH_HIP
# include "device/device.h"
# include "device/hip/kernel.h"
# include "device/hip/queue.h"
# include "device/hip/util.h"
# include "util/util_map.h"
# ifdef WITH_HIP_DYNLOAD
# include "hipew.h"
# else
# include "util/util_opengl.h"
# endif
CCL_NAMESPACE_BEGIN
class DeviceQueue;
class HIPDevice : public Device {
friend class HIPContextScope;
public:
hipDevice_t hipDevice;
hipCtx_t hipContext;
hipModule_t hipModule;
size_t device_texture_headroom;
size_t device_working_headroom;
bool move_texture_to_host;
size_t map_host_used;
size_t map_host_limit;
int can_map_host;
int pitch_alignment;
int hipDevId;
int hipDevArchitecture;
bool first_error;
struct HIPMem {
HIPMem() : texobject(0), array(0), use_mapped_host(false)
{
}
hipTextureObject_t texobject;
hArray array;
/* If true, a mapped host memory in shared_pointer is being used. */
bool use_mapped_host;
};
typedef map<device_memory *, HIPMem> HIPMemMap;
HIPMemMap hip_mem_map;
thread_mutex hip_mem_map_mutex;
/* Bindless Textures */
device_vector<TextureInfo> texture_info;
bool need_texture_info;
HIPDeviceKernels kernels;
static bool have_precompiled_kernels();
virtual bool show_samples() const override;
virtual BVHLayoutMask get_bvh_layout_mask() const override;
void set_error(const string &error) override;
HIPDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler);
virtual ~HIPDevice();
bool support_device(const uint /*kernel_features*/);
bool check_peer_access(Device *peer_device) override;
bool use_adaptive_compilation();
virtual string compile_kernel_get_common_cflags(const uint kernel_features);
string compile_kernel(const uint kernel_features,
const char *name,
const char *base = "hip",
bool force_ptx = false);
virtual bool load_kernels(const uint kernel_features) override;
void reserve_local_memory(const uint kernel_features);
void init_host_memory();
void load_texture_info();
void move_textures_to_host(size_t size, bool for_texture);
HIPMem *generic_alloc(device_memory &mem, size_t pitch_padding = 0);
void generic_copy_to(device_memory &mem);
void generic_free(device_memory &mem);
void mem_alloc(device_memory &mem) override;
void mem_copy_to(device_memory &mem) override;
void mem_copy_from(device_memory &mem, size_t y, size_t w, size_t h, size_t elem) override;
void mem_zero(device_memory &mem) override;
void mem_free(device_memory &mem) override;
device_ptr mem_alloc_sub_ptr(device_memory &mem, size_t offset, size_t /*size*/) override;
virtual void const_copy_to(const char *name, void *host, size_t size) override;
void global_alloc(device_memory &mem);
void global_free(device_memory &mem);
void tex_alloc(device_texture &mem);
void tex_free(device_texture &mem);
/* Graphics resources interoperability. */
virtual bool should_use_graphics_interop() override;
virtual unique_ptr<DeviceQueue> gpu_queue_create() override;
int get_num_multiprocessors();
int get_max_num_threads_per_multiprocessor();
protected:
bool get_device_attribute(hipDeviceAttribute_t attribute, int *value);
int get_device_default_attribute(hipDeviceAttribute_t attribute, int default_value);
};
CCL_NAMESPACE_END
#endif

View File

@@ -0,0 +1,105 @@
/*
* Copyright 2011-2021 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.
*/
#ifdef WITH_HIP
# include "device/hip/graphics_interop.h"
# include "device/hip/device_impl.h"
# include "device/hip/util.h"
CCL_NAMESPACE_BEGIN
HIPDeviceGraphicsInterop::HIPDeviceGraphicsInterop(HIPDeviceQueue *queue)
: queue_(queue), device_(static_cast<HIPDevice *>(queue->device))
{
}
HIPDeviceGraphicsInterop::~HIPDeviceGraphicsInterop()
{
HIPContextScope scope(device_);
if (hip_graphics_resource_) {
hip_device_assert(device_, hipGraphicsUnregisterResource(hip_graphics_resource_));
}
}
void HIPDeviceGraphicsInterop::set_display_interop(
const DisplayDriver::GraphicsInterop &display_interop)
{
const int64_t new_buffer_area = int64_t(display_interop.buffer_width) *
display_interop.buffer_height;
need_clear_ = display_interop.need_clear;
if (opengl_pbo_id_ == display_interop.opengl_pbo_id && buffer_area_ == new_buffer_area) {
return;
}
HIPContextScope scope(device_);
if (hip_graphics_resource_) {
hip_device_assert(device_, hipGraphicsUnregisterResource(hip_graphics_resource_));
}
const hipError_t result = hipGraphicsGLRegisterBuffer(
&hip_graphics_resource_, display_interop.opengl_pbo_id, hipGraphicsRegisterFlagsNone);
if (result != hipSuccess) {
LOG(ERROR) << "Error registering OpenGL buffer: " << hipewErrorString(result);
}
opengl_pbo_id_ = display_interop.opengl_pbo_id;
buffer_area_ = new_buffer_area;
}
device_ptr HIPDeviceGraphicsInterop::map()
{
if (!hip_graphics_resource_) {
return 0;
}
HIPContextScope scope(device_);
hipDeviceptr_t hip_buffer;
size_t bytes;
hip_device_assert(device_,
hipGraphicsMapResources(1, &hip_graphics_resource_, queue_->stream()));
hip_device_assert(
device_, hipGraphicsResourceGetMappedPointer(&hip_buffer, &bytes, hip_graphics_resource_));
if (need_clear_) {
hip_device_assert(
device_,
hipMemsetD8Async(static_cast<hipDeviceptr_t>(hip_buffer), 0, bytes, queue_->stream()));
need_clear_ = false;
}
return static_cast<device_ptr>(hip_buffer);
}
void HIPDeviceGraphicsInterop::unmap()
{
HIPContextScope scope(device_);
hip_device_assert(device_,
hipGraphicsUnmapResources(1, &hip_graphics_resource_, queue_->stream()));
}
CCL_NAMESPACE_END
#endif

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2011-2021 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.
*/
#ifdef WITH_HIP
# include "device/device_graphics_interop.h"
# ifdef WITH_HIP_DYNLOAD
# include "hipew.h"
# endif
CCL_NAMESPACE_BEGIN
class HIPDevice;
class HIPDeviceQueue;
class HIPDeviceGraphicsInterop : public DeviceGraphicsInterop {
public:
explicit HIPDeviceGraphicsInterop(HIPDeviceQueue *queue);
HIPDeviceGraphicsInterop(const HIPDeviceGraphicsInterop &other) = delete;
HIPDeviceGraphicsInterop(HIPDeviceGraphicsInterop &&other) noexcept = delete;
~HIPDeviceGraphicsInterop();
HIPDeviceGraphicsInterop &operator=(const HIPDeviceGraphicsInterop &other) = delete;
HIPDeviceGraphicsInterop &operator=(HIPDeviceGraphicsInterop &&other) = delete;
virtual void set_display_interop(const DisplayDriver::GraphicsInterop &display_interop) override;
virtual device_ptr map() override;
virtual void unmap() override;
protected:
HIPDeviceQueue *queue_ = nullptr;
HIPDevice *device_ = nullptr;
/* OpenGL PBO which is currently registered as the destination for the CUDA buffer. */
uint opengl_pbo_id_ = 0;
/* Buffer area in pixels of the corresponding PBO. */
int64_t buffer_area_ = 0;
/* The destination was requested to be cleared. */
bool need_clear_ = false;
hipGraphicsResource hip_graphics_resource_ = nullptr;
};
CCL_NAMESPACE_END
#endif

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2011-2021 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.
*/
#ifdef WITH_HIP
# include "device/hip/kernel.h"
# include "device/hip/device_impl.h"
CCL_NAMESPACE_BEGIN
void HIPDeviceKernels::load(HIPDevice *device)
{
hipModule_t hipModule = device->hipModule;
for (int i = 0; i < (int)DEVICE_KERNEL_NUM; i++) {
HIPDeviceKernel &kernel = kernels_[i];
/* No mega-kernel used for GPU. */
if (i == DEVICE_KERNEL_INTEGRATOR_MEGAKERNEL) {
continue;
}
const std::string function_name = std::string("kernel_gpu_") +
device_kernel_as_string((DeviceKernel)i);
hip_device_assert(device,
hipModuleGetFunction(&kernel.function, hipModule, function_name.c_str()));
if (kernel.function) {
hip_device_assert(device, hipFuncSetCacheConfig(kernel.function, hipFuncCachePreferL1));
hip_device_assert(
device,
hipModuleOccupancyMaxPotentialBlockSize(
&kernel.min_blocks, &kernel.num_threads_per_block, kernel.function, 0, 0));
}
else {
LOG(ERROR) << "Unable to load kernel " << function_name;
}
}
loaded = true;
}
const HIPDeviceKernel &HIPDeviceKernels::get(DeviceKernel kernel) const
{
return kernels_[(int)kernel];
}
bool HIPDeviceKernels::available(DeviceKernel kernel) const
{
return kernels_[(int)kernel].function != nullptr;
}
CCL_NAMESPACE_END
#endif /* WITH_HIP*/

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2011-2021 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
#ifdef WITH_HIP
# include "device/device_kernel.h"
# ifdef WITH_HIP_DYNLOAD
# include "hipew.h"
# endif
CCL_NAMESPACE_BEGIN
class HIPDevice;
/* HIP kernel and associate occupancy information. */
class HIPDeviceKernel {
public:
hipFunction_t function = nullptr;
int num_threads_per_block = 0;
int min_blocks = 0;
};
/* Cache of HIP kernels for each DeviceKernel. */
class HIPDeviceKernels {
public:
void load(HIPDevice *device);
const HIPDeviceKernel &get(DeviceKernel kernel) const;
bool available(DeviceKernel kernel) const;
protected:
HIPDeviceKernel kernels_[DEVICE_KERNEL_NUM];
bool loaded = false;
};
CCL_NAMESPACE_END
#endif /* WITH_HIP */

View File

@@ -0,0 +1,209 @@
/*
* Copyright 2011-2021 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.
*/
#ifdef WITH_HIP
# include "device/hip/queue.h"
# include "device/hip/device_impl.h"
# include "device/hip/graphics_interop.h"
# include "device/hip/kernel.h"
CCL_NAMESPACE_BEGIN
/* HIPDeviceQueue */
HIPDeviceQueue::HIPDeviceQueue(HIPDevice *device)
: DeviceQueue(device), hip_device_(device), hip_stream_(nullptr)
{
const HIPContextScope scope(hip_device_);
hip_device_assert(hip_device_, hipStreamCreateWithFlags(&hip_stream_, hipStreamNonBlocking));
}
HIPDeviceQueue::~HIPDeviceQueue()
{
const HIPContextScope scope(hip_device_);
hipStreamDestroy(hip_stream_);
}
int HIPDeviceQueue::num_concurrent_states(const size_t /*state_size*/) const
{
/* TODO: compute automatically. */
/* TODO: must have at least num_threads_per_block. */
return 14416128;
}
int HIPDeviceQueue::num_concurrent_busy_states() const
{
const int max_num_threads = hip_device_->get_num_multiprocessors() *
hip_device_->get_max_num_threads_per_multiprocessor();
if (max_num_threads == 0) {
return 65536;
}
return 4 * max_num_threads;
}
void HIPDeviceQueue::init_execution()
{
/* Synchronize all textures and memory copies before executing task. */
HIPContextScope scope(hip_device_);
hip_device_->load_texture_info();
hip_device_assert(hip_device_, hipDeviceSynchronize());
debug_init_execution();
}
bool HIPDeviceQueue::kernel_available(DeviceKernel kernel) const
{
return hip_device_->kernels.available(kernel);
}
bool HIPDeviceQueue::enqueue(DeviceKernel kernel, const int work_size, void *args[])
{
if (hip_device_->have_error()) {
return false;
}
debug_enqueue(kernel, work_size);
const HIPContextScope scope(hip_device_);
const HIPDeviceKernel &hip_kernel = hip_device_->kernels.get(kernel);
/* Compute kernel launch parameters. */
const int num_threads_per_block = hip_kernel.num_threads_per_block;
const int num_blocks = divide_up(work_size, num_threads_per_block);
int shared_mem_bytes = 0;
switch (kernel) {
case DEVICE_KERNEL_INTEGRATOR_QUEUED_PATHS_ARRAY:
case DEVICE_KERNEL_INTEGRATOR_QUEUED_SHADOW_PATHS_ARRAY:
case DEVICE_KERNEL_INTEGRATOR_ACTIVE_PATHS_ARRAY:
case DEVICE_KERNEL_INTEGRATOR_TERMINATED_PATHS_ARRAY:
case DEVICE_KERNEL_INTEGRATOR_SORTED_PATHS_ARRAY:
case DEVICE_KERNEL_INTEGRATOR_COMPACT_PATHS_ARRAY:
/* See parall_active_index.h for why this amount of shared memory is needed. */
shared_mem_bytes = (num_threads_per_block + 1) * sizeof(int);
break;
default:
break;
}
/* Launch kernel. */
hip_device_assert(hip_device_,
hipModuleLaunchKernel(hip_kernel.function,
num_blocks,
1,
1,
num_threads_per_block,
1,
1,
shared_mem_bytes,
hip_stream_,
args,
0));
return !(hip_device_->have_error());
}
bool HIPDeviceQueue::synchronize()
{
if (hip_device_->have_error()) {
return false;
}
const HIPContextScope scope(hip_device_);
hip_device_assert(hip_device_, hipStreamSynchronize(hip_stream_));
debug_synchronize();
return !(hip_device_->have_error());
}
void HIPDeviceQueue::zero_to_device(device_memory &mem)
{
assert(mem.type != MEM_GLOBAL && mem.type != MEM_TEXTURE);
if (mem.memory_size() == 0) {
return;
}
/* Allocate on demand. */
if (mem.device_pointer == 0) {
hip_device_->mem_alloc(mem);
}
/* Zero memory on device. */
assert(mem.device_pointer != 0);
const HIPContextScope scope(hip_device_);
hip_device_assert(
hip_device_,
hipMemsetD8Async((hipDeviceptr_t)mem.device_pointer, 0, mem.memory_size(), hip_stream_));
}
void HIPDeviceQueue::copy_to_device(device_memory &mem)
{
assert(mem.type != MEM_GLOBAL && mem.type != MEM_TEXTURE);
if (mem.memory_size() == 0) {
return;
}
/* Allocate on demand. */
if (mem.device_pointer == 0) {
hip_device_->mem_alloc(mem);
}
assert(mem.device_pointer != 0);
assert(mem.host_pointer != nullptr);
/* Copy memory to device. */
const HIPContextScope scope(hip_device_);
hip_device_assert(
hip_device_,
hipMemcpyHtoDAsync(
(hipDeviceptr_t)mem.device_pointer, mem.host_pointer, mem.memory_size(), hip_stream_));
}
void HIPDeviceQueue::copy_from_device(device_memory &mem)
{
assert(mem.type != MEM_GLOBAL && mem.type != MEM_TEXTURE);
if (mem.memory_size() == 0) {
return;
}
assert(mem.device_pointer != 0);
assert(mem.host_pointer != nullptr);
/* Copy memory from device. */
const HIPContextScope scope(hip_device_);
hip_device_assert(
hip_device_,
hipMemcpyDtoHAsync(
mem.host_pointer, (hipDeviceptr_t)mem.device_pointer, mem.memory_size(), hip_stream_));
}
// TODO : (Arya) Enable this after stabilizing dev branch
unique_ptr<DeviceGraphicsInterop> HIPDeviceQueue::graphics_interop_create()
{
return make_unique<HIPDeviceGraphicsInterop>(this);
}
CCL_NAMESPACE_END
#endif /* WITH_HIP */

View File

@@ -0,0 +1,68 @@
/*
* Copyright 2011-2021 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
#ifdef WITH_HIP
# include "device/device_kernel.h"
# include "device/device_memory.h"
# include "device/device_queue.h"
# include "device/hip/util.h"
CCL_NAMESPACE_BEGIN
class HIPDevice;
class device_memory;
/* Base class for HIP queues. */
class HIPDeviceQueue : public DeviceQueue {
public:
HIPDeviceQueue(HIPDevice *device);
~HIPDeviceQueue();
virtual int num_concurrent_states(const size_t state_size) const override;
virtual int num_concurrent_busy_states() const override;
virtual void init_execution() override;
virtual bool kernel_available(DeviceKernel kernel) const override;
virtual bool enqueue(DeviceKernel kernel, const int work_size, void *args[]) override;
virtual bool synchronize() override;
virtual void zero_to_device(device_memory &mem) override;
virtual void copy_to_device(device_memory &mem) override;
virtual void copy_from_device(device_memory &mem) override;
virtual hipStream_t stream()
{
return hip_stream_;
}
// TODO : (Arya) Enable this after stabilizing the dev branch
virtual unique_ptr<DeviceGraphicsInterop> graphics_interop_create() override;
protected:
HIPDevice *hip_device_;
hipStream_t hip_stream_;
};
CCL_NAMESPACE_END
#endif /* WITH_HIP */

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2011-2021 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.
*/
#ifdef WITH_HIP
# include "device/hip/util.h"
# include "device/hip/device_impl.h"
CCL_NAMESPACE_BEGIN
HIPContextScope::HIPContextScope(HIPDevice *device) : device(device)
{
hip_device_assert(device, hipCtxPushCurrent(device->hipContext));
}
HIPContextScope::~HIPContextScope()
{
hip_device_assert(device, hipCtxPopCurrent(NULL));
}
# ifndef WITH_HIP_DYNLOAD
const char *hipewErrorString(hipError_t result)
{
/* We can only give error code here without major code duplication, that
* should be enough since dynamic loading is only being disabled by folks
* who knows what they're doing anyway.
*
* NOTE: Avoid call from several threads.
*/
static string error;
error = string_printf("%d", result);
return error.c_str();
}
const char *hipewCompilerPath()
{
return CYCLES_HIP_HIPCC_EXECUTABLE;
}
int hipewCompilerVersion()
{
return (HIP_VERSION / 100) + (HIP_VERSION % 100 / 10);
}
# endif
CCL_NAMESPACE_END
#endif /* WITH_HIP */

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2011-2021 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
#ifdef WITH_HIP
# ifdef WITH_HIP_DYNLOAD
# include "hipew.h"
# endif
CCL_NAMESPACE_BEGIN
class HIPDevice;
/* Utility to push/pop HIP context. */
class HIPContextScope {
public:
HIPContextScope(HIPDevice *device);
~HIPContextScope();
private:
HIPDevice *device;
};
/* Utility for checking return values of HIP function calls. */
# define hip_device_assert(hip_device, stmt) \
{ \
hipError_t result = stmt; \
if (result != hipSuccess) { \
const char *name = hipewErrorString(result); \
hip_device->set_error( \
string_printf("%s in %s (%s:%d)", name, #stmt, __FILE__, __LINE__)); \
} \
} \
(void)0
# define hip_assert(stmt) hip_device_assert(this, stmt)
# ifndef WITH_HIP_DYNLOAD
/* Transparently implement some functions, so majority of the file does not need
* to worry about difference between dynamically loaded and linked HIP at all. */
const char *hipewErrorString(hipError_t result);
const char *hipewCompilerPath();
int hipewCompilerVersion();
# endif /* WITH_HIP_DYNLOAD */
CCL_NAMESPACE_END
#endif /* WITH_HIP */

View File

@@ -315,14 +315,14 @@ class MultiDevice : public Device {
stats.mem_alloc(mem.device_size - existing_size);
}
void mem_copy_from(device_memory &mem, int y, int w, int h, int elem) override
void mem_copy_from(device_memory &mem, size_t y, size_t w, size_t h, size_t elem) override
{
device_ptr key = mem.device_pointer;
int i = 0, sub_h = h / devices.size();
size_t i = 0, sub_h = h / devices.size();
foreach (SubDevice &sub, devices) {
int sy = y + i * sub_h;
int sh = (i == (int)devices.size() - 1) ? h - sub_h * i : sub_h;
size_t sy = y + i * sub_h;
size_t sh = (i == (size_t)devices.size() - 1) ? h - sub_h * i : sub_h;
SubDevice *owner_sub = find_matching_mem_device(key, sub);
mem.device = owner_sub->device;

View File

@@ -315,6 +315,11 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
group_descs[PG_HITS].kind = OPTIX_PROGRAM_GROUP_KIND_HITGROUP;
group_descs[PG_HITS].hitgroup.moduleAH = optix_module;
group_descs[PG_HITS].hitgroup.entryFunctionNameAH = "__anyhit__kernel_optix_shadow_all_hit";
group_descs[PG_HITV].kind = OPTIX_PROGRAM_GROUP_KIND_HITGROUP;
group_descs[PG_HITV].hitgroup.moduleCH = optix_module;
group_descs[PG_HITV].hitgroup.entryFunctionNameCH = "__closesthit__kernel_optix_hit";
group_descs[PG_HITV].hitgroup.moduleAH = optix_module;
group_descs[PG_HITV].hitgroup.entryFunctionNameAH = "__anyhit__kernel_optix_volume_test";
if (kernel_features & KERNEL_FEATURE_HAIR) {
if (kernel_features & KERNEL_FEATURE_HAIR_THICK) {
@@ -397,6 +402,7 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
trace_css = std::max(trace_css, stack_size[PG_HITD].cssIS + stack_size[PG_HITD].cssAH);
trace_css = std::max(trace_css, stack_size[PG_HITS].cssIS + stack_size[PG_HITS].cssAH);
trace_css = std::max(trace_css, stack_size[PG_HITL].cssIS + stack_size[PG_HITL].cssAH);
trace_css = std::max(trace_css, stack_size[PG_HITV].cssIS + stack_size[PG_HITV].cssAH);
trace_css = std::max(trace_css,
stack_size[PG_HITD_MOTION].cssIS + stack_size[PG_HITD_MOTION].cssAH);
trace_css = std::max(trace_css,
@@ -421,6 +427,7 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
pipeline_groups.push_back(groups[PG_HITD]);
pipeline_groups.push_back(groups[PG_HITS]);
pipeline_groups.push_back(groups[PG_HITL]);
pipeline_groups.push_back(groups[PG_HITV]);
if (motion_blur) {
pipeline_groups.push_back(groups[PG_HITD_MOTION]);
pipeline_groups.push_back(groups[PG_HITS_MOTION]);
@@ -459,6 +466,7 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
pipeline_groups.push_back(groups[PG_HITD]);
pipeline_groups.push_back(groups[PG_HITS]);
pipeline_groups.push_back(groups[PG_HITL]);
pipeline_groups.push_back(groups[PG_HITV]);
if (motion_blur) {
pipeline_groups.push_back(groups[PG_HITD_MOTION]);
pipeline_groups.push_back(groups[PG_HITS_MOTION]);
@@ -760,7 +768,13 @@ void OptiXDevice::denoise_color_read(DenoiseContext &context, const DenoisePass
destination.num_components = 3;
destination.pixel_stride = context.buffer_params.pass_stride;
pass_accessor.get_render_tile_pixels(context.render_buffers, context.buffer_params, destination);
BufferParams buffer_params = context.buffer_params;
buffer_params.window_x = 0;
buffer_params.window_y = 0;
buffer_params.window_width = buffer_params.width;
buffer_params.window_height = buffer_params.height;
pass_accessor.get_render_tile_pixels(context.render_buffers, buffer_params, destination);
}
bool OptiXDevice::denoise_filter_color_preprocess(DenoiseContext &context, const DenoisePass &pass)
@@ -1238,7 +1252,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
build_input.curveArray.indexBuffer = (CUdeviceptr)index_data.device_pointer;
build_input.curveArray.indexStrideInBytes = sizeof(int);
build_input.curveArray.flag = build_flags;
build_input.curveArray.primitiveIndexOffset = hair->optix_prim_offset;
build_input.curveArray.primitiveIndexOffset = hair->curve_segment_offset;
}
else {
/* Disable visibility test any-hit program, since it is already checked during
@@ -1251,7 +1265,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
build_input.customPrimitiveArray.strideInBytes = sizeof(OptixAabb);
build_input.customPrimitiveArray.flags = &build_flags;
build_input.customPrimitiveArray.numSbtRecords = 1;
build_input.customPrimitiveArray.primitiveIndexOffset = hair->optix_prim_offset;
build_input.customPrimitiveArray.primitiveIndexOffset = hair->curve_segment_offset;
}
if (!build_optix_bvh(bvh_optix, operation, build_input, num_motion_steps)) {
@@ -1320,7 +1334,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
* buffers for that purpose. OptiX does not allow this to be zero though, so just pass in
* one and rely on that having the same meaning in this case. */
build_input.triangleArray.numSbtRecords = 1;
build_input.triangleArray.primitiveIndexOffset = mesh->optix_prim_offset;
build_input.triangleArray.primitiveIndexOffset = mesh->prim_offset;
if (!build_optix_bvh(bvh_optix, operation, build_input, num_motion_steps)) {
progress.set_error("Failed to build OptiX acceleration structure");
@@ -1387,28 +1401,36 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
instance.transform[5] = 1.0f;
instance.transform[10] = 1.0f;
/* Set user instance ID to object index (but leave low bit blank). */
instance.instanceId = ob->get_device_index() << 1;
/* Set user instance ID to object index. */
instance.instanceId = ob->get_device_index();
/* Add some of the object visibility bits to the mask.
* __prim_visibility contains the combined visibility bits of all instances, so is not
* reliable if they differ between instances. But the OptiX visibility mask can only contain
* 8 bits, so have to trade-off here and select just a few important ones.
*/
instance.visibilityMask = ob->visibility_for_tracing() & 0xFF;
/* Have to have at least one bit in the mask, or else instance would always be culled. */
instance.visibilityMask = 1;
if (ob->get_geometry()->has_volume) {
/* Volumes have a special bit set in the visibility mask so a trace can mask only volumes.
*/
instance.visibilityMask |= 2;
if (0 == instance.visibilityMask) {
instance.visibilityMask = 0xFF;
}
if (ob->get_geometry()->geometry_type == Geometry::HAIR) {
/* Same applies to curves (so they can be skipped in local trace calls). */
instance.visibilityMask |= 4;
if (motion_blur && ob->get_geometry()->has_motion_blur() &&
static_cast<const Hair *>(ob->get_geometry())->curve_shape == CURVE_THICK) {
if (ob->get_geometry()->geometry_type == Geometry::HAIR &&
static_cast<const Hair *>(ob->get_geometry())->curve_shape == CURVE_THICK) {
if (motion_blur && ob->get_geometry()->has_motion_blur()) {
/* Select between motion blur and non-motion blur built-in intersection module. */
instance.sbtOffset = PG_HITD_MOTION - PG_HITD;
}
}
else {
/* Can disable __anyhit__kernel_optix_visibility_test by default (except for thick curves,
* since it needs to filter out end-caps there).
* It is enabled where necessary (visibility mask exceeds 8 bits or the other any-hit
* programs like __anyhit__kernel_optix_shadow_all_hit) via OPTIX_RAY_FLAG_ENFORCE_ANYHIT.
*/
instance.flags = OPTIX_INSTANCE_FLAG_DISABLE_ANYHIT;
}
/* Insert motion traversable if object has motion. */
if (motion_blur && ob->use_motion()) {
@@ -1474,7 +1496,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
delete[] reinterpret_cast<uint8_t *>(&motion_transform);
/* Disable instance transform if object uses motion transform already. */
instance.flags = OPTIX_INSTANCE_FLAG_DISABLE_TRANSFORM;
instance.flags |= OPTIX_INSTANCE_FLAG_DISABLE_TRANSFORM;
/* Get traversable handle to motion transform. */
optixConvertPointerToTraversableHandle(context,
@@ -1491,10 +1513,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
}
else {
/* Disable instance transform if geometry already has it applied to vertex data. */
instance.flags = OPTIX_INSTANCE_FLAG_DISABLE_TRANSFORM;
/* Non-instanced objects read ID from 'prim_object', so distinguish
* them from instanced objects with the low bit set. */
instance.instanceId |= 1;
instance.flags |= OPTIX_INSTANCE_FLAG_DISABLE_TRANSFORM;
}
}
}

View File

@@ -40,6 +40,7 @@ enum {
PG_HITD, /* Default hit group. */
PG_HITS, /* __SHADOW_RECORD_ALL__ hit group. */
PG_HITL, /* __BVH_LOCAL__ hit group (only used for triangles). */
PG_HITV, /* __VOLUME__ hit group. */
PG_HITD_MOTION,
PG_HITS_MOTION,
PG_CALL_SVM_AO,
@@ -51,7 +52,7 @@ enum {
static const int MISS_PROGRAM_GROUP_OFFSET = PG_MISS;
static const int NUM_MIS_PROGRAM_GROUPS = 1;
static const int HIT_PROGAM_GROUP_OFFSET = PG_HITD;
static const int NUM_HIT_PROGRAM_GROUPS = 5;
static const int NUM_HIT_PROGRAM_GROUPS = 6;
static const int CALLABLE_PROGRAM_GROUPS_BASE = PG_CALL_SVM_AO;
static const int NUM_CALLABLE_PROGRAM_GROUPS = 3;

View File

@@ -27,6 +27,8 @@ set(SRC
pass_accessor.cpp
pass_accessor_cpu.cpp
pass_accessor_gpu.cpp
path_trace_display.cpp
path_trace_tile.cpp
path_trace_work.cpp
path_trace_work_cpu.cpp
path_trace_work_gpu.cpp
@@ -47,6 +49,8 @@ set(SRC_HEADERS
pass_accessor.h
pass_accessor_cpu.h
pass_accessor_gpu.h
path_trace_display.h
path_trace_tile.h
path_trace_work.h
path_trace_work_cpu.h
path_trace_work_gpu.h

View File

@@ -289,7 +289,13 @@ class OIDNDenoiseContext {
* pixels. */
const PassAccessorCPU pass_accessor(pass_access_info, 1.0f, num_samples_);
pass_accessor.get_render_tile_pixels(render_buffers_, buffer_params_, destination);
BufferParams buffer_params = buffer_params_;
buffer_params.window_x = 0;
buffer_params.window_y = 0;
buffer_params.window_width = buffer_params.width;
buffer_params.window_height = buffer_params.height;
pass_accessor.get_render_tile_pixels(render_buffers_, buffer_params, destination);
}
/* Read pass pixels using PassAccessor into a temporary buffer which is owned by the pass.. */

View File

@@ -149,9 +149,6 @@ bool PassAccessor::get_render_tile_pixels(const RenderBuffers *render_buffers,
/* Denoised passes store their final pixels, no need in special calculation. */
get_pass_float(render_buffers, buffer_params, destination);
}
else if (type == PASS_RENDER_TIME) {
/* TODO(sergey): Needs implementation. */
}
else if (type == PASS_DEPTH) {
get_pass_depth(render_buffers, buffer_params, destination);
}

View File

@@ -99,17 +99,22 @@ inline void PassAccessorCPU::run_get_pass_kernel_processor_float(
{
DCHECK_EQ(destination.stride, 0) << "Custom stride for float destination is not implemented.";
const float *buffer_data = render_buffers->buffer.data();
const int64_t pass_stride = buffer_params.pass_stride;
const int64_t buffer_row_stride = buffer_params.stride * buffer_params.pass_stride;
const float *window_data = render_buffers->buffer.data() + buffer_params.window_x * pass_stride +
buffer_params.window_y * buffer_row_stride;
const int pixel_stride = destination.pixel_stride ? destination.pixel_stride :
destination.num_components;
tbb::parallel_for(0, buffer_params.height, [&](int64_t y) {
int64_t pixel_index = y * buffer_params.width;
for (int64_t x = 0; x < buffer_params.width; ++x, ++pixel_index) {
const int64_t input_pixel_offset = pixel_index * buffer_params.pass_stride;
const float *buffer = buffer_data + input_pixel_offset;
float *pixel = destination.pixels + (pixel_index + destination.offset) * pixel_stride;
tbb::parallel_for(0, buffer_params.window_height, [&](int64_t y) {
const float *buffer = window_data + y * buffer_row_stride;
float *pixel = destination.pixels +
(y * buffer_params.width + destination.offset) * pixel_stride;
for (int64_t x = 0; x < buffer_params.window_width;
++x, buffer += pass_stride, pixel += pixel_stride) {
processor(kfilm_convert, buffer, pixel);
}
});
@@ -123,26 +128,28 @@ inline void PassAccessorCPU::run_get_pass_kernel_processor_half_rgba(
const Destination &destination,
const Processor &processor) const
{
const float *buffer_data = render_buffers->buffer.data();
const int64_t pass_stride = buffer_params.pass_stride;
const int64_t buffer_row_stride = buffer_params.stride * buffer_params.pass_stride;
const float *window_data = render_buffers->buffer.data() + buffer_params.window_x * pass_stride +
buffer_params.window_y * buffer_row_stride;
half4 *dst_start = destination.pixels_half_rgba + destination.offset;
const int destination_stride = destination.stride != 0 ? destination.stride :
buffer_params.width;
tbb::parallel_for(0, buffer_params.height, [&](int64_t y) {
int64_t pixel_index = y * buffer_params.width;
half4 *dst_row_start = dst_start + y * destination_stride;
for (int64_t x = 0; x < buffer_params.width; ++x, ++pixel_index) {
const int64_t input_pixel_offset = pixel_index * buffer_params.pass_stride;
const float *buffer = buffer_data + input_pixel_offset;
tbb::parallel_for(0, buffer_params.window_height, [&](int64_t y) {
const float *buffer = window_data + y * buffer_row_stride;
half4 *pixel = dst_start + y * destination_stride;
for (int64_t x = 0; x < buffer_params.window_width; ++x, buffer += pass_stride, ++pixel) {
float pixel[4];
processor(kfilm_convert, buffer, pixel);
float pixel_rgba[4];
processor(kfilm_convert, buffer, pixel_rgba);
film_apply_pass_pixel_overlays_rgba(kfilm_convert, buffer, pixel);
film_apply_pass_pixel_overlays_rgba(kfilm_convert, buffer, pixel_rgba);
half4 *pixel_half_rgba = dst_row_start + x;
float4_store_half(&pixel_half_rgba->x, make_float4(pixel[0], pixel[1], pixel[2], pixel[3]));
float4_store_half(&pixel->x,
make_float4(pixel_rgba[0], pixel_rgba[1], pixel_rgba[2], pixel_rgba[3]));
}
});
}

View File

@@ -43,10 +43,13 @@ void PassAccessorGPU::run_film_convert_kernels(DeviceKernel kernel,
KernelFilmConvert kfilm_convert;
init_kernel_film_convert(&kfilm_convert, buffer_params, destination);
const int work_size = buffer_params.width * buffer_params.height;
const int work_size = buffer_params.window_width * buffer_params.window_height;
const int destination_stride = destination.stride != 0 ? destination.stride :
buffer_params.width;
buffer_params.window_width;
const int offset = buffer_params.window_x * buffer_params.pass_stride +
buffer_params.window_y * buffer_params.stride * buffer_params.pass_stride;
if (destination.d_pixels) {
DCHECK_EQ(destination.stride, 0) << "Custom stride for float destination is not implemented.";
@@ -55,8 +58,8 @@ void PassAccessorGPU::run_film_convert_kernels(DeviceKernel kernel,
const_cast<device_ptr *>(&destination.d_pixels),
const_cast<device_ptr *>(&render_buffers->buffer.device_pointer),
const_cast<int *>(&work_size),
const_cast<int *>(&buffer_params.width),
const_cast<int *>(&buffer_params.offset),
const_cast<int *>(&buffer_params.window_width),
const_cast<int *>(&offset),
const_cast<int *>(&buffer_params.stride),
const_cast<int *>(&destination.offset),
const_cast<int *>(&destination_stride)};
@@ -70,8 +73,8 @@ void PassAccessorGPU::run_film_convert_kernels(DeviceKernel kernel,
const_cast<device_ptr *>(&destination.d_pixels_half_rgba),
const_cast<device_ptr *>(&render_buffers->buffer.device_pointer),
const_cast<int *>(&work_size),
const_cast<int *>(&buffer_params.width),
const_cast<int *>(&buffer_params.offset),
const_cast<int *>(&buffer_params.window_width),
const_cast<int *>(&offset),
const_cast<int *>(&buffer_params.stride),
const_cast<int *>(&destination.offset),
const_cast<int *>(&destination_stride)};

View File

@@ -19,8 +19,9 @@
#include "device/cpu/device.h"
#include "device/device.h"
#include "integrator/pass_accessor.h"
#include "integrator/path_trace_display.h"
#include "integrator/path_trace_tile.h"
#include "integrator/render_scheduler.h"
#include "render/gpu_display.h"
#include "render/pass.h"
#include "render/scene.h"
#include "render/tile.h"
@@ -67,11 +68,11 @@ PathTrace::PathTrace(Device *device,
PathTrace::~PathTrace()
{
/* Destroy any GPU resource which was used for graphics interop.
* Need to have access to the GPUDisplay as it is the only source of drawing context which is
* used for interop. */
if (gpu_display_) {
* 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(gpu_display_.get());
path_trace_work->destroy_gpu_resources(display_.get());
}
}
}
@@ -94,7 +95,7 @@ bool PathTrace::ready_to_reset()
{
/* The logic here is optimized for the best feedback in the viewport, which implies having a GPU
* display. Of there is no such display, the logic here will break. */
DCHECK(gpu_display_);
DCHECK(display_);
/* The logic here tries to provide behavior which feels the most interactive feel to artists.
* General idea is to be able to reset as quickly as possible, while still providing interactive
@@ -126,8 +127,8 @@ void PathTrace::reset(const BufferParams &full_params, const BufferParams &big_t
/* NOTE: GPU display checks for buffer modification and avoids unnecessary re-allocation.
* It is requires to inform about reset whenever it happens, so that the redraw state tracking is
* properly updated. */
if (gpu_display_) {
gpu_display_->reset(full_params);
if (display_) {
display_->reset(full_params);
}
render_state_.has_denoised_result = false;
@@ -233,42 +234,53 @@ template<typename Callback>
static void foreach_sliced_buffer_params(const vector<unique_ptr<PathTraceWork>> &path_trace_works,
const vector<WorkBalanceInfo> &work_balance_infos,
const BufferParams &buffer_params,
const int overscan,
const Callback &callback)
{
const int num_works = path_trace_works.size();
const int height = buffer_params.height;
const int window_height = buffer_params.window_height;
int current_y = 0;
for (int i = 0; i < num_works; ++i) {
const double weight = work_balance_infos[i].weight;
const int slice_height = max(lround(height * weight), 1);
const int slice_window_full_y = buffer_params.full_y + buffer_params.window_y + current_y;
const int slice_window_height = max(lround(window_height * weight), 1);
/* Disallow negative values to deal with situations when there are more compute devices than
* scanlines. */
const int remaining_height = max(0, height - current_y);
* scan-lines. */
const int remaining_window_height = max(0, window_height - current_y);
BufferParams slice_params = buffer_params;
slice_params.full_y = max(slice_window_full_y - overscan, buffer_params.full_y);
slice_params.window_y = slice_window_full_y - slice_params.full_y;
BufferParams slide_params = buffer_params;
slide_params.full_y = buffer_params.full_y + current_y;
if (i < num_works - 1) {
slide_params.height = min(slice_height, remaining_height);
slice_params.window_height = min(slice_window_height, remaining_window_height);
}
else {
slide_params.height = remaining_height;
slice_params.window_height = remaining_window_height;
}
slide_params.update_offset_stride();
slice_params.height = slice_params.window_y + slice_params.window_height + overscan;
slice_params.height = min(slice_params.height,
buffer_params.height + buffer_params.full_y - slice_params.full_y);
callback(path_trace_works[i].get(), slide_params);
slice_params.update_offset_stride();
current_y += slide_params.height;
callback(path_trace_works[i].get(), slice_params);
current_y += slice_params.window_height;
}
}
void PathTrace::update_allocated_work_buffer_params()
{
const int overscan = tile_manager_.get_tile_overscan();
foreach_sliced_buffer_params(path_trace_works_,
work_balance_infos_,
big_tile_params_,
overscan,
[](PathTraceWork *path_trace_work, const BufferParams &params) {
RenderBuffers *buffers = path_trace_work->get_render_buffers();
buffers->reset(params);
@@ -281,6 +293,12 @@ static BufferParams scale_buffer_params(const BufferParams &params, int resoluti
scaled_params.width = max(1, params.width / resolution_divider);
scaled_params.height = max(1, params.height / resolution_divider);
scaled_params.window_x = params.window_x / resolution_divider;
scaled_params.window_y = params.window_y / resolution_divider;
scaled_params.window_width = params.window_width / resolution_divider;
scaled_params.window_height = params.window_height / resolution_divider;
scaled_params.full_x = params.full_x / resolution_divider;
scaled_params.full_y = params.full_y / resolution_divider;
scaled_params.full_width = params.full_width / resolution_divider;
@@ -299,9 +317,12 @@ void PathTrace::update_effective_work_buffer_params(const RenderWork &render_wor
const BufferParams scaled_big_tile_params = scale_buffer_params(big_tile_params_,
resolution_divider);
const int overscan = tile_manager_.get_tile_overscan();
foreach_sliced_buffer_params(path_trace_works_,
work_balance_infos_,
scaled_big_tile_params,
overscan,
[&](PathTraceWork *path_trace_work, const BufferParams params) {
path_trace_work->set_effective_buffer_params(
scaled_full_params, scaled_big_tile_params, params);
@@ -535,25 +556,35 @@ void PathTrace::denoise(const RenderWork &render_work)
render_scheduler_.report_denoise_time(render_work, time_dt() - start_time);
}
void PathTrace::set_gpu_display(unique_ptr<GPUDisplay> gpu_display)
void PathTrace::set_output_driver(unique_ptr<OutputDriver> driver)
{
gpu_display_ = move(gpu_display);
output_driver_ = move(driver);
}
void PathTrace::clear_gpu_display()
void PathTrace::set_display_driver(unique_ptr<DisplayDriver> driver)
{
if (gpu_display_) {
gpu_display_->clear();
if (driver) {
display_ = make_unique<PathTraceDisplay>(move(driver));
}
else {
display_ = nullptr;
}
}
void PathTrace::clear_display()
{
if (display_) {
display_->clear();
}
}
void PathTrace::draw()
{
if (!gpu_display_) {
if (!display_) {
return;
}
did_draw_after_reset_ |= gpu_display_->draw();
did_draw_after_reset_ |= display_->draw();
}
void PathTrace::update_display(const RenderWork &render_work)
@@ -562,31 +593,32 @@ void PathTrace::update_display(const RenderWork &render_work)
return;
}
if (!gpu_display_ && !tile_buffer_update_cb) {
if (!display_ && !output_driver_) {
VLOG(3) << "Ignore display update.";
return;
}
if (full_params_.width == 0 || full_params_.height == 0) {
VLOG(3) << "Skipping GPUDisplay update due to 0 size of the render buffer.";
VLOG(3) << "Skipping PathTraceDisplay update due to 0 size of the render buffer.";
return;
}
const double start_time = time_dt();
if (tile_buffer_update_cb) {
if (output_driver_) {
VLOG(3) << "Invoke buffer update callback.";
tile_buffer_update_cb();
PathTraceTile tile(*this);
output_driver_->update_render_tile(tile);
}
if (gpu_display_) {
if (display_) {
VLOG(3) << "Perform copy to GPUDisplay work.";
const int resolution_divider = render_work.resolution_divider;
const int texture_width = max(1, full_params_.width / resolution_divider);
const int texture_height = max(1, full_params_.height / resolution_divider);
if (!gpu_display_->update_begin(texture_width, texture_height)) {
if (!display_->update_begin(texture_width, texture_height)) {
LOG(ERROR) << "Error beginning GPUDisplay update.";
return;
}
@@ -600,10 +632,10 @@ void PathTrace::update_display(const RenderWork &render_work)
* all works in parallel. */
const int num_samples = get_num_samples_in_buffer();
for (auto &&path_trace_work : path_trace_works_) {
path_trace_work->copy_to_gpu_display(gpu_display_.get(), pass_mode, num_samples);
path_trace_work->copy_to_display(display_.get(), pass_mode, num_samples);
}
gpu_display_->update_end();
display_->update_end();
}
render_scheduler_.report_display_update_time(render_work, time_dt() - start_time);
@@ -753,20 +785,26 @@ bool PathTrace::is_cancel_requested()
void PathTrace::tile_buffer_write()
{
if (!tile_buffer_write_cb) {
if (!output_driver_) {
return;
}
tile_buffer_write_cb();
PathTraceTile tile(*this);
output_driver_->write_render_tile(tile);
}
void PathTrace::tile_buffer_read()
{
if (!tile_buffer_read_cb) {
if (!device_scene_->data.bake.use) {
return;
}
if (tile_buffer_read_cb()) {
if (!output_driver_) {
return;
}
PathTraceTile tile(*this);
if (output_driver_->read_render_tile(tile)) {
tbb::parallel_for_each(path_trace_works_, [](unique_ptr<PathTraceWork> &path_trace_work) {
path_trace_work->copy_render_buffers_to_device();
});
@@ -801,7 +839,7 @@ void PathTrace::tile_buffer_write_to_disk()
}
if (!tile_manager_.write_tile(*buffers)) {
LOG(ERROR) << "Error writing tile to file.";
device_->set_error("Error writing tile to file");
}
}
@@ -894,7 +932,14 @@ void PathTrace::process_full_buffer_from_disk(string_view filename)
DenoiseParams denoise_params;
if (!tile_manager_.read_full_buffer_from_disk(filename, &full_frame_buffers, &denoise_params)) {
LOG(ERROR) << "Error reading tiles from file.";
const string error_message = "Error reading tiles from file";
if (progress_) {
progress_->set_error(error_message);
progress_->set_cancel(error_message);
}
else {
LOG(ERROR) << error_message;
}
return;
}
@@ -980,12 +1025,12 @@ bool PathTrace::set_render_tile_pixels(PassAccessor &pass_accessor,
int2 PathTrace::get_render_tile_size() const
{
if (full_frame_state_.render_buffers) {
return make_int2(full_frame_state_.render_buffers->params.width,
full_frame_state_.render_buffers->params.height);
return make_int2(full_frame_state_.render_buffers->params.window_width,
full_frame_state_.render_buffers->params.window_height);
}
const Tile &tile = tile_manager_.get_current_tile();
return make_int2(tile.width, tile.height);
return make_int2(tile.window_width, tile.window_height);
}
int2 PathTrace::get_render_tile_offset() const
@@ -995,7 +1040,12 @@ int2 PathTrace::get_render_tile_offset() const
}
const Tile &tile = tile_manager_.get_current_tile();
return make_int2(tile.x, tile.y);
return make_int2(tile.x + tile.window_x, tile.y + tile.window_y);
}
int2 PathTrace::get_render_size() const
{
return tile_manager_.get_size();
}
const BufferParams &PathTrace::get_render_tile_params() const
@@ -1028,6 +1078,8 @@ static const char *device_type_for_description(const DeviceType type)
return "CUDA";
case DEVICE_OPTIX:
return "OptiX";
case DEVICE_HIP:
return "HIP";
case DEVICE_DUMMY:
return "Dummy";
case DEVICE_MULTI:

View File

@@ -31,12 +31,14 @@ CCL_NAMESPACE_BEGIN
class AdaptiveSampling;
class Device;
class DeviceScene;
class DisplayDriver;
class Film;
class RenderBuffers;
class RenderScheduler;
class RenderWork;
class PathTraceDisplay;
class OutputDriver;
class Progress;
class GPUDisplay;
class TileManager;
/* PathTrace class takes care of kernel graph and scheduling on a (multi)device. It takes care of
@@ -98,13 +100,16 @@ class PathTrace {
* Use this to configure the adaptive sampler before rendering any samples. */
void set_adaptive_sampling(const AdaptiveSampling &adaptive_sampling);
/* Set GPU display which takes care of drawing the render result. */
void set_gpu_display(unique_ptr<GPUDisplay> gpu_display);
/* Sets output driver for render buffer output. */
void set_output_driver(unique_ptr<OutputDriver> driver);
/* Clear the GPU display by filling it in with all zeroes. */
void clear_gpu_display();
/* Set display driver for interactive render buffer display. */
void set_display_driver(unique_ptr<DisplayDriver> driver);
/* Perform drawing of the current state of the GPUDisplay. */
/* Clear the display buffer by filling it in with all zeroes. */
void clear_display();
/* Perform drawing of the current state of the DisplayDriver. */
void draw();
/* Cancel rendering process as soon as possible, without waiting for full tile to be sampled.
@@ -157,6 +162,7 @@ class PathTrace {
* instead. */
int2 get_render_tile_size() const;
int2 get_render_tile_offset() const;
int2 get_render_size() const;
/* Get buffer parameters of the current tile.
*
@@ -168,18 +174,6 @@ class PathTrace {
* times, and so on. */
string full_report() const;
/* Callback which communicates an updates state of the render buffer of the current big tile.
* Is called during path tracing to communicate work-in-progress state of the final buffer. */
function<void(void)> tile_buffer_update_cb;
/* Callback which communicates final rendered buffer. Is called after path-tracing is done. */
function<void(void)> tile_buffer_write_cb;
/* Callback which initializes rendered buffer. Is called before path-tracing starts.
*
* This is used for baking. */
function<bool(void)> tile_buffer_read_cb;
/* Callback which is called to report current rendering progress.
*
* It is supposed to be cheaper than buffer update/write, hence can be called more often.
@@ -252,7 +246,11 @@ class PathTrace {
RenderScheduler &render_scheduler_;
TileManager &tile_manager_;
unique_ptr<GPUDisplay> gpu_display_;
/* Display driver for interactive render buffer display. */
unique_ptr<PathTraceDisplay> display_;
/* Output driver to write render buffer to. */
unique_ptr<OutputDriver> output_driver_;
/* Per-compute device descriptors of work which is responsible for path tracing on its configured
* device. */
@@ -286,7 +284,7 @@ class PathTrace {
/* Parameters of the big tile with the current resolution divider applied. */
BufferParams effective_big_tile_params;
/* Denosier was run and there are denoised versions of the passes in the render buffers. */
/* Denoiser was run and there are denoised versions of the passes in the render buffers. */
bool has_denoised_result = false;
/* Current tile has been written (to either disk or callback.

View File

@@ -14,20 +14,25 @@
* limitations under the License.
*/
#include "render/gpu_display.h"
#include "integrator/path_trace_display.h"
#include "render/buffers.h"
#include "util/util_logging.h"
CCL_NAMESPACE_BEGIN
void GPUDisplay::reset(const BufferParams &buffer_params)
PathTraceDisplay::PathTraceDisplay(unique_ptr<DisplayDriver> driver) : driver_(move(driver))
{
}
void PathTraceDisplay::reset(const BufferParams &buffer_params)
{
thread_scoped_lock lock(mutex_);
const GPUDisplayParams old_params = params_;
const DisplayDriver::Params old_params = params_;
params_.offset = make_int2(buffer_params.full_x, buffer_params.full_y);
params_.full_offset = make_int2(buffer_params.full_x, buffer_params.full_y);
params_.full_size = make_int2(buffer_params.full_width, buffer_params.full_height);
params_.size = make_int2(buffer_params.width, buffer_params.height);
@@ -44,7 +49,7 @@ void GPUDisplay::reset(const BufferParams &buffer_params)
texture_state_.is_outdated = true;
}
void GPUDisplay::mark_texture_updated()
void PathTraceDisplay::mark_texture_updated()
{
texture_state_.is_outdated = false;
texture_state_.is_usable = true;
@@ -54,7 +59,7 @@ void GPUDisplay::mark_texture_updated()
* Update procedure.
*/
bool GPUDisplay::update_begin(int texture_width, int texture_height)
bool PathTraceDisplay::update_begin(int texture_width, int texture_height)
{
DCHECK(!update_state_.is_active);
@@ -66,15 +71,15 @@ bool GPUDisplay::update_begin(int texture_width, int texture_height)
/* Get parameters within a mutex lock, to avoid reset() modifying them at the same time.
* The update itself is non-blocking however, for better performance and to avoid
* potential deadlocks due to locks held by the subclass. */
GPUDisplayParams params;
DisplayDriver::Params params;
{
thread_scoped_lock lock(mutex_);
params = params_;
texture_state_.size = make_int2(texture_width, texture_height);
}
if (!do_update_begin(params, texture_width, texture_height)) {
LOG(ERROR) << "GPUDisplay implementation could not begin update.";
if (!driver_->update_begin(params, texture_width, texture_height)) {
LOG(ERROR) << "PathTraceDisplay implementation could not begin update.";
return false;
}
@@ -83,7 +88,7 @@ bool GPUDisplay::update_begin(int texture_width, int texture_height)
return true;
}
void GPUDisplay::update_end()
void PathTraceDisplay::update_end()
{
DCHECK(update_state_.is_active);
@@ -92,12 +97,12 @@ void GPUDisplay::update_end()
return;
}
do_update_end();
driver_->update_end();
update_state_.is_active = false;
}
int2 GPUDisplay::get_texture_size() const
int2 PathTraceDisplay::get_texture_size() const
{
return texture_state_.size;
}
@@ -106,25 +111,54 @@ int2 GPUDisplay::get_texture_size() const
* Texture update from CPU buffer.
*/
void GPUDisplay::copy_pixels_to_texture(
void PathTraceDisplay::copy_pixels_to_texture(
const half4 *rgba_pixels, int texture_x, int texture_y, int pixels_width, int pixels_height)
{
DCHECK(update_state_.is_active);
if (!update_state_.is_active) {
LOG(ERROR) << "Attempt to copy pixels data outside of GPUDisplay update.";
LOG(ERROR) << "Attempt to copy pixels data outside of PathTraceDisplay update.";
return;
}
mark_texture_updated();
do_copy_pixels_to_texture(rgba_pixels, texture_x, texture_y, pixels_width, pixels_height);
/* This call copies pixels to a mapped texture buffer which is typically much cheaper from CPU
* time point of view than to copy data directly to a texture.
*
* The possible downside of this approach is that it might require a higher peak memory when
* doing partial updates of the texture (although, in practice even partial updates might peak
* with a full-frame buffer stored on the CPU if the GPU is currently occupied). */
half4 *mapped_rgba_pixels = map_texture_buffer();
if (!mapped_rgba_pixels) {
return;
}
const int texture_width = texture_state_.size.x;
const int texture_height = texture_state_.size.y;
if (texture_x == 0 && texture_y == 0 && pixels_width == texture_width &&
pixels_height == texture_height) {
const size_t size_in_bytes = sizeof(half4) * texture_width * texture_height;
memcpy(mapped_rgba_pixels, rgba_pixels, size_in_bytes);
}
else {
const half4 *rgba_row = rgba_pixels;
half4 *mapped_rgba_row = mapped_rgba_pixels + texture_y * texture_width + texture_x;
for (int y = 0; y < pixels_height;
++y, rgba_row += pixels_width, mapped_rgba_row += texture_width) {
memcpy(mapped_rgba_row, rgba_row, sizeof(half4) * pixels_width);
}
}
unmap_texture_buffer();
}
/* --------------------------------------------------------------------
* Texture buffer mapping.
*/
half4 *GPUDisplay::map_texture_buffer()
half4 *PathTraceDisplay::map_texture_buffer()
{
DCHECK(!texture_buffer_state_.is_mapped);
DCHECK(update_state_.is_active);
@@ -135,11 +169,11 @@ half4 *GPUDisplay::map_texture_buffer()
}
if (!update_state_.is_active) {
LOG(ERROR) << "Attempt to copy pixels data outside of GPUDisplay update.";
LOG(ERROR) << "Attempt to copy pixels data outside of PathTraceDisplay update.";
return nullptr;
}
half4 *mapped_rgba_pixels = do_map_texture_buffer();
half4 *mapped_rgba_pixels = driver_->map_texture_buffer();
if (mapped_rgba_pixels) {
texture_buffer_state_.is_mapped = true;
@@ -148,7 +182,7 @@ half4 *GPUDisplay::map_texture_buffer()
return mapped_rgba_pixels;
}
void GPUDisplay::unmap_texture_buffer()
void PathTraceDisplay::unmap_texture_buffer()
{
DCHECK(texture_buffer_state_.is_mapped);
@@ -160,14 +194,14 @@ void GPUDisplay::unmap_texture_buffer()
texture_buffer_state_.is_mapped = false;
mark_texture_updated();
do_unmap_texture_buffer();
driver_->unmap_texture_buffer();
}
/* --------------------------------------------------------------------
* Graphics interoperability.
*/
DeviceGraphicsInteropDestination GPUDisplay::graphics_interop_get()
DisplayDriver::GraphicsInterop PathTraceDisplay::graphics_interop_get()
{
DCHECK(!texture_buffer_state_.is_mapped);
DCHECK(update_state_.is_active);
@@ -175,38 +209,45 @@ DeviceGraphicsInteropDestination GPUDisplay::graphics_interop_get()
if (texture_buffer_state_.is_mapped) {
LOG(ERROR)
<< "Attempt to use graphics interoperability mode while the texture buffer is mapped.";
return DeviceGraphicsInteropDestination();
return DisplayDriver::GraphicsInterop();
}
if (!update_state_.is_active) {
LOG(ERROR) << "Attempt to use graphics interoperability outside of GPUDisplay update.";
return DeviceGraphicsInteropDestination();
LOG(ERROR) << "Attempt to use graphics interoperability outside of PathTraceDisplay update.";
return DisplayDriver::GraphicsInterop();
}
/* Assume that interop will write new values to the texture. */
mark_texture_updated();
return do_graphics_interop_get();
return driver_->graphics_interop_get();
}
void GPUDisplay::graphics_interop_activate()
void PathTraceDisplay::graphics_interop_activate()
{
driver_->graphics_interop_activate();
}
void GPUDisplay::graphics_interop_deactivate()
void PathTraceDisplay::graphics_interop_deactivate()
{
driver_->graphics_interop_deactivate();
}
/* --------------------------------------------------------------------
* Drawing.
*/
bool GPUDisplay::draw()
void PathTraceDisplay::clear()
{
driver_->clear();
}
bool PathTraceDisplay::draw()
{
/* Get parameters within a mutex lock, to avoid reset() modifying them at the same time.
* The drawing itself is non-blocking however, for better performance and to avoid
* potential deadlocks due to locks held by the subclass. */
GPUDisplayParams params;
DisplayDriver::Params params;
bool is_usable;
bool is_outdated;
@@ -218,7 +259,7 @@ bool GPUDisplay::draw()
}
if (is_usable) {
do_draw(params);
driver_->draw(params);
}
return !is_outdated;

View File

@@ -16,52 +16,30 @@
#pragma once
#include "device/device_graphics_interop.h"
#include "render/display_driver.h"
#include "util/util_half.h"
#include "util/util_thread.h"
#include "util/util_types.h"
#include "util/util_unique_ptr.h"
CCL_NAMESPACE_BEGIN
class BufferParams;
/* GPUDisplay class takes care of drawing render result in a viewport. The render result is stored
* in a GPU-side texture, which is updated from a path tracer and drawn by an application.
/* PathTraceDisplay is used for efficient render buffer display.
*
* The base GPUDisplay does some special texture state tracking, which allows render Session to
* make decisions on whether reset for an updated state is possible or not. This state should only
* be tracked in a base class and a particular implementation should not worry about it.
* The host applications implements a DisplayDriver, storing a render pass in a GPU-side
* textures. This texture is continuously updated by the path tracer and drawn by the host
* application.
*
* The subclasses should only implement the pure virtual methods, which allows them to not worry
* about parent method calls, which helps them to be as small and reliable as possible. */
* PathTraceDisplay is a wrapper around the DisplayDriver, adding thread safety, state tracking
* and error checking. */
class GPUDisplayParams {
class PathTraceDisplay {
public:
/* Offset of the display within a viewport.
* For example, set to a lower-bottom corner of border render in Blender's viewport. */
int2 offset = make_int2(0, 0);
/* Full viewport size.
*
* NOTE: Is not affected by the resolution divider. */
int2 full_size = make_int2(0, 0);
/* Effective vieport size.
* In the case of border render, size of the border rectangle.
*
* NOTE: Is not affected by the resolution divider. */
int2 size = make_int2(0, 0);
bool modified(const GPUDisplayParams &other) const
{
return !(offset == other.offset && full_size == other.full_size && size == other.size);
}
};
class GPUDisplay {
public:
GPUDisplay() = default;
virtual ~GPUDisplay() = default;
PathTraceDisplay(unique_ptr<DisplayDriver> driver);
virtual ~PathTraceDisplay() = default;
/* Reset the display for the new state of render session. Is called whenever session is reset,
* which happens on changes like viewport navigation or viewport dimension change.
@@ -69,11 +47,6 @@ class GPUDisplay {
* This call will configure parameters for a changed buffer and reset the texture state. */
void reset(const BufferParams &buffer_params);
const GPUDisplayParams &get_params() const
{
return params_;
}
/* --------------------------------------------------------------------
* Update procedure.
*
@@ -94,7 +67,8 @@ class GPUDisplay {
/* --------------------------------------------------------------------
* Texture update from CPU buffer.
*
* NOTE: The GPUDisplay should be marked for an update being in process with `update_begin()`.
* NOTE: The PathTraceDisplay should be marked for an update being in process with
* `update_begin()`.
*
* Most portable implementation, which must be supported by all platforms. Might not be the most
* efficient one.
@@ -115,7 +89,8 @@ class GPUDisplay {
* This functionality is used to update GPU-side texture content without need to maintain CPU
* side buffer on the caller.
*
* NOTE: The GPUDisplay should be marked for an update being in process with `update_begin()`.
* NOTE: The PathTraceDisplay should be marked for an update being in process with
* `update_begin()`.
*
* NOTE: Texture buffer can not be mapped while graphics interoperability is active. This means
* that `map_texture_buffer()` is not allowed between `graphics_interop_begin()` and
@@ -145,14 +120,14 @@ class GPUDisplay {
* that `graphics_interop_get()` is not allowed between `map_texture_buffer()` and
* `unmap_texture_buffer()` calls. */
/* Get GPUDisplay graphics interoperability information which acts as a destination for the
/* Get PathTraceDisplay graphics interoperability information which acts as a destination for the
* device API. */
DeviceGraphicsInteropDestination graphics_interop_get();
DisplayDriver::GraphicsInterop graphics_interop_get();
/* (De)activate GPU display for graphics interoperability outside of regular display update
* routines. */
virtual void graphics_interop_activate();
virtual void graphics_interop_deactivate();
void graphics_interop_activate();
void graphics_interop_deactivate();
/* --------------------------------------------------------------------
* Drawing.
@@ -163,47 +138,26 @@ class GPUDisplay {
* This call might happen in parallel with draw, but can never happen in parallel with the
* update.
*
* The actual zero-ing can be deferred to a later moment. What is important is that after clear
* The actual zeroing can be deferred to a later moment. What is important is that after clear
* and before pixels update the drawing texture will be fully empty, and that partial update
* after clear will write new pixel values for an updating area, leaving everything else zeroed.
*
* If the GPU display supports graphics interoperability then the zeroing the display is to be
* delegated to the device via the `DeviceGraphicsInteropDestination`. */
virtual void clear() = 0;
* delegated to the device via the `DisplayDriver::GraphicsInterop`. */
void clear();
/* Draw the current state of the texture.
*
* Returns true if this call did draw an updated state of the texture. */
bool draw();
protected:
/* Implementation-specific calls which subclasses are to implement.
* These `do_foo()` method corresponds to their `foo()` calls, but they are purely virtual to
* simplify their particular implementation. */
virtual bool do_update_begin(const GPUDisplayParams &params,
int texture_width,
int texture_height) = 0;
virtual void do_update_end() = 0;
virtual void do_copy_pixels_to_texture(const half4 *rgba_pixels,
int texture_x,
int texture_y,
int pixels_width,
int pixels_height) = 0;
virtual half4 *do_map_texture_buffer() = 0;
virtual void do_unmap_texture_buffer() = 0;
/* Note that this might be called in parallel to do_update_begin() and do_update_end(),
* the subclass is responsible for appropriate mutex locks to avoid multiple threads
* editing and drawing the texture at the same time. */
virtual void do_draw(const GPUDisplayParams &params) = 0;
virtual DeviceGraphicsInteropDestination do_graphics_interop_get() = 0;
private:
/* Display driver implemented by the host application. */
unique_ptr<DisplayDriver> driver_;
/* Current display parameters */
thread_mutex mutex_;
GPUDisplayParams params_;
DisplayDriver::Params params_;
/* Mark texture as its content has been updated.
* Used from places which knows that the texture content has been brought up-to-date, so that the

View File

@@ -0,0 +1,107 @@
/*
* Copyright 2021 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 "integrator/path_trace_tile.h"
#include "integrator/pass_accessor_cpu.h"
#include "integrator/path_trace.h"
#include "render/buffers.h"
#include "render/film.h"
#include "render/pass.h"
#include "render/scene.h"
CCL_NAMESPACE_BEGIN
PathTraceTile::PathTraceTile(PathTrace &path_trace)
: OutputDriver::Tile(path_trace.get_render_tile_offset(),
path_trace.get_render_tile_size(),
path_trace.get_render_size(),
path_trace.get_render_tile_params().layer,
path_trace.get_render_tile_params().view),
path_trace_(path_trace),
copied_from_device_(false)
{
}
bool PathTraceTile::get_pass_pixels(const string_view pass_name,
const int num_channels,
float *pixels) const
{
/* NOTE: The code relies on a fact that session is fully update and no scene/buffer modification
* is happening while this function runs. */
if (!copied_from_device_) {
/* Copy from device on demand. */
path_trace_.copy_render_tile_from_device();
const_cast<PathTraceTile *>(this)->copied_from_device_ = true;
}
const BufferParams &buffer_params = path_trace_.get_render_tile_params();
const BufferPass *pass = buffer_params.find_pass(pass_name);
if (pass == nullptr) {
return false;
}
const bool has_denoised_result = path_trace_.has_denoised_result();
if (pass->mode == PassMode::DENOISED && !has_denoised_result) {
pass = buffer_params.find_pass(pass->type);
if (pass == nullptr) {
/* Happens when denoised result pass is requested but is never written by the kernel. */
return false;
}
}
pass = buffer_params.get_actual_display_pass(pass);
const float exposure = buffer_params.exposure;
const int num_samples = path_trace_.get_num_render_tile_samples();
PassAccessor::PassAccessInfo pass_access_info(*pass);
pass_access_info.use_approximate_shadow_catcher = buffer_params.use_approximate_shadow_catcher;
pass_access_info.use_approximate_shadow_catcher_background =
pass_access_info.use_approximate_shadow_catcher && !buffer_params.use_transparent_background;
const PassAccessorCPU pass_accessor(pass_access_info, exposure, num_samples);
const PassAccessor::Destination destination(pixels, num_channels);
return path_trace_.get_render_tile_pixels(pass_accessor, destination);
}
bool PathTraceTile::set_pass_pixels(const string_view pass_name,
const int num_channels,
const float *pixels) const
{
/* NOTE: The code relies on a fact that session is fully update and no scene/buffer modification
* is happening while this function runs. */
const BufferParams &buffer_params = path_trace_.get_render_tile_params();
const BufferPass *pass = buffer_params.find_pass(pass_name);
if (!pass) {
return false;
}
const float exposure = buffer_params.exposure;
const int num_samples = 1;
const PassAccessor::PassAccessInfo pass_access_info(*pass);
PassAccessorCPU pass_accessor(pass_access_info, exposure, num_samples);
PassAccessor::Source source(pixels, num_channels);
return path_trace_.set_render_tile_pixels(pass_accessor, source);
}
CCL_NAMESPACE_END

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2021 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 "render/output_driver.h"
CCL_NAMESPACE_BEGIN
/* PathTraceTile
*
* Implementation of OutputDriver::Tile interface for path tracer. */
class PathTrace;
class PathTraceTile : public OutputDriver::Tile {
public:
PathTraceTile(PathTrace &path_trace);
bool get_pass_pixels(const string_view pass_name, const int num_channels, float *pixels) const;
bool set_pass_pixels(const string_view pass_name,
const int num_channels,
const float *pixels) const;
private:
PathTrace &path_trace_;
bool copied_from_device_;
};
CCL_NAMESPACE_END

View File

@@ -16,12 +16,12 @@
#include "device/device.h"
#include "integrator/path_trace_display.h"
#include "integrator/path_trace_work.h"
#include "integrator/path_trace_work_cpu.h"
#include "integrator/path_trace_work_gpu.h"
#include "render/buffers.h"
#include "render/film.h"
#include "render/gpu_display.h"
#include "render/scene.h"
#include "kernel/kernel_types.h"
@@ -134,7 +134,8 @@ void PathTraceWork::copy_from_denoised_render_buffers(const RenderBuffers *rende
bool PathTraceWork::get_render_tile_pixels(const PassAccessor &pass_accessor,
const PassAccessor::Destination &destination)
{
const int offset_y = effective_buffer_params_.full_y - effective_big_tile_params_.full_y;
const int offset_y = (effective_buffer_params_.full_y + effective_buffer_params_.window_y) -
(effective_big_tile_params_.full_y + effective_big_tile_params_.window_y);
const int width = effective_buffer_params_.width;
PassAccessor::Destination slice_destination = destination;
@@ -185,14 +186,16 @@ PassAccessor::PassAccessInfo PathTraceWork::get_display_pass_access_info(PassMod
return pass_access_info;
}
PassAccessor::Destination PathTraceWork::get_gpu_display_destination_template(
const GPUDisplay *gpu_display) const
PassAccessor::Destination PathTraceWork::get_display_destination_template(
const PathTraceDisplay *display) const
{
PassAccessor::Destination destination(film_->get_display_pass());
const int2 display_texture_size = gpu_display->get_texture_size();
const int texture_x = effective_buffer_params_.full_x - effective_full_params_.full_x;
const int texture_y = effective_buffer_params_.full_y - effective_full_params_.full_y;
const int2 display_texture_size = display->get_texture_size();
const int texture_x = effective_buffer_params_.full_x - effective_full_params_.full_x +
effective_buffer_params_.window_x;
const int texture_y = effective_buffer_params_.full_y - effective_full_params_.full_y +
effective_buffer_params_.window_y;
destination.offset = texture_y * display_texture_size.x + texture_x;
destination.stride = display_texture_size.x;

View File

@@ -28,7 +28,7 @@ class BufferParams;
class Device;
class DeviceScene;
class Film;
class GPUDisplay;
class PathTraceDisplay;
class RenderBuffers;
class PathTraceWork {
@@ -83,11 +83,9 @@ class PathTraceWork {
* noisy pass mode will be passed here when it is known that the buffer does not have denoised
* passes yet (because denoiser did not run). If the denoised pass is requested and denoiser is
* not used then this function will fall-back to the noisy pass instead. */
virtual void copy_to_gpu_display(GPUDisplay *gpu_display,
PassMode pass_mode,
int num_samples) = 0;
virtual void copy_to_display(PathTraceDisplay *display, PassMode pass_mode, int num_samples) = 0;
virtual void destroy_gpu_resources(GPUDisplay *gpu_display) = 0;
virtual void destroy_gpu_resources(PathTraceDisplay *display) = 0;
/* Copy data from/to given render buffers.
* Will copy pixels from a corresponding place (from multi-device point of view) of the render
@@ -104,7 +102,7 @@ class PathTraceWork {
* - Copies work's render buffer to its device. */
void copy_from_render_buffers(const RenderBuffers *render_buffers);
/* Special version of the `copy_from_render_buffers()` which only copies denosied passes from the
/* Special version of the `copy_from_render_buffers()` which only copies denoised passes from the
* given render buffers, leaving rest of the passes.
*
* Same notes about device copying applies to this call as well. */
@@ -162,8 +160,8 @@ class PathTraceWork {
/* Get destination which offset and stride are configured so that writing to it will write to a
* proper location of GPU display texture, taking current tile and device slice into account. */
PassAccessor::Destination get_gpu_display_destination_template(
const GPUDisplay *gpu_display) const;
PassAccessor::Destination get_display_destination_template(
const PathTraceDisplay *display) const;
/* Device which will be used for path tracing.
* Note that it is an actual render device (and never is a multi-device). */

View File

@@ -19,10 +19,12 @@
#include "device/cpu/kernel.h"
#include "device/device.h"
#include "kernel/kernel_path_state.h"
#include "integrator/pass_accessor_cpu.h"
#include "integrator/path_trace_display.h"
#include "render/buffers.h"
#include "render/gpu_display.h"
#include "render/scene.h"
#include "util/util_atomic.h"
@@ -116,13 +118,17 @@ void PathTraceWorkCPU::render_samples_full_pipeline(KernelGlobals *kernel_global
const KernelWorkTile &work_tile,
const int samples_num)
{
const bool has_shadow_catcher = device_scene_->data.integrator.has_shadow_catcher;
const bool has_bake = device_scene_->data.bake.use;
IntegratorStateCPU integrator_states[2] = {};
IntegratorStateCPU integrator_states[2];
IntegratorStateCPU *state = &integrator_states[0];
IntegratorStateCPU *shadow_catcher_state = &integrator_states[1];
IntegratorStateCPU *shadow_catcher_state = nullptr;
if (device_scene_->data.integrator.has_shadow_catcher) {
shadow_catcher_state = &integrator_states[1];
path_state_init_queues(kernel_globals, shadow_catcher_state);
}
KernelWorkTile sample_work_tile = work_tile;
float *render_buffer = buffers_->buffer.data();
@@ -147,7 +153,7 @@ void PathTraceWorkCPU::render_samples_full_pipeline(KernelGlobals *kernel_global
kernels_.integrator_megakernel(kernel_globals, state, render_buffer);
if (has_shadow_catcher) {
if (shadow_catcher_state) {
kernels_.integrator_megakernel(kernel_globals, shadow_catcher_state, render_buffer);
}
@@ -155,14 +161,14 @@ void PathTraceWorkCPU::render_samples_full_pipeline(KernelGlobals *kernel_global
}
}
void PathTraceWorkCPU::copy_to_gpu_display(GPUDisplay *gpu_display,
PassMode pass_mode,
int num_samples)
void PathTraceWorkCPU::copy_to_display(PathTraceDisplay *display,
PassMode pass_mode,
int num_samples)
{
half4 *rgba_half = gpu_display->map_texture_buffer();
half4 *rgba_half = display->map_texture_buffer();
if (!rgba_half) {
/* TODO(sergey): Look into using copy_to_gpu_display() if mapping failed. Might be needed for
* some implementations of GPUDisplay which can not map memory? */
/* TODO(sergey): Look into using copy_to_display() if mapping failed. Might be needed for
* some implementations of PathTraceDisplay which can not map memory? */
return;
}
@@ -172,7 +178,7 @@ void PathTraceWorkCPU::copy_to_gpu_display(GPUDisplay *gpu_display,
const PassAccessorCPU pass_accessor(pass_access_info, kfilm.exposure, num_samples);
PassAccessor::Destination destination = get_gpu_display_destination_template(gpu_display);
PassAccessor::Destination destination = get_display_destination_template(display);
destination.pixels_half_rgba = rgba_half;
tbb::task_arena local_arena = local_tbb_arena_create(device_);
@@ -180,10 +186,10 @@ void PathTraceWorkCPU::copy_to_gpu_display(GPUDisplay *gpu_display,
pass_accessor.get_render_tile_pixels(buffers_.get(), effective_buffer_params_, destination);
});
gpu_display->unmap_texture_buffer();
display->unmap_texture_buffer();
}
void PathTraceWorkCPU::destroy_gpu_resources(GPUDisplay * /*gpu_display*/)
void PathTraceWorkCPU::destroy_gpu_resources(PathTraceDisplay * /*display*/)
{
}

View File

@@ -50,10 +50,10 @@ class PathTraceWorkCPU : public PathTraceWork {
int start_sample,
int samples_num) override;
virtual void copy_to_gpu_display(GPUDisplay *gpu_display,
PassMode pass_mode,
int num_samples) override;
virtual void destroy_gpu_resources(GPUDisplay *gpu_display) override;
virtual void copy_to_display(PathTraceDisplay *display,
PassMode pass_mode,
int num_samples) override;
virtual void destroy_gpu_resources(PathTraceDisplay *display) override;
virtual bool copy_render_buffers_from_device() override;
virtual bool copy_render_buffers_to_device() override;

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