diff options
-rw-r--r-- | intern/cycles/bvh/bvh.cpp | 88 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh.h | 8 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_motion_triangle.h | 32 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_triangle.h | 61 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_triangle_intersect.h | 28 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_textures.h | 6 | ||||
-rw-r--r-- | intern/cycles/render/mesh.cpp | 181 | ||||
-rw-r--r-- | intern/cycles/render/mesh.h | 41 | ||||
-rw-r--r-- | intern/cycles/render/scene.h | 6 |
9 files changed, 275 insertions, 176 deletions
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index 311d7296c65..5669bab857c 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -121,7 +121,7 @@ void BVH::refit(Progress& progress) /* Triangles */ -void BVH::pack_triangle(int idx, float4 storage[3]) +void BVH::pack_triangle(int idx, float4 tri_verts[3]) { int tob = pack.prim_object[idx]; assert(tob >= 0 && tob < objects.size()); @@ -129,49 +129,58 @@ void BVH::pack_triangle(int idx, float4 storage[3]) int tidx = pack.prim_index[idx]; Mesh::Triangle t = mesh->get_triangle(tidx); - const float3* vpos = &mesh->verts[0]; + const float3 *vpos = &mesh->verts[0]; float3 v0 = vpos[t.v[0]]; float3 v1 = vpos[t.v[1]]; float3 v2 = vpos[t.v[2]]; - storage[0] = float3_to_float4(v0); - storage[1] = float3_to_float4(v1); - storage[2] = float3_to_float4(v2); + tri_verts[0] = float3_to_float4(v0); + tri_verts[1] = float3_to_float4(v1); + tri_verts[2] = float3_to_float4(v2); } void BVH::pack_primitives() { - int nsize = TRI_NODE_SIZE; - size_t tidx_size = pack.prim_index.size(); - - pack.tri_storage.clear(); - pack.tri_storage.resize(tidx_size * nsize); + const size_t tidx_size = pack.prim_index.size(); + size_t num_prim_triangles = 0; + /* Count number of triangles primitives in BVH. */ + for(unsigned int i = 0; i < tidx_size; i++) { + if((pack.prim_index[i] != -1)) { + if ((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) { + ++num_prim_triangles; + } + } + } + /* Reserve size for arrays. */ + pack.prim_tri_index.clear(); + pack.prim_tri_index.resize(tidx_size); + pack.prim_tri_verts.clear(); + pack.prim_tri_verts.resize(num_prim_triangles * 3); pack.prim_visibility.clear(); pack.prim_visibility.resize(tidx_size); - + /* Fill in all the arrays. */ + size_t prim_triangle_index = 0; for(unsigned int i = 0; i < tidx_size; i++) { if(pack.prim_index[i] != -1) { - float4 storage[3]; + int tob = pack.prim_object[i]; + Object *ob = objects[tob]; - if(pack.prim_type[i] & PRIMITIVE_TRIANGLE) { - pack_triangle(i, storage); + if((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) { + pack_triangle(i, (float4*)&pack.prim_tri_verts[3 * prim_triangle_index]); + pack.prim_tri_index[i] = 3 * prim_triangle_index; + ++prim_triangle_index; } else { - /* Avoid use of uninitialized memory. */ - memset(&storage, 0, sizeof(storage)); + pack.prim_tri_index[i] = -1; } - memcpy(&pack.tri_storage[i * nsize], storage, sizeof(float4)*3); - - int tob = pack.prim_object[i]; - Object *ob = objects[tob]; pack.prim_visibility[i] = ob->visibility; if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE) pack.prim_visibility[i] |= PATH_RAY_CURVE; } else { - memset(&pack.tri_storage[i * nsize], 0, sizeof(float4)*3); + pack.prim_tri_index[i] = -1; pack.prim_visibility[i] = 0; } } @@ -208,10 +217,10 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) /* reserve */ size_t prim_index_size = pack.prim_index.size(); - size_t tri_storage_size = pack.tri_storage.size(); + size_t prim_tri_verts_size = pack.prim_tri_verts.size(); size_t pack_prim_index_offset = prim_index_size; - size_t pack_tri_storage_offset = tri_storage_size; + size_t pack_prim_tri_verts_offset = prim_tri_verts_size; size_t pack_nodes_offset = nodes_size; size_t pack_leaf_nodes_offset = leaf_nodes_size; size_t object_offset = 0; @@ -225,7 +234,7 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) if(mesh->need_build_bvh()) { if(mesh_map.find(mesh) == mesh_map.end()) { prim_index_size += bvh->pack.prim_index.size(); - tri_storage_size += bvh->pack.tri_storage.size(); + prim_tri_verts_size += bvh->pack.prim_tri_verts.size(); nodes_size += bvh->pack.nodes.size(); leaf_nodes_size += bvh->pack.leaf_nodes.size(); @@ -240,7 +249,8 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) pack.prim_type.resize(prim_index_size); pack.prim_object.resize(prim_index_size); pack.prim_visibility.resize(prim_index_size); - pack.tri_storage.resize(tri_storage_size); + pack.prim_tri_verts.resize(prim_tri_verts_size); + pack.prim_tri_index.resize(prim_index_size); pack.nodes.resize(nodes_size); pack.leaf_nodes.resize(leaf_nodes_size); pack.object_node.resize(objects.size()); @@ -249,7 +259,8 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) int *pack_prim_type = (pack.prim_type.size())? &pack.prim_type[0]: NULL; int *pack_prim_object = (pack.prim_object.size())? &pack.prim_object[0]: NULL; uint *pack_prim_visibility = (pack.prim_visibility.size())? &pack.prim_visibility[0]: NULL; - float4 *pack_tri_storage = (pack.tri_storage.size())? &pack.tri_storage[0]: NULL; + float4 *pack_prim_tri_verts = (pack.prim_tri_verts.size())? &pack.prim_tri_verts[0]: NULL; + uint *pack_prim_tri_index = (pack.prim_tri_index.size())? &pack.prim_tri_index[0]: NULL; int4 *pack_nodes = (pack.nodes.size())? &pack.nodes[0]: NULL; int4 *pack_leaf_nodes = (pack.leaf_nodes.size())? &pack.leaf_nodes[0]: NULL; @@ -290,18 +301,24 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) mesh_map[mesh] = pack.object_node[object_offset-1]; - /* merge primitive and object indexes */ + /* merge primitive, object and triangle indexes */ if(bvh->pack.prim_index.size()) { size_t bvh_prim_index_size = bvh->pack.prim_index.size(); int *bvh_prim_index = &bvh->pack.prim_index[0]; int *bvh_prim_type = &bvh->pack.prim_type[0]; uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0]; + uint *bvh_prim_tri_index = &bvh->pack.prim_tri_index[0]; for(size_t i = 0; i < bvh_prim_index_size; i++) { - if(bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) + if(bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) { pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_curve_offset; - else + pack_prim_tri_index[pack_prim_index_offset] = -1; + } + else { pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset; + pack_prim_tri_index[pack_prim_index_offset] = + bvh_prim_tri_index[i] + pack_prim_tri_verts_offset; + } pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i]; pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i]; @@ -310,12 +327,13 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) } } - /* merge triangle intersection data */ - if(bvh->pack.tri_storage.size()) { - memcpy(pack_tri_storage + pack_tri_storage_offset, - &bvh->pack.tri_storage[0], - bvh->pack.tri_storage.size()*sizeof(float4)); - pack_tri_storage_offset += bvh->pack.tri_storage.size(); + /* Merge triangle vertices data. */ + if(bvh->pack.prim_tri_verts.size()) { + const size_t prim_tri_size = bvh->pack.prim_tri_verts.size(); + memcpy(pack_prim_tri_verts + pack_prim_tri_verts_offset, + &bvh->pack.prim_tri_verts[0], + prim_tri_size*sizeof(float4)); + pack_prim_tri_verts_offset += prim_tri_size; } /* merge nodes */ diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h index b1655f0c5d0..da7c9f3834d 100644 --- a/intern/cycles/bvh/bvh.h +++ b/intern/cycles/bvh/bvh.h @@ -52,8 +52,10 @@ struct PackedBVH { array<int4> leaf_nodes; /* object index to BVH node index mapping for instances */ array<int> object_node; - /* Aligned triangle storage for fatser lookup in the kernel. */ - array<float4> tri_storage; + /* Mapping from primitive index to index in triangle array. */ + array<uint> prim_tri_index; + /* Continuous storage of triangle vertices. */ + array<float4> prim_tri_verts; /* primitive type - triangle or strand */ array<int> prim_type; /* visibility visibilitys for primitives */ @@ -91,7 +93,7 @@ public: protected: BVH(const BVHParams& params, const vector<Object*>& objects); - /* triangles and strands*/ + /* triangles and strands */ void pack_primitives(); void pack_triangle(int idx, float4 storage[3]); diff --git a/intern/cycles/kernel/geom/geom_motion_triangle.h b/intern/cycles/kernel/geom/geom_motion_triangle.h index ffe55529110..2fb8e219884 100644 --- a/intern/cycles/kernel/geom/geom_motion_triangle.h +++ b/intern/cycles/kernel/geom/geom_motion_triangle.h @@ -47,13 +47,13 @@ ccl_device_inline int find_attribute_motion(KernelGlobals *kg, int object, uint return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z; } -ccl_device_inline void motion_triangle_verts_for_step(KernelGlobals *kg, float3 tri_vindex, int offset, int numverts, int numsteps, int step, float3 verts[3]) +ccl_device_inline void motion_triangle_verts_for_step(KernelGlobals *kg, uint4 tri_vindex, int offset, int numverts, int numsteps, int step, float3 verts[3]) { if(step == numsteps) { /* center step: regular vertex location */ - verts[0] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x))); - verts[1] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y))); - verts[2] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z))); + verts[0] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0)); + verts[1] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1)); + verts[2] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2)); } else { /* center step not store in this array */ @@ -62,19 +62,19 @@ ccl_device_inline void motion_triangle_verts_for_step(KernelGlobals *kg, float3 offset += step*numverts; - verts[0] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.x))); - verts[1] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.y))); - verts[2] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.z))); + verts[0] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.x)); + verts[1] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.y)); + verts[2] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.z)); } } -ccl_device_inline void motion_triangle_normals_for_step(KernelGlobals *kg, float3 tri_vindex, int offset, int numverts, int numsteps, int step, float3 normals[3]) +ccl_device_inline void motion_triangle_normals_for_step(KernelGlobals *kg, uint4 tri_vindex, int offset, int numverts, int numsteps, int step, float3 normals[3]) { if(step == numsteps) { /* center step: regular vertex location */ - normals[0] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.x))); - normals[1] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.y))); - normals[2] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.z))); + normals[0] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x)); + normals[1] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y)); + normals[2] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z)); } else { /* center step not stored in this array */ @@ -83,9 +83,9 @@ ccl_device_inline void motion_triangle_normals_for_step(KernelGlobals *kg, float offset += step*numverts; - normals[0] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.x))); - normals[1] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.y))); - normals[2] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.z))); + normals[0] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.x)); + normals[1] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.y)); + normals[2] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.z)); } } @@ -107,7 +107,7 @@ ccl_device_inline void motion_triangle_vertices(KernelGlobals *kg, int object, i /* fetch vertex coordinates */ float3 next_verts[3]; - float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, prim)); + uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts); motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step+1, next_verts); @@ -259,7 +259,7 @@ ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals *kg, ShaderD /* fetch vertex coordinates */ float3 verts[3], next_verts[3]; - float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim))); + uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim)); motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts); motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step+1, next_verts); diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h index 995dfac5b09..0c2351e1d1b 100644 --- a/intern/cycles/kernel/geom/geom_triangle.h +++ b/intern/cycles/kernel/geom/geom_triangle.h @@ -27,12 +27,11 @@ CCL_NAMESPACE_BEGIN ccl_device_inline float3 triangle_normal(KernelGlobals *kg, ShaderData *sd) { /* load triangle vertices */ - float4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim)); + const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim)); + const float3 v0 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0)); + const float3 v1 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1)); + const float3 v2 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2)); - float3 v0 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x))); - float3 v1 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y))); - float3 v2 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z))); - /* return normal */ if(ccl_fetch(sd, flag) & SD_NEGATIVE_SCALE_APPLIED) return normalize(cross(v2 - v0, v1 - v0)); @@ -44,11 +43,10 @@ ccl_device_inline float3 triangle_normal(KernelGlobals *kg, ShaderData *sd) ccl_device_inline void triangle_point_normal(KernelGlobals *kg, int object, int prim, float u, float v, float3 *P, float3 *Ng, int *shader) { /* load triangle vertices */ - float4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); - - float3 v0 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x))); - float3 v1 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y))); - float3 v2 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z))); + const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); + float3 v0 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0)); + float3 v1 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1)); + float3 v2 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2)); /* compute point */ float t = 1.0f - u - v; @@ -71,11 +69,10 @@ ccl_device_inline void triangle_point_normal(KernelGlobals *kg, int object, int ccl_device_inline void triangle_vertices(KernelGlobals *kg, int prim, float3 P[3]) { - float4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); - - P[0] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x))); - P[1] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y))); - P[2] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z))); + const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); + P[0] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0)); + P[1] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1)); + P[2] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2)); } /* Interpolate smooth vertex normal from vertices */ @@ -83,11 +80,10 @@ ccl_device_inline void triangle_vertices(KernelGlobals *kg, int prim, float3 P[3 ccl_device_inline float3 triangle_smooth_normal(KernelGlobals *kg, int prim, float u, float v) { /* load triangle vertices */ - float4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); - - float3 n0 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.x))); - float3 n1 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.y))); - float3 n2 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.z))); + const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); + float3 n0 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x)); + float3 n1 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y)); + float3 n2 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z)); return normalize((1.0f - u - v)*n2 + u*n0 + v*n1); } @@ -97,11 +93,10 @@ ccl_device_inline float3 triangle_smooth_normal(KernelGlobals *kg, int prim, flo ccl_device_inline void triangle_dPdudv(KernelGlobals *kg, int prim, ccl_addr_space float3 *dPdu, ccl_addr_space float3 *dPdv) { /* fetch triangle vertex coordinates */ - float4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); - - float3 p0 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x))); - float3 p1 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y))); - float3 p2 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z))); + const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); + const float3 p0 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0)); + const float3 p1 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1)); + const float3 p2 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2)); /* compute derivatives of P w.r.t. uv */ *dPdu = (p0 - p2); @@ -119,11 +114,11 @@ ccl_device float triangle_attribute_float(KernelGlobals *kg, const ShaderData *s return kernel_tex_fetch(__attributes_float, offset + ccl_fetch(sd, prim)); } else if(elem == ATTR_ELEMENT_VERTEX || elem == ATTR_ELEMENT_VERTEX_MOTION) { - float4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim)); + uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim)); - float f0 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.x)); - float f1 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.y)); - float f2 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.z)); + float f0 = kernel_tex_fetch(__attributes_float, offset + tri_vindex.x); + float f1 = kernel_tex_fetch(__attributes_float, offset + tri_vindex.y); + float f2 = kernel_tex_fetch(__attributes_float, offset + tri_vindex.z); #ifdef __RAY_DIFFERENTIALS__ if(dx) *dx = ccl_fetch(sd, du).dx*f0 + ccl_fetch(sd, dv).dx*f1 - (ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*f2; @@ -162,11 +157,11 @@ ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + ccl_fetch(sd, prim))); } else if(elem == ATTR_ELEMENT_VERTEX || elem == ATTR_ELEMENT_VERTEX_MOTION) { - float4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim)); + uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim)); - float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.x))); - float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.y))); - float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.z))); + float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.x)); + float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.y)); + float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.z)); #ifdef __RAY_DIFFERENTIALS__ if(dx) *dx = ccl_fetch(sd, du).dx*f0 + ccl_fetch(sd, dv).dx*f1 - (ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*f2; diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h index b6dfc769012..fc081bda525 100644 --- a/intern/cycles/kernel/geom/geom_triangle_intersect.h +++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h @@ -106,9 +106,10 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, const float Sz = isect_precalc->Sz; /* Calculate vertices relative to ray origin. */ - const float4 tri_a = kernel_tex_fetch(__tri_storage, triAddr*TRI_NODE_SIZE+0), - tri_b = kernel_tex_fetch(__tri_storage, triAddr*TRI_NODE_SIZE+1), - tri_c = kernel_tex_fetch(__tri_storage, triAddr*TRI_NODE_SIZE+2); + const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, triAddr); + const float4 tri_a = kernel_tex_fetch(__prim_tri_verts, tri_vindex+0), + tri_b = kernel_tex_fetch(__prim_tri_verts, tri_vindex+1), + tri_c = kernel_tex_fetch(__prim_tri_verts, tri_vindex+2); const float3 A = make_float3(tri_a.x - P.x, tri_a.y - P.y, tri_a.z - P.z); const float3 B = make_float3(tri_b.x - P.x, tri_b.y - P.y, tri_b.z - P.z); const float3 C = make_float3(tri_c.x - P.x, tri_c.y - P.y, tri_c.z - P.z); @@ -202,9 +203,10 @@ ccl_device_inline void triangle_intersect_subsurface( const float Sz = isect_precalc->Sz; /* Calculate vertices relative to ray origin. */ - const float4 tri_a = kernel_tex_fetch(__tri_storage, triAddr*TRI_NODE_SIZE+0), - tri_b = kernel_tex_fetch(__tri_storage, triAddr*TRI_NODE_SIZE+1), - tri_c = kernel_tex_fetch(__tri_storage, triAddr*TRI_NODE_SIZE+2); + const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, triAddr); + const float4 tri_a = kernel_tex_fetch(__prim_tri_verts, tri_vindex+0), + tri_b = kernel_tex_fetch(__prim_tri_verts, tri_vindex+1), + tri_c = kernel_tex_fetch(__prim_tri_verts, tri_vindex+2); const float3 A = make_float3(tri_a.x - P.x, tri_a.y - P.y, tri_a.z - P.z); const float3 B = make_float3(tri_b.x - P.x, tri_b.y - P.y, tri_b.z - P.z); const float3 C = make_float3(tri_c.x - P.x, tri_c.y - P.y, tri_c.z - P.z); @@ -324,9 +326,10 @@ ccl_device_inline float3 triangle_refine(KernelGlobals *kg, P = P + D*t; - const float4 tri_a = kernel_tex_fetch(__tri_storage, isect->prim*TRI_NODE_SIZE+0), - tri_b = kernel_tex_fetch(__tri_storage, isect->prim*TRI_NODE_SIZE+1), - tri_c = kernel_tex_fetch(__tri_storage, isect->prim*TRI_NODE_SIZE+2); + const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, isect->prim); + const float4 tri_a = kernel_tex_fetch(__prim_tri_verts, tri_vindex+0), + tri_b = kernel_tex_fetch(__prim_tri_verts, tri_vindex+1), + tri_c = kernel_tex_fetch(__prim_tri_verts, tri_vindex+2); float3 edge1 = make_float3(tri_a.x - tri_c.x, tri_a.y - tri_c.y, tri_a.z - tri_c.z); float3 edge2 = make_float3(tri_b.x - tri_c.x, tri_b.y - tri_c.y, tri_b.z - tri_c.z); float3 tvec = make_float3(P.x - tri_c.x, P.y - tri_c.y, P.z - tri_c.z); @@ -381,9 +384,10 @@ ccl_device_inline float3 triangle_refine_subsurface(KernelGlobals *kg, P = P + D*t; #ifdef __INTERSECTION_REFINE__ - const float4 tri_a = kernel_tex_fetch(__tri_storage, isect->prim*TRI_NODE_SIZE+0), - tri_b = kernel_tex_fetch(__tri_storage, isect->prim*TRI_NODE_SIZE+1), - tri_c = kernel_tex_fetch(__tri_storage, isect->prim*TRI_NODE_SIZE+2); + const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, isect->prim); + const float4 tri_a = kernel_tex_fetch(__prim_tri_verts, tri_vindex+0), + tri_b = kernel_tex_fetch(__prim_tri_verts, tri_vindex+1), + tri_c = kernel_tex_fetch(__prim_tri_verts, tri_vindex+2); float3 edge1 = make_float3(tri_a.x - tri_c.x, tri_a.y - tri_c.y, tri_a.z - tri_c.z); float3 edge2 = make_float3(tri_b.x - tri_c.x, tri_b.y - tri_c.y, tri_b.z - tri_c.z); float3 tvec = make_float3(P.x - tri_c.x, P.y - tri_c.y, P.z - tri_c.z); diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h index 245d236ff97..5ba262c1044 100644 --- a/intern/cycles/kernel/kernel_textures.h +++ b/intern/cycles/kernel/kernel_textures.h @@ -25,7 +25,8 @@ /* bvh */ KERNEL_TEX(float4, texture_float4, __bvh_nodes) KERNEL_TEX(float4, texture_float4, __bvh_leaf_nodes) -KERNEL_TEX(float4, texture_float4, __tri_storage) +KERNEL_TEX(float4, texture_float4, __prim_tri_verts) +KERNEL_TEX(uint, texture_uint, __prim_tri_index) KERNEL_TEX(uint, texture_uint, __prim_type) KERNEL_TEX(uint, texture_uint, __prim_visibility) KERNEL_TEX(uint, texture_uint, __prim_index) @@ -39,8 +40,7 @@ KERNEL_TEX(float4, texture_float4, __objects_vector) /* triangles */ KERNEL_TEX(uint, texture_uint, __tri_shader) KERNEL_TEX(float4, texture_float4, __tri_vnormal) -KERNEL_TEX(float4, texture_float4, __tri_vindex) -KERNEL_TEX(float4, texture_float4, __tri_verts) +KERNEL_TEX(uint4, texture_uint4, __tri_vindex) /* curves */ KERNEL_TEX(float4, texture_float4, __curves) diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 764a925983e..4e1e36d7658 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -472,30 +472,19 @@ void Mesh::pack_normals(Scene *scene, uint *tri_shader, float4 *vnormal) } } -void Mesh::pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset) +void Mesh::pack_verts(const vector<uint>& tri_prim_index, + uint4 *tri_vindex, + size_t vert_offset, + size_t tri_offset) { - size_t verts_size = verts.size(); - - if(verts_size) { - float3 *verts_ptr = &verts[0]; - - for(size_t i = 0; i < verts_size; i++) { - float3 p = verts_ptr[i]; - tri_verts[i] = make_float4(p.x, p.y, p.z, 0.0f); - } - } - - size_t triangles_size = num_triangles(); - + const size_t triangles_size = num_triangles(); if(triangles_size) { for(size_t i = 0; i < triangles_size; i++) { Triangle t = get_triangle(i); - - tri_vindex[i] = make_float4( - __int_as_float(t.v[0] + vert_offset), - __int_as_float(t.v[1] + vert_offset), - __int_as_float(t.v[2] + vert_offset), - 0); + tri_vindex[i] = make_uint4(t.v[0] + vert_offset, + t.v[1] + vert_offset, + t.v[2] + vert_offset, + tri_prim_index[i + tri_offset]); } } } @@ -1070,42 +1059,82 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene, } } -void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) +void MeshManager::mesh_calc_offset(Scene *scene) { - /* count and update offsets */ size_t vert_size = 0; size_t tri_size = 0; - size_t curve_key_size = 0; size_t curve_size = 0; foreach(Mesh *mesh, scene->meshes) { mesh->vert_offset = vert_size; mesh->tri_offset = tri_size; - mesh->curvekey_offset = curve_key_size; mesh->curve_offset = curve_size; vert_size += mesh->verts.size(); tri_size += mesh->num_triangles(); - curve_key_size += mesh->curve_keys.size(); curve_size += mesh->num_curves(); } +} +void MeshManager::device_update_mesh(Device *device, + DeviceScene *dscene, + Scene *scene, + bool for_displacement, + Progress& progress) +{ + /* Count. */ + size_t vert_size = 0; + size_t tri_size = 0; + size_t curve_key_size = 0; + size_t curve_size = 0; + foreach(Mesh *mesh, scene->meshes) { + vert_size += mesh->verts.size(); + tri_size += mesh->num_triangles(); + curve_key_size += mesh->curve_keys.size(); + curve_size += mesh->num_curves(); + } + /* Create mapping from triangle to primitive triangle array. */ + vector<uint> tri_prim_index(tri_size); + if(for_displacement) { + /* For displacement kernels we do some trickery to make them believe + * we've got all required data ready. However, that data is different + * from final render kernels since we don't have BVH yet, so can't + * really use same semantic of arrays. + */ + foreach(Mesh *mesh, scene->meshes) { + for(size_t i = 0; i < mesh->num_triangles(); ++i) { + tri_prim_index[i + mesh->tri_offset] = 3 * (i + mesh->tri_offset); + } + } + } + else { + PackedBVH& pack = bvh->pack; + for(size_t i = 0; i < pack.prim_index.size(); ++i) { + if ((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) { + tri_prim_index[pack.prim_index[i]] = pack.prim_tri_index[i]; + } + } + } + /* Fill in all the arrays. */ if(tri_size != 0) { /* normals */ progress.set_status("Updating Mesh", "Computing normals"); uint *tri_shader = dscene->tri_shader.resize(tri_size); float4 *vnormal = dscene->tri_vnormal.resize(vert_size); - float4 *tri_verts = dscene->tri_verts.resize(vert_size); - float4 *tri_vindex = dscene->tri_vindex.resize(tri_size); + uint4 *tri_vindex = dscene->tri_vindex.resize(tri_size); foreach(Mesh *mesh, scene->meshes) { - mesh->pack_normals(scene, &tri_shader[mesh->tri_offset], &vnormal[mesh->vert_offset]); - mesh->pack_verts(&tri_verts[mesh->vert_offset], &tri_vindex[mesh->tri_offset], mesh->vert_offset); - + mesh->pack_normals(scene, + &tri_shader[mesh->tri_offset], + &vnormal[mesh->vert_offset]); + mesh->pack_verts(tri_prim_index, + &tri_vindex[mesh->tri_offset], + mesh->vert_offset, + mesh->tri_offset); if(progress.get_cancel()) return; } @@ -1114,10 +1143,8 @@ void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene device->tex_alloc("__tri_shader", dscene->tri_shader); device->tex_alloc("__tri_vnormal", dscene->tri_vnormal); - device->tex_alloc("__tri_verts", dscene->tri_verts); device->tex_alloc("__tri_vindex", dscene->tri_vindex); } - if(curve_size != 0) { progress.set_status("Updating Mesh", "Copying Strands to device"); @@ -1132,6 +1159,19 @@ void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene device->tex_alloc("__curve_keys", dscene->curve_keys); device->tex_alloc("__curves", dscene->curves); } + if(for_displacement) { + float4 *prim_tri_verts = dscene->prim_tri_verts.resize(tri_size * 3); + foreach(Mesh *mesh, scene->meshes) { + for(size_t i = 0; i < mesh->num_triangles(); ++i) { + Mesh::Triangle t = mesh->get_triangle(i); + size_t offset = 3 * (i + mesh->tri_offset); + prim_tri_verts[offset + 0] = float3_to_float4(mesh->verts[t.v[0]]); + prim_tri_verts[offset + 1] = float3_to_float4(mesh->verts[t.v[1]]); + prim_tri_verts[offset + 2] = float3_to_float4(mesh->verts[t.v[2]]); + } + } + device->tex_alloc("__prim_tri_verts", dscene->prim_tri_verts); + } } void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) @@ -1170,9 +1210,13 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene * dscene->object_node.reference((uint*)&pack.object_node[0], pack.object_node.size()); device->tex_alloc("__object_node", dscene->object_node); } - if(pack.tri_storage.size()) { - dscene->tri_storage.reference(&pack.tri_storage[0], pack.tri_storage.size()); - device->tex_alloc("__tri_storage", dscene->tri_storage); + if(pack.prim_tri_index.size()) { + dscene->prim_tri_index.reference((uint*)&pack.prim_tri_index[0], pack.prim_tri_index.size()); + device->tex_alloc("__prim_tri_index", dscene->prim_tri_index); + } + if(pack.prim_tri_verts.size()) { + dscene->prim_tri_verts.reference((float4*)&pack.prim_tri_verts[0], pack.prim_tri_verts.size()); + device->tex_alloc("__prim_tri_verts", dscene->prim_tri_verts); } if(pack.prim_type.size()) { dscene->prim_type.reference((uint*)&pack.prim_type[0], pack.prim_type.size()); @@ -1273,7 +1317,7 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen VLOG(1) << "Total " << scene->meshes.size() << " meshes."; - /* update normals */ + /* Update normals. */ foreach(Mesh *mesh, scene->meshes) { foreach(Shader *shader, mesh->used_shaders) { if(shader->need_update_attributes) @@ -1289,17 +1333,17 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen } /* Update images needed for true displacement. */ - bool need_displacement_images = false; + bool true_displacement_used = false; bool old_need_object_flags_update = false; foreach(Mesh *mesh, scene->meshes) { if(mesh->need_update && mesh->displacement_method != Mesh::DISPLACE_BUMP) { - need_displacement_images = true; + true_displacement_used = true; break; } } - if(need_displacement_images) { + if(true_displacement_used) { VLOG(1) << "Updating images used for true displacement."; device_update_displacement_images(device, dscene, scene, progress); old_need_object_flags_update = scene->object_manager->need_flags_update; @@ -1310,45 +1354,47 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen false); } - /* device update */ + /* Device update. */ device_free(device, dscene); - device_update_mesh(device, dscene, scene, progress); + mesh_calc_offset(scene); + if(true_displacement_used) { + device_update_mesh(device, dscene, scene, true, progress); + } if(progress.get_cancel()) return; device_update_attributes(device, dscene, scene, progress); if(progress.get_cancel()) return; - /* update displacement */ + /* Update displacement. */ bool displacement_done = false; - - foreach(Mesh *mesh, scene->meshes) - if(mesh->need_update && displace(device, dscene, scene, mesh, progress)) + foreach(Mesh *mesh, scene->meshes) { + if(mesh->need_update && + displace(device, dscene, scene, mesh, progress)) + { displacement_done = true; + } + } - /* todo: properly handle cancel halfway displacement */ + /* TODO: properly handle cancel halfway displacement */ if(progress.get_cancel()) return; - /* device re-update after displacement */ + /* Device re-update after displacement. */ if(displacement_done) { device_free(device, dscene); - device_update_mesh(device, dscene, scene, progress); - if(progress.get_cancel()) return; - device_update_attributes(device, dscene, scene, progress); if(progress.get_cancel()) return; } - /* update bvh */ + /* Update bvh. */ size_t i = 0, num_bvh = 0; - - foreach(Mesh *mesh, scene->meshes) - if(mesh->need_update && mesh->need_build_bvh()) + foreach(Mesh *mesh, scene->meshes) { + if(mesh->need_update && mesh->need_build_bvh()) { num_bvh++; - + } + } TaskPool pool; - foreach(Mesh *mesh, scene->meshes) { if(mesh->need_update) { pool.push(function_bind(&Mesh::compute_bvh, @@ -1362,14 +1408,14 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen } } } - TaskPool::Summary summary; pool.wait_work(&summary); VLOG(2) << "Objects BVH build pool statistics:\n" << summary.full_report(); - foreach(Shader *shader, scene->shaders) + foreach(Shader *shader, scene->shaders) { shader->need_update_attributes = false; + } #ifdef __OBJECT_MOTION__ Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading); @@ -1378,18 +1424,23 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen bool motion_blur = false; #endif - /* update obejcts */ + /* Update objects. */ vector<Object *> volume_objects; - foreach(Object *object, scene->objects) + foreach(Object *object, scene->objects) { object->compute_bounds(motion_blur); + } if(progress.get_cancel()) return; device_update_bvh(device, dscene, scene, progress); + if(progress.get_cancel()) return; + + device_update_mesh(device, dscene, scene, false, progress); + if(progress.get_cancel()) return; need_update = false; - if(need_displacement_images) { + if(true_displacement_used) { /* Re-tag flags for update, so they're re-evaluated * for meshes with correct bounding boxes. * @@ -1405,7 +1456,8 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene) device->tex_free(dscene->bvh_nodes); device->tex_free(dscene->bvh_leaf_nodes); device->tex_free(dscene->object_node); - device->tex_free(dscene->tri_storage); + device->tex_free(dscene->prim_tri_verts); + device->tex_free(dscene->prim_tri_index); device->tex_free(dscene->prim_type); device->tex_free(dscene->prim_visibility); device->tex_free(dscene->prim_index); @@ -1413,7 +1465,6 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene) device->tex_free(dscene->tri_shader); device->tex_free(dscene->tri_vnormal); device->tex_free(dscene->tri_vindex); - device->tex_free(dscene->tri_verts); device->tex_free(dscene->curves); device->tex_free(dscene->curve_keys); device->tex_free(dscene->attributes_map); @@ -1423,7 +1474,8 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene) dscene->bvh_nodes.clear(); dscene->object_node.clear(); - dscene->tri_storage.clear(); + dscene->prim_tri_verts.clear(); + dscene->prim_tri_index.clear(); dscene->prim_type.clear(); dscene->prim_visibility.clear(); dscene->prim_index.clear(); @@ -1431,7 +1483,6 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene) dscene->tri_shader.clear(); dscene->tri_vnormal.clear(); dscene->tri_vindex.clear(); - dscene->tri_verts.clear(); dscene->curves.clear(); dscene->curve_keys.clear(); dscene->attributes_map.clear(); diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h index edad6d32f00..bc3d30af499 100644 --- a/intern/cycles/render/mesh.h +++ b/intern/cycles/render/mesh.h @@ -167,7 +167,10 @@ public: void add_vertex_normals(); void pack_normals(Scene *scene, uint *shader, float4 *vnormal); - void pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset); + void pack_verts(const vector<uint>& tri_prim_index, + uint4 *tri_vindex, + size_t vert_offset, + size_t tri_offset); void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset); void compute_bvh(SceneParams *params, Progress *progress, int n, int total); @@ -213,15 +216,41 @@ public: void update_svm_attributes(Device *device, DeviceScene *dscene, Scene *scene, vector<AttributeRequestSet>& mesh_attributes); void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); - void device_update_object(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); - void device_update_mesh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); - void device_update_attributes(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); - void device_update_bvh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); void device_update_flags(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); - void device_update_displacement_images(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); + void device_free(Device *device, DeviceScene *dscene); void tag_update(Scene *scene); + +protected: + /* Calculate verts/triangles/curves offsets in global arrays. */ + void mesh_calc_offset(Scene *scene); + + void device_update_object(Device *device, + DeviceScene *dscene, + Scene *scene, + Progress& progress); + + void device_update_mesh(Device *device, + DeviceScene *dscene, + Scene *scene, + bool for_displacement, + Progress& progress); + + void device_update_attributes(Device *device, + DeviceScene *dscene, + Scene *scene, + Progress& progress); + + void device_update_bvh(Device *device, + DeviceScene *dscene, + Scene *scene, + Progress& progress); + + void device_update_displacement_images(Device *device, + DeviceScene *dscene, + Scene *scene, + Progress& progress); }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index b821e2b6475..925e84ad96d 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -63,7 +63,8 @@ public: device_vector<float4> bvh_nodes; device_vector<float4> bvh_leaf_nodes; device_vector<uint> object_node; - device_vector<float4> tri_storage; + device_vector<uint> prim_tri_index; + device_vector<float4> prim_tri_verts; device_vector<uint> prim_type; device_vector<uint> prim_visibility; device_vector<uint> prim_index; @@ -72,8 +73,7 @@ public: /* mesh */ device_vector<uint> tri_shader; device_vector<float4> tri_vnormal; - device_vector<float4> tri_vindex; - device_vector<float4> tri_verts; + device_vector<uint4> tri_vindex; device_vector<float4> curves; device_vector<float4> curve_keys; |