Commit: b69363290246bb0771f1195242456f49b08c0645 Author: Stefan Werner Date: Tue Jun 19 14:25:21 2018 +0200 Branches: cycles_embree https://developer.blender.org/rBb69363290246bb0771f1195242456f49b08c0645
Merge branch 'master' of git.blender.org:blender into cycles_embree =================================================================== =================================================================== diff --cc intern/cycles/bvh/bvh_embree.cpp index ac2bd0e756e,00000000000..e45cfe79184 mode 100644,000000..100644 --- a/intern/cycles/bvh/bvh_embree.cpp +++ b/intern/cycles/bvh/bvh_embree.cpp @@@ -1,866 -1,0 +1,870 @@@ +/* + * Copyright 2017, Blender Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef WITH_EMBREE + +#include "bvh/bvh_embree.h" + +#include "render/mesh.h" +#include "render/object.h" +#include "util/util_progress.h" +#include "util/util_foreach.h" +#include "util/util_logging.h" + +#include "embree2/rtcore_geometry.h" + +/* Kernel includes are necessary so that the filter function for Embree can access the packed BVH. */ +#include "kernel/kernel_compat_cpu.h" +#include "kernel/split/kernel_split_data_types.h" +#include "kernel/kernel_globals.h" +#include "kernel/kernel_random.h" +#include "kernel/bvh/bvh_embree_traversal.h" + +#include "xmmintrin.h" +#include "pmmintrin.h" + +/* this doesn't work with refitting unforutnately + * #define EMBREE_SHARED_MEM 1 + */ + +CCL_NAMESPACE_BEGIN + +/* This gets called by Embree at every valid ray/object intersection. + * Things like recording subsurface or shadow hits for later evaluation + * as well as filtering for volume objects happen here. + * Cycles' own BVH does that directly inside the traversal calls. + */ + + +void rtc_filter_func(void*, RTCRay& ray_); +void rtc_filter_func(void*, RTCRay& ray_) +{ + CCLRay &ray = (CCLRay&)ray_; + KernelGlobals *kg = ray.kg; + + /* For all ray types: check if there is backfacing hair to ignore */ + if((kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) + && !(kernel_data.curve.curveflags & CURVE_KN_BACKFACING) + && !(kernel_data.curve.curveflags & CURVE_KN_RIBBONS) && ray.geomID & 1) { + if(dot(make_float3(ray.dir[0], ray.dir[1], ray.dir[2]), make_float3(ray.Ng[0], ray.Ng[1], ray.Ng[2])) > 0.0f) { + ray.geomID = RTC_INVALID_GEOMETRY_ID; + return; + } + } + + if(ray.type == CCLRay::RAY_REGULAR) { + return; + } + else if(ray.type == CCLRay::RAY_SHADOW_ALL) { + /* Append the intersection to the end of the array. */ + if(ray.num_hits < ray.max_hits) { + Intersection *isect = &ray.isect_s[ray.num_hits]; + ray.num_hits++; + ray.isect_to_ccl(isect); + int prim = kernel_tex_fetch(__prim_index, isect->prim); + int shader = 0; + if(kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE) { + shader = kernel_tex_fetch(__tri_shader, prim); + } + else { + float4 str = kernel_tex_fetch(__curves, prim); + shader = __float_as_int(str.z); + } + int flag = kernel_tex_fetch(__shaders, shader & SHADER_MASK).flags; + /* If no transparent shadows, all light is blocked. */ + if(flag & (SD_HAS_TRANSPARENT_SHADOW)) { + /* This tells Embree to continue tracing. */ + ray.geomID = RTC_INVALID_GEOMETRY_ID; + } + else { + ray.num_hits = ray.max_hits+1; + } + } + else { + /* Increase the number of hits beyond ray.max_hits + * so that the caller can detect this as opaque. */ + ray.num_hits++; + } + return; + } + else if(ray.type == CCLRay::RAY_SSS) { ++ /* No intersection information requested, just return a hit. */ ++ if(ray.ss_isect->num_hits == 0) { ++ return; ++ } + /* Only accept hits from the same object and triangles. */ + if(ray.instID/2 != ray.sss_object_id || ray.geomID & 1) { + /* This tells Embree to continue tracing. */ + ray.geomID = RTC_INVALID_GEOMETRY_ID; + return; + } + + /* See triangle_intersect_subsurface() for the native equivalent. */ + for(int i = min(ray.max_hits, ray.ss_isect->num_hits) - 1; i >= 0; --i) { + if(ray.ss_isect->hits[i].t == ray.tfar) { + /* This tells Embree to continue tracing. */ + ray.geomID = RTC_INVALID_GEOMETRY_ID; + return; + } + } + + ray.ss_isect->num_hits++; + int hit; + + if(ray.ss_isect->num_hits <= ray.max_hits) { + hit = ray.ss_isect->num_hits - 1; + } + else { + /* reservoir sampling: if we are at the maximum number of + * hits, randomly replace element or skip it */ + hit = lcg_step_uint(ray.lcg_state) % ray.ss_isect->num_hits; + + if(hit >= ray.max_hits) { + /* This tells Embree to continue tracing. */ + ray.geomID = RTC_INVALID_GEOMETRY_ID; + return; + } + } + /* record intersection */ + ray.isect_to_ccl(&ray.ss_isect->hits[hit]); + ray.ss_isect->Ng[hit].x = -ray.Ng[0]; + ray.ss_isect->Ng[hit].y = -ray.Ng[1]; + ray.ss_isect->Ng[hit].z = -ray.Ng[2]; + ray.ss_isect->Ng[hit] = normalize(ray.ss_isect->Ng[hit]); + /* this tells Embree to continue tracing */ + ray.geomID = RTC_INVALID_GEOMETRY_ID; + return; + } else if(ray.type == CCLRay::RAY_VOLUME_ALL) { + /* Append the intersection to the end of the array. */ + if(ray.num_hits < ray.max_hits) { + Intersection *isect = &ray.isect_s[ray.num_hits]; + ray.num_hits++; + ray.isect_to_ccl(isect); + /* Only primitives from volume object. */ + uint tri_object = (isect->object == OBJECT_NONE) ?kernel_tex_fetch(__prim_object, isect->prim) : isect->object; + int object_flag = kernel_tex_fetch(__object_flag, tri_object); + if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) { + ray.num_hits--; + } + /* This tells Embree to continue tracing. */ + ray.geomID = RTC_INVALID_GEOMETRY_ID; + return; + } + return; + } + + return; +} +bool rtc_memory_monitor_func(void* userPtr, const ssize_t bytes, const bool post); +bool rtc_memory_monitor_func(void* userPtr, const ssize_t bytes, const bool) +{ + BVHEmbree *bvh = (BVHEmbree*)userPtr; + if(bvh) { + bvh->mem_monitor(bytes); + } + return true; +} + +static double progress_start_time = 0.0f; + +bool rtc_progress_func(void* user_ptr, const double n); +bool rtc_progress_func(void* user_ptr, const double n) +{ + Progress *progress = (Progress*)user_ptr; + + if(time_dt() - progress_start_time < 0.25) + return true; + + string msg = string_printf("Building BVH %.0f%%", n * 100.0); + + progress->set_substatus(msg); + progress_start_time = time_dt(); + + return !progress->get_cancel(); +} + +/* This is to have a shared device between all BVH instances */ +RTCDevice BVHEmbree::rtc_shared_device = NULL; +int BVHEmbree::rtc_shared_users = 0; +thread_mutex BVHEmbree::rtc_shared_mutex; + +BVHEmbree::BVHEmbree(const BVHParams& params_, const vector<Object*>& objects_) +: BVH(params_, objects_), scene(NULL), mem_used(0), top_level(NULL), stats(NULL), + curve_subdivisions(params.curve_subdivisions), use_curves(params_.curve_flags & CURVE_KN_INTERPOLATE), + use_ribbons(params.curve_flags & CURVE_KN_RIBBONS), dynamic_scene(true) +{ + _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); + _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); + thread_scoped_lock lock(rtc_shared_mutex); + if(rtc_shared_users == 0) { + rtc_shared_device = rtcNewDevice("verbose=1"); + + /* Check here if Embree was built with the correct flags. */ + ssize_t ret = rtcDeviceGetParameter1i(rtc_shared_device, RTC_CONFIG_RAY_MASK); + if(ret != 1) { + assert(0); + VLOG(1) << "Embree is compiled without the EMBREE_RAY_MASK flag. Ray visiblity will not work."; + } + ret = rtcDeviceGetParameter1i(rtc_shared_device, RTC_CONFIG_INTERSECTION_FILTER); + if(ret != 1) { + assert(0); + VLOG(1) << "Embree is compiled without the EMBREE_INTERSECTION_FILTER flag. Renders may not look as expected."; + } + ret = rtcDeviceGetParameter1i(rtc_shared_device, RTC_CONFIG_LINE_GEOMETRY); + if(ret != 1) { + assert(0); + VLOG(1) << "Embree is compiled without the EMBREE_GEOMETRY_LINES flag. Line primitives will not be rendered."; + } + ret = rtcDeviceGetParameter1i(rtc_shared_device, RTC_CONFIG_HAIR_GEOMETRY); + if(ret != 1) { + assert(0); + VLOG(1) << "Embree is compiled without the EMBREE_GEOMETRY_HAIR flag. Hair primitives will not be rendered."; + } + ret = rtcDeviceGetParameter1i(rtc_shared_device, RTC_CONFIG_TRIANGLE_GEOMETRY); + if(ret != 1) { + assert(0); + VLOG(1) << "Embree is compiled without the EMBREE_GEOMETRY_TRIANGLES flag. Triangle primitives will not be rendered."; + } + ret = rtcDeviceGetParameter1i(rtc_shared_device, RTC_CONFIG_BACKFACE_CULLING); + if(ret != 0) { + assert(0); + VLOG(1) << "Embree is compiled with the EMBREE_BACKFACE_CULLING flag. Renders may not look as expected."; + } + } + rtc_shared_users++; + + rtcDeviceSetMemoryMonitorFunction2(rtc_shared_device, rtc_memory_monitor_func, this); + + /* BVH_CUSTOM as root index signals to the rest of the code that this is not Cycle's own BVH. */ + pack.root_index = BVH_CUSTOM; +} + +BVHEmbree::~BVHEmbree() +{ + if(!params.top_level) { + destroy(scene); + } +} + +void BVHEmbree::destroy(RTCScene scene) +{ + if(scene) { + rtcDeleteScene(scene); + scene = NULL; + } + thread_scoped_lock lock(rtc_shared_mutex); + rtc_shared_users--; + if(rtc_shared_users == 0) { + rtcDeleteDevice(rtc_shared_device); + rtc_shared_device = NULL; + } +} + +void BVHEmbree::delete_rtcScene() +{ + if(scene) { + /* When this BVH is used as an instance in a top level BVH, don't delete now + * Let the top_level BVH know that it should delete it later. */ + if(top_level) { + top_level->add_delayed_delete_scene(scene); + } + else { + rtcDeleteScene(scene); + if(delayed_delete_scenes.size()) { + foreach(RTCScene s, delayed_delete_scenes) { + rtcDeleteScene(s); + } + } + delayed_delete_scenes.clear(); + } + scene = NULL; + } +} + +void BVHEmbree::mem_monitor(ssize_t bytes) +{ + if(stats) { + if(bytes > 0) { + stats->me @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] https://lists.blender.org/mailman/listinfo/bf-blender-cvs
