Cycles: Cleanup, move Embree BVH logic to own file
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 9 Nov 2018 11:28:55 +0000 (12:28 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 9 Nov 2018 11:28:55 +0000 (12:28 +0100)
There is no way we can keep generic entry point functions easy to
follow if we start adding actual logic in them.

intern/cycles/kernel/bvh/bvh.h
intern/cycles/kernel/bvh/bvh_embree.h

index 72bba8d968ffdc589d62150e6e2d2f19f9d939b6..1ef6500e78c0a798f779acf554096fd0ef58979f 100644 (file)
@@ -190,25 +190,16 @@ ccl_device_intersect bool scene_intersect(KernelGlobals *kg,
                return false;
        }
 #ifdef __EMBREE__
-       if(kernel_data.bvh.scene) {
-               isect->t = ray.t;
-               CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_REGULAR);
-               IntersectContext rtc_ctx(&ctx);
-               RTCRayHit ray_hit;
-               kernel_embree_setup_rayhit(ray, ray_hit, visibility);
-               rtcIntersect1(kernel_data.bvh.scene, &rtc_ctx.context, &ray_hit);
-               if(ray_hit.hit.geomID != RTC_INVALID_GEOMETRY_ID && ray_hit.hit.primID != RTC_INVALID_GEOMETRY_ID) {
-                       kernel_embree_convert_hit(kg, &ray_hit.ray, &ray_hit.hit, isect);
-                       return true;
-               }
-               return false;
+       if(kernel_data.bvh.scene != NULL) {
+               return embree_scene_intersect(kg, ray, visibility, isect);
        }
 #endif  /* __EMBREE__ */
 #ifdef __OBJECT_MOTION__
        if(kernel_data.bvh.have_motion) {
 #  ifdef __HAIR__
                if(kernel_data.bvh.have_curves)
-                       return bvh_intersect_hair_motion(kg, &ray, isect, visibility, lcg_state, difl, extmax);
+                       return bvh_intersect_hair_motion(
+                               kg, &ray, isect, visibility, lcg_state, difl, extmax);
 #  endif  /* __HAIR__ */
 
                return bvh_intersect_motion(kg, &ray, isect, visibility);
@@ -217,7 +208,8 @@ ccl_device_intersect bool scene_intersect(KernelGlobals *kg,
 
 #ifdef __HAIR__
        if(kernel_data.bvh.have_curves)
-               return bvh_intersect_hair(kg, &ray, isect, visibility, lcg_state, difl, extmax);
+               return bvh_intersect_hair(
+                       kg, &ray, isect, visibility, lcg_state, difl, extmax);
 #endif  /* __HAIR__ */
 
 #ifdef __KERNEL_CPU__
@@ -252,70 +244,19 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals *kg,
                return false;
        }
 #ifdef __EMBREE__
-       if(kernel_data.bvh.scene) {
-               CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SSS);
-               ctx.lcg_state = lcg_state;
-               ctx.max_hits = max_hits;
-               ctx.ss_isect = local_isect;
-               local_isect->num_hits = 0;
-               ctx.sss_object_id = local_object;
-               IntersectContext rtc_ctx(&ctx);
-               RTCRay rtc_ray;
-               kernel_embree_setup_ray(ray, rtc_ray, PATH_RAY_ALL_VISIBILITY);
-
-               /* Get the Embree scene for this intersection. */
-               RTCGeometry geom = rtcGetGeometry(kernel_data.bvh.scene, local_object * 2);
-               if(geom) {
-                       float3 P = ray.P;
-                       float3 dir = ray.D;
-                       float3 idir = ray.D;
-                       const int object_flag = kernel_tex_fetch(__object_flag, local_object);
-                       if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
-                               Transform ob_itfm;
-                               rtc_ray.tfar = bvh_instance_motion_push(kg,
-                                                                       local_object,
-                                                                       &ray,
-                                                                       &P,
-                                                                       &dir,
-                                                                       &idir,
-                                                                       ray.t,
-                                                                       &ob_itfm);
-                               /* bvh_instance_motion_push() returns the inverse transform but
-                                * it's not needed here. */
-                               (void) ob_itfm;
-
-                               rtc_ray.org_x = P.x;
-                               rtc_ray.org_y = P.y;
-                               rtc_ray.org_z = P.z;
-                               rtc_ray.dir_x = dir.x;
-                               rtc_ray.dir_y = dir.y;
-                               rtc_ray.dir_z = dir.z;
-                       }
-                       RTCScene scene = (RTCScene)rtcGetGeometryUserData(geom);
-                       if(scene) {
-                               rtcOccluded1(scene, &rtc_ctx.context, &rtc_ray);
-                       }
-               }
-
-               return local_isect->num_hits > 0;
+       if(kernel_data.bvh.scene != NULL) {
+               return embree_scene_intersect_local(
+                       kg, ray, local_isect, local_object, lcg_state, max_hits);
        }
 #endif  /* __EMBREE__ */
 #ifdef __OBJECT_MOTION__
        if(kernel_data.bvh.have_motion) {
-               return bvh_intersect_local_motion(kg,
-                                                 &ray,
-                                                 local_isect,
-                                                 local_object,
-                                                 lcg_state,
-                                                 max_hits);
+               return bvh_intersect_local_motion(
+                       kg, &ray, local_isect, local_object, lcg_state, max_hits);
        }
 #endif  /* __OBJECT_MOTION__ */
-       return bvh_intersect_local(kg,
-                                   &ray,
-                                   local_isect,
-                                   local_object,
-                                   lcg_state,
-                                   max_hits);
+       return bvh_intersect_local(
+               kg, &ray, local_isect, local_object, lcg_state, max_hits);
 }
 #endif
 
