[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