2023-06-14 16:52:36 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: Apache-2.0 */
|
2020-02-02 12:04:19 +01:00
|
|
|
|
|
|
|
|
#include "bvh/bvh.h"
|
|
|
|
|
|
2020-06-05 11:39:11 +02:00
|
|
|
#include "device/device.h"
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2021-10-24 14:19:19 +02:00
|
|
|
#include "scene/attribute.h"
|
|
|
|
|
#include "scene/camera.h"
|
|
|
|
|
#include "scene/geometry.h"
|
|
|
|
|
#include "scene/hair.h"
|
|
|
|
|
#include "scene/light.h"
|
|
|
|
|
#include "scene/mesh.h"
|
|
|
|
|
#include "scene/object.h"
|
2023-02-08 22:02:39 +01:00
|
|
|
#include "scene/osl.h"
|
2021-12-01 17:30:46 +01:00
|
|
|
#include "scene/pointcloud.h"
|
2021-10-24 14:19:19 +02:00
|
|
|
#include "scene/scene.h"
|
|
|
|
|
#include "scene/shader.h"
|
|
|
|
|
#include "scene/shader_nodes.h"
|
|
|
|
|
#include "scene/stats.h"
|
|
|
|
|
#include "scene/volume.h"
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2021-10-24 14:19:19 +02:00
|
|
|
#include "subd/split.h"
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2023-01-31 16:35:47 +01:00
|
|
|
#ifdef WITH_OSL
|
|
|
|
|
# include "kernel/osl/globals.h"
|
|
|
|
|
#endif
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2021-10-24 14:19:19 +02:00
|
|
|
#include "util/log.h"
|
|
|
|
|
#include "util/progress.h"
|
|
|
|
|
#include "util/task.h"
|
2020-02-02 12:04:19 +01:00
|
|
|
|
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
|
|
/* Geometry */
|
|
|
|
|
|
|
|
|
|
NODE_ABSTRACT_DEFINE(Geometry)
|
|
|
|
|
{
|
2024-12-26 17:53:55 +01:00
|
|
|
NodeType *type = NodeType::add("geometry_base", nullptr);
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2025-01-29 01:59:38 +01:00
|
|
|
SOCKET_UINT(motion_steps, "Motion Steps", 0);
|
2020-02-02 12:04:19 +01:00
|
|
|
SOCKET_BOOLEAN(use_motion_blur, "Use Motion Blur", false);
|
2021-03-15 16:11:12 +01:00
|
|
|
SOCKET_NODE_ARRAY(used_shaders, "Shaders", Shader::get_node_type());
|
2020-02-02 12:04:19 +01:00
|
|
|
|
|
|
|
|
return type;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-03 21:40:58 +01:00
|
|
|
Geometry::Geometry(const NodeType *node_type, const Type type)
|
2020-11-04 11:17:38 +01:00
|
|
|
: Node(node_type), geometry_type(type), attributes(this, ATTR_PRIM_GEOMETRY)
|
2020-02-02 12:04:19 +01:00
|
|
|
{
|
|
|
|
|
need_update_rebuild = false;
|
2021-02-16 20:45:19 +01:00
|
|
|
need_update_bvh_for_offset = false;
|
2020-02-02 12:04:19 +01:00
|
|
|
|
|
|
|
|
transform_applied = false;
|
|
|
|
|
transform_negative_scaled = false;
|
|
|
|
|
transform_normal = transform_identity();
|
|
|
|
|
bounds = BoundBox::empty;
|
|
|
|
|
|
|
|
|
|
has_volume = false;
|
|
|
|
|
has_surface_bssrdf = false;
|
|
|
|
|
|
|
|
|
|
attr_map_offset = 0;
|
|
|
|
|
prim_offset = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Geometry::~Geometry()
|
|
|
|
|
{
|
2021-05-02 02:23:34 +02:00
|
|
|
dereference_all_used_nodes();
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
|
2020-10-31 19:21:07 +03:00
|
|
|
void Geometry::clear(bool preserve_shaders)
|
2020-02-02 12:04:19 +01:00
|
|
|
{
|
2023-09-17 09:01:48 +10:00
|
|
|
if (!preserve_shaders) {
|
2020-10-31 19:21:07 +03:00
|
|
|
used_shaders.clear();
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2020-10-31 19:21:07 +03:00
|
|
|
|
2020-02-02 12:04:19 +01:00
|
|
|
transform_applied = false;
|
|
|
|
|
transform_negative_scaled = false;
|
|
|
|
|
transform_normal = transform_identity();
|
2021-03-23 15:55:01 +01:00
|
|
|
tag_modified();
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
float Geometry::motion_time(const int step) const
|
2020-02-02 12:04:19 +01:00
|
|
|
{
|
|
|
|
|
return (motion_steps > 1) ? 2.0f * step / (motion_steps - 1) - 1.0f : 0.0f;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
int Geometry::motion_step(const float time) const
|
2020-02-02 12:04:19 +01:00
|
|
|
{
|
|
|
|
|
if (motion_steps > 1) {
|
|
|
|
|
int attr_step = 0;
|
|
|
|
|
|
|
|
|
|
for (int step = 0; step < motion_steps; step++) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const float step_time = motion_time(step);
|
2020-02-02 12:04:19 +01:00
|
|
|
if (step_time == time) {
|
|
|
|
|
return attr_step;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Center step is stored in a separate attribute. */
|
|
|
|
|
if (step != motion_steps / 2) {
|
|
|
|
|
attr_step++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Geometry::need_build_bvh(BVHLayout layout) const
|
|
|
|
|
{
|
2020-12-10 14:18:25 +01:00
|
|
|
return is_instanced() || layout == BVH_LAYOUT_OPTIX || layout == BVH_LAYOUT_MULTI_OPTIX ||
|
2021-11-29 15:06:22 +00:00
|
|
|
layout == BVH_LAYOUT_METAL || layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE ||
|
2023-04-24 19:05:30 +02:00
|
|
|
layout == BVH_LAYOUT_MULTI_METAL || layout == BVH_LAYOUT_MULTI_METAL_EMBREE ||
|
|
|
|
|
layout == BVH_LAYOUT_HIPRT || layout == BVH_LAYOUT_MULTI_HIPRT ||
|
2023-05-16 23:26:19 +02:00
|
|
|
layout == BVH_LAYOUT_MULTI_HIPRT_EMBREE || layout == BVH_LAYOUT_EMBREEGPU ||
|
|
|
|
|
layout == BVH_LAYOUT_MULTI_EMBREEGPU || layout == BVH_LAYOUT_MULTI_EMBREEGPU_EMBREE;
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Geometry::is_instanced() const
|
|
|
|
|
{
|
|
|
|
|
/* Currently we treat subsurface objects as instanced.
|
|
|
|
|
*
|
|
|
|
|
* While it might be not very optimal for ray traversal, it avoids having
|
|
|
|
|
* duplicated BVH in the memory, saving quite some space.
|
|
|
|
|
*/
|
|
|
|
|
return !transform_applied || has_surface_bssrdf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Geometry::has_true_displacement() const
|
|
|
|
|
{
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Node *node : used_shaders) {
|
2020-11-04 11:17:38 +01:00
|
|
|
Shader *shader = static_cast<Shader *>(node);
|
|
|
|
|
if (shader->has_displacement && shader->get_displacement_method() != DISPLACE_BUMP) {
|
2020-02-02 12:04:19 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Geometry::has_motion_blur() const
|
|
|
|
|
{
|
|
|
|
|
return (use_motion_blur && attributes.find(ATTR_STD_MOTION_VERTEX_POSITION));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Geometry::tag_update(Scene *scene, bool rebuild)
|
|
|
|
|
{
|
|
|
|
|
if (rebuild) {
|
|
|
|
|
need_update_rebuild = true;
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
scene->light_manager->tag_update(scene, LightManager::MESH_NEED_REBUILD);
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Node *node : used_shaders) {
|
2020-11-04 11:17:38 +01:00
|
|
|
Shader *shader = static_cast<Shader *>(node);
|
2022-11-30 20:50:11 +01:00
|
|
|
if (shader->emission_sampling != EMISSION_SAMPLING_NONE) {
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
scene->light_manager->tag_update(scene, LightManager::EMISSIVE_MESH_MODIFIED);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-11-04 11:17:38 +01:00
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
scene->geometry_manager->tag_update(scene, GeometryManager::GEOMETRY_MODIFIED);
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Geometry Manager */
|
|
|
|
|
|
|
|
|
|
GeometryManager::GeometryManager()
|
|
|
|
|
{
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
update_flags = UPDATE_ALL;
|
2020-02-02 12:04:19 +01:00
|
|
|
need_flags_update = true;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-26 17:53:59 +01:00
|
|
|
GeometryManager::~GeometryManager() = default;
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2022-09-09 11:55:35 +02:00
|
|
|
void GeometryManager::update_osl_globals(Device *device, Scene *scene)
|
2020-02-02 12:04:19 +01:00
|
|
|
{
|
|
|
|
|
#ifdef WITH_OSL
|
2024-12-29 23:13:45 +01:00
|
|
|
OSLGlobals *og = device->get_cpu_osl_memory();
|
2023-01-30 19:40:02 +01:00
|
|
|
if (og == nullptr) {
|
|
|
|
|
/* Can happen when rendering with multiple GPUs, but no CPU (in which case the name maps filled
|
|
|
|
|
* below are not used anyway) */
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
|
|
|
|
|
og->object_name_map.clear();
|
|
|
|
|
og->object_names.clear();
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < scene->objects.size(); i++) {
|
|
|
|
|
/* set object name to object index map */
|
|
|
|
|
Object *object = scene->objects[i];
|
|
|
|
|
og->object_name_map[object->name] = i;
|
|
|
|
|
og->object_names.push_back(object->name);
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
(void)device;
|
|
|
|
|
(void)scene;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-20 12:26:02 +02:00
|
|
|
static void update_device_flags_attribute(uint32_t &device_update_flags,
|
|
|
|
|
const AttributeSet &attributes)
|
2020-02-02 12:04:19 +01:00
|
|
|
{
|
2024-12-26 19:41:25 +01:00
|
|
|
for (const Attribute &attr : attributes.attributes) {
|
2023-04-20 12:26:02 +02:00
|
|
|
if (!attr.modified) {
|
|
|
|
|
continue;
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
const AttrKernelDataType kernel_type = Attribute::kernel_type(attr);
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2023-04-20 12:26:02 +02:00
|
|
|
switch (kernel_type) {
|
|
|
|
|
case AttrKernelDataType::FLOAT: {
|
|
|
|
|
device_update_flags |= ATTR_FLOAT_MODIFIED;
|
|
|
|
|
break;
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
2023-04-20 12:26:02 +02:00
|
|
|
case AttrKernelDataType::FLOAT2: {
|
|
|
|
|
device_update_flags |= ATTR_FLOAT2_MODIFIED;
|
|
|
|
|
break;
|
2021-11-16 14:03:59 +01:00
|
|
|
}
|
2023-04-20 12:26:02 +02:00
|
|
|
case AttrKernelDataType::FLOAT3: {
|
|
|
|
|
device_update_flags |= ATTR_FLOAT3_MODIFIED;
|
|
|
|
|
break;
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
2023-04-20 12:26:02 +02:00
|
|
|
case AttrKernelDataType::FLOAT4: {
|
|
|
|
|
device_update_flags |= ATTR_FLOAT4_MODIFIED;
|
|
|
|
|
break;
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
2023-04-20 12:26:02 +02:00
|
|
|
case AttrKernelDataType::UCHAR4: {
|
|
|
|
|
device_update_flags |= ATTR_UCHAR4_MODIFIED;
|
|
|
|
|
break;
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
2023-04-20 12:26:02 +02:00
|
|
|
case AttrKernelDataType::NUM: {
|
|
|
|
|
break;
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-20 12:26:02 +02:00
|
|
|
static void update_attribute_realloc_flags(uint32_t &device_update_flags,
|
|
|
|
|
const AttributeSet &attributes)
|
2020-02-02 12:04:19 +01:00
|
|
|
{
|
2023-04-20 12:26:02 +02:00
|
|
|
if (attributes.modified(AttrKernelDataType::FLOAT)) {
|
|
|
|
|
device_update_flags |= ATTR_FLOAT_NEEDS_REALLOC;
|
2020-10-26 15:37:07 +01:00
|
|
|
}
|
2023-04-20 12:26:02 +02:00
|
|
|
if (attributes.modified(AttrKernelDataType::FLOAT2)) {
|
|
|
|
|
device_update_flags |= ATTR_FLOAT2_NEEDS_REALLOC;
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
2023-04-20 12:26:02 +02:00
|
|
|
if (attributes.modified(AttrKernelDataType::FLOAT3)) {
|
|
|
|
|
device_update_flags |= ATTR_FLOAT3_NEEDS_REALLOC;
|
2020-10-26 15:37:07 +01:00
|
|
|
}
|
2023-04-20 12:26:02 +02:00
|
|
|
if (attributes.modified(AttrKernelDataType::FLOAT4)) {
|
|
|
|
|
device_update_flags |= ATTR_FLOAT4_NEEDS_REALLOC;
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
2023-04-20 12:26:02 +02:00
|
|
|
if (attributes.modified(AttrKernelDataType::UCHAR4)) {
|
|
|
|
|
device_update_flags |= ATTR_UCHAR4_NEEDS_REALLOC;
|
2020-10-26 15:37:07 +01:00
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
|
2022-01-05 16:01:59 +01:00
|
|
|
void GeometryManager::geom_calc_offset(Scene *scene, BVHLayout bvh_layout)
|
2020-02-02 12:04:19 +01:00
|
|
|
{
|
|
|
|
|
size_t vert_size = 0;
|
|
|
|
|
size_t tri_size = 0;
|
|
|
|
|
|
|
|
|
|
size_t curve_size = 0;
|
2021-02-28 23:23:24 +01:00
|
|
|
size_t curve_key_size = 0;
|
|
|
|
|
size_t curve_segment_size = 0;
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2021-12-01 17:30:46 +01:00
|
|
|
size_t point_size = 0;
|
|
|
|
|
|
2020-02-02 12:04:19 +01:00
|
|
|
size_t face_size = 0;
|
|
|
|
|
size_t corner_size = 0;
|
|
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Geometry *geom : scene->geometry) {
|
2021-02-28 23:23:24 +01:00
|
|
|
bool prim_offset_changed = false;
|
2021-01-05 14:39:29 +01:00
|
|
|
|
2024-10-30 16:45:56 +01:00
|
|
|
if (geom->is_mesh() || geom->is_volume()) {
|
2020-02-02 12:04:19 +01:00
|
|
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
|
|
|
|
|
2021-02-28 23:23:24 +01:00
|
|
|
prim_offset_changed = (mesh->prim_offset != tri_size);
|
|
|
|
|
|
2020-02-02 12:04:19 +01:00
|
|
|
mesh->vert_offset = vert_size;
|
|
|
|
|
mesh->prim_offset = tri_size;
|
|
|
|
|
|
|
|
|
|
mesh->face_offset = face_size;
|
|
|
|
|
mesh->corner_offset = corner_size;
|
|
|
|
|
|
|
|
|
|
vert_size += mesh->verts.size();
|
|
|
|
|
tri_size += mesh->num_triangles();
|
|
|
|
|
|
2020-11-04 11:17:38 +01:00
|
|
|
face_size += mesh->get_num_subd_faces();
|
2020-02-02 12:04:19 +01:00
|
|
|
corner_size += mesh->subd_face_corners.size();
|
|
|
|
|
}
|
2020-11-04 11:17:38 +01:00
|
|
|
else if (geom->is_hair()) {
|
2020-02-02 12:04:19 +01:00
|
|
|
Hair *hair = static_cast<Hair *>(geom);
|
|
|
|
|
|
2021-02-28 23:23:24 +01:00
|
|
|
prim_offset_changed = (hair->curve_segment_offset != curve_segment_size);
|
|
|
|
|
hair->curve_key_offset = curve_key_size;
|
|
|
|
|
hair->curve_segment_offset = curve_segment_size;
|
2020-02-02 12:04:19 +01:00
|
|
|
hair->prim_offset = curve_size;
|
|
|
|
|
|
|
|
|
|
curve_size += hair->num_curves();
|
2021-02-28 23:23:24 +01:00
|
|
|
curve_key_size += hair->get_curve_keys().size();
|
|
|
|
|
curve_segment_size += hair->num_segments();
|
|
|
|
|
}
|
2021-12-01 17:30:46 +01:00
|
|
|
else if (geom->is_pointcloud()) {
|
|
|
|
|
PointCloud *pointcloud = static_cast<PointCloud *>(geom);
|
|
|
|
|
|
|
|
|
|
prim_offset_changed = (pointcloud->prim_offset != point_size);
|
|
|
|
|
|
|
|
|
|
pointcloud->prim_offset = point_size;
|
|
|
|
|
point_size += pointcloud->num_points();
|
|
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2021-02-28 23:23:24 +01:00
|
|
|
if (prim_offset_changed) {
|
2025-01-23 13:05:59 +01:00
|
|
|
/* Need to rebuild BVH in OptiX, since refit only allows modified mesh data.
|
|
|
|
|
* Metal has optimization for static BVH, that also require a rebuild. */
|
|
|
|
|
const bool need_update_rebuild = (bvh_layout == BVH_LAYOUT_OPTIX ||
|
|
|
|
|
bvh_layout == BVH_LAYOUT_MULTI_OPTIX ||
|
|
|
|
|
bvh_layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE) ||
|
|
|
|
|
((bvh_layout == BVH_LAYOUT_METAL ||
|
|
|
|
|
bvh_layout == BVH_LAYOUT_MULTI_METAL ||
|
|
|
|
|
bvh_layout == BVH_LAYOUT_MULTI_METAL_EMBREE) &&
|
|
|
|
|
scene->params.bvh_type == BVH_TYPE_STATIC);
|
|
|
|
|
geom->need_update_rebuild |= need_update_rebuild;
|
2021-02-28 23:23:24 +01:00
|
|
|
geom->need_update_bvh_for_offset = true;
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Progress &progress)
|
|
|
|
|
{
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
if (!need_update() && !need_flags_update) {
|
2020-02-02 12:04:19 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
uint32_t device_update_flags = 0;
|
|
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
const scoped_callback_timer timer([scene](double time) {
|
2020-10-01 23:16:01 +02:00
|
|
|
if (scene->update_stats) {
|
|
|
|
|
scene->update_stats->geometry.times.add_entry({"device_update_preprocess", time});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2020-02-02 12:04:19 +01:00
|
|
|
progress.set_status("Updating Meshes Flags");
|
|
|
|
|
|
|
|
|
|
/* Update flags. */
|
|
|
|
|
bool volume_images_updated = false;
|
|
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Geometry *geom : scene->geometry) {
|
2020-02-02 12:04:19 +01:00
|
|
|
geom->has_volume = false;
|
|
|
|
|
|
Cycles: optimize attributes device updates
When an `AttributeSet` is tagged as modified, which happens after the addition or
removal of an `Attribute` from the set, during the following GeometryManager device
update, we update and repack the kernel data for all attribute types. However, if we
only add or remove a `float` attribute, `float2` or `float3` attributes should not
be repacked for efficiency.
This patch adds some mechanisms to detect which attribute types are modified from
the AttributeSet.
Firstly, this adds an `AttrKernelDataType` to map the data type of the Attribute to
the one used in the kernel as there is no one to one match between the two since e.g.
`Transform` or `float4` data are stored as `float3s` in the kernel.
Then, this replaces the `AttributeSet.modified` boolean with a set of flags to detect
which types have been modified. There is no specific flag type (e.g.
`enum ModifiedType`), rather the flags used derive simply from the
`AttrKernelDataType` enumeration, to keep things synchronized.
The logic to remove an `Attribute` from the `AttributeSet` and tag the latter as modified
is centralized in a new `AttributeSet.remove` method taking an iterator as input.
Lastly, as some attributes like standard normals are not stored in the various
kernel attribute arrays (`DeviceScene::attribute_*`), the modified flags are only
set if the associated standard corresponds to an attribute which will be stored
in the kernel's attribute arrays. This makes it so adding or removing such attributes
does not trigger an unnecessary update of other type-related attributes.
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D11373
2021-05-18 13:09:29 +02:00
|
|
|
update_attribute_realloc_flags(device_update_flags, geom->attributes);
|
2021-02-17 12:04:45 +01:00
|
|
|
|
|
|
|
|
if (geom->is_mesh()) {
|
|
|
|
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
Cycles: optimize attributes device updates
When an `AttributeSet` is tagged as modified, which happens after the addition or
removal of an `Attribute` from the set, during the following GeometryManager device
update, we update and repack the kernel data for all attribute types. However, if we
only add or remove a `float` attribute, `float2` or `float3` attributes should not
be repacked for efficiency.
This patch adds some mechanisms to detect which attribute types are modified from
the AttributeSet.
Firstly, this adds an `AttrKernelDataType` to map the data type of the Attribute to
the one used in the kernel as there is no one to one match between the two since e.g.
`Transform` or `float4` data are stored as `float3s` in the kernel.
Then, this replaces the `AttributeSet.modified` boolean with a set of flags to detect
which types have been modified. There is no specific flag type (e.g.
`enum ModifiedType`), rather the flags used derive simply from the
`AttrKernelDataType` enumeration, to keep things synchronized.
The logic to remove an `Attribute` from the `AttributeSet` and tag the latter as modified
is centralized in a new `AttributeSet.remove` method taking an iterator as input.
Lastly, as some attributes like standard normals are not stored in the various
kernel attribute arrays (`DeviceScene::attribute_*`), the modified flags are only
set if the associated standard corresponds to an attribute which will be stored
in the kernel's attribute arrays. This makes it so adding or removing such attributes
does not trigger an unnecessary update of other type-related attributes.
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D11373
2021-05-18 13:09:29 +02:00
|
|
|
update_attribute_realloc_flags(device_update_flags, mesh->subd_attributes);
|
2021-02-17 12:04:45 +01:00
|
|
|
}
|
|
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Node *node : geom->get_used_shaders()) {
|
2020-11-04 11:17:38 +01:00
|
|
|
Shader *shader = static_cast<Shader *>(node);
|
2020-02-02 12:04:19 +01:00
|
|
|
if (shader->has_volume) {
|
|
|
|
|
geom->has_volume = true;
|
|
|
|
|
}
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
|
2020-02-02 12:04:19 +01:00
|
|
|
if (shader->has_surface_bssrdf) {
|
|
|
|
|
geom->has_surface_bssrdf = true;
|
|
|
|
|
}
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
|
|
|
|
|
if (shader->need_update_uvs) {
|
|
|
|
|
device_update_flags |= ATTR_FLOAT2_NEEDS_REALLOC;
|
|
|
|
|
|
2021-02-05 16:23:34 +11:00
|
|
|
/* Attributes might need to be tessellated if added. */
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
if (geom->is_mesh()) {
|
|
|
|
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
|
|
|
|
if (mesh->need_tesselation()) {
|
|
|
|
|
mesh->tag_modified();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (shader->need_update_attribute) {
|
|
|
|
|
device_update_flags |= ATTRS_NEED_REALLOC;
|
|
|
|
|
|
2021-02-05 16:23:34 +11:00
|
|
|
/* Attributes might need to be tessellated if added. */
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
if (geom->is_mesh()) {
|
|
|
|
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
|
|
|
|
if (mesh->need_tesselation()) {
|
|
|
|
|
mesh->tag_modified();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (shader->need_update_displacement) {
|
|
|
|
|
/* tag displacement related sockets as modified */
|
|
|
|
|
if (geom->is_mesh()) {
|
|
|
|
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
|
|
|
|
mesh->tag_verts_modified();
|
|
|
|
|
mesh->tag_subd_dicing_rate_modified();
|
|
|
|
|
mesh->tag_subd_max_level_modified();
|
|
|
|
|
mesh->tag_subd_objecttoworld_modified();
|
|
|
|
|
|
|
|
|
|
device_update_flags |= ATTRS_NEED_REALLOC;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* only check for modified attributes if we do not need to reallocate them already */
|
|
|
|
|
if ((device_update_flags & ATTRS_NEED_REALLOC) == 0) {
|
|
|
|
|
update_device_flags_attribute(device_update_flags, geom->attributes);
|
|
|
|
|
/* don't check for subd_attributes, as if they were modified, we would need to reallocate
|
|
|
|
|
* anyway */
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
|
2020-10-30 17:28:08 +01:00
|
|
|
/* Re-create volume mesh if we will rebuild or refit the BVH. Note we
|
|
|
|
|
* should only do it in that case, otherwise the BVH and mesh can go
|
|
|
|
|
* out of sync. */
|
2024-10-30 16:45:56 +01:00
|
|
|
if (geom->is_modified() && geom->is_volume()) {
|
2020-02-02 12:04:19 +01:00
|
|
|
/* Create volume meshes if there is voxel data. */
|
2020-08-19 15:46:50 +02:00
|
|
|
if (!volume_images_updated) {
|
|
|
|
|
progress.set_status("Updating Meshes Volume Bounds");
|
|
|
|
|
device_update_volume_images(device, scene, progress);
|
|
|
|
|
volume_images_updated = true;
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
2020-08-19 15:46:50 +02:00
|
|
|
|
|
|
|
|
Volume *volume = static_cast<Volume *>(geom);
|
2022-04-19 16:28:14 +02:00
|
|
|
create_volume_mesh(scene, volume, progress);
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
|
|
|
|
|
/* always reallocate when we have a volume, as we need to rebuild the BVH */
|
|
|
|
|
device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
2020-06-10 19:07:07 +02:00
|
|
|
|
2020-11-04 11:17:38 +01:00
|
|
|
if (geom->is_hair()) {
|
2020-06-10 19:07:07 +02:00
|
|
|
/* Set curve shape, still a global scene setting for now. */
|
|
|
|
|
Hair *hair = static_cast<Hair *>(geom);
|
|
|
|
|
hair->curve_shape = scene->params.hair_shape;
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
|
|
|
|
|
if (hair->need_update_rebuild) {
|
|
|
|
|
device_update_flags |= DEVICE_CURVE_DATA_NEEDS_REALLOC;
|
|
|
|
|
}
|
|
|
|
|
else if (hair->is_modified()) {
|
|
|
|
|
device_update_flags |= DEVICE_CURVE_DATA_MODIFIED;
|
|
|
|
|
}
|
2020-06-10 19:07:07 +02:00
|
|
|
}
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
|
|
|
|
|
if (geom->is_mesh()) {
|
|
|
|
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
|
|
|
|
|
|
|
|
|
if (mesh->need_update_rebuild) {
|
|
|
|
|
device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
|
|
|
|
|
}
|
2021-01-25 07:37:41 +01:00
|
|
|
else if (mesh->is_modified()) {
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
device_update_flags |= DEVICE_MESH_DATA_MODIFIED;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-12-01 17:30:46 +01:00
|
|
|
|
|
|
|
|
if (geom->is_pointcloud()) {
|
|
|
|
|
PointCloud *pointcloud = static_cast<PointCloud *>(geom);
|
|
|
|
|
|
|
|
|
|
if (pointcloud->need_update_rebuild) {
|
|
|
|
|
device_update_flags |= DEVICE_POINT_DATA_NEEDS_REALLOC;
|
|
|
|
|
}
|
|
|
|
|
else if (pointcloud->is_modified()) {
|
|
|
|
|
device_update_flags |= DEVICE_POINT_DATA_MODIFIED;
|
|
|
|
|
}
|
|
|
|
|
}
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (update_flags & (MESH_ADDED | MESH_REMOVED)) {
|
|
|
|
|
device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (update_flags & (HAIR_ADDED | HAIR_REMOVED)) {
|
|
|
|
|
device_update_flags |= DEVICE_CURVE_DATA_NEEDS_REALLOC;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-01 17:30:46 +01:00
|
|
|
if (update_flags & (POINT_ADDED | POINT_REMOVED)) {
|
|
|
|
|
device_update_flags |= DEVICE_POINT_DATA_NEEDS_REALLOC;
|
|
|
|
|
}
|
|
|
|
|
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
/* tag the device arrays for reallocation or modification */
|
|
|
|
|
DeviceScene *dscene = &scene->dscene;
|
|
|
|
|
|
2021-12-01 17:30:46 +01:00
|
|
|
if (device_update_flags & (DEVICE_MESH_DATA_NEEDS_REALLOC | DEVICE_CURVE_DATA_NEEDS_REALLOC |
|
|
|
|
|
DEVICE_POINT_DATA_NEEDS_REALLOC))
|
|
|
|
|
{
|
2024-12-29 23:13:45 +01:00
|
|
|
scene->bvh.reset();
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
|
|
|
|
|
dscene->bvh_nodes.tag_realloc();
|
|
|
|
|
dscene->bvh_leaf_nodes.tag_realloc();
|
|
|
|
|
dscene->object_node.tag_realloc();
|
|
|
|
|
dscene->prim_type.tag_realloc();
|
|
|
|
|
dscene->prim_visibility.tag_realloc();
|
|
|
|
|
dscene->prim_index.tag_realloc();
|
|
|
|
|
dscene->prim_object.tag_realloc();
|
|
|
|
|
dscene->prim_time.tag_realloc();
|
|
|
|
|
|
|
|
|
|
if (device_update_flags & DEVICE_MESH_DATA_NEEDS_REALLOC) {
|
2021-10-08 16:08:04 +02:00
|
|
|
dscene->tri_verts.tag_realloc();
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
dscene->tri_vnormal.tag_realloc();
|
|
|
|
|
dscene->tri_vindex.tag_realloc();
|
2021-02-25 02:16:58 +01:00
|
|
|
dscene->tri_shader.tag_realloc();
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (device_update_flags & DEVICE_CURVE_DATA_NEEDS_REALLOC) {
|
|
|
|
|
dscene->curves.tag_realloc();
|
|
|
|
|
dscene->curve_keys.tag_realloc();
|
2021-02-28 23:23:24 +01:00
|
|
|
dscene->curve_segments.tag_realloc();
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
}
|
2021-12-01 17:30:46 +01:00
|
|
|
|
|
|
|
|
if (device_update_flags & DEVICE_POINT_DATA_NEEDS_REALLOC) {
|
|
|
|
|
dscene->points.tag_realloc();
|
|
|
|
|
dscene->points_shader.tag_realloc();
|
|
|
|
|
}
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
}
|
|
|
|
|
|
2021-05-10 18:23:32 +02:00
|
|
|
if ((update_flags & VISIBILITY_MODIFIED) != 0) {
|
|
|
|
|
dscene->prim_visibility.tag_modified();
|
|
|
|
|
}
|
|
|
|
|
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
if (device_update_flags & ATTR_FLOAT_NEEDS_REALLOC) {
|
|
|
|
|
dscene->attributes_map.tag_realloc();
|
|
|
|
|
dscene->attributes_float.tag_realloc();
|
|
|
|
|
}
|
|
|
|
|
else if (device_update_flags & ATTR_FLOAT_MODIFIED) {
|
|
|
|
|
dscene->attributes_float.tag_modified();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (device_update_flags & ATTR_FLOAT2_NEEDS_REALLOC) {
|
|
|
|
|
dscene->attributes_map.tag_realloc();
|
|
|
|
|
dscene->attributes_float2.tag_realloc();
|
|
|
|
|
}
|
2021-02-09 14:49:33 +01:00
|
|
|
else if (device_update_flags & ATTR_FLOAT2_MODIFIED) {
|
|
|
|
|
dscene->attributes_float2.tag_modified();
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (device_update_flags & ATTR_FLOAT3_NEEDS_REALLOC) {
|
|
|
|
|
dscene->attributes_map.tag_realloc();
|
|
|
|
|
dscene->attributes_float3.tag_realloc();
|
|
|
|
|
}
|
2021-02-09 14:49:33 +01:00
|
|
|
else if (device_update_flags & ATTR_FLOAT3_MODIFIED) {
|
|
|
|
|
dscene->attributes_float3.tag_modified();
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 14:03:59 +01:00
|
|
|
if (device_update_flags & ATTR_FLOAT4_NEEDS_REALLOC) {
|
|
|
|
|
dscene->attributes_map.tag_realloc();
|
|
|
|
|
dscene->attributes_float4.tag_realloc();
|
|
|
|
|
}
|
|
|
|
|
else if (device_update_flags & ATTR_FLOAT4_MODIFIED) {
|
|
|
|
|
dscene->attributes_float4.tag_modified();
|
|
|
|
|
}
|
|
|
|
|
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
if (device_update_flags & ATTR_UCHAR4_NEEDS_REALLOC) {
|
|
|
|
|
dscene->attributes_map.tag_realloc();
|
|
|
|
|
dscene->attributes_uchar4.tag_realloc();
|
|
|
|
|
}
|
|
|
|
|
else if (device_update_flags & ATTR_UCHAR4_MODIFIED) {
|
|
|
|
|
dscene->attributes_uchar4.tag_modified();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (device_update_flags & DEVICE_MESH_DATA_MODIFIED) {
|
2021-01-25 07:37:41 +01:00
|
|
|
/* if anything else than vertices or shaders are modified, we would need to reallocate, so
|
|
|
|
|
* these are the only arrays that can be updated */
|
2021-02-28 23:23:24 +01:00
|
|
|
dscene->tri_verts.tag_modified();
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
dscene->tri_vnormal.tag_modified();
|
2021-01-25 07:37:41 +01:00
|
|
|
dscene->tri_shader.tag_modified();
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (device_update_flags & DEVICE_CURVE_DATA_MODIFIED) {
|
|
|
|
|
dscene->curve_keys.tag_modified();
|
|
|
|
|
dscene->curves.tag_modified();
|
2021-02-28 23:23:24 +01:00
|
|
|
dscene->curve_segments.tag_modified();
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
|
2021-12-01 17:30:46 +01:00
|
|
|
if (device_update_flags & DEVICE_POINT_DATA_MODIFIED) {
|
|
|
|
|
dscene->points.tag_modified();
|
|
|
|
|
dscene->points_shader.tag_modified();
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-02 12:04:19 +01:00
|
|
|
need_flags_update = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GeometryManager::device_update_displacement_images(Device *device,
|
|
|
|
|
Scene *scene,
|
|
|
|
|
Progress &progress)
|
|
|
|
|
{
|
|
|
|
|
progress.set_status("Updating Displacement Images");
|
|
|
|
|
TaskPool pool;
|
2024-12-29 23:13:45 +01:00
|
|
|
ImageManager *image_manager = scene->image_manager.get();
|
2020-02-02 12:04:19 +01:00
|
|
|
set<int> bump_images;
|
2024-04-29 15:13:14 +02:00
|
|
|
#ifdef WITH_OSL
|
2023-01-31 16:35:47 +01:00
|
|
|
bool has_osl_node = false;
|
2024-04-29 15:13:14 +02:00
|
|
|
#endif
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Geometry *geom : scene->geometry) {
|
2020-11-04 11:17:38 +01:00
|
|
|
if (geom->is_modified()) {
|
2021-11-02 11:05:29 +01:00
|
|
|
/* Geometry-level check for hair shadow transparency.
|
|
|
|
|
* This matches the logic in the `Hair::update_shadow_transparency()`, avoiding access to
|
|
|
|
|
* possible non-loaded images. */
|
|
|
|
|
bool need_shadow_transparency = false;
|
2024-10-30 16:45:56 +01:00
|
|
|
if (geom->is_hair()) {
|
2021-11-02 11:05:29 +01:00
|
|
|
Hair *hair = static_cast<Hair *>(geom);
|
|
|
|
|
need_shadow_transparency = hair->need_shadow_transparency();
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Node *node : geom->get_used_shaders()) {
|
2020-11-04 11:17:38 +01:00
|
|
|
Shader *shader = static_cast<Shader *>(node);
|
2021-11-02 11:05:29 +01:00
|
|
|
const bool is_true_displacement = (shader->has_displacement &&
|
|
|
|
|
shader->get_displacement_method() != DISPLACE_BUMP);
|
|
|
|
|
if (!is_true_displacement && !need_shadow_transparency) {
|
2020-02-02 12:04:19 +01:00
|
|
|
continue;
|
|
|
|
|
}
|
2024-12-26 19:41:25 +01:00
|
|
|
for (ShaderNode *node : shader->graph->nodes) {
|
2024-04-29 15:13:14 +02:00
|
|
|
#ifdef WITH_OSL
|
2023-01-31 16:35:47 +01:00
|
|
|
if (node->special_type == SHADER_SPECIAL_TYPE_OSL) {
|
|
|
|
|
has_osl_node = true;
|
|
|
|
|
}
|
2024-04-29 15:13:14 +02:00
|
|
|
#endif
|
2020-02-02 12:04:19 +01:00
|
|
|
if (node->special_type != SHADER_SPECIAL_TYPE_IMAGE_SLOT) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImageSlotTextureNode *image_node = static_cast<ImageSlotTextureNode *>(node);
|
2025-01-23 21:20:01 +01:00
|
|
|
for (int i = 0; i < image_node->handle.num_svm_slots(); i++) {
|
2020-03-08 10:42:11 +01:00
|
|
|
const int slot = image_node->handle.svm_slot(i);
|
2020-02-02 12:04:19 +01:00
|
|
|
if (slot != -1) {
|
|
|
|
|
bump_images.insert(slot);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-01-31 16:35:47 +01:00
|
|
|
|
|
|
|
|
#ifdef WITH_OSL
|
|
|
|
|
/* If any OSL node is used for displacement, it may reference a texture. But it's
|
|
|
|
|
* unknown which ones, so have to load them all. */
|
|
|
|
|
if (has_osl_node) {
|
2023-02-08 22:02:39 +01:00
|
|
|
OSLShaderManager::osl_image_slots(device, image_manager, bump_images);
|
2023-01-31 16:35:47 +01:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
for (const int slot : bump_images) {
|
2024-12-26 17:53:55 +01:00
|
|
|
pool.push([image_manager, device, scene, slot, &progress] {
|
|
|
|
|
image_manager->device_update_slot(device, scene, slot, progress);
|
|
|
|
|
});
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
pool.wait_work();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GeometryManager::device_update_volume_images(Device *device, Scene *scene, Progress &progress)
|
|
|
|
|
{
|
|
|
|
|
progress.set_status("Updating Volume Images");
|
|
|
|
|
TaskPool pool;
|
2024-12-29 23:13:45 +01:00
|
|
|
ImageManager *image_manager = scene->image_manager.get();
|
2020-02-02 12:04:19 +01:00
|
|
|
set<int> volume_images;
|
|
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Geometry *geom : scene->geometry) {
|
2020-11-04 11:17:38 +01:00
|
|
|
if (!geom->is_modified()) {
|
2020-02-02 12:04:19 +01:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Attribute &attr : geom->attributes.attributes) {
|
2020-02-02 12:04:19 +01:00
|
|
|
if (attr.element != ATTR_ELEMENT_VOXEL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
const ImageHandle &handle = attr.data_voxel();
|
2020-08-11 17:34:34 +02:00
|
|
|
/* We can build directly from OpenVDB data structures, no need to
|
|
|
|
|
* load such images early. */
|
|
|
|
|
if (!handle.vdb_loader()) {
|
|
|
|
|
const int slot = handle.svm_slot();
|
|
|
|
|
if (slot != -1) {
|
|
|
|
|
volume_images.insert(slot);
|
|
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
for (const int slot : volume_images) {
|
2024-12-26 17:53:55 +01:00
|
|
|
pool.push([image_manager, device, scene, slot, &progress] {
|
|
|
|
|
image_manager->device_update_slot(device, scene, slot, progress);
|
|
|
|
|
});
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
pool.wait_work();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GeometryManager::device_update(Device *device,
|
|
|
|
|
DeviceScene *dscene,
|
|
|
|
|
Scene *scene,
|
|
|
|
|
Progress &progress)
|
|
|
|
|
{
|
2023-09-17 09:01:48 +10:00
|
|
|
if (!need_update()) {
|
2020-02-02 12:04:19 +01:00
|
|
|
return;
|
2023-09-17 09:01:48 +10:00
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2022-06-16 19:39:13 +02:00
|
|
|
VLOG_INFO << "Total " << scene->geometry.size() << " meshes.";
|
2020-02-02 12:04:19 +01:00
|
|
|
|
|
|
|
|
bool true_displacement_used = false;
|
2021-09-20 16:16:11 +02:00
|
|
|
bool curve_shadow_transparency_used = false;
|
2025-03-25 23:44:23 +01:00
|
|
|
size_t num_tessellation = 0;
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2020-10-01 23:16:01 +02:00
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const scoped_callback_timer timer([scene](double time) {
|
2020-10-01 23:16:01 +02:00
|
|
|
if (scene->update_stats) {
|
|
|
|
|
scene->update_stats->geometry.times.add_entry({"device_update (normals)", time});
|
|
|
|
|
}
|
|
|
|
|
});
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Geometry *geom : scene->geometry) {
|
2021-09-20 16:16:11 +02:00
|
|
|
if (geom->is_modified()) {
|
2024-10-30 16:45:56 +01:00
|
|
|
if (geom->is_mesh() || geom->is_volume()) {
|
2021-09-20 16:16:11 +02:00
|
|
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2021-09-20 16:16:11 +02:00
|
|
|
if (mesh->need_attribute(scene, ATTR_STD_POSITION_UNDISPLACED)) {
|
|
|
|
|
mesh->add_undisplaced();
|
|
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2025-01-02 15:20:57 +01:00
|
|
|
/* Test if we need tessellation and setup normals if required. */
|
2021-09-20 16:16:11 +02:00
|
|
|
if (mesh->need_tesselation()) {
|
2025-03-25 23:44:23 +01:00
|
|
|
num_tessellation++;
|
2025-01-02 15:20:57 +01:00
|
|
|
/* OPENSUBDIV Catmull-Clark does not make use of input normals and will overwrite them.
|
|
|
|
|
*/
|
|
|
|
|
#ifdef WITH_OPENSUBDIV
|
|
|
|
|
if (mesh->get_subdivision_type() != Mesh::SUBDIVISION_CATMULL_CLARK)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
mesh->add_vertex_normals();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
mesh->add_vertex_normals();
|
2021-09-20 16:16:11 +02:00
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2021-09-20 16:16:11 +02:00
|
|
|
/* Test if we need displacement. */
|
|
|
|
|
if (mesh->has_true_displacement()) {
|
|
|
|
|
true_displacement_used = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-30 16:45:56 +01:00
|
|
|
else if (geom->is_hair()) {
|
2021-09-20 16:16:11 +02:00
|
|
|
Hair *hair = static_cast<Hair *>(geom);
|
|
|
|
|
if (hair->need_shadow_transparency()) {
|
|
|
|
|
curve_shadow_transparency_used = true;
|
|
|
|
|
}
|
2020-10-01 23:16:01 +02:00
|
|
|
}
|
|
|
|
|
|
2020-11-11 18:39:46 +01:00
|
|
|
if (progress.get_cancel()) {
|
2020-10-01 23:16:01 +02:00
|
|
|
return;
|
2020-11-11 18:39:46 +01:00
|
|
|
}
|
2020-10-01 23:16:01 +02:00
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-11 18:39:46 +01:00
|
|
|
if (progress.get_cancel()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-02 12:04:19 +01:00
|
|
|
/* Tessellate meshes that are using subdivision */
|
2025-03-25 23:44:23 +01:00
|
|
|
const scoped_callback_timer timer([scene, num_tessellation](double time) {
|
|
|
|
|
if (scene->update_stats) {
|
|
|
|
|
scene->update_stats->geometry.times.add_entry(
|
|
|
|
|
{(num_tessellation) ? "device_update (tessellation and tangents)" :
|
|
|
|
|
"device_update (tangents)",
|
|
|
|
|
time});
|
|
|
|
|
}
|
|
|
|
|
});
|
2020-10-01 23:16:01 +02:00
|
|
|
|
2025-03-25 23:44:23 +01:00
|
|
|
Camera *dicing_camera = scene->dicing_camera;
|
|
|
|
|
if (num_tessellation) {
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
dicing_camera->set_screen_size(dicing_camera->get_full_width(),
|
|
|
|
|
dicing_camera->get_full_height());
|
2020-02-02 12:04:19 +01:00
|
|
|
dicing_camera->update(scene);
|
2025-03-25 23:44:23 +01:00
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2025-03-25 23:44:23 +01:00
|
|
|
size_t i = 0;
|
|
|
|
|
for (Geometry *geom : scene->geometry) {
|
|
|
|
|
if (!(geom->is_modified() && geom->is_mesh())) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2025-03-25 23:44:23 +01:00
|
|
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2025-03-25 23:44:23 +01:00
|
|
|
if (num_tessellation && mesh->need_tesselation()) {
|
|
|
|
|
string msg = "Tessellating ";
|
|
|
|
|
if (mesh->name.empty()) {
|
|
|
|
|
msg += string_printf("%u/%u", (uint)(i + 1), (uint)num_tessellation);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
msg += string_printf(
|
|
|
|
|
"%s %u/%u", mesh->name.c_str(), (uint)(i + 1), (uint)num_tessellation);
|
|
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2025-03-25 23:44:23 +01:00
|
|
|
progress.set_status("Updating Mesh", msg);
|
2025-03-09 04:20:05 +01:00
|
|
|
|
2025-03-25 23:44:23 +01:00
|
|
|
SubdParams subd_params(mesh);
|
|
|
|
|
subd_params.dicing_rate = mesh->get_subd_dicing_rate();
|
|
|
|
|
subd_params.max_level = mesh->get_subd_max_level();
|
|
|
|
|
subd_params.objecttoworld = mesh->get_subd_objecttoworld();
|
|
|
|
|
subd_params.camera = dicing_camera;
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2025-03-25 23:44:23 +01:00
|
|
|
mesh->tessellate(subd_params);
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2025-03-25 23:44:23 +01:00
|
|
|
i++;
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
2020-11-11 18:39:46 +01:00
|
|
|
|
2025-03-25 23:44:23 +01:00
|
|
|
/* Apply generated attribute if needed or remove if not needed */
|
|
|
|
|
mesh->update_generated(scene);
|
|
|
|
|
/* Apply tangents for generated and UVs (if any need them) or remove if not needed */
|
|
|
|
|
mesh->update_tangents(scene);
|
|
|
|
|
|
2020-11-11 18:39:46 +01:00
|
|
|
if (progress.get_cancel()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
|
2025-03-25 23:44:23 +01:00
|
|
|
if (progress.get_cancel()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-02 12:04:19 +01:00
|
|
|
/* Update images needed for true displacement. */
|
2021-09-20 16:16:11 +02:00
|
|
|
if (true_displacement_used || curve_shadow_transparency_used) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const scoped_callback_timer timer([scene](double time) {
|
2020-10-01 23:16:01 +02:00
|
|
|
if (scene->update_stats) {
|
|
|
|
|
scene->update_stats->geometry.times.add_entry(
|
|
|
|
|
{"device_update (displacement: load images)", time});
|
|
|
|
|
}
|
|
|
|
|
});
|
2020-02-02 12:04:19 +01:00
|
|
|
device_update_displacement_images(device, scene, progress);
|
|
|
|
|
scene->object_manager->device_update_flags(device, dscene, scene, progress, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Device update. */
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
device_free(device, dscene, false);
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2023-04-06 12:16:13 +02:00
|
|
|
const BVHLayout bvh_layout = BVHParams::best_bvh_layout(
|
|
|
|
|
scene->params.bvh_layout, device->get_bvh_layout_mask(dscene->data.kernel_features));
|
2022-01-05 16:01:59 +01:00
|
|
|
geom_calc_offset(scene, bvh_layout);
|
2021-09-20 16:16:11 +02:00
|
|
|
if (true_displacement_used || curve_shadow_transparency_used) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const scoped_callback_timer timer([scene](double time) {
|
2020-10-01 23:16:01 +02:00
|
|
|
if (scene->update_stats) {
|
|
|
|
|
scene->update_stats->geometry.times.add_entry(
|
|
|
|
|
{"device_update (displacement: copy meshes to device)", time});
|
|
|
|
|
}
|
|
|
|
|
});
|
2021-02-28 23:23:24 +01:00
|
|
|
device_update_mesh(device, dscene, scene, progress);
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
2025-03-26 18:51:10 +01:00
|
|
|
|
|
|
|
|
if (progress.get_cancel()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Apply transforms, to prepare for static BVH building. */
|
|
|
|
|
if (scene->params.bvh_type == BVH_TYPE_STATIC) {
|
|
|
|
|
const scoped_callback_timer timer([scene](double time) {
|
|
|
|
|
if (scene->update_stats) {
|
|
|
|
|
scene->update_stats->object.times.add_entry(
|
|
|
|
|
{"device_update (apply static transforms)", time});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
progress.set_status("Updating Objects", "Applying Static Transformations");
|
|
|
|
|
scene->object_manager->apply_static_transforms(dscene, scene, progress);
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-11 18:39:46 +01:00
|
|
|
if (progress.get_cancel()) {
|
2020-02-02 12:04:19 +01:00
|
|
|
return;
|
2020-11-11 18:39:46 +01:00
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2020-10-01 23:16:01 +02:00
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const scoped_callback_timer timer([scene](double time) {
|
2020-10-01 23:16:01 +02:00
|
|
|
if (scene->update_stats) {
|
|
|
|
|
scene->update_stats->geometry.times.add_entry({"device_update (attributes)", time});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
device_update_attributes(device, dscene, scene, progress);
|
2020-11-11 18:39:46 +01:00
|
|
|
if (progress.get_cancel()) {
|
2020-10-01 23:16:01 +02:00
|
|
|
return;
|
2020-11-11 18:39:46 +01:00
|
|
|
}
|
2020-10-01 23:16:01 +02:00
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2021-09-20 16:16:11 +02:00
|
|
|
/* Update displacement and hair shadow transparency. */
|
2020-10-01 23:16:01 +02:00
|
|
|
bool displacement_done = false;
|
2021-09-20 16:16:11 +02:00
|
|
|
bool curve_shadow_transparency_done = false;
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2020-10-01 23:16:01 +02:00
|
|
|
{
|
2021-10-14 17:52:19 +02:00
|
|
|
/* Copy constant data needed by shader evaluation. */
|
2022-06-17 17:16:37 +02:00
|
|
|
device->const_copy_to("data", &dscene->data, sizeof(dscene->data));
|
2021-10-14 17:52:19 +02:00
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
const scoped_callback_timer timer([scene](double time) {
|
2020-10-01 23:16:01 +02:00
|
|
|
if (scene->update_stats) {
|
|
|
|
|
scene->update_stats->geometry.times.add_entry({"device_update (displacement)", time});
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
2020-10-01 23:16:01 +02:00
|
|
|
});
|
|
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Geometry *geom : scene->geometry) {
|
2020-11-04 11:17:38 +01:00
|
|
|
if (geom->is_modified()) {
|
|
|
|
|
if (geom->is_mesh()) {
|
2020-10-01 23:16:01 +02:00
|
|
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
2021-10-15 23:39:17 +02:00
|
|
|
if (displace(device, scene, mesh, progress)) {
|
2020-10-01 23:16:01 +02:00
|
|
|
displacement_done = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-30 16:45:56 +01:00
|
|
|
else if (geom->is_hair()) {
|
2021-09-20 16:16:11 +02:00
|
|
|
Hair *hair = static_cast<Hair *>(geom);
|
|
|
|
|
if (hair->update_shadow_transparency(device, scene, progress)) {
|
|
|
|
|
curve_shadow_transparency_done = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-02-16 20:45:19 +01:00
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2020-11-11 18:39:46 +01:00
|
|
|
if (progress.get_cancel()) {
|
2020-10-01 23:16:01 +02:00
|
|
|
return;
|
2020-11-11 18:39:46 +01:00
|
|
|
}
|
2020-10-01 23:16:01 +02:00
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
|
2020-11-11 18:39:46 +01:00
|
|
|
if (progress.get_cancel()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-26 18:51:10 +01:00
|
|
|
/* Device re-update after applying transforms and displacement. */
|
2021-09-20 16:16:11 +02:00
|
|
|
if (displacement_done || curve_shadow_transparency_done) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const scoped_callback_timer timer([scene](double time) {
|
2020-10-01 23:16:01 +02:00
|
|
|
if (scene->update_stats) {
|
|
|
|
|
scene->update_stats->geometry.times.add_entry(
|
|
|
|
|
{"device_update (displacement: attributes)", time});
|
|
|
|
|
}
|
|
|
|
|
});
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
device_free(device, dscene, false);
|
2020-02-02 12:04:19 +01:00
|
|
|
|
|
|
|
|
device_update_attributes(device, dscene, scene, progress);
|
2020-11-11 18:39:46 +01:00
|
|
|
if (progress.get_cancel()) {
|
2020-02-02 12:04:19 +01:00
|
|
|
return;
|
2020-11-11 18:39:46 +01:00
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
|
2021-03-24 10:36:31 +01:00
|
|
|
/* Update the BVH even when there is no geometry so the kernel's BVH data is still valid,
|
|
|
|
|
* especially when removing all of the objects during interactive renders.
|
|
|
|
|
* Also update the BVH if the transformations change, we cannot rely on tagging the Geometry
|
|
|
|
|
* as modified in this case, as we may accumulate displacement if the vertices do not also
|
|
|
|
|
* change. */
|
2021-05-14 17:35:08 +10:00
|
|
|
bool need_update_scene_bvh = (scene->bvh == nullptr ||
|
|
|
|
|
(update_flags & (TRANSFORM_MODIFIED | VISIBILITY_MODIFIED)) != 0);
|
2020-10-01 23:16:01 +02:00
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const scoped_callback_timer timer([scene](double time) {
|
2020-10-01 23:16:01 +02:00
|
|
|
if (scene->update_stats) {
|
|
|
|
|
scene->update_stats->geometry.times.add_entry({"device_update (build object BVHs)", time});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
TaskPool pool;
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2025-02-18 16:20:59 +01:00
|
|
|
/* Work around Embree/oneAPI bug #129596 with BVH updates. */
|
|
|
|
|
const bool use_multithreaded_build = first_bvh_build ||
|
|
|
|
|
!device->info.contains_device_type(DEVICE_ONEAPI);
|
|
|
|
|
first_bvh_build = false;
|
|
|
|
|
|
2020-10-01 23:16:01 +02:00
|
|
|
size_t i = 0;
|
2025-03-26 18:51:10 +01:00
|
|
|
size_t num_bvh = 0;
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Geometry *geom : scene->geometry) {
|
2021-02-16 20:45:19 +01:00
|
|
|
if (geom->is_modified() || geom->need_update_bvh_for_offset) {
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
need_update_scene_bvh = true;
|
2025-03-26 18:51:10 +01:00
|
|
|
|
|
|
|
|
if (geom->need_build_bvh(bvh_layout)) {
|
|
|
|
|
i++;
|
|
|
|
|
num_bvh++;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-18 16:20:59 +01:00
|
|
|
if (use_multithreaded_build) {
|
2025-03-26 18:51:10 +01:00
|
|
|
pool.push([geom, device, dscene, scene, &progress, i, &num_bvh] {
|
2025-02-18 16:20:59 +01:00
|
|
|
geom->compute_bvh(device, dscene, &scene->params, &progress, i, num_bvh);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
else {
|
2024-12-26 17:53:55 +01:00
|
|
|
geom->compute_bvh(device, dscene, &scene->params, &progress, i, num_bvh);
|
2025-02-18 16:20:59 +01:00
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-01 23:16:01 +02:00
|
|
|
TaskPool::Summary summary;
|
|
|
|
|
pool.wait_work(&summary);
|
2022-06-16 19:39:13 +02:00
|
|
|
VLOG_WORK << "Objects BVH build pool statistics:\n" << summary.full_report();
|
2020-10-01 23:16:01 +02:00
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Shader *shader : scene->shaders) {
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
shader->need_update_uvs = false;
|
|
|
|
|
shader->need_update_attribute = false;
|
|
|
|
|
shader->need_update_displacement = false;
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
|
2024-12-29 17:32:00 +01:00
|
|
|
const Scene::MotionType need_motion = scene->need_motion();
|
|
|
|
|
const bool motion_blur = need_motion == Scene::MOTION_BLUR;
|
2020-02-02 12:04:19 +01:00
|
|
|
|
|
|
|
|
/* Update objects. */
|
2020-10-01 23:16:01 +02:00
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const scoped_callback_timer timer([scene](double time) {
|
2020-10-01 23:16:01 +02:00
|
|
|
if (scene->update_stats) {
|
|
|
|
|
scene->update_stats->geometry.times.add_entry({"device_update (compute bounds)", time});
|
|
|
|
|
}
|
|
|
|
|
});
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Object *object : scene->objects) {
|
2020-10-01 23:16:01 +02:00
|
|
|
object->compute_bounds(motion_blur);
|
|
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
|
2020-11-11 18:39:46 +01:00
|
|
|
if (progress.get_cancel()) {
|
2020-02-02 12:04:19 +01:00
|
|
|
return;
|
2020-11-11 18:39:46 +01:00
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
if (need_update_scene_bvh) {
|
2024-12-29 17:32:00 +01:00
|
|
|
const scoped_callback_timer timer([scene](double time) {
|
2020-10-01 23:16:01 +02:00
|
|
|
if (scene->update_stats) {
|
|
|
|
|
scene->update_stats->geometry.times.add_entry({"device_update (build scene BVH)", time});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
device_update_bvh(device, dscene, scene, progress);
|
2020-11-11 18:39:46 +01:00
|
|
|
if (progress.get_cancel()) {
|
2020-10-01 23:16:01 +02:00
|
|
|
return;
|
2020-11-11 18:39:46 +01:00
|
|
|
}
|
2020-10-01 23:16:01 +02:00
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
|
2021-04-12 20:10:07 +02:00
|
|
|
/* Always set BVH layout again after displacement where it was set to none,
|
|
|
|
|
* to avoid ray-tracing at that stage. */
|
2023-04-06 12:16:13 +02:00
|
|
|
dscene->data.bvh.bvh_layout = BVHParams::best_bvh_layout(
|
|
|
|
|
scene->params.bvh_layout, device->get_bvh_layout_mask(dscene->data.kernel_features));
|
2021-04-12 20:10:07 +02:00
|
|
|
|
2020-10-01 23:16:01 +02:00
|
|
|
{
|
2024-12-29 17:32:00 +01:00
|
|
|
const scoped_callback_timer timer([scene](double time) {
|
2020-10-01 23:16:01 +02:00
|
|
|
if (scene->update_stats) {
|
|
|
|
|
scene->update_stats->geometry.times.add_entry(
|
|
|
|
|
{"device_update (copy meshes to device)", time});
|
|
|
|
|
}
|
|
|
|
|
});
|
2021-02-28 23:23:24 +01:00
|
|
|
device_update_mesh(device, dscene, scene, progress);
|
2020-11-11 18:39:46 +01:00
|
|
|
if (progress.get_cancel()) {
|
2020-10-01 23:16:01 +02:00
|
|
|
return;
|
2020-11-11 18:39:46 +01:00
|
|
|
}
|
2020-10-01 23:16:01 +02:00
|
|
|
}
|
2020-02-02 12:04:19 +01:00
|
|
|
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
/* unset flags */
|
|
|
|
|
|
2024-12-26 19:41:25 +01:00
|
|
|
for (Geometry *geom : scene->geometry) {
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
geom->clear_modified();
|
|
|
|
|
geom->attributes.clear_modified();
|
|
|
|
|
|
|
|
|
|
if (geom->is_mesh()) {
|
|
|
|
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
|
|
|
|
mesh->subd_attributes.clear_modified();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
update_flags = UPDATE_NONE;
|
|
|
|
|
|
|
|
|
|
dscene->bvh_nodes.clear_modified();
|
|
|
|
|
dscene->bvh_leaf_nodes.clear_modified();
|
|
|
|
|
dscene->object_node.clear_modified();
|
|
|
|
|
dscene->prim_type.clear_modified();
|
|
|
|
|
dscene->prim_visibility.clear_modified();
|
|
|
|
|
dscene->prim_index.clear_modified();
|
|
|
|
|
dscene->prim_object.clear_modified();
|
|
|
|
|
dscene->prim_time.clear_modified();
|
2021-02-28 23:23:24 +01:00
|
|
|
dscene->tri_verts.clear_modified();
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
dscene->tri_shader.clear_modified();
|
|
|
|
|
dscene->tri_vindex.clear_modified();
|
|
|
|
|
dscene->tri_vnormal.clear_modified();
|
|
|
|
|
dscene->curves.clear_modified();
|
|
|
|
|
dscene->curve_keys.clear_modified();
|
2021-02-28 23:23:24 +01:00
|
|
|
dscene->curve_segments.clear_modified();
|
2021-12-01 17:30:46 +01:00
|
|
|
dscene->points.clear_modified();
|
|
|
|
|
dscene->points_shader.clear_modified();
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
dscene->attributes_map.clear_modified();
|
|
|
|
|
dscene->attributes_float.clear_modified();
|
|
|
|
|
dscene->attributes_float2.clear_modified();
|
|
|
|
|
dscene->attributes_float3.clear_modified();
|
2021-11-16 14:03:59 +01:00
|
|
|
dscene->attributes_float4.clear_modified();
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
dscene->attributes_uchar4.clear_modified();
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
void GeometryManager::device_free(Device *device, DeviceScene *dscene, bool force_free)
|
2020-02-02 12:04:19 +01:00
|
|
|
{
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
dscene->bvh_nodes.free_if_need_realloc(force_free);
|
|
|
|
|
dscene->bvh_leaf_nodes.free_if_need_realloc(force_free);
|
|
|
|
|
dscene->object_node.free_if_need_realloc(force_free);
|
|
|
|
|
dscene->prim_type.free_if_need_realloc(force_free);
|
|
|
|
|
dscene->prim_visibility.free_if_need_realloc(force_free);
|
|
|
|
|
dscene->prim_index.free_if_need_realloc(force_free);
|
|
|
|
|
dscene->prim_object.free_if_need_realloc(force_free);
|
|
|
|
|
dscene->prim_time.free_if_need_realloc(force_free);
|
2021-02-28 23:23:24 +01:00
|
|
|
dscene->tri_verts.free_if_need_realloc(force_free);
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
dscene->tri_shader.free_if_need_realloc(force_free);
|
|
|
|
|
dscene->tri_vnormal.free_if_need_realloc(force_free);
|
|
|
|
|
dscene->tri_vindex.free_if_need_realloc(force_free);
|
|
|
|
|
dscene->curves.free_if_need_realloc(force_free);
|
|
|
|
|
dscene->curve_keys.free_if_need_realloc(force_free);
|
2021-02-28 23:23:24 +01:00
|
|
|
dscene->curve_segments.free_if_need_realloc(force_free);
|
2021-12-01 17:30:46 +01:00
|
|
|
dscene->points.free_if_need_realloc(force_free);
|
|
|
|
|
dscene->points_shader.free_if_need_realloc(force_free);
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
dscene->attributes_map.free_if_need_realloc(force_free);
|
|
|
|
|
dscene->attributes_float.free_if_need_realloc(force_free);
|
|
|
|
|
dscene->attributes_float2.free_if_need_realloc(force_free);
|
|
|
|
|
dscene->attributes_float3.free_if_need_realloc(force_free);
|
2021-11-16 14:03:59 +01:00
|
|
|
dscene->attributes_float4.free_if_need_realloc(force_free);
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
dscene->attributes_uchar4.free_if_need_realloc(force_free);
|
2020-02-02 12:04:19 +01:00
|
|
|
|
|
|
|
|
/* Signal for shaders like displacement not to do ray tracing. */
|
|
|
|
|
dscene->data.bvh.bvh_layout = BVH_LAYOUT_NONE;
|
|
|
|
|
|
|
|
|
|
#ifdef WITH_OSL
|
2024-12-29 23:13:45 +01:00
|
|
|
OSLGlobals *og = device->get_cpu_osl_memory();
|
2020-02-02 12:04:19 +01:00
|
|
|
|
|
|
|
|
if (og) {
|
|
|
|
|
og->object_name_map.clear();
|
|
|
|
|
og->object_names.clear();
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
(void)device;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
void GeometryManager::tag_update(Scene *scene, const uint32_t flag)
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
{
|
|
|
|
|
update_flags |= flag;
|
|
|
|
|
|
|
|
|
|
/* do not tag the object manager for an update if it is the one who tagged us */
|
|
|
|
|
if ((flag & OBJECT_MANAGER) == 0) {
|
|
|
|
|
scene->object_manager->tag_update(scene, ObjectManager::GEOMETRY_MANAGER);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool GeometryManager::need_update() const
|
2020-02-02 12:04:19 +01:00
|
|
|
{
|
Cycles: optimize device updates
This optimizes device updates (during user edits or frame changes in
the viewport) by avoiding unnecessary computations. To achieve this,
we use a combination of the sockets' update flags as well as some new
flags passed to the various managers when tagging for an update to tell
exactly what the tagging is for (e.g. shader was modified, object was
removed, etc.).
Besides avoiding recomputations, we also avoid resending to the devices
unmodified data arrays, thus reducing bandwidth usage. For OptiX and
Embree, BVH packing was also multithreaded.
The performance improvements may vary depending on the used device (CPU
or GPU), and the content of the scene. Simple scenes (e.g. with no adaptive
subdivision or volumes) rendered using OptiX will benefit from this work
the most.
On average, for a variety of animated scenes, this gives a 3x speedup.
Reviewed By: #cycles, brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D9555
2021-01-22 15:01:26 +01:00
|
|
|
return update_flags != UPDATE_NONE;
|
2020-02-02 12:04:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GeometryManager::collect_statistics(const Scene *scene, RenderStats *stats)
|
|
|
|
|
{
|
2024-12-30 02:20:36 +01:00
|
|
|
for (const Geometry *geometry : scene->geometry) {
|
2020-02-02 12:04:19 +01:00
|
|
|
stats->mesh.geometry.add_entry(
|
|
|
|
|
NamedSizeEntry(string(geometry->name.c_str()), geometry->get_total_size_in_bytes()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CCL_NAMESPACE_END
|