@@ -331,73 +272,41 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg,
                return false;
        }
 #  ifdef __EMBREE__
-       if(kernel_data.bvh.scene) {
-               CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SHADOW_ALL);
-               ctx.isect_s = isect;
-               ctx.max_hits = max_hits;
-               ctx.num_hits = 0;
-               IntersectContext rtc_ctx(&ctx);
-               RTCRay rtc_ray;
-               kernel_embree_setup_ray(*ray, rtc_ray, PATH_RAY_SHADOW);
-               rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray);
-
-               if(ctx.num_hits > max_hits) {
-                       return true;
-               }
-               *num_hits = ctx.num_hits;
-               return rtc_ray.tfar == -INFINITY;
+       if(kernel_data.bvh.scene != NULL) {
+               return embree_scene_intersect_shadow_all(
+                       kg, ray, isect, max_hits, num_hits);
        }
 #  endif
 #  ifdef __OBJECT_MOTION__
        if(kernel_data.bvh.have_motion) {
 #    ifdef __HAIR__
                if(kernel_data.bvh.have_curves) {
-                       return bvh_intersect_shadow_all_hair_motion(kg,
-                                                                   ray,
-                                                                   isect,
-                                                                   visibility,
-                                                                   max_hits,
-                                                                   num_hits);
+                       return bvh_intersect_shadow_all_hair_motion(
+                               kg, ray, isect, visibility, max_hits, num_hits);
                }
 #    endif  /* __HAIR__ */
 
-               return bvh_intersect_shadow_all_motion(kg,
-                                                      ray,
-                                                      isect,
-                                                      visibility,
-                                                      max_hits,
-                                                      num_hits);
+               return bvh_intersect_shadow_all_motion(
+                       kg, ray, isect, visibility, max_hits, num_hits);
        }
 #  endif  /* __OBJECT_MOTION__ */
 
 #  ifdef __HAIR__
        if(kernel_data.bvh.have_curves) {
-               return bvh_intersect_shadow_all_hair(kg,
-                                                    ray,
-                                                    isect,
-                                                    visibility,
-                                                    max_hits,
-                                                    num_hits);
+               return bvh_intersect_shadow_all_hair(
+                       kg, ray, isect, visibility, max_hits, num_hits);
        }
 #  endif  /* __HAIR__ */
 
 #  ifdef __INSTANCING__
        if(kernel_data.bvh.have_instancing) {
-               return bvh_intersect_shadow_all_instancing(kg,
-                                                          ray,
-                                                          isect,
-                                                          visibility,
-                                                          max_hits,
-                                                          num_hits);
+               return bvh_intersect_shadow_all_instancing(
+                       kg, ray, isect, visibility, max_hits, num_hits);
        }
 #  endif  /* __INSTANCING__ */
 
