[Bf-blender-cvs] [3c5d1076f4f] cycles_embree: Cycles: Some more cleanup/commenting for Embree integration.
Stefan Werner
noreply at git.blender.org
Mon Sep 10 13:52:35 CEST 2018
Commit: 3c5d1076f4f60eebd4d1d53e7019fc2b69a83d1d
Author: Stefan Werner
Date: Mon Sep 10 13:52:33 2018 +0200
Branches: cycles_embree
https://developer.blender.org/rB3c5d1076f4f60eebd4d1d53e7019fc2b69a83d1d
Cycles: Some more cleanup/commenting for Embree integration.
===================================================================
M intern/cycles/bvh/bvh_embree.cpp
===================================================================
diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp
index d0dac07c7e2..2122d09ec7e 100644
--- a/intern/cycles/bvh/bvh_embree.cpp
+++ b/intern/cycles/bvh/bvh_embree.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2017, Blender Foundation.
+ * Copyright 2018, Blender Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,24 @@
* limitations under the License.
*/
+/* This class implemens a ray accelerator for Cycles using Intel's Embree library.
+ * It supports triangles, curves, object and deformation blur and instancing.
+ * Not supported are thick line segments, those have no native equivalent in Embree.
+ * They could be implemented using Embree's thick curves, at the expense of wasted memory.
+ * User defined intersections for Embree could also be an option, but since Embree only uses aligned BVHs
+ * for user geometry, this would come with reduced performance and/or higher memory usage.
+ *
+ * Since Embree allows object to be either curves or triangles but not both, Cycles object IDs are maapped
+ * to Embree IDs by multiplying by two and adding one for curves.
+ *
+ * This implementation shares RTCDevices between Cycles instances. Eventually each instance should get
+ * a separate RTCDevice to correctly keep track of memory usage.
+ *
+ * Vertex and index buffers are duplicated between Cycles device arrays and Embree. These could be merged,
+ * which would requrie changes to intersection refinement, shader setup, mesh light sampling and a few
+ * other places in Cycles where direct access to vertex data is required.
+ */
+
#ifdef WITH_EMBREE
#include <pmmintrin.h>
@@ -46,6 +64,7 @@ CCL_NAMESPACE_BEGIN
void rtc_filter_func(const RTCFilterFunctionNArguments *args);
void rtc_filter_func(const RTCFilterFunctionNArguments *args)
{
+ /* Current implementation in Cycles assumes only single-ray intersection queries. */
assert(args->N == 1);
const RTCRay *ray = (RTCRay*)args->ray;
@@ -83,120 +102,122 @@ void rtc_filter_occluded_func(const RTCFilterFunctionNArguments* args)
}
}
- if(ctx->type == CCLIntersectContext::RAY_SHADOW_ALL) {
- /* Append the intersection to the end of the array. */
- if(ctx->num_hits < ctx->max_hits) {
- Intersection current_isect;
- kernel_embree_convert_hit(kg, ray, hit, ¤t_isect);
- for(size_t i = 0; i < ctx->max_hits; ++i) {
- if(current_isect.object == ctx->isect_s[i].object &&
- current_isect.prim == ctx->isect_s[i].prim &&
- current_isect.t == ctx->isect_s[i].t) {
- /* This intersection was already recorded, skip it. */
+ switch(ctx->type) {
+ case CCLIntersectContext::RAY_SHADOW_ALL: {
+ /* Append the intersection to the end of the array. */
+ if(ctx->num_hits < ctx->max_hits) {
+ Intersection current_isect;
+ kernel_embree_convert_hit(kg, ray, hit, ¤t_isect);
+ for(size_t i = 0; i < ctx->max_hits; ++i) {
+ if(current_isect.object == ctx->isect_s[i].object &&
+ current_isect.prim == ctx->isect_s[i].prim &&
+ current_isect.t == ctx->isect_s[i].t) {
+ /* This intersection was already recorded, skip it. */
+ *args->valid = 0;
+ break;
+ }
+ }
+ Intersection *isect = &ctx->isect_s[ctx->num_hits];
+ ctx->num_hits++;
+ *isect = current_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. */
*args->valid = 0;
- return;
}
}
- Intersection *isect = &ctx->isect_s[ctx->num_hits];
- ctx->num_hits++;
- *isect = current_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);
+ /* Increase the number of hits beyond ray.max_hits
+ * so that the caller can detect this as opaque. */
+ ctx->num_hits++;
}
- 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. */
- *args->valid = 0;
- }
- }
- else {
- /* Increase the number of hits beyond ray.max_hits
- * so that the caller can detect this as opaque. */
- ctx->num_hits++;
- }
- return;
- }
- else if(ctx->type == CCLIntersectContext::RAY_SSS) {
- /* No intersection information requested, just return a hit. */
- if(ctx->max_hits == 0) {
- return;
+ break;
}
-
- /* See triangle_intersect_subsurface() for the native equivalent. */
- for(int i = min(ctx->max_hits, ctx->ss_isect->num_hits) - 1; i >= 0; --i) {
- if(ctx->ss_isect->hits[i].t == ray->tfar) {
- /* This tells Embree to continue tracing. */
- *args->valid = 0;
- return;
+ case CCLIntersectContext::RAY_SSS: {
+ /* No intersection information requested, just return a hit. */
+ if(ctx->max_hits == 0) {
+ break;
}
- }
- ctx->ss_isect->num_hits++;
- int hit_idx;
+ /* See triangle_intersect_subsurface() for the native equivalent. */
+ for(int i = min(ctx->max_hits, ctx->ss_isect->num_hits) - 1; i >= 0; --i) {
+ if(ctx->ss_isect->hits[i].t == ray->tfar) {
+ /* This tells Embree to continue tracing. */
+ *args->valid = 0;
+ break;
+ }
+ }
- if(ctx->ss_isect->num_hits <= ctx->max_hits) {
- hit_idx = ctx->ss_isect->num_hits - 1;
- }
- else {
- /* reservoir sampling: if we are at the maximum number of
- * hits, randomly replace element or skip it */
- hit_idx = lcg_step_uint(ctx->lcg_state) % ctx->ss_isect->num_hits;
+ ctx->ss_isect->num_hits++;
+ int hit_idx;
- if(hit_idx >= ctx->max_hits) {
- /* This tells Embree to continue tracing. */
- *args->valid = 0;
- return;
+ if(ctx->ss_isect->num_hits <= ctx->max_hits) {
+ hit_idx = ctx->ss_isect->num_hits - 1;
}
- }
- /* record intersection */
- kernel_embree_convert_local_hit(kg, ray, hit, &ctx->ss_isect->hits[hit_idx], ctx->sss_object_id);
- ctx->ss_isect->Ng[hit_idx].x = hit->Ng_x;
- ctx->ss_isect->Ng[hit_idx].y = hit->Ng_y;
- ctx->ss_isect->Ng[hit_idx].z = hit->Ng_z;
- ctx->ss_isect->Ng[hit_idx] = normalize(ctx->ss_isect->Ng[hit_idx]);
- /* this tells Embree to continue tracing */
- *args->valid = 0;
- return;
- }
- else if(ctx->type == CCLIntersectContext::RAY_VOLUME_ALL) {
- /* Append the intersection to the end of the array. */
- if(ctx->num_hits < ctx->max_hits) {
- Intersection current_isect;
- kernel_embree_convert_hit(kg, ray, hit, ¤t_isect);
- for(size_t i = 0; i < ctx->max_hits; ++i) {
- if(current_isect.object == ctx->isect_s[i].object &&
- current_isect.prim == ctx->isect_s[i].prim &&
- current_isect.t == ctx->isect_s[i].t) {
- /* This intersection was already recorded, skip it. */
+ else {
+ /* reservoir sampling: if we are at the maximum number of
+ * hits, randomly replace element or skip it */
+ hit_idx = lcg_step_uint(ctx->lcg_state) % ctx->ss_isect->num_hits;
+
+ if(hit_idx >= ctx->max_hits) {
+ /* This tells Embree to continue tracing. */
*args->valid = 0;
- return;
+ break;
}
}
- Intersection *isect = &ctx->isect_s[ctx->num_hits];
- ctx->num_hits++;
- *isect = current_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) {
- ctx->num_hits--;
- }
- /* This tells Embree to continue tracing. */
+ /* record intersection */
+ kernel_embree_convert_local_hit(kg, ray, hit, &ctx->ss_isect->hits[hit_idx], ctx->sss_object_id);
+ ctx->ss_isect->Ng[hit_idx].x = hit->Ng_x;
+ ctx->ss_isect->Ng[hit_idx].y = hit->Ng_y;
+ ctx->ss_isect->Ng[hit_idx].z = hit->Ng_z;
+ ctx->ss_isect->Ng[hit_idx] = normalize(ctx->ss_isect->Ng[hit_idx]);
+ /* this tells Embree to continue tracing */
*args->valid = 0;
- return;
+ break;
+ }
+ case CCLIntersectContext::RAY_VOLUME_ALL: {
+ /* Append the intersection to the end of the array. */
+ if(ctx->num_hits < ctx->max_hits) {
+ Intersection current_isect;
+ kernel_embree_convert_hit(kg, ray, hit, ¤t_isect);
+ for(size_t i = 0; i < ctx->max_hits; ++i) {
+ if(current_isect.object == ctx->isect_s[i].object &&
+ current_isect.prim == ctx->isect_s[i].prim &&
+ current_isect.t == ctx->isect_s[i].t) {
+ /* This intersection was already recorded, skip it. */
+ *args->valid = 0;
+ break;
+ }
+ }
+ Intersection *isect = &ctx->isect_s[ctx->num_hits];
+ ctx->num_hits++;
+ *isect = current_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) {
+ ctx->num_hits--;
+ }
+ /* This tells Embree to continue tracing. */
+ *args->valid = 0;
+ break;
+ }
}
- return;
+ case CCLIntersectContext::RAY_REGULAR:
+ /* nothing to do here. */
+ break;
}
-
- return;
}
static size_t unaccounted_mem = 0;
@@ -605,11 +626,11 @@ void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Mesh* mesh
if(use_curves) {
rtc_tangents = (float4*)rtcSetNewGeometryBuffer(geom_id, RTC_BUFFER_TYPE_TANGENT, t,
RTC_FORMAT_FLOAT4
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list