1 /*
2 * Copyright 2011-2020 Blender Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "bvh/bvh.h"
18 #include "bvh/bvh_build.h"
19 #include "bvh/bvh_embree.h"
20
21 #include "device/device.h"
22
23 #include "render/attribute.h"
24 #include "render/camera.h"
25 #include "render/geometry.h"
26 #include "render/hair.h"
27 #include "render/light.h"
28 #include "render/mesh.h"
29 #include "render/nodes.h"
30 #include "render/object.h"
31 #include "render/scene.h"
32 #include "render/shader.h"
33 #include "render/stats.h"
34 #include "render/volume.h"
35
36 #include "subd/subd_patch_table.h"
37 #include "subd/subd_split.h"
38
39 #include "kernel/osl/osl_globals.h"
40
41 #include "util/util_foreach.h"
42 #include "util/util_logging.h"
43 #include "util/util_progress.h"
44
45 CCL_NAMESPACE_BEGIN
46
47 /* Geometry */
48
NODE_ABSTRACT_DEFINE(Geometry)49 NODE_ABSTRACT_DEFINE(Geometry)
50 {
51 NodeType *type = NodeType::add("geometry_base", NULL);
52
53 SOCKET_UINT(motion_steps, "Motion Steps", 3);
54 SOCKET_BOOLEAN(use_motion_blur, "Use Motion Blur", false);
55
56 return type;
57 }
58
Geometry(const NodeType * node_type,const Type type)59 Geometry::Geometry(const NodeType *node_type, const Type type)
60 : Node(node_type), type(type), attributes(this, ATTR_PRIM_GEOMETRY)
61 {
62 need_update = true;
63 need_update_rebuild = false;
64
65 transform_applied = false;
66 transform_negative_scaled = false;
67 transform_normal = transform_identity();
68 bounds = BoundBox::empty;
69
70 has_volume = false;
71 has_surface_bssrdf = false;
72
73 bvh = NULL;
74 attr_map_offset = 0;
75 optix_prim_offset = 0;
76 prim_offset = 0;
77 }
78
~Geometry()79 Geometry::~Geometry()
80 {
81 delete bvh;
82 }
83
clear()84 void Geometry::clear()
85 {
86 used_shaders.clear();
87 transform_applied = false;
88 transform_negative_scaled = false;
89 transform_normal = transform_identity();
90 }
91
need_attribute(Scene * scene,AttributeStandard std)92 bool Geometry::need_attribute(Scene *scene, AttributeStandard std)
93 {
94 if (std == ATTR_STD_NONE)
95 return false;
96
97 if (scene->need_global_attribute(std))
98 return true;
99
100 foreach (Shader *shader, used_shaders)
101 if (shader->attributes.find(std))
102 return true;
103
104 return false;
105 }
106
need_attribute(Scene *,ustring name)107 bool Geometry::need_attribute(Scene * /*scene*/, ustring name)
108 {
109 if (name == ustring())
110 return false;
111
112 foreach (Shader *shader, used_shaders)
113 if (shader->attributes.find(name))
114 return true;
115
116 return false;
117 }
118
motion_time(int step) const119 float Geometry::motion_time(int step) const
120 {
121 return (motion_steps > 1) ? 2.0f * step / (motion_steps - 1) - 1.0f : 0.0f;
122 }
123
motion_step(float time) const124 int Geometry::motion_step(float time) const
125 {
126 if (motion_steps > 1) {
127 int attr_step = 0;
128
129 for (int step = 0; step < motion_steps; step++) {
130 float step_time = motion_time(step);
131 if (step_time == time) {
132 return attr_step;
133 }
134
135 /* Center step is stored in a separate attribute. */
136 if (step != motion_steps / 2) {
137 attr_step++;
138 }
139 }
140 }
141
142 return -1;
143 }
144
need_build_bvh(BVHLayout layout) const145 bool Geometry::need_build_bvh(BVHLayout layout) const
146 {
147 return !transform_applied || has_surface_bssrdf || layout == BVH_LAYOUT_OPTIX;
148 }
149
is_instanced() const150 bool Geometry::is_instanced() const
151 {
152 /* Currently we treat subsurface objects as instanced.
153 *
154 * While it might be not very optimal for ray traversal, it avoids having
155 * duplicated BVH in the memory, saving quite some space.
156 */
157 return !transform_applied || has_surface_bssrdf;
158 }
159
has_true_displacement() const160 bool Geometry::has_true_displacement() const
161 {
162 foreach (Shader *shader, used_shaders) {
163 if (shader->has_displacement && shader->displacement_method != DISPLACE_BUMP) {
164 return true;
165 }
166 }
167
168 return false;
169 }
170
compute_bvh(Device * device,DeviceScene * dscene,SceneParams * params,Progress * progress,int n,int total)171 void Geometry::compute_bvh(
172 Device *device, DeviceScene *dscene, SceneParams *params, Progress *progress, int n, int total)
173 {
174 if (progress->get_cancel())
175 return;
176
177 compute_bounds();
178
179 const BVHLayout bvh_layout = BVHParams::best_bvh_layout(params->bvh_layout,
180 device->get_bvh_layout_mask());
181 if (need_build_bvh(bvh_layout)) {
182 string msg = "Updating Geometry BVH ";
183 if (name.empty())
184 msg += string_printf("%u/%u", (uint)(n + 1), (uint)total);
185 else
186 msg += string_printf("%s %u/%u", name.c_str(), (uint)(n + 1), (uint)total);
187
188 Object object;
189 object.geometry = this;
190
191 vector<Geometry *> geometry;
192 geometry.push_back(this);
193 vector<Object *> objects;
194 objects.push_back(&object);
195
196 if (bvh && !need_update_rebuild) {
197 progress->set_status(msg, "Refitting BVH");
198
199 bvh->geometry = geometry;
200 bvh->objects = objects;
201
202 bvh->refit(*progress);
203 }
204 else {
205 progress->set_status(msg, "Building BVH");
206
207 BVHParams bparams;
208 bparams.use_spatial_split = params->use_bvh_spatial_split;
209 bparams.bvh_layout = bvh_layout;
210 bparams.use_unaligned_nodes = dscene->data.bvh.have_curves &&
211 params->use_bvh_unaligned_nodes;
212 bparams.num_motion_triangle_steps = params->num_bvh_time_steps;
213 bparams.num_motion_curve_steps = params->num_bvh_time_steps;
214 bparams.bvh_type = params->bvh_type;
215 bparams.curve_subdivisions = params->curve_subdivisions();
216
217 delete bvh;
218 bvh = BVH::create(bparams, geometry, objects, device);
219 MEM_GUARDED_CALL(progress, bvh->build, *progress);
220 }
221 }
222
223 need_update = false;
224 need_update_rebuild = false;
225 }
226
has_motion_blur() const227 bool Geometry::has_motion_blur() const
228 {
229 return (use_motion_blur && attributes.find(ATTR_STD_MOTION_VERTEX_POSITION));
230 }
231
has_voxel_attributes() const232 bool Geometry::has_voxel_attributes() const
233 {
234 foreach (const Attribute &attr, attributes.attributes) {
235 if (attr.element == ATTR_ELEMENT_VOXEL) {
236 return true;
237 }
238 }
239
240 return false;
241 }
242
tag_update(Scene * scene,bool rebuild)243 void Geometry::tag_update(Scene *scene, bool rebuild)
244 {
245 need_update = true;
246
247 if (rebuild) {
248 need_update_rebuild = true;
249 scene->light_manager->need_update = true;
250 }
251 else {
252 foreach (Shader *shader, used_shaders)
253 if (shader->has_surface_emission)
254 scene->light_manager->need_update = true;
255 }
256
257 scene->geometry_manager->need_update = true;
258 scene->object_manager->need_update = true;
259 }
260
261 /* Geometry Manager */
262
GeometryManager()263 GeometryManager::GeometryManager()
264 {
265 need_update = true;
266 need_flags_update = true;
267 }
268
~GeometryManager()269 GeometryManager::~GeometryManager()
270 {
271 }
272
update_osl_attributes(Device * device,Scene * scene,vector<AttributeRequestSet> & geom_attributes)273 void GeometryManager::update_osl_attributes(Device *device,
274 Scene *scene,
275 vector<AttributeRequestSet> &geom_attributes)
276 {
277 #ifdef WITH_OSL
278 /* for OSL, a hash map is used to lookup the attribute by name. */
279 OSLGlobals *og = (OSLGlobals *)device->osl_memory();
280
281 og->object_name_map.clear();
282 og->attribute_map.clear();
283 og->object_names.clear();
284
285 og->attribute_map.resize(scene->objects.size() * ATTR_PRIM_TYPES);
286
287 for (size_t i = 0; i < scene->objects.size(); i++) {
288 /* set object name to object index map */
289 Object *object = scene->objects[i];
290 og->object_name_map[object->name] = i;
291 og->object_names.push_back(object->name);
292
293 /* set object attributes */
294 foreach (ParamValue &attr, object->attributes) {
295 OSLGlobals::Attribute osl_attr;
296
297 osl_attr.type = attr.type();
298 osl_attr.desc.element = ATTR_ELEMENT_OBJECT;
299 osl_attr.value = attr;
300 osl_attr.desc.offset = 0;
301 osl_attr.desc.flags = 0;
302
303 og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][attr.name()] = osl_attr;
304 og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][attr.name()] = osl_attr;
305 }
306
307 /* find geometry attributes */
308 size_t j;
309
310 for (j = 0; j < scene->geometry.size(); j++)
311 if (scene->geometry[j] == object->geometry)
312 break;
313
314 AttributeRequestSet &attributes = geom_attributes[j];
315
316 /* set object attributes */
317 foreach (AttributeRequest &req, attributes.requests) {
318 OSLGlobals::Attribute osl_attr;
319
320 if (req.desc.element != ATTR_ELEMENT_NONE) {
321 osl_attr.desc = req.desc;
322
323 if (req.type == TypeDesc::TypeFloat)
324 osl_attr.type = TypeDesc::TypeFloat;
325 else if (req.type == TypeDesc::TypeMatrix)
326 osl_attr.type = TypeDesc::TypeMatrix;
327 else if (req.type == TypeFloat2)
328 osl_attr.type = TypeFloat2;
329 else if (req.type == TypeRGBA)
330 osl_attr.type = TypeRGBA;
331 else
332 osl_attr.type = TypeDesc::TypeColor;
333
334 if (req.std != ATTR_STD_NONE) {
335 /* if standard attribute, add lookup by geom: name convention */
336 ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
337 og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][stdname] = osl_attr;
338 }
339 else if (req.name != ustring()) {
340 /* add lookup by geometry attribute name */
341 og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][req.name] = osl_attr;
342 }
343 }
344
345 if (req.subd_desc.element != ATTR_ELEMENT_NONE) {
346 osl_attr.desc = req.subd_desc;
347
348 if (req.subd_type == TypeDesc::TypeFloat)
349 osl_attr.type = TypeDesc::TypeFloat;
350 else if (req.subd_type == TypeDesc::TypeMatrix)
351 osl_attr.type = TypeDesc::TypeMatrix;
352 else if (req.subd_type == TypeFloat2)
353 osl_attr.type = TypeFloat2;
354 else if (req.subd_type == TypeRGBA)
355 osl_attr.type = TypeRGBA;
356 else
357 osl_attr.type = TypeDesc::TypeColor;
358
359 if (req.std != ATTR_STD_NONE) {
360 /* if standard attribute, add lookup by geom: name convention */
361 ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
362 og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][stdname] = osl_attr;
363 }
364 else if (req.name != ustring()) {
365 /* add lookup by geometry attribute name */
366 og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][req.name] = osl_attr;
367 }
368 }
369 }
370 }
371 #else
372 (void)device;
373 (void)scene;
374 (void)geom_attributes;
375 #endif
376 }
377
update_svm_attributes(Device *,DeviceScene * dscene,Scene * scene,vector<AttributeRequestSet> & geom_attributes)378 void GeometryManager::update_svm_attributes(Device *,
379 DeviceScene *dscene,
380 Scene *scene,
381 vector<AttributeRequestSet> &geom_attributes)
382 {
383 /* for SVM, the attributes_map table is used to lookup the offset of an
384 * attribute, based on a unique shader attribute id. */
385
386 /* compute array stride */
387 int attr_map_size = 0;
388
389 for (size_t i = 0; i < scene->geometry.size(); i++) {
390 Geometry *geom = scene->geometry[i];
391 geom->attr_map_offset = attr_map_size;
392 attr_map_size += (geom_attributes[i].size() + 1) * ATTR_PRIM_TYPES;
393 }
394
395 if (attr_map_size == 0)
396 return;
397
398 /* create attribute map */
399 uint4 *attr_map = dscene->attributes_map.alloc(attr_map_size);
400 memset(attr_map, 0, dscene->attributes_map.size() * sizeof(uint));
401
402 for (size_t i = 0; i < scene->geometry.size(); i++) {
403 Geometry *geom = scene->geometry[i];
404 AttributeRequestSet &attributes = geom_attributes[i];
405
406 /* set object attributes */
407 int index = geom->attr_map_offset;
408
409 foreach (AttributeRequest &req, attributes.requests) {
410 uint id;
411
412 if (req.std == ATTR_STD_NONE)
413 id = scene->shader_manager->get_attribute_id(req.name);
414 else
415 id = scene->shader_manager->get_attribute_id(req.std);
416
417 attr_map[index].x = id;
418 attr_map[index].y = req.desc.element;
419 attr_map[index].z = as_uint(req.desc.offset);
420
421 if (req.type == TypeDesc::TypeFloat)
422 attr_map[index].w = NODE_ATTR_FLOAT;
423 else if (req.type == TypeDesc::TypeMatrix)
424 attr_map[index].w = NODE_ATTR_MATRIX;
425 else if (req.type == TypeFloat2)
426 attr_map[index].w = NODE_ATTR_FLOAT2;
427 else if (req.type == TypeRGBA)
428 attr_map[index].w = NODE_ATTR_RGBA;
429 else
430 attr_map[index].w = NODE_ATTR_FLOAT3;
431
432 attr_map[index].w |= req.desc.flags << 8;
433
434 index++;
435
436 if (geom->type == Geometry::MESH) {
437 Mesh *mesh = static_cast<Mesh *>(geom);
438 if (mesh->subd_faces.size()) {
439 attr_map[index].x = id;
440 attr_map[index].y = req.subd_desc.element;
441 attr_map[index].z = as_uint(req.subd_desc.offset);
442
443 if (req.subd_type == TypeDesc::TypeFloat)
444 attr_map[index].w = NODE_ATTR_FLOAT;
445 else if (req.subd_type == TypeDesc::TypeMatrix)
446 attr_map[index].w = NODE_ATTR_MATRIX;
447 else if (req.subd_type == TypeFloat2)
448 attr_map[index].w = NODE_ATTR_FLOAT2;
449 else if (req.subd_type == TypeRGBA)
450 attr_map[index].w = NODE_ATTR_RGBA;
451 else
452 attr_map[index].w = NODE_ATTR_FLOAT3;
453
454 attr_map[index].w |= req.subd_desc.flags << 8;
455 }
456 }
457
458 index++;
459 }
460
461 /* terminator */
462 for (int j = 0; j < ATTR_PRIM_TYPES; j++) {
463 attr_map[index].x = ATTR_STD_NONE;
464 attr_map[index].y = 0;
465 attr_map[index].z = 0;
466 attr_map[index].w = 0;
467
468 index++;
469 }
470 }
471
472 /* copy to device */
473 dscene->attributes_map.copy_to_device();
474 }
475
update_attribute_element_size(Geometry * geom,Attribute * mattr,AttributePrimitive prim,size_t * attr_float_size,size_t * attr_float2_size,size_t * attr_float3_size,size_t * attr_uchar4_size)476 static void update_attribute_element_size(Geometry *geom,
477 Attribute *mattr,
478 AttributePrimitive prim,
479 size_t *attr_float_size,
480 size_t *attr_float2_size,
481 size_t *attr_float3_size,
482 size_t *attr_uchar4_size)
483 {
484 if (mattr) {
485 size_t size = mattr->element_size(geom, prim);
486
487 if (mattr->element == ATTR_ELEMENT_VOXEL) {
488 /* pass */
489 }
490 else if (mattr->element == ATTR_ELEMENT_CORNER_BYTE) {
491 *attr_uchar4_size += size;
492 }
493 else if (mattr->type == TypeDesc::TypeFloat) {
494 *attr_float_size += size;
495 }
496 else if (mattr->type == TypeFloat2) {
497 *attr_float2_size += size;
498 }
499 else if (mattr->type == TypeDesc::TypeMatrix) {
500 *attr_float3_size += size * 4;
501 }
502 else {
503 *attr_float3_size += size;
504 }
505 }
506 }
507
update_attribute_element_offset(Geometry * geom,device_vector<float> & attr_float,size_t & attr_float_offset,device_vector<float2> & attr_float2,size_t & attr_float2_offset,device_vector<float4> & attr_float3,size_t & attr_float3_offset,device_vector<uchar4> & attr_uchar4,size_t & attr_uchar4_offset,Attribute * mattr,AttributePrimitive prim,TypeDesc & type,AttributeDescriptor & desc)508 static void update_attribute_element_offset(Geometry *geom,
509 device_vector<float> &attr_float,
510 size_t &attr_float_offset,
511 device_vector<float2> &attr_float2,
512 size_t &attr_float2_offset,
513 device_vector<float4> &attr_float3,
514 size_t &attr_float3_offset,
515 device_vector<uchar4> &attr_uchar4,
516 size_t &attr_uchar4_offset,
517 Attribute *mattr,
518 AttributePrimitive prim,
519 TypeDesc &type,
520 AttributeDescriptor &desc)
521 {
522 if (mattr) {
523 /* store element and type */
524 desc.element = mattr->element;
525 desc.flags = mattr->flags;
526 type = mattr->type;
527
528 /* store attribute data in arrays */
529 size_t size = mattr->element_size(geom, prim);
530
531 AttributeElement &element = desc.element;
532 int &offset = desc.offset;
533
534 if (mattr->element == ATTR_ELEMENT_VOXEL) {
535 /* store slot in offset value */
536 ImageHandle &handle = mattr->data_voxel();
537 offset = handle.svm_slot();
538 }
539 else if (mattr->element == ATTR_ELEMENT_CORNER_BYTE) {
540 uchar4 *data = mattr->data_uchar4();
541 offset = attr_uchar4_offset;
542
543 assert(attr_uchar4.size() >= offset + size);
544 for (size_t k = 0; k < size; k++) {
545 attr_uchar4[offset + k] = data[k];
546 }
547 attr_uchar4_offset += size;
548 }
549 else if (mattr->type == TypeDesc::TypeFloat) {
550 float *data = mattr->data_float();
551 offset = attr_float_offset;
552
553 assert(attr_float.size() >= offset + size);
554 for (size_t k = 0; k < size; k++) {
555 attr_float[offset + k] = data[k];
556 }
557 attr_float_offset += size;
558 }
559 else if (mattr->type == TypeFloat2) {
560 float2 *data = mattr->data_float2();
561 offset = attr_float2_offset;
562
563 assert(attr_float2.size() >= offset + size);
564 for (size_t k = 0; k < size; k++) {
565 attr_float2[offset + k] = data[k];
566 }
567 attr_float2_offset += size;
568 }
569 else if (mattr->type == TypeDesc::TypeMatrix) {
570 Transform *tfm = mattr->data_transform();
571 offset = attr_float3_offset;
572
573 assert(attr_float3.size() >= offset + size * 3);
574 for (size_t k = 0; k < size * 3; k++) {
575 attr_float3[offset + k] = (&tfm->x)[k];
576 }
577 attr_float3_offset += size * 3;
578 }
579 else {
580 float4 *data = mattr->data_float4();
581 offset = attr_float3_offset;
582
583 assert(attr_float3.size() >= offset + size);
584 for (size_t k = 0; k < size; k++) {
585 attr_float3[offset + k] = data[k];
586 }
587 attr_float3_offset += size;
588 }
589
590 /* mesh vertex/curve index is global, not per object, so we sneak
591 * a correction for that in here */
592 if (geom->type == Geometry::MESH) {
593 Mesh *mesh = static_cast<Mesh *>(geom);
594 if (mesh->subdivision_type == Mesh::SUBDIVISION_CATMULL_CLARK &&
595 desc.flags & ATTR_SUBDIVIDED) {
596 /* indices for subdivided attributes are retrieved
597 * from patch table so no need for correction here*/
598 }
599 else if (element == ATTR_ELEMENT_VERTEX)
600 offset -= mesh->vert_offset;
601 else if (element == ATTR_ELEMENT_VERTEX_MOTION)
602 offset -= mesh->vert_offset;
603 else if (element == ATTR_ELEMENT_FACE) {
604 if (prim == ATTR_PRIM_GEOMETRY)
605 offset -= mesh->prim_offset;
606 else
607 offset -= mesh->face_offset;
608 }
609 else if (element == ATTR_ELEMENT_CORNER || element == ATTR_ELEMENT_CORNER_BYTE) {
610 if (prim == ATTR_PRIM_GEOMETRY)
611 offset -= 3 * mesh->prim_offset;
612 else
613 offset -= mesh->corner_offset;
614 }
615 }
616 else if (geom->type == Geometry::HAIR) {
617 Hair *hair = static_cast<Hair *>(geom);
618 if (element == ATTR_ELEMENT_CURVE)
619 offset -= hair->prim_offset;
620 else if (element == ATTR_ELEMENT_CURVE_KEY)
621 offset -= hair->curvekey_offset;
622 else if (element == ATTR_ELEMENT_CURVE_KEY_MOTION)
623 offset -= hair->curvekey_offset;
624 }
625 }
626 else {
627 /* attribute not found */
628 desc.element = ATTR_ELEMENT_NONE;
629 desc.offset = 0;
630 }
631 }
632
device_update_attributes(Device * device,DeviceScene * dscene,Scene * scene,Progress & progress)633 void GeometryManager::device_update_attributes(Device *device,
634 DeviceScene *dscene,
635 Scene *scene,
636 Progress &progress)
637 {
638 progress.set_status("Updating Mesh", "Computing attributes");
639
640 /* gather per mesh requested attributes. as meshes may have multiple
641 * shaders assigned, this merges the requested attributes that have
642 * been set per shader by the shader manager */
643 vector<AttributeRequestSet> geom_attributes(scene->geometry.size());
644
645 for (size_t i = 0; i < scene->geometry.size(); i++) {
646 Geometry *geom = scene->geometry[i];
647
648 scene->need_global_attributes(geom_attributes[i]);
649
650 foreach (Shader *shader, geom->used_shaders) {
651 geom_attributes[i].add(shader->attributes);
652 }
653 }
654
655 /* mesh attribute are stored in a single array per data type. here we fill
656 * those arrays, and set the offset and element type to create attribute
657 * maps next */
658
659 /* Pre-allocate attributes to avoid arrays re-allocation which would
660 * take 2x of overall attribute memory usage.
661 */
662 size_t attr_float_size = 0;
663 size_t attr_float2_size = 0;
664 size_t attr_float3_size = 0;
665 size_t attr_uchar4_size = 0;
666 for (size_t i = 0; i < scene->geometry.size(); i++) {
667 Geometry *geom = scene->geometry[i];
668 AttributeRequestSet &attributes = geom_attributes[i];
669 foreach (AttributeRequest &req, attributes.requests) {
670 Attribute *attr = geom->attributes.find(req);
671
672 update_attribute_element_size(geom,
673 attr,
674 ATTR_PRIM_GEOMETRY,
675 &attr_float_size,
676 &attr_float2_size,
677 &attr_float3_size,
678 &attr_uchar4_size);
679
680 if (geom->type == Geometry::MESH) {
681 Mesh *mesh = static_cast<Mesh *>(geom);
682 Attribute *subd_attr = mesh->subd_attributes.find(req);
683
684 update_attribute_element_size(mesh,
685 subd_attr,
686 ATTR_PRIM_SUBD,
687 &attr_float_size,
688 &attr_float2_size,
689 &attr_float3_size,
690 &attr_uchar4_size);
691 }
692 }
693 }
694
695 dscene->attributes_float.alloc(attr_float_size);
696 dscene->attributes_float2.alloc(attr_float2_size);
697 dscene->attributes_float3.alloc(attr_float3_size);
698 dscene->attributes_uchar4.alloc(attr_uchar4_size);
699
700 size_t attr_float_offset = 0;
701 size_t attr_float2_offset = 0;
702 size_t attr_float3_offset = 0;
703 size_t attr_uchar4_offset = 0;
704
705 /* Fill in attributes. */
706 for (size_t i = 0; i < scene->geometry.size(); i++) {
707 Geometry *geom = scene->geometry[i];
708 AttributeRequestSet &attributes = geom_attributes[i];
709
710 /* todo: we now store std and name attributes from requests even if
711 * they actually refer to the same mesh attributes, optimize */
712 foreach (AttributeRequest &req, attributes.requests) {
713 Attribute *attr = geom->attributes.find(req);
714 update_attribute_element_offset(geom,
715 dscene->attributes_float,
716 attr_float_offset,
717 dscene->attributes_float2,
718 attr_float2_offset,
719 dscene->attributes_float3,
720 attr_float3_offset,
721 dscene->attributes_uchar4,
722 attr_uchar4_offset,
723 attr,
724 ATTR_PRIM_GEOMETRY,
725 req.type,
726 req.desc);
727
728 if (geom->type == Geometry::MESH) {
729 Mesh *mesh = static_cast<Mesh *>(geom);
730 Attribute *subd_attr = mesh->subd_attributes.find(req);
731
732 update_attribute_element_offset(mesh,
733 dscene->attributes_float,
734 attr_float_offset,
735 dscene->attributes_float2,
736 attr_float2_offset,
737 dscene->attributes_float3,
738 attr_float3_offset,
739 dscene->attributes_uchar4,
740 attr_uchar4_offset,
741 subd_attr,
742 ATTR_PRIM_SUBD,
743 req.subd_type,
744 req.subd_desc);
745 }
746
747 if (progress.get_cancel())
748 return;
749 }
750 }
751
752 /* create attribute lookup maps */
753 if (scene->shader_manager->use_osl())
754 update_osl_attributes(device, scene, geom_attributes);
755
756 update_svm_attributes(device, dscene, scene, geom_attributes);
757
758 if (progress.get_cancel())
759 return;
760
761 /* copy to device */
762 progress.set_status("Updating Mesh", "Copying Attributes to device");
763
764 if (dscene->attributes_float.size()) {
765 dscene->attributes_float.copy_to_device();
766 }
767 if (dscene->attributes_float2.size()) {
768 dscene->attributes_float2.copy_to_device();
769 }
770 if (dscene->attributes_float3.size()) {
771 dscene->attributes_float3.copy_to_device();
772 }
773 if (dscene->attributes_uchar4.size()) {
774 dscene->attributes_uchar4.copy_to_device();
775 }
776
777 if (progress.get_cancel())
778 return;
779
780 /* After mesh attributes and patch tables have been copied to device memory,
781 * we need to update offsets in the objects. */
782 scene->object_manager->device_update_mesh_offsets(device, dscene, scene);
783 }
784
mesh_calc_offset(Scene * scene)785 void GeometryManager::mesh_calc_offset(Scene *scene)
786 {
787 size_t vert_size = 0;
788 size_t tri_size = 0;
789
790 size_t curve_key_size = 0;
791 size_t curve_size = 0;
792
793 size_t patch_size = 0;
794 size_t face_size = 0;
795 size_t corner_size = 0;
796
797 size_t optix_prim_size = 0;
798
799 foreach (Geometry *geom, scene->geometry) {
800 if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) {
801 Mesh *mesh = static_cast<Mesh *>(geom);
802
803 mesh->vert_offset = vert_size;
804 mesh->prim_offset = tri_size;
805
806 mesh->patch_offset = patch_size;
807 mesh->face_offset = face_size;
808 mesh->corner_offset = corner_size;
809
810 vert_size += mesh->verts.size();
811 tri_size += mesh->num_triangles();
812
813 if (mesh->subd_faces.size()) {
814 Mesh::SubdFace &last = mesh->subd_faces[mesh->subd_faces.size() - 1];
815 patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8;
816
817 /* patch tables are stored in same array so include them in patch_size */
818 if (mesh->patch_table) {
819 mesh->patch_table_offset = patch_size;
820 patch_size += mesh->patch_table->total_size();
821 }
822 }
823
824 face_size += mesh->subd_faces.size();
825 corner_size += mesh->subd_face_corners.size();
826
827 mesh->optix_prim_offset = optix_prim_size;
828 optix_prim_size += mesh->num_triangles();
829 }
830 else if (geom->type == Geometry::HAIR) {
831 Hair *hair = static_cast<Hair *>(geom);
832
833 hair->curvekey_offset = curve_key_size;
834 hair->prim_offset = curve_size;
835
836 curve_key_size += hair->curve_keys.size();
837 curve_size += hair->num_curves();
838
839 hair->optix_prim_offset = optix_prim_size;
840 optix_prim_size += hair->num_segments();
841 }
842 }
843 }
844
device_update_mesh(Device *,DeviceScene * dscene,Scene * scene,bool for_displacement,Progress & progress)845 void GeometryManager::device_update_mesh(
846 Device *, DeviceScene *dscene, Scene *scene, bool for_displacement, Progress &progress)
847 {
848 /* Count. */
849 size_t vert_size = 0;
850 size_t tri_size = 0;
851
852 size_t curve_key_size = 0;
853 size_t curve_size = 0;
854
855 size_t patch_size = 0;
856
857 foreach (Geometry *geom, scene->geometry) {
858 if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) {
859 Mesh *mesh = static_cast<Mesh *>(geom);
860
861 vert_size += mesh->verts.size();
862 tri_size += mesh->num_triangles();
863
864 if (mesh->subd_faces.size()) {
865 Mesh::SubdFace &last = mesh->subd_faces[mesh->subd_faces.size() - 1];
866 patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8;
867
868 /* patch tables are stored in same array so include them in patch_size */
869 if (mesh->patch_table) {
870 mesh->patch_table_offset = patch_size;
871 patch_size += mesh->patch_table->total_size();
872 }
873 }
874 }
875 else if (geom->type == Geometry::HAIR) {
876 Hair *hair = static_cast<Hair *>(geom);
877
878 curve_key_size += hair->curve_keys.size();
879 curve_size += hair->num_curves();
880 }
881 }
882
883 /* Create mapping from triangle to primitive triangle array. */
884 vector<uint> tri_prim_index(tri_size);
885 if (for_displacement) {
886 /* For displacement kernels we do some trickery to make them believe
887 * we've got all required data ready. However, that data is different
888 * from final render kernels since we don't have BVH yet, so can't
889 * really use same semantic of arrays.
890 */
891 foreach (Geometry *geom, scene->geometry) {
892 if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) {
893 Mesh *mesh = static_cast<Mesh *>(geom);
894 for (size_t i = 0; i < mesh->num_triangles(); ++i) {
895 tri_prim_index[i + mesh->prim_offset] = 3 * (i + mesh->prim_offset);
896 }
897 }
898 }
899 }
900 else {
901 for (size_t i = 0; i < dscene->prim_index.size(); ++i) {
902 if ((dscene->prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
903 tri_prim_index[dscene->prim_index[i]] = dscene->prim_tri_index[i];
904 }
905 }
906 }
907
908 /* Fill in all the arrays. */
909 if (tri_size != 0) {
910 /* normals */
911 progress.set_status("Updating Mesh", "Computing normals");
912
913 uint *tri_shader = dscene->tri_shader.alloc(tri_size);
914 float4 *vnormal = dscene->tri_vnormal.alloc(vert_size);
915 uint4 *tri_vindex = dscene->tri_vindex.alloc(tri_size);
916 uint *tri_patch = dscene->tri_patch.alloc(tri_size);
917 float2 *tri_patch_uv = dscene->tri_patch_uv.alloc(vert_size);
918
919 foreach (Geometry *geom, scene->geometry) {
920 if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) {
921 Mesh *mesh = static_cast<Mesh *>(geom);
922 mesh->pack_shaders(scene, &tri_shader[mesh->prim_offset]);
923 mesh->pack_normals(&vnormal[mesh->vert_offset]);
924 mesh->pack_verts(tri_prim_index,
925 &tri_vindex[mesh->prim_offset],
926 &tri_patch[mesh->prim_offset],
927 &tri_patch_uv[mesh->vert_offset],
928 mesh->vert_offset,
929 mesh->prim_offset);
930 if (progress.get_cancel())
931 return;
932 }
933 }
934
935 /* vertex coordinates */
936 progress.set_status("Updating Mesh", "Copying Mesh to device");
937
938 dscene->tri_shader.copy_to_device();
939 dscene->tri_vnormal.copy_to_device();
940 dscene->tri_vindex.copy_to_device();
941 dscene->tri_patch.copy_to_device();
942 dscene->tri_patch_uv.copy_to_device();
943 }
944
945 if (curve_size != 0) {
946 progress.set_status("Updating Mesh", "Copying Strands to device");
947
948 float4 *curve_keys = dscene->curve_keys.alloc(curve_key_size);
949 float4 *curves = dscene->curves.alloc(curve_size);
950
951 foreach (Geometry *geom, scene->geometry) {
952 if (geom->type == Geometry::HAIR) {
953 Hair *hair = static_cast<Hair *>(geom);
954 hair->pack_curves(scene,
955 &curve_keys[hair->curvekey_offset],
956 &curves[hair->prim_offset],
957 hair->curvekey_offset);
958 if (progress.get_cancel())
959 return;
960 }
961 }
962
963 dscene->curve_keys.copy_to_device();
964 dscene->curves.copy_to_device();
965 }
966
967 if (patch_size != 0) {
968 progress.set_status("Updating Mesh", "Copying Patches to device");
969
970 uint *patch_data = dscene->patches.alloc(patch_size);
971
972 foreach (Geometry *geom, scene->geometry) {
973 if (geom->type == Geometry::MESH) {
974 Mesh *mesh = static_cast<Mesh *>(geom);
975 mesh->pack_patches(&patch_data[mesh->patch_offset],
976 mesh->vert_offset,
977 mesh->face_offset,
978 mesh->corner_offset);
979
980 if (mesh->patch_table) {
981 mesh->patch_table->copy_adjusting_offsets(&patch_data[mesh->patch_table_offset],
982 mesh->patch_table_offset);
983 }
984
985 if (progress.get_cancel())
986 return;
987 }
988 }
989
990 dscene->patches.copy_to_device();
991 }
992
993 if (for_displacement) {
994 float4 *prim_tri_verts = dscene->prim_tri_verts.alloc(tri_size * 3);
995 foreach (Geometry *geom, scene->geometry) {
996 if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) {
997 Mesh *mesh = static_cast<Mesh *>(geom);
998 for (size_t i = 0; i < mesh->num_triangles(); ++i) {
999 Mesh::Triangle t = mesh->get_triangle(i);
1000 size_t offset = 3 * (i + mesh->prim_offset);
1001 prim_tri_verts[offset + 0] = float3_to_float4(mesh->verts[t.v[0]]);
1002 prim_tri_verts[offset + 1] = float3_to_float4(mesh->verts[t.v[1]]);
1003 prim_tri_verts[offset + 2] = float3_to_float4(mesh->verts[t.v[2]]);
1004 }
1005 }
1006 }
1007 dscene->prim_tri_verts.copy_to_device();
1008 }
1009 }
1010
device_update_bvh(Device * device,DeviceScene * dscene,Scene * scene,Progress & progress)1011 void GeometryManager::device_update_bvh(Device *device,
1012 DeviceScene *dscene,
1013 Scene *scene,
1014 Progress &progress)
1015 {
1016 /* bvh build */
1017 progress.set_status("Updating Scene BVH", "Building");
1018
1019 BVHParams bparams;
1020 bparams.top_level = true;
1021 bparams.bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout,
1022 device->get_bvh_layout_mask());
1023 bparams.use_spatial_split = scene->params.use_bvh_spatial_split;
1024 bparams.use_unaligned_nodes = dscene->data.bvh.have_curves &&
1025 scene->params.use_bvh_unaligned_nodes;
1026 bparams.num_motion_triangle_steps = scene->params.num_bvh_time_steps;
1027 bparams.num_motion_curve_steps = scene->params.num_bvh_time_steps;
1028 bparams.bvh_type = scene->params.bvh_type;
1029 bparams.curve_subdivisions = scene->params.curve_subdivisions();
1030
1031 VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout.";
1032
1033 BVH *bvh = BVH::create(bparams, scene->geometry, scene->objects, device);
1034 bvh->build(progress, &device->stats);
1035
1036 if (progress.get_cancel()) {
1037 #ifdef WITH_EMBREE
1038 if (dscene->data.bvh.scene) {
1039 BVHEmbree::destroy(dscene->data.bvh.scene);
1040 dscene->data.bvh.scene = NULL;
1041 }
1042 #endif
1043 delete bvh;
1044 return;
1045 }
1046
1047 /* copy to device */
1048 progress.set_status("Updating Scene BVH", "Copying BVH to device");
1049
1050 PackedBVH &pack = bvh->pack;
1051
1052 if (pack.nodes.size()) {
1053 dscene->bvh_nodes.steal_data(pack.nodes);
1054 dscene->bvh_nodes.copy_to_device();
1055 }
1056 if (pack.leaf_nodes.size()) {
1057 dscene->bvh_leaf_nodes.steal_data(pack.leaf_nodes);
1058 dscene->bvh_leaf_nodes.copy_to_device();
1059 }
1060 if (pack.object_node.size()) {
1061 dscene->object_node.steal_data(pack.object_node);
1062 dscene->object_node.copy_to_device();
1063 }
1064 if (pack.prim_tri_index.size()) {
1065 dscene->prim_tri_index.steal_data(pack.prim_tri_index);
1066 dscene->prim_tri_index.copy_to_device();
1067 }
1068 if (pack.prim_tri_verts.size()) {
1069 dscene->prim_tri_verts.steal_data(pack.prim_tri_verts);
1070 dscene->prim_tri_verts.copy_to_device();
1071 }
1072 if (pack.prim_type.size()) {
1073 dscene->prim_type.steal_data(pack.prim_type);
1074 dscene->prim_type.copy_to_device();
1075 }
1076 if (pack.prim_visibility.size()) {
1077 dscene->prim_visibility.steal_data(pack.prim_visibility);
1078 dscene->prim_visibility.copy_to_device();
1079 }
1080 if (pack.prim_index.size()) {
1081 dscene->prim_index.steal_data(pack.prim_index);
1082 dscene->prim_index.copy_to_device();
1083 }
1084 if (pack.prim_object.size()) {
1085 dscene->prim_object.steal_data(pack.prim_object);
1086 dscene->prim_object.copy_to_device();
1087 }
1088 if (pack.prim_time.size()) {
1089 dscene->prim_time.steal_data(pack.prim_time);
1090 dscene->prim_time.copy_to_device();
1091 }
1092
1093 dscene->data.bvh.root = pack.root_index;
1094 dscene->data.bvh.bvh_layout = bparams.bvh_layout;
1095 dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0);
1096 dscene->data.bvh.curve_subdivisions = scene->params.curve_subdivisions();
1097
1098 bvh->copy_to_device(progress, dscene);
1099
1100 delete bvh;
1101 }
1102
device_update_preprocess(Device * device,Scene * scene,Progress & progress)1103 void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Progress &progress)
1104 {
1105 if (!need_update && !need_flags_update) {
1106 return;
1107 }
1108
1109 scoped_callback_timer timer([scene](double time) {
1110 if (scene->update_stats) {
1111 scene->update_stats->geometry.times.add_entry({"device_update_preprocess", time});
1112 }
1113 });
1114
1115 progress.set_status("Updating Meshes Flags");
1116
1117 /* Update flags. */
1118 bool volume_images_updated = false;
1119
1120 foreach (Geometry *geom, scene->geometry) {
1121 geom->has_volume = false;
1122
1123 foreach (const Shader *shader, geom->used_shaders) {
1124 if (shader->has_volume) {
1125 geom->has_volume = true;
1126 }
1127 if (shader->has_surface_bssrdf) {
1128 geom->has_surface_bssrdf = true;
1129 }
1130 }
1131
1132 /* Re-create volume mesh if we will rebuild or refit the BVH. Note we
1133 * should only do it in that case, otherwise the BVH and mesh can go
1134 * out of sync. */
1135 if (geom->need_update && geom->type == Geometry::VOLUME) {
1136 /* Create volume meshes if there is voxel data. */
1137 if (!volume_images_updated) {
1138 progress.set_status("Updating Meshes Volume Bounds");
1139 device_update_volume_images(device, scene, progress);
1140 volume_images_updated = true;
1141 }
1142
1143 Volume *volume = static_cast<Volume *>(geom);
1144 create_volume_mesh(volume, progress);
1145 }
1146
1147 if (geom->type == Geometry::HAIR) {
1148 /* Set curve shape, still a global scene setting for now. */
1149 Hair *hair = static_cast<Hair *>(geom);
1150 hair->curve_shape = scene->params.hair_shape;
1151 }
1152 }
1153
1154 need_flags_update = false;
1155 }
1156
device_update_displacement_images(Device * device,Scene * scene,Progress & progress)1157 void GeometryManager::device_update_displacement_images(Device *device,
1158 Scene *scene,
1159 Progress &progress)
1160 {
1161 progress.set_status("Updating Displacement Images");
1162 TaskPool pool;
1163 ImageManager *image_manager = scene->image_manager;
1164 set<int> bump_images;
1165 foreach (Geometry *geom, scene->geometry) {
1166 if (geom->need_update) {
1167 foreach (Shader *shader, geom->used_shaders) {
1168 if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) {
1169 continue;
1170 }
1171 foreach (ShaderNode *node, shader->graph->nodes) {
1172 if (node->special_type != SHADER_SPECIAL_TYPE_IMAGE_SLOT) {
1173 continue;
1174 }
1175
1176 ImageSlotTextureNode *image_node = static_cast<ImageSlotTextureNode *>(node);
1177 for (int i = 0; i < image_node->handle.num_tiles(); i++) {
1178 const int slot = image_node->handle.svm_slot(i);
1179 if (slot != -1) {
1180 bump_images.insert(slot);
1181 }
1182 }
1183 }
1184 }
1185 }
1186 }
1187 foreach (int slot, bump_images) {
1188 pool.push(function_bind(
1189 &ImageManager::device_update_slot, image_manager, device, scene, slot, &progress));
1190 }
1191 pool.wait_work();
1192 }
1193
device_update_volume_images(Device * device,Scene * scene,Progress & progress)1194 void GeometryManager::device_update_volume_images(Device *device, Scene *scene, Progress &progress)
1195 {
1196 progress.set_status("Updating Volume Images");
1197 TaskPool pool;
1198 ImageManager *image_manager = scene->image_manager;
1199 set<int> volume_images;
1200
1201 foreach (Geometry *geom, scene->geometry) {
1202 if (!geom->need_update) {
1203 continue;
1204 }
1205
1206 foreach (Attribute &attr, geom->attributes.attributes) {
1207 if (attr.element != ATTR_ELEMENT_VOXEL) {
1208 continue;
1209 }
1210
1211 ImageHandle &handle = attr.data_voxel();
1212 /* We can build directly from OpenVDB data structures, no need to
1213 * load such images early. */
1214 if (!handle.vdb_loader()) {
1215 const int slot = handle.svm_slot();
1216 if (slot != -1) {
1217 volume_images.insert(slot);
1218 }
1219 }
1220 }
1221 }
1222
1223 foreach (int slot, volume_images) {
1224 pool.push(function_bind(
1225 &ImageManager::device_update_slot, image_manager, device, scene, slot, &progress));
1226 }
1227 pool.wait_work();
1228 }
1229
device_update(Device * device,DeviceScene * dscene,Scene * scene,Progress & progress)1230 void GeometryManager::device_update(Device *device,
1231 DeviceScene *dscene,
1232 Scene *scene,
1233 Progress &progress)
1234 {
1235 if (!need_update)
1236 return;
1237
1238 VLOG(1) << "Total " << scene->geometry.size() << " meshes.";
1239
1240 bool true_displacement_used = false;
1241 size_t total_tess_needed = 0;
1242
1243 {
1244 scoped_callback_timer timer([scene](double time) {
1245 if (scene->update_stats) {
1246 scene->update_stats->geometry.times.add_entry({"device_update (normals)", time});
1247 }
1248 });
1249
1250 foreach (Geometry *geom, scene->geometry) {
1251 foreach (Shader *shader, geom->used_shaders) {
1252 if (shader->need_update_geometry)
1253 geom->need_update = true;
1254 }
1255
1256 if (geom->need_update && (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME)) {
1257 Mesh *mesh = static_cast<Mesh *>(geom);
1258
1259 /* Update normals. */
1260 mesh->add_face_normals();
1261 mesh->add_vertex_normals();
1262
1263 if (mesh->need_attribute(scene, ATTR_STD_POSITION_UNDISPLACED)) {
1264 mesh->add_undisplaced();
1265 }
1266
1267 /* Test if we need tessellation. */
1268 if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE && mesh->num_subd_verts == 0 &&
1269 mesh->subd_params) {
1270 total_tess_needed++;
1271 }
1272
1273 /* Test if we need displacement. */
1274 if (mesh->has_true_displacement()) {
1275 true_displacement_used = true;
1276 }
1277
1278 if (progress.get_cancel()) {
1279 return;
1280 }
1281 }
1282 }
1283 }
1284
1285 if (progress.get_cancel()) {
1286 return;
1287 }
1288
1289 /* Tessellate meshes that are using subdivision */
1290 if (total_tess_needed) {
1291 scoped_callback_timer timer([scene](double time) {
1292 if (scene->update_stats) {
1293 scene->update_stats->geometry.times.add_entry(
1294 {"device_update (adaptive subdivision)", time});
1295 }
1296 });
1297
1298 Camera *dicing_camera = scene->dicing_camera;
1299 dicing_camera->update(scene);
1300
1301 size_t i = 0;
1302 foreach (Geometry *geom, scene->geometry) {
1303 if (!(geom->need_update && geom->type == Geometry::MESH)) {
1304 continue;
1305 }
1306
1307 Mesh *mesh = static_cast<Mesh *>(geom);
1308 if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE && mesh->num_subd_verts == 0 &&
1309 mesh->subd_params) {
1310 string msg = "Tessellating ";
1311 if (mesh->name == "")
1312 msg += string_printf("%u/%u", (uint)(i + 1), (uint)total_tess_needed);
1313 else
1314 msg += string_printf(
1315 "%s %u/%u", mesh->name.c_str(), (uint)(i + 1), (uint)total_tess_needed);
1316
1317 progress.set_status("Updating Mesh", msg);
1318
1319 mesh->subd_params->camera = dicing_camera;
1320 DiagSplit dsplit(*mesh->subd_params);
1321 mesh->tessellate(&dsplit);
1322
1323 i++;
1324
1325 if (progress.get_cancel()) {
1326 return;
1327 }
1328 }
1329 }
1330
1331 if (progress.get_cancel()) {
1332 return;
1333 }
1334 }
1335
1336 /* Update images needed for true displacement. */
1337 bool old_need_object_flags_update = false;
1338 if (true_displacement_used) {
1339 scoped_callback_timer timer([scene](double time) {
1340 if (scene->update_stats) {
1341 scene->update_stats->geometry.times.add_entry(
1342 {"device_update (displacement: load images)", time});
1343 }
1344 });
1345 device_update_displacement_images(device, scene, progress);
1346 old_need_object_flags_update = scene->object_manager->need_flags_update;
1347 scene->object_manager->device_update_flags(device, dscene, scene, progress, false);
1348 }
1349
1350 /* Device update. */
1351 device_free(device, dscene);
1352
1353 mesh_calc_offset(scene);
1354 if (true_displacement_used) {
1355 scoped_callback_timer timer([scene](double time) {
1356 if (scene->update_stats) {
1357 scene->update_stats->geometry.times.add_entry(
1358 {"device_update (displacement: copy meshes to device)", time});
1359 }
1360 });
1361 device_update_mesh(device, dscene, scene, true, progress);
1362 }
1363 if (progress.get_cancel()) {
1364 return;
1365 }
1366
1367 {
1368 scoped_callback_timer timer([scene](double time) {
1369 if (scene->update_stats) {
1370 scene->update_stats->geometry.times.add_entry({"device_update (attributes)", time});
1371 }
1372 });
1373 device_update_attributes(device, dscene, scene, progress);
1374 if (progress.get_cancel()) {
1375 return;
1376 }
1377 }
1378
1379 /* Update displacement. */
1380 BVHLayout bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout,
1381 device->get_bvh_layout_mask());
1382 bool displacement_done = false;
1383 size_t num_bvh = 0;
1384
1385 {
1386 scoped_callback_timer timer([scene](double time) {
1387 if (scene->update_stats) {
1388 scene->update_stats->geometry.times.add_entry({"device_update (displacement)", time});
1389 }
1390 });
1391
1392 foreach (Geometry *geom, scene->geometry) {
1393 if (geom->need_update) {
1394 if (geom->type == Geometry::MESH) {
1395 Mesh *mesh = static_cast<Mesh *>(geom);
1396 if (displace(device, dscene, scene, mesh, progress)) {
1397 displacement_done = true;
1398 }
1399 }
1400
1401 if (geom->need_build_bvh(bvh_layout)) {
1402 num_bvh++;
1403 }
1404 }
1405
1406 if (progress.get_cancel()) {
1407 return;
1408 }
1409 }
1410 }
1411
1412 if (progress.get_cancel()) {
1413 return;
1414 }
1415
1416 /* Device re-update after displacement. */
1417 if (displacement_done) {
1418 scoped_callback_timer timer([scene](double time) {
1419 if (scene->update_stats) {
1420 scene->update_stats->geometry.times.add_entry(
1421 {"device_update (displacement: attributes)", time});
1422 }
1423 });
1424 device_free(device, dscene);
1425
1426 device_update_attributes(device, dscene, scene, progress);
1427 if (progress.get_cancel()) {
1428 return;
1429 }
1430 }
1431
1432 {
1433 scoped_callback_timer timer([scene](double time) {
1434 if (scene->update_stats) {
1435 scene->update_stats->geometry.times.add_entry({"device_update (build object BVHs)", time});
1436 }
1437 });
1438 TaskPool pool;
1439
1440 size_t i = 0;
1441 foreach (Geometry *geom, scene->geometry) {
1442 if (geom->need_update) {
1443 pool.push(function_bind(
1444 &Geometry::compute_bvh, geom, device, dscene, &scene->params, &progress, i, num_bvh));
1445 if (geom->need_build_bvh(bvh_layout)) {
1446 i++;
1447 }
1448 }
1449 }
1450
1451 TaskPool::Summary summary;
1452 pool.wait_work(&summary);
1453 VLOG(2) << "Objects BVH build pool statistics:\n" << summary.full_report();
1454 }
1455
1456 foreach (Shader *shader, scene->shaders) {
1457 shader->need_update_geometry = false;
1458 }
1459
1460 Scene::MotionType need_motion = scene->need_motion();
1461 bool motion_blur = need_motion == Scene::MOTION_BLUR;
1462
1463 /* Update objects. */
1464 {
1465 scoped_callback_timer timer([scene](double time) {
1466 if (scene->update_stats) {
1467 scene->update_stats->geometry.times.add_entry({"device_update (compute bounds)", time});
1468 }
1469 });
1470 vector<Object *> volume_objects;
1471 foreach (Object *object, scene->objects) {
1472 object->compute_bounds(motion_blur);
1473 }
1474 }
1475
1476 if (progress.get_cancel()) {
1477 return;
1478 }
1479
1480 {
1481 scoped_callback_timer timer([scene](double time) {
1482 if (scene->update_stats) {
1483 scene->update_stats->geometry.times.add_entry({"device_update (build scene BVH)", time});
1484 }
1485 });
1486 device_update_bvh(device, dscene, scene, progress);
1487 if (progress.get_cancel()) {
1488 return;
1489 }
1490 }
1491
1492 {
1493 scoped_callback_timer timer([scene](double time) {
1494 if (scene->update_stats) {
1495 scene->update_stats->geometry.times.add_entry(
1496 {"device_update (copy meshes to device)", time});
1497 }
1498 });
1499 device_update_mesh(device, dscene, scene, false, progress);
1500 if (progress.get_cancel()) {
1501 return;
1502 }
1503 }
1504
1505 need_update = false;
1506
1507 if (true_displacement_used) {
1508 /* Re-tag flags for update, so they're re-evaluated
1509 * for meshes with correct bounding boxes.
1510 *
1511 * This wouldn't cause wrong results, just true
1512 * displacement might be less optimal ot calculate.
1513 */
1514 scene->object_manager->need_flags_update = old_need_object_flags_update;
1515 }
1516 }
1517
device_free(Device * device,DeviceScene * dscene)1518 void GeometryManager::device_free(Device *device, DeviceScene *dscene)
1519 {
1520 #ifdef WITH_EMBREE
1521 if (dscene->data.bvh.scene) {
1522 if (dscene->data.bvh.bvh_layout == BVH_LAYOUT_EMBREE)
1523 BVHEmbree::destroy(dscene->data.bvh.scene);
1524 dscene->data.bvh.scene = NULL;
1525 }
1526 #endif
1527
1528 dscene->bvh_nodes.free();
1529 dscene->bvh_leaf_nodes.free();
1530 dscene->object_node.free();
1531 dscene->prim_tri_verts.free();
1532 dscene->prim_tri_index.free();
1533 dscene->prim_type.free();
1534 dscene->prim_visibility.free();
1535 dscene->prim_index.free();
1536 dscene->prim_object.free();
1537 dscene->prim_time.free();
1538 dscene->tri_shader.free();
1539 dscene->tri_vnormal.free();
1540 dscene->tri_vindex.free();
1541 dscene->tri_patch.free();
1542 dscene->tri_patch_uv.free();
1543 dscene->curves.free();
1544 dscene->curve_keys.free();
1545 dscene->patches.free();
1546 dscene->attributes_map.free();
1547 dscene->attributes_float.free();
1548 dscene->attributes_float2.free();
1549 dscene->attributes_float3.free();
1550 dscene->attributes_uchar4.free();
1551
1552 /* Signal for shaders like displacement not to do ray tracing. */
1553 dscene->data.bvh.bvh_layout = BVH_LAYOUT_NONE;
1554
1555 #ifdef WITH_OSL
1556 OSLGlobals *og = (OSLGlobals *)device->osl_memory();
1557
1558 if (og) {
1559 og->object_name_map.clear();
1560 og->attribute_map.clear();
1561 og->object_names.clear();
1562 }
1563 #else
1564 (void)device;
1565 #endif
1566 }
1567
tag_update(Scene * scene)1568 void GeometryManager::tag_update(Scene *scene)
1569 {
1570 need_update = true;
1571 scene->object_manager->need_update = true;
1572 }
1573
collect_statistics(const Scene * scene,RenderStats * stats)1574 void GeometryManager::collect_statistics(const Scene *scene, RenderStats *stats)
1575 {
1576 foreach (Geometry *geometry, scene->geometry) {
1577 stats->mesh.geometry.add_entry(
1578 NamedSizeEntry(string(geometry->name.c_str()), geometry->get_total_size_in_bytes()));
1579 }
1580 }
1581
1582 CCL_NAMESPACE_END
1583