-       return bvh_intersect_shadow_all(kg,
-                                       ray,
-                                       isect,
-                                       visibility,
-                                       max_hits,
-                                       num_hits);
+       return bvh_intersect_shadow_all(
+               kg, ray, isect, visibility, max_hits, num_hits);
 }
 #endif  /* __SHADOW_RECORD_ALL__ */
 
@@ -442,26 +351,21 @@ ccl_device_intersect uint scene_intersect_volume_all(KernelGlobals *kg,
                return false;
        }
 #  ifdef __EMBREE__
-       if(kernel_data.bvh.scene) {
-               CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_VOLUME_ALL);
-               ctx.isect_s = isect;
-               ctx.max_hits = max_hits;
-               ctx.num_hits = 0;
-               IntersectContext rtc_ctx(&ctx);
-               RTCRay rtc_ray;
-               kernel_embree_setup_ray(*ray, rtc_ray, visibility);
-               rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray);
-               return rtc_ray.tfar == -INFINITY;
+       if(kernel_data.bvh.scene != NULL) {
+               return embree_scene_intersect_volume_all(
+                       kg, ray, isect, max_hits, visibility);
        }
 #  endif
 #  ifdef __OBJECT_MOTION__
        if(kernel_data.bvh.have_motion) {
-               return bvh_intersect_volume_all_motion(kg, ray, isect, max_hits, visibility);
+               return bvh_intersect_volume_all_motion(
+                       kg, ray, isect, max_hits, visibility);
        }
 #  endif  /* __OBJECT_MOTION__ */
 #  ifdef __INSTANCING__
        if(kernel_data.bvh.have_instancing)
-               return bvh_intersect_volume_all_instancing(kg, ray, isect, max_hits, visibility);
+               return bvh_intersect_volume_all_instancing(
+                       kg, ray, isect, max_hits, visibility);
 #  endif  /* __INSTANCING__ */
        return bvh_intersect_volume_all(kg, ray, isect, max_hits, visibility);
 }
index 34a099ebb4dc2151fe55b70645d12a6053a32eba..db6a1e3ac08c07c0dfb9227cbdbbf5e5f34fe19f 100644 (file)
@@ -123,4 +123,125 @@ ccl_device_inline void kernel_embree_convert_local_hit(KernelGlobals *kg, const
        isect->type = kernel_tex_fetch(__prim_type, isect->prim);
 }
 
