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

Reply via email to