Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht@blender.org>2022-01-13 19:15:30 +0300
committerBrecht Van Lommel <brecht@blender.org>2022-01-17 19:35:23 +0300
commit4d10a46e6368f0b48a901325b94ebd43b672db32 (patch)
treeda3a7e85d4a82f4d06b4852858dfc187a13c80c0 /intern
parenta25cfc5db2625d147c4f2d89584e6d87748a47bb (diff)
Cleanup: refactor BVH2 in preparation of self intersection skip
Move some logic out of triangle intersection functions and into BVH traversal, so we can share logic between primitives. Ref D12954
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/kernel/bvh/local.h26
-rw-r--r--intern/cycles/kernel/bvh/shadow_all.h53
-rw-r--r--intern/cycles/kernel/bvh/traversal.h48
-rw-r--r--intern/cycles/kernel/bvh/volume.h34
-rw-r--r--intern/cycles/kernel/bvh/volume_all.h32
-rw-r--r--intern/cycles/kernel/geom/motion_triangle_intersect.h25
-rw-r--r--intern/cycles/kernel/geom/triangle_intersect.h18
7 files changed, 134 insertions, 102 deletions
diff --git a/intern/cycles/kernel/bvh/local.h b/intern/cycles/kernel/bvh/local.h
index 79cde69699e..4d0e6aac901 100644
--- a/intern/cycles/kernel/bvh/local.h
+++ b/intern/cycles/kernel/bvh/local.h
@@ -148,12 +148,23 @@ ccl_device_inline
/* intersect ray against primitive */
for (; prim_addr < prim_addr2; prim_addr++) {
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+
+ /* Only intersect with matching object, for instanced objects we
+ * already know we are only intersecting the right object. */
+ if (object == OBJECT_NONE) {
+ if (kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
+ continue;
+ }
+ }
+
+ const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+
if (triangle_intersect_local(kg,
local_isect,
P,
dir,
- object,
local_object,
+ prim,
prim_addr,
isect_t,
lcg_state,
@@ -168,13 +179,24 @@ ccl_device_inline
/* intersect ray against primitive */
for (; prim_addr < prim_addr2; prim_addr++) {
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+
+ /* Only intersect with matching object, for instanced objects we
+ * already know we are only intersecting the right object. */
+ if (object == OBJECT_NONE) {
+ if (kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
+ continue;
+ }
+ }
+
+ const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+
if (motion_triangle_intersect_local(kg,
local_isect,
P,
dir,
ray->time,
- object,
local_object,
+ prim,
prim_addr,
isect_t,
lcg_state,
diff --git a/intern/cycles/kernel/bvh/shadow_all.h b/intern/cycles/kernel/bvh/shadow_all.h
index b0e799675e0..0fb86bfda77 100644
--- a/intern/cycles/kernel/bvh/shadow_all.h
+++ b/intern/cycles/kernel/bvh/shadow_all.h
@@ -146,7 +146,7 @@ ccl_device_inline
--stack_ptr;
/* primitive intersection */
- while (prim_addr < prim_addr2) {
+ for (; prim_addr < prim_addr2; prim_addr++) {
kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) ==
(type & PRIMITIVE_ALL));
bool hit;
@@ -156,16 +156,29 @@ ccl_device_inline
* might give a few % performance improvement */
Intersection isect ccl_optional_struct_init;
+ const int prim_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+
switch (type & PRIMITIVE_ALL) {
case PRIMITIVE_TRIANGLE: {
hit = triangle_intersect(
- kg, &isect, P, dir, t_max_current, visibility, object, prim_addr);
+ kg, &isect, P, dir, t_max_current, visibility, prim_object, prim, prim_addr);
break;
}
#if BVH_FEATURE(BVH_MOTION)
case PRIMITIVE_MOTION_TRIANGLE: {
- hit = motion_triangle_intersect(
- kg, &isect, P, dir, t_max_current, ray->time, visibility, object, prim_addr);
+ hit = motion_triangle_intersect(kg,
+ &isect,
+ P,
+ dir,
+ t_max_current,
+ ray->time,
+ visibility,
+ prim_object,
+ prim,
+ prim_addr);
break;
}
#endif
@@ -182,20 +195,9 @@ ccl_device_inline
}
}
- const int curve_object = (object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, prim_addr) :
- object;
const int curve_type = kernel_tex_fetch(__prim_type, prim_addr);
- const int curve_prim = kernel_tex_fetch(__prim_index, prim_addr);
- hit = curve_intersect(kg,
- &isect,
- P,
- dir,
- t_max_current,
- curve_object,
- curve_prim,
- ray->time,
- curve_type);
+ hit = curve_intersect(
+ kg, &isect, P, dir, t_max_current, prim_object, prim, ray->time, curve_type);
break;
}
@@ -211,20 +213,9 @@ ccl_device_inline
}
}
- const int point_object = (object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, prim_addr) :
- object;
- const int point_prim = kernel_tex_fetch(__prim_index, prim_addr);
const int point_type = kernel_tex_fetch(__prim_type, prim_addr);
- hit = point_intersect(kg,
- &isect,
- P,
- dir,
- t_max_current,
- point_object,
- point_prim,
- ray->time,
- point_type);
+ hit = point_intersect(
+ kg, &isect, P, dir, t_max_current, prim_object, prim, ray->time, point_type);
break;
}
#endif /* BVH_FEATURE(BVH_POINTCLOUD) */
@@ -301,8 +292,6 @@ ccl_device_inline
integrator_state_write_shadow_isect(state, &isect, record_index);
}
}
-
- prim_addr++;
}
}
else {
diff --git a/intern/cycles/kernel/bvh/traversal.h b/intern/cycles/kernel/bvh/traversal.h
index e4bff1a8a80..dc2d1422df6 100644
--- a/intern/cycles/kernel/bvh/traversal.h
+++ b/intern/cycles/kernel/bvh/traversal.h
@@ -137,8 +137,14 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
case PRIMITIVE_TRIANGLE: {
for (; prim_addr < prim_addr2; prim_addr++) {
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+
+ const int prim_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+
if (triangle_intersect(
- kg, isect, P, dir, isect->t, visibility, object, prim_addr)) {
+ kg, isect, P, dir, isect->t, visibility, prim_object, prim, prim_addr)) {
/* shadow ray early termination */
if (visibility & PATH_RAY_SHADOW_OPAQUE)
return true;
@@ -150,8 +156,22 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
case PRIMITIVE_MOTION_TRIANGLE: {
for (; prim_addr < prim_addr2; prim_addr++) {
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
- if (motion_triangle_intersect(
- kg, isect, P, dir, isect->t, ray->time, visibility, object, prim_addr)) {
+
+ const int prim_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+
+ if (motion_triangle_intersect(kg,
+ isect,
+ P,
+ dir,
+ isect->t,
+ ray->time,
+ visibility,
+ prim_object,
+ prim,
+ prim_addr)) {
/* shadow ray early termination */
if (visibility & PATH_RAY_SHADOW_OPAQUE)
return true;
@@ -173,13 +193,14 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
}
}
- const int curve_object = (object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, prim_addr) :
- object;
- const int curve_prim = kernel_tex_fetch(__prim_index, prim_addr);
+ const int prim_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+
const int curve_type = kernel_tex_fetch(__prim_type, prim_addr);
const bool hit = curve_intersect(
- kg, isect, P, dir, isect->t, curve_object, curve_prim, ray->time, curve_type);
+ kg, isect, P, dir, isect->t, prim_object, prim, ray->time, curve_type);
if (hit) {
/* shadow ray early termination */
if (visibility & PATH_RAY_SHADOW_OPAQUE)
@@ -200,13 +221,14 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
}
}
- const int point_object = (object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, prim_addr) :
- object;
- const int point_prim = kernel_tex_fetch(__prim_index, prim_addr);
+ const int prim_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+
const int point_type = kernel_tex_fetch(__prim_type, prim_addr);
const bool hit = point_intersect(
- kg, isect, P, dir, isect->t, point_object, point_prim, ray->time, point_type);
+ kg, isect, P, dir, isect->t, prim_object, prim, ray->time, point_type);
if (hit) {
/* shadow ray early termination */
if (visibility & PATH_RAY_SHADOW_OPAQUE)
diff --git a/intern/cycles/kernel/bvh/volume.h b/intern/cycles/kernel/bvh/volume.h
index fa56bd02bef..c0746c8efc3 100644
--- a/intern/cycles/kernel/bvh/volume.h
+++ b/intern/cycles/kernel/bvh/volume.h
@@ -140,14 +140,17 @@ ccl_device_inline
for (; prim_addr < prim_addr2; prim_addr++) {
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
/* only primitives from volume object */
- uint tri_object = (object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, prim_addr) :
- object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ const int prim_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+
+ int object_flag = kernel_tex_fetch(__object_flag, prim_object);
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
continue;
}
- triangle_intersect(kg, isect, P, dir, isect->t, visibility, object, prim_addr);
+ triangle_intersect(
+ kg, isect, P, dir, isect->t, visibility, prim_object, prim, prim_addr);
}
break;
}
@@ -157,15 +160,24 @@ ccl_device_inline
for (; prim_addr < prim_addr2; prim_addr++) {
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
/* only primitives from volume object */
- uint tri_object = (object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, prim_addr) :
- object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ const int prim_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+ int object_flag = kernel_tex_fetch(__object_flag, prim_object);
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
continue;
}
- motion_triangle_intersect(
- kg, isect, P, dir, isect->t, ray->time, visibility, object, prim_addr);
+ motion_triangle_intersect(kg,
+ isect,
+ P,
+ dir,
+ isect->t,
+ ray->time,
+ visibility,
+ prim_object,
+ prim,
+ prim_addr);
}
break;
}
diff --git a/intern/cycles/kernel/bvh/volume_all.h b/intern/cycles/kernel/bvh/volume_all.h
index 1d7d942e736..a88c9d95d46 100644
--- a/intern/cycles/kernel/bvh/volume_all.h
+++ b/intern/cycles/kernel/bvh/volume_all.h
@@ -143,15 +143,16 @@ ccl_device_inline
for (; prim_addr < prim_addr2; prim_addr++) {
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
/* only primitives from volume object */
- uint tri_object = (object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, prim_addr) :
- object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ const int prim_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+ int object_flag = kernel_tex_fetch(__object_flag, prim_object);
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
continue;
}
hit = triangle_intersect(
- kg, isect_array, P, dir, isect_t, visibility, object, prim_addr);
+ kg, isect_array, P, dir, isect_t, visibility, prim_object, prim, prim_addr);
if (hit) {
/* Move on to next entry in intersections array. */
isect_array++;
@@ -183,15 +184,24 @@ ccl_device_inline
for (; prim_addr < prim_addr2; prim_addr++) {
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
/* only primitives from volume object */
- uint tri_object = (object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, prim_addr) :
- object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ const int prim_object = (object == OBJECT_NONE) ?
+ kernel_tex_fetch(__prim_object, prim_addr) :
+ object;
+ const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+ int object_flag = kernel_tex_fetch(__object_flag, prim_object);
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
continue;
}
- hit = motion_triangle_intersect(
- kg, isect_array, P, dir, isect_t, ray->time, visibility, object, prim_addr);
+ hit = motion_triangle_intersect(kg,
+ isect_array,
+ P,
+ dir,
+ isect_t,
+ ray->time,
+ visibility,
+ prim_object,
+ prim,
+ prim_addr);
if (hit) {
/* Move on to next entry in intersections array. */
isect_array++;
diff --git a/intern/cycles/kernel/geom/motion_triangle_intersect.h b/intern/cycles/kernel/geom/motion_triangle_intersect.h
index 3bbb7be685d..cb6d210d90f 100644
--- a/intern/cycles/kernel/geom/motion_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/motion_triangle_intersect.h
@@ -153,14 +153,12 @@ ccl_device_inline bool motion_triangle_intersect(KernelGlobals kg,
float time,
uint visibility,
int object,
+ int prim,
int prim_addr)
{
- /* Primitive index for vertex location lookup. */
- int prim = kernel_tex_fetch(__prim_index, prim_addr);
- int fobject = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, prim_addr) : object;
/* Get vertex locations for intersection. */
float3 verts[3];
- motion_triangle_vertices(kg, fobject, prim, time, verts);
+ motion_triangle_vertices(kg, object, prim, time, verts);
/* Ray-triangle intersection, unoptimized. */
float t, u, v;
if (ray_triangle_intersect(P, dir, tmax, verts[0], verts[1], verts[2], &u, &v, &t)) {
@@ -175,8 +173,7 @@ ccl_device_inline bool motion_triangle_intersect(KernelGlobals kg,
isect->u = u;
isect->v = v;
isect->prim = prim;
- isect->object = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, prim_addr) :
- object;
+ isect->object = object;
isect->type = PRIMITIVE_MOTION_TRIANGLE;
return true;
}
@@ -196,25 +193,15 @@ ccl_device_inline bool motion_triangle_intersect_local(KernelGlobals kg,
float3 dir,
float time,
int object,
- int local_object,
+ int prim,
int prim_addr,
float tmax,
ccl_private uint *lcg_state,
int max_hits)
{
- /* Only intersect with matching object, for instanced objects we
- * already know we are only intersecting the right object. */
- if (object == OBJECT_NONE) {
- if (kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
- return false;
- }
- }
-
- /* Primitive index for vertex location lookup. */
- int prim = kernel_tex_fetch(__prim_index, prim_addr);
/* Get vertex locations for intersection. */
float3 verts[3];
- motion_triangle_vertices(kg, local_object, prim, time, verts);
+ motion_triangle_vertices(kg, object, prim, time, verts);
/* Ray-triangle intersection, unoptimized. */
float t, u, v;
if (!ray_triangle_intersect(P, dir, tmax, verts[0], verts[1], verts[2], &u, &v, &t)) {
@@ -266,7 +253,7 @@ ccl_device_inline bool motion_triangle_intersect_local(KernelGlobals kg,
isect->u = u;
isect->v = v;
isect->prim = prim;
- isect->object = local_object;
+ isect->object = object;
isect->type = PRIMITIVE_MOTION_TRIANGLE;
/* Record geometric normal. */
diff --git a/intern/cycles/kernel/geom/triangle_intersect.h b/intern/cycles/kernel/geom/triangle_intersect.h
index 4a7f38131da..0169b40bc34 100644
--- a/intern/cycles/kernel/geom/triangle_intersect.h
+++ b/intern/cycles/kernel/geom/triangle_intersect.h
@@ -33,9 +33,9 @@ ccl_device_inline bool triangle_intersect(KernelGlobals kg,
float tmax,
uint visibility,
int object,
+ int prim,
int prim_addr)
{
- const int prim = kernel_tex_fetch(__prim_index, prim_addr);
const uint tri_vindex = kernel_tex_fetch(__tri_vindex, prim).w;
const float3 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
@@ -49,8 +49,7 @@ ccl_device_inline bool triangle_intersect(KernelGlobals kg,
if (kernel_tex_fetch(__prim_visibility, prim_addr) & visibility)
#endif
{
- isect->object = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, prim_addr) :
- object;
+ isect->object = object;
isect->prim = prim;
isect->type = PRIMITIVE_TRIANGLE;
isect->u = u;
@@ -74,21 +73,12 @@ ccl_device_inline bool triangle_intersect_local(KernelGlobals kg,
float3 P,
float3 dir,
int object,
- int local_object,
+ int prim,
int prim_addr,
float tmax,
ccl_private uint *lcg_state,
int max_hits)
{
- /* Only intersect with matching object, for instanced objects we
- * already know we are only intersecting the right object. */
- if (object == OBJECT_NONE) {
- if (kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
- return false;
- }
- }
-
- const int prim = kernel_tex_fetch(__prim_index, prim_addr);
const uint tri_vindex = kernel_tex_fetch(__tri_vindex, prim).w;
const float3 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
@@ -139,7 +129,7 @@ ccl_device_inline bool triangle_intersect_local(KernelGlobals kg,
/* Record intersection. */
ccl_private Intersection *isect = &local_isect->hits[hit];
isect->prim = prim;
- isect->object = local_object;
+ isect->object = object;
isect->type = PRIMITIVE_TRIANGLE;
isect->u = u;
isect->v = v;