+ccl_device_inline bool embree_scene_intersect(KernelGlobals *kg,
+                                              const Ray *ray,
+                                              const uint visibility,
+                                              Intersection *isect)
+{
+       kernel_assert(kernel_data.bvh.scene != NULL);
+       isect->t = ray->t;
+       CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_REGULAR);
+       IntersectContext rtc_ctx(&ctx);
+       RTCRayHit ray_hit;
+       kernel_embree_setup_rayhit(*ray, ray_hit, visibility);
+       rtcIntersect1(kernel_data.bvh.scene, &rtc_ctx.context, &ray_hit);
+       if(ray_hit.hit.geomID != RTC_INVALID_GEOMETRY_ID && ray_hit.hit.primID != RTC_INVALID_GEOMETRY_ID) {
+               kernel_embree_convert_hit(kg, &ray_hit.ray, &ray_hit.hit, isect);
+               return true;
+       }
+       return false;
+}
+
+#ifdef __BVH_LOCAL__
+ccl_device_inline bool embree_scene_intersect_local(
+        KernelGlobals *kg,
+        const Ray ray,
+        LocalIntersection *local_isect,
+        int local_object,
+        uint *lcg_state,
+        int max_hits)
+{
+       kernel_assert(kernel_data.bvh.scene != NULL);
+       CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SSS);
+       ctx.lcg_state = lcg_state;
+       ctx.max_hits = max_hits;
+       ctx.ss_isect = local_isect;
+       local_isect->num_hits = 0;
+       ctx.sss_object_id = local_object;
+       IntersectContext rtc_ctx(&ctx);
+       RTCRay rtc_ray;
+       kernel_embree_setup_ray(ray, rtc_ray, PATH_RAY_ALL_VISIBILITY);
+       /* Get the Embree scene for this intersection. */
+       RTCGeometry geom = rtcGetGeometry(kernel_data.bvh.scene, local_object * 2);
+       if(geom) {
+               float3 P = ray.P;
+               float3 dir = ray.D;
+               float3 idir = ray.D;
+               const int object_flag = kernel_tex_fetch(__object_flag, local_object);
+               if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+                       Transform ob_itfm;
+                       rtc_ray.tfar = bvh_instance_motion_push(kg,
+                                                                                                       local_object,
+                                                                                                       &ray,
+                                                                                                       &P,
+                                                                                                       &dir,
+                                                                                                       &idir,
+                                                                                                       ray.t,
+                                                                                                       &ob_itfm);
+                       /* bvh_instance_motion_push() returns the inverse transform but
+                               * it's not needed here. */
+                       (void) ob_itfm;
+
+                       rtc_ray.org_x = P.x;
+                       rtc_ray.org_y = P.y;
+                       rtc_ray.org_z = P.z;
+                       rtc_ray.dir_x = dir.x;
+                       rtc_ray.dir_y = dir.y;
+                       rtc_ray.dir_z = dir.z;
+               }
+               RTCScene scene = (RTCScene)rtcGetGeometryUserData(geom);
+               if(scene) {
+                       rtcOccluded1(scene, &rtc_ctx.context, &rtc_ray);
+               }
+       }
+       return local_isect->num_hits > 0;
+}
+#endif  /* __BVH_LOCAL__ */
+
+#ifdef __SHADOW_RECORD_ALL__
+ccl_device_inline bool embree_scene_intersect_shadow_all(
+        KernelGlobals *kg,
+        const Ray *ray,
+        Intersection *isect,
+        uint max_hits,
+        uint *num_hits)
+{
+       kernel_assert(kernel_data.bvh.scene != NULL);
+       CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SHADOW_ALL);
+       ctx.isect_s = isect;
+       ctx.max_hits = max_hits;
+       ctx.num_hits = 0;
+       IntersectContext rtc_ctx(&ctx);
+       RTCRay rtc_ray;
+       kernel_embree_setup_ray(*ray, rtc_ray, PATH_RAY_SHADOW);
+       rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray);
+       if(ctx.num_hits > max_hits) {
+               return true;
+       }
+       *num_hits = ctx.num_hits;
+       return rtc_ray.tfar == -INFINITY;
+}
+#endif  /* __SHADOW_RECORD_ALL__ */
+
+#ifdef __VOLUME_RECORD_ALL__
+ccl_device_inline uint embree_scene_intersect_volume_all(
+        KernelGlobals *kg,
+        const Ray *ray,
+        Intersection *isect,
+        const uint max_hits,
+        const uint visibility)
+{
+       kernel_assert(kernel_data.bvh.scene != NULL);
+       CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_VOLUME_ALL);
+       ctx.isect_s = isect;
+       ctx.max_hits = max_hits;
+       ctx.num_hits = 0;
+       IntersectContext rtc_ctx(&ctx);
+       RTCRay rtc_ray;
+       kernel_embree_setup_ray(*ray, rtc_ray, visibility);
+       rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray);
+       return rtc_ray.tfar == -INFINITY;
+}
+#endif  /* __VOLUME_RECORD_ALL__ */
+
 CCL_NAMESPACE_END