[Bf-blender-cvs] [b6936329024] cycles_embree: Merge branch 'master' of git.blender.org:blender into cycles_embree
Stefan Werner
noreply at git.blender.org
Tue Jun 19 14:40:58 CEST 2018
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. @@
More information about the Bf-blender-cvs
mailing list