Merge branch 'blender-v4.0-release'
This commit is contained in:
@@ -504,12 +504,14 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
||||
add_custom_command(
|
||||
OUTPUT ${cuda_file}
|
||||
COMMAND ${CCACHE_PROGRAM} ${cuda_nvcc_executable} ${_cuda_nvcc_args}
|
||||
DEPENDS ${kernel_sources})
|
||||
DEPENDS ${kernel_sources}
|
||||
USES_TERMINAL)
|
||||
else()
|
||||
add_custom_command(
|
||||
OUTPUT ${cuda_file}
|
||||
COMMAND ${cuda_nvcc_executable} ${_cuda_nvcc_args}
|
||||
DEPENDS ${kernel_sources})
|
||||
DEPENDS ${kernel_sources}
|
||||
USES_TERMINAL)
|
||||
endif()
|
||||
|
||||
unset(_cuda_nvcc_args)
|
||||
@@ -646,7 +648,8 @@ if(WITH_CYCLES_HIP_BINARIES AND WITH_CYCLES_DEVICE_HIP)
|
||||
add_custom_command(
|
||||
OUTPUT ${hip_file}
|
||||
COMMAND ${hip_command} ${hip_flags}
|
||||
DEPENDS ${kernel_sources})
|
||||
DEPENDS ${kernel_sources}
|
||||
USES_TERMINAL)
|
||||
delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${hip_file}" ${CYCLES_INSTALL_PATH}/lib)
|
||||
list(APPEND hip_fatbins ${hip_file})
|
||||
endmacro()
|
||||
@@ -714,7 +717,8 @@ if(WITH_CYCLES_DEVICE_HIPRT AND WITH_CYCLES_HIP_BINARIES)
|
||||
add_custom_command(
|
||||
OUTPUT ${bitcode_file}
|
||||
COMMAND ${hiprt_compile_command} ${hiprt_compile_flags}
|
||||
DEPENDS ${kernel_sources})
|
||||
DEPENDS ${kernel_sources}
|
||||
USES_TERMINAL)
|
||||
if(WIN32)
|
||||
set(hiprt_link_command ${CMAKE_COMMAND})
|
||||
set(hiprt_link_flags -E env "HIP_PATH=${HIP_ROOT_DIR}"
|
||||
@@ -734,7 +738,8 @@ if(WITH_CYCLES_DEVICE_HIPRT AND WITH_CYCLES_HIP_BINARIES)
|
||||
add_custom_command(
|
||||
OUTPUT ${hiprt_file}
|
||||
COMMAND ${hiprt_link_command} ${hiprt_link_flags}
|
||||
DEPENDS ${bitcode_file})
|
||||
DEPENDS ${bitcode_file}
|
||||
USES_TERMINAL)
|
||||
delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${hiprt_file}" ${CYCLES_INSTALL_PATH}/lib)
|
||||
add_custom_target(cycles_kernel_hiprt ALL DEPENDS ${hiprt_file})
|
||||
cycles_set_solution_folder(cycles_kernel_hiprt)
|
||||
@@ -785,7 +790,8 @@ if(WITH_CYCLES_DEVICE_OPTIX AND WITH_CYCLES_CUDA_BINARIES)
|
||||
${cuda_flags}
|
||||
${input}
|
||||
WORKING_DIRECTORY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
USES_TERMINAL)
|
||||
|
||||
list(APPEND optix_ptx ${output})
|
||||
|
||||
@@ -1069,7 +1075,8 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
|
||||
"$<$<CONFIG:Debug>:${sycl_compiler_flags_Debug}>"
|
||||
"$<$<CONFIG:MinSizeRel>:${sycl_compiler_flags_Release}>"
|
||||
COMMAND_EXPAND_LISTS
|
||||
DEPENDS ${cycles_oneapi_kernel_sources})
|
||||
DEPENDS ${cycles_oneapi_kernel_sources}
|
||||
USES_TERMINAL)
|
||||
else()
|
||||
if(NOT IGC_INSTALL_DIR)
|
||||
get_filename_component(IGC_INSTALL_DIR "${sycl_compiler_root}/../lib/igc" ABSOLUTE)
|
||||
@@ -1094,7 +1101,8 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
|
||||
"$<$<CONFIG:Debug>:${sycl_compiler_flags_Debug_str}>"
|
||||
"$<$<CONFIG:MinSizeRel>:${sycl_compiler_flags_Release_str}>"
|
||||
COMMAND_EXPAND_LISTS
|
||||
DEPENDS ${cycles_oneapi_kernel_sources})
|
||||
DEPENDS ${cycles_oneapi_kernel_sources}
|
||||
USES_TERMINAL)
|
||||
endif()
|
||||
|
||||
if(NOT WITH_BLENDER)
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "DEG_depsgraph.hh"
|
||||
#include "DEG_depsgraph_build.hh"
|
||||
#include "DEG_depsgraph_query.hh"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
@@ -167,6 +168,7 @@ static void store_result_geometry(Main &bmain,
|
||||
Object &object,
|
||||
bke::GeometrySet geometry)
|
||||
{
|
||||
geometry.ensure_owns_direct_data();
|
||||
switch (object.type) {
|
||||
case OB_CURVES: {
|
||||
Curves &curves = *static_cast<Curves *>(object.data);
|
||||
@@ -225,10 +227,34 @@ static void store_result_geometry(Main &bmain,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a dependency graph referencing all data-blocks used by the tree, and all selected
|
||||
* objects. Adding the selected objects is necessary because they are currently compared by pointer
|
||||
* to other evaluated objects inside of geometry nodes.
|
||||
*/
|
||||
static Depsgraph *build_depsgraph_from_indirect_ids(Main &bmain,
|
||||
Scene &scene,
|
||||
ViewLayer &view_layer,
|
||||
const bNodeTree &node_tree_orig,
|
||||
const Span<const Object *> objects)
|
||||
{
|
||||
Set<ID *> ids_for_relations;
|
||||
bool needs_own_transform_relation = false;
|
||||
nodes::find_node_tree_dependencies(node_tree_orig, ids_for_relations, needs_own_transform_relation);
|
||||
|
||||
Vector<const ID *> ids;
|
||||
ids.append(&node_tree_orig.id);
|
||||
ids.extend(objects.cast<const ID *>());
|
||||
ids.insert(ids.size(), ids_for_relations.begin(), ids_for_relations.end());
|
||||
|
||||
Depsgraph *depsgraph = DEG_graph_new(&bmain, &scene, &view_layer, DAG_EVAL_VIEWPORT);
|
||||
DEG_graph_build_from_ids(depsgraph, const_cast<ID **>(ids.data()), ids.size());
|
||||
return depsgraph;
|
||||
}
|
||||
|
||||
static int run_node_group_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
Object *active_object = CTX_data_active_object(C);
|
||||
@@ -240,11 +266,24 @@ static int run_node_group_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
const eObjectMode mode = eObjectMode(active_object->mode);
|
||||
|
||||
const bNodeTree *node_tree = get_node_group(*C, *op->ptr, op->reports);
|
||||
if (!node_tree) {
|
||||
const bNodeTree *node_tree_orig = get_node_group(*C, *op->ptr, op->reports);
|
||||
if (!node_tree_orig) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
uint objects_len = 0;
|
||||
Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data(
|
||||
scene, view_layer, CTX_wm_view3d(C), &objects_len, mode);
|
||||
BLI_SCOPED_DEFER([&]() { MEM_SAFE_FREE(objects); });
|
||||
|
||||
Depsgraph *depsgraph = build_depsgraph_from_indirect_ids(
|
||||
*bmain, *scene, *view_layer, *node_tree_orig, {objects, objects_len});
|
||||
DEG_evaluate_on_refresh(depsgraph);
|
||||
BLI_SCOPED_DEFER([&]() { DEG_graph_free(depsgraph); });
|
||||
|
||||
const bNodeTree *node_tree = reinterpret_cast<const bNodeTree *>(
|
||||
DEG_get_evaluated_id(depsgraph, const_cast<ID *>(&node_tree_orig->id)));
|
||||
|
||||
const nodes::GeometryNodesLazyFunctionGraphInfo *lf_graph_info =
|
||||
nodes::ensure_geometry_nodes_lazy_function_graph(*node_tree);
|
||||
if (lf_graph_info == nullptr) {
|
||||
@@ -257,10 +296,6 @@ static int run_node_group_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
uint objects_len = 0;
|
||||
Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data(
|
||||
scene, view_layer, CTX_wm_view3d(C), &objects_len, mode);
|
||||
|
||||
OperatorComputeContext compute_context(op->type->idname);
|
||||
|
||||
for (Object *object : Span(objects, objects_len)) {
|
||||
@@ -269,8 +304,8 @@ static int run_node_group_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
nodes::GeoNodesOperatorData operator_eval_data{};
|
||||
operator_eval_data.depsgraph = depsgraph;
|
||||
operator_eval_data.self_object = object;
|
||||
operator_eval_data.scene = scene;
|
||||
operator_eval_data.self_object = DEG_get_evaluated_object(depsgraph, object);
|
||||
operator_eval_data.scene = DEG_get_evaluated_scene(depsgraph);
|
||||
|
||||
bke::GeometrySet geometry_orig = get_original_geometry_eval_copy(*object);
|
||||
|
||||
@@ -290,8 +325,6 @@ static int run_node_group_exec(bContext *C, wmOperator *op)
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, object->data);
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(objects);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
||||
@@ -156,7 +156,6 @@ void MTLBackend::render_step()
|
||||
MTLContext::get_global_memory_manager()->get_current_safe_list();
|
||||
if (cmd_free_buffer_list->should_flush()) {
|
||||
MTLContext::get_global_memory_manager()->begin_new_safe_list();
|
||||
cmd_free_buffer_list->decrement_reference();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -418,6 +418,9 @@ class MTLBufferPool {
|
||||
std::atomic<MTLSafeFreeList *> current_free_list_;
|
||||
std::atomic<int64_t> allocations_in_pool_;
|
||||
|
||||
/* Previous list, to be released after one full frame. */
|
||||
MTLSafeFreeList *prev_free_buffer_list_ = nullptr;
|
||||
|
||||
public:
|
||||
void init(id<MTLDevice> device);
|
||||
~MTLBufferPool();
|
||||
|
||||
@@ -425,8 +425,17 @@ MTLSafeFreeList *MTLBufferPool::get_current_safe_list()
|
||||
void MTLBufferPool::begin_new_safe_list()
|
||||
{
|
||||
safelist_lock_.lock();
|
||||
MTLSafeFreeList *previous_list = prev_free_buffer_list_;
|
||||
MTLSafeFreeList *active_list = get_current_safe_list();
|
||||
current_free_list_ = new MTLSafeFreeList();
|
||||
prev_free_buffer_list_ = active_list;
|
||||
safelist_lock_.unlock();
|
||||
|
||||
/* Release final reference for previous list.
|
||||
* Note: Outside of lock as this function itself locks. */
|
||||
if (previous_list) {
|
||||
previous_list->decrement_reference();
|
||||
}
|
||||
}
|
||||
|
||||
void MTLBufferPool::ensure_buffer_pool(MTLResourceOptions options)
|
||||
|
||||
@@ -112,98 +112,6 @@ static void init_data(ModifierData *md)
|
||||
nmd->runtime->cache = std::make_shared<bake::ModifierCache>();
|
||||
}
|
||||
|
||||
static void add_used_ids_from_sockets(const ListBase &sockets, Set<ID *> &ids)
|
||||
{
|
||||
LISTBASE_FOREACH (const bNodeSocket *, socket, &sockets) {
|
||||
switch (socket->type) {
|
||||
case SOCK_OBJECT: {
|
||||
if (Object *object = ((bNodeSocketValueObject *)socket->default_value)->value) {
|
||||
ids.add(&object->id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SOCK_COLLECTION: {
|
||||
if (Collection *collection = ((bNodeSocketValueCollection *)socket->default_value)->value)
|
||||
{
|
||||
ids.add(&collection->id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SOCK_MATERIAL: {
|
||||
if (Material *material = ((bNodeSocketValueMaterial *)socket->default_value)->value) {
|
||||
ids.add(&material->id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SOCK_TEXTURE: {
|
||||
if (Tex *texture = ((bNodeSocketValueTexture *)socket->default_value)->value) {
|
||||
ids.add(&texture->id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SOCK_IMAGE: {
|
||||
if (Image *image = ((bNodeSocketValueImage *)socket->default_value)->value) {
|
||||
ids.add(&image->id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \note We can only check properties here that cause the dependency graph to update relations when
|
||||
* they are changed, otherwise there may be a missing relation after editing. So this could check
|
||||
* more properties like whether the node is muted, but we would have to accept the cost of updating
|
||||
* relations when those properties are changed.
|
||||
*/
|
||||
static bool node_needs_own_transform_relation(const bNode &node)
|
||||
{
|
||||
if (node.type == GEO_NODE_COLLECTION_INFO) {
|
||||
const NodeGeometryCollectionInfo &storage = *static_cast<const NodeGeometryCollectionInfo *>(
|
||||
node.storage);
|
||||
return storage.transform_space == GEO_NODE_TRANSFORM_SPACE_RELATIVE;
|
||||
}
|
||||
|
||||
if (node.type == GEO_NODE_OBJECT_INFO) {
|
||||
const NodeGeometryObjectInfo &storage = *static_cast<const NodeGeometryObjectInfo *>(
|
||||
node.storage);
|
||||
return storage.transform_space == GEO_NODE_TRANSFORM_SPACE_RELATIVE;
|
||||
}
|
||||
|
||||
if (node.type == GEO_NODE_SELF_OBJECT) {
|
||||
return true;
|
||||
}
|
||||
if (node.type == GEO_NODE_DEFORM_CURVES_ON_SURFACE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void process_nodes_for_depsgraph(const bNodeTree &tree,
|
||||
Set<ID *> &ids,
|
||||
bool &r_needs_own_transform_relation,
|
||||
Set<const bNodeTree *> &checked_groups)
|
||||
{
|
||||
if (!checked_groups.add(&tree)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tree.ensure_topology_cache();
|
||||
for (const bNode *node : tree.all_nodes()) {
|
||||
add_used_ids_from_sockets(node->inputs, ids);
|
||||
add_used_ids_from_sockets(node->outputs, ids);
|
||||
r_needs_own_transform_relation |= node_needs_own_transform_relation(*node);
|
||||
}
|
||||
|
||||
for (const bNode *node : tree.group_nodes()) {
|
||||
if (const bNodeTree *sub_tree = reinterpret_cast<const bNodeTree *>(node->id)) {
|
||||
process_nodes_for_depsgraph(*sub_tree, ids, r_needs_own_transform_relation, checked_groups);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void find_used_ids_from_settings(const NodesModifierSettings &settings, Set<ID *> &ids)
|
||||
{
|
||||
IDP_foreach_property(
|
||||
@@ -259,9 +167,7 @@ static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphCont
|
||||
bool needs_own_transform_relation = false;
|
||||
Set<ID *> used_ids;
|
||||
find_used_ids_from_settings(nmd->settings, used_ids);
|
||||
Set<const bNodeTree *> checked_groups;
|
||||
process_nodes_for_depsgraph(
|
||||
*nmd->node_group, used_ids, needs_own_transform_relation, checked_groups);
|
||||
nodes::find_node_tree_dependencies(*nmd->node_group, used_ids, needs_own_transform_relation);
|
||||
|
||||
if (ctx->object->type == OB_CURVES) {
|
||||
Curves *curves_id = static_cast<Curves *>(ctx->object->data);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "BLI_compute_context.hh"
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_multi_value_map.hh"
|
||||
#include "BLI_set.hh"
|
||||
|
||||
#include "BKE_idprop.hh"
|
||||
#include "BKE_node.h"
|
||||
@@ -29,6 +30,10 @@ class GeoModifierLog;
|
||||
|
||||
namespace blender::nodes {
|
||||
|
||||
void find_node_tree_dependencies(const bNodeTree &tree,
|
||||
Set<ID *> &r_ids,
|
||||
bool &r_needs_own_transform_relation);
|
||||
|
||||
StringRef input_use_attribute_suffix();
|
||||
StringRef input_attribute_name_suffix();
|
||||
|
||||
|
||||
@@ -32,6 +32,106 @@ namespace geo_log = blender::nodes::geo_eval_log;
|
||||
|
||||
namespace blender::nodes {
|
||||
|
||||
static void add_used_ids_from_sockets(const ListBase &sockets, Set<ID *> &ids)
|
||||
{
|
||||
LISTBASE_FOREACH (const bNodeSocket *, socket, &sockets) {
|
||||
switch (socket->type) {
|
||||
case SOCK_OBJECT: {
|
||||
if (Object *object = ((bNodeSocketValueObject *)socket->default_value)->value) {
|
||||
ids.add(reinterpret_cast<ID *>(object));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SOCK_COLLECTION: {
|
||||
if (Collection *collection = ((bNodeSocketValueCollection *)socket->default_value)->value)
|
||||
{
|
||||
ids.add(reinterpret_cast<ID *>(collection));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SOCK_MATERIAL: {
|
||||
if (Material *material = ((bNodeSocketValueMaterial *)socket->default_value)->value) {
|
||||
ids.add(reinterpret_cast<ID *>(material));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SOCK_TEXTURE: {
|
||||
if (Tex *texture = ((bNodeSocketValueTexture *)socket->default_value)->value) {
|
||||
ids.add(reinterpret_cast<ID *>(texture));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SOCK_IMAGE: {
|
||||
if (Image *image = ((bNodeSocketValueImage *)socket->default_value)->value) {
|
||||
ids.add(reinterpret_cast<ID *>(image));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \note We can only check properties here that cause the dependency graph to update relations when
|
||||
* they are changed, otherwise there may be a missing relation after editing. So this could check
|
||||
* more properties like whether the node is muted, but we would have to accept the cost of updating
|
||||
* relations when those properties are changed.
|
||||
*/
|
||||
static bool node_needs_own_transform_relation(const bNode &node)
|
||||
{
|
||||
if (node.type == GEO_NODE_COLLECTION_INFO) {
|
||||
const NodeGeometryCollectionInfo &storage = *static_cast<const NodeGeometryCollectionInfo *>(
|
||||
node.storage);
|
||||
return storage.transform_space == GEO_NODE_TRANSFORM_SPACE_RELATIVE;
|
||||
}
|
||||
|
||||
if (node.type == GEO_NODE_OBJECT_INFO) {
|
||||
const NodeGeometryObjectInfo &storage = *static_cast<const NodeGeometryObjectInfo *>(
|
||||
node.storage);
|
||||
return storage.transform_space == GEO_NODE_TRANSFORM_SPACE_RELATIVE;
|
||||
}
|
||||
|
||||
if (node.type == GEO_NODE_SELF_OBJECT) {
|
||||
return true;
|
||||
}
|
||||
if (node.type == GEO_NODE_DEFORM_CURVES_ON_SURFACE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void process_nodes_for_depsgraph(const bNodeTree &tree,
|
||||
Set<ID *> &ids,
|
||||
bool &r_needs_own_transform_relation,
|
||||
Set<const bNodeTree *> &checked_groups)
|
||||
{
|
||||
if (!checked_groups.add(&tree)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tree.ensure_topology_cache();
|
||||
for (const bNode *node : tree.all_nodes()) {
|
||||
add_used_ids_from_sockets(node->inputs, ids);
|
||||
add_used_ids_from_sockets(node->outputs, ids);
|
||||
r_needs_own_transform_relation |= node_needs_own_transform_relation(*node);
|
||||
}
|
||||
|
||||
for (const bNode *node : tree.group_nodes()) {
|
||||
if (const bNodeTree *sub_tree = reinterpret_cast<const bNodeTree *>(node->id)) {
|
||||
process_nodes_for_depsgraph(*sub_tree, ids, r_needs_own_transform_relation, checked_groups);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void find_node_tree_dependencies(const bNodeTree &tree,
|
||||
Set<ID *> &r_ids,
|
||||
bool &r_needs_own_transform_relation)
|
||||
{
|
||||
Set<const bNodeTree *> checked_groups;
|
||||
process_nodes_for_depsgraph(tree, r_ids, r_needs_own_transform_relation, checked_groups);
|
||||
}
|
||||
|
||||
StringRef input_use_attribute_suffix()
|
||||
{
|
||||
return "_use_attribute";
|
||||
|
||||
Reference in New Issue
Block a user