diff options
-rw-r--r-- | intern/cycles/kernel/geom/geom_attribute.h | 11 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_motion_curve.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_motion_triangle.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 3 | ||||
-rw-r--r-- | intern/cycles/render/mesh.cpp | 43 | ||||
-rw-r--r-- | intern/cycles/render/mesh.h | 2 | ||||
-rw-r--r-- | intern/cycles/render/object.cpp | 12 | ||||
-rw-r--r-- | intern/cycles/render/object.h | 2 |
8 files changed, 43 insertions, 34 deletions
diff --git a/intern/cycles/kernel/geom/geom_attribute.h b/intern/cycles/kernel/geom/geom_attribute.h index cc62192ef21..18f5c813cc8 100644 --- a/intern/cycles/kernel/geom/geom_attribute.h +++ b/intern/cycles/kernel/geom/geom_attribute.h @@ -51,14 +51,21 @@ ccl_device_inline AttributeDescriptor attribute_not_found() /* Find attribute based on ID */ +ccl_device_inline uint object_attribute_map_offset(KernelGlobals *kg, int object) +{ + int offset = object*OBJECT_SIZE + 11; + float4 f = kernel_tex_fetch(__objects, offset); + return __float_as_uint(f.y); +} + ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id) { - if(sd->object == PRIM_NONE) { + if(sd->object == OBJECT_NONE) { return attribute_not_found(); } /* for SVM, find attribute by unique id */ - uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride; + uint attr_offset = object_attribute_map_offset(kg, sd->object); attr_offset += attribute_primitive_type(kg, sd); uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset); diff --git a/intern/cycles/kernel/geom/geom_motion_curve.h b/intern/cycles/kernel/geom/geom_motion_curve.h index 119bdb2f15c..fad29e431ec 100644 --- a/intern/cycles/kernel/geom/geom_motion_curve.h +++ b/intern/cycles/kernel/geom/geom_motion_curve.h @@ -33,7 +33,7 @@ ccl_device_inline int find_attribute_curve_motion(KernelGlobals *kg, int object, * zero iterations and rendering is really slow with motion curves. For until other * areas are speed up it's probably not so crucial to optimize this out. */ - uint attr_offset = object*kernel_data.bvh.attributes_map_stride + ATTR_PRIM_CURVE; + uint attr_offset = object_attribute_map_offset(kg, object) + ATTR_PRIM_CURVE; uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset); while(attr_map.x != id) { diff --git a/intern/cycles/kernel/geom/geom_motion_triangle.h b/intern/cycles/kernel/geom/geom_motion_triangle.h index 4e84aa97776..cd28b75c22c 100644 --- a/intern/cycles/kernel/geom/geom_motion_triangle.h +++ b/intern/cycles/kernel/geom/geom_motion_triangle.h @@ -32,7 +32,7 @@ CCL_NAMESPACE_BEGIN ccl_device_inline int find_attribute_motion(KernelGlobals *kg, int object, uint id, AttributeElement *elem) { /* todo: find a better (faster) solution for this, maybe store offset per object */ - uint attr_offset = object*kernel_data.bvh.attributes_map_stride; + uint attr_offset = object_attribute_map_offset(kg, object); uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset); while(attr_map.x != id) { diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 49ec6d97f28..d1733d8a6e7 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -1295,13 +1295,12 @@ static_assert_align(KernelIntegrator, 16); typedef struct KernelBVH { /* root node */ int root; - int attributes_map_stride; int have_motion; int have_curves; int have_instancing; int use_qbvh; int use_bvh_steps; - int pad1; + int pad1, pad2; } KernelBVH; static_assert_align(KernelBVH, 16); diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 75bdf71616f..189ba80ad2a 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -436,6 +436,8 @@ Mesh::Mesh() face_offset = 0; corner_offset = 0; + attr_map_offset = 0; + num_subd_verts = 0; attributes.triangle_mesh = this; @@ -1258,33 +1260,27 @@ void MeshManager::update_svm_attributes(Device *, DeviceScene *dscene, Scene *sc * attribute, based on a unique shader attribute id. */ /* compute array stride */ - int attr_map_stride = 0; + int attr_map_size = 0; - for(size_t i = 0; i < scene->meshes.size(); i++) - attr_map_stride = max(attr_map_stride, (mesh_attributes[i].size() + 1)*ATTR_PRIM_TYPES); + for(size_t i = 0; i < scene->meshes.size(); i++) { + Mesh *mesh = scene->meshes[i]; + mesh->attr_map_offset = attr_map_size; + attr_map_size += (mesh_attributes[i].size() + 1)*ATTR_PRIM_TYPES; + } - if(attr_map_stride == 0) + if(attr_map_size == 0) return; /* create attribute map */ - uint4 *attr_map = dscene->attributes_map.alloc(attr_map_stride*scene->objects.size()); + uint4 *attr_map = dscene->attributes_map.alloc(attr_map_size*scene->meshes.size()); memset(attr_map, 0, dscene->attributes_map.size()*sizeof(uint)); - for(size_t i = 0; i < scene->objects.size(); i++) { - Object *object = scene->objects[i]; - Mesh *mesh = object->mesh; - - /* find mesh attributes */ - size_t j; - - for(j = 0; j < scene->meshes.size(); j++) - if(scene->meshes[j] == mesh) - break; - - AttributeRequestSet& attributes = mesh_attributes[j]; + for(size_t i = 0; i < scene->meshes.size(); i++) { + Mesh *mesh = scene->meshes[i]; + AttributeRequestSet& attributes = mesh_attributes[i]; /* set object attributes */ - int index = i*attr_map_stride; + int index = mesh->attr_map_offset; foreach(AttributeRequest& req, attributes.requests) { uint id; @@ -1358,7 +1354,6 @@ void MeshManager::update_svm_attributes(Device *, DeviceScene *dscene, Scene *sc } /* copy to device */ - dscene->data.bvh.attributes_map_stride = attr_map_stride; dscene->attributes_map.copy_to_device(); } @@ -1625,6 +1620,12 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene, if(dscene->attributes_uchar4.size()) { dscene->attributes_uchar4.copy_to_device(); } + + if(progress.get_cancel()) return; + + /* After mesh attributes and patch tables have been copied to device memory, + * we need to update offsets in the objects. */ + scene->object_manager->device_update_mesh_offsets(device, dscene, scene); } void MeshManager::mesh_calc_offset(Scene *scene) @@ -2042,10 +2043,6 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen } if(progress.get_cancel()) return; - /* after mesh data has been copied to device memory we need to update - * offsets for patch tables as this can't be known before hand */ - scene->object_manager->device_update_patch_map_offsets(device, dscene, scene); - device_update_attributes(device, dscene, scene, progress); if(progress.get_cancel()) return; diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h index 30f5e9063e6..07d8bbdbf31 100644 --- a/intern/cycles/render/mesh.h +++ b/intern/cycles/render/mesh.h @@ -250,6 +250,8 @@ public: size_t face_offset; size_t corner_offset; + size_t attr_map_offset; + size_t num_subd_verts; /* Functions */ diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 3b93b0c0d1e..a12a0d297f0 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -641,7 +641,7 @@ void ObjectManager::device_update_flags(Device *, dscene->object_flag.copy_to_device(); } -void ObjectManager::device_update_patch_map_offsets(Device *, DeviceScene *dscene, Scene *scene) +void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Scene *scene) { if(scene->objects.size() == 0) { return; @@ -650,12 +650,11 @@ void ObjectManager::device_update_patch_map_offsets(Device *, DeviceScene *dscen uint4* objects = (uint4*)dscene->objects.data(); bool update = false; - int object_index = 0; - foreach(Object *object, scene->objects) { - int offset = object_index*OBJECT_SIZE + 11; + foreach(Object *object, scene->objects) { Mesh* mesh = object->mesh; + int offset = object_index*OBJECT_SIZE + 11; if(mesh->patch_table) { uint patch_map_offset = 2*(mesh->patch_table_offset + mesh->patch_table->total_size() - @@ -667,6 +666,11 @@ void ObjectManager::device_update_patch_map_offsets(Device *, DeviceScene *dscen } } + if(objects[offset].y != mesh->attr_map_offset) { + objects[offset].y = mesh->attr_map_offset; + update = true; + } + object_index++; } diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index 6927bbfe4c7..9f86c342acd 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -104,7 +104,7 @@ public: Scene *scene, Progress& progress, bool bounds_valid = true); - void device_update_patch_map_offsets(Device *device, DeviceScene *dscene, Scene *scene); + void device_update_mesh_offsets(Device *device, DeviceScene *dscene, Scene *scene); void device_free(Device *device, DeviceScene *dscene); |