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