Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/cycles/kernel/kernel_path.h26
-rw-r--r--intern/cycles/kernel/kernel_path_branched.h51
-rw-r--r--intern/cycles/kernel/kernel_path_state.h1
-rw-r--r--intern/cycles/kernel/kernel_path_surface.h10
-rw-r--r--intern/cycles/kernel/kernel_types.h7
-rw-r--r--intern/cycles/kernel/split/kernel_next_iteration_setup.h63
-rw-r--r--intern/cycles/kernel/split/kernel_queue_enqueue.h1
-rw-r--r--intern/cycles/kernel/split/kernel_shader_setup.h10
-rw-r--r--source/blender/gpu/intern/gpu_select.c23
-rw-r--r--source/blender/gpu/intern/gpu_select_pick.c22
-rw-r--r--source/blender/gpu/intern/gpu_select_private.h1
11 files changed, 127 insertions, 88 deletions
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index aef350b0658..b0f53aef2d5 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -445,8 +445,15 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
break;
}
- /* Setup and evaluate shader. */
+ /* Setup shader data. */
shader_setup_from_ray(kg, sd, &isect, ray);
+
+ /* Skip most work for volume bounding surface. */
+#ifdef __VOLUME__
+ if(!(sd->flag & SD_HAS_ONLY_VOLUME)) {
+#endif
+
+ /* Evaluate shader. */
shader_eval_surface(kg, sd, state, state->flag);
shader_prepare_closures(sd, state);
@@ -523,6 +530,10 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
}
#endif /* defined(__EMISSION__) */
+#ifdef __VOLUME__
+ }
+#endif
+
if(!kernel_path_surface_bounce(kg, sd, &throughput, state, &L->state, ray))
break;
}
@@ -605,8 +616,15 @@ ccl_device_forceinline void kernel_path_integrate(
break;
}
- /* Setup and evaluate shader. */
+ /* Setup shader data. */
shader_setup_from_ray(kg, &sd, &isect, ray);
+
+ /* Skip most work for volume bounding surface. */
+#ifdef __VOLUME__
+ if(!(sd.flag & SD_HAS_ONLY_VOLUME)) {
+#endif
+
+ /* Evaluate shader. */
shader_eval_surface(kg, &sd, state, state->flag);
shader_prepare_closures(&sd, state);
@@ -669,6 +687,10 @@ ccl_device_forceinline void kernel_path_integrate(
/* direct lighting */
kernel_path_surface_connect_light(kg, &sd, emission_sd, throughput, state, L);
+#ifdef __VOLUME__
+ }
+#endif
+
/* compute direct lighting and next bounce */
if(!kernel_path_surface_bounce(kg, &sd, &throughput, state, &L->state, ray))
break;
diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h
index 441a06eeba3..d43d418db29 100644
--- a/intern/cycles/kernel/kernel_path_branched.h
+++ b/intern/cycles/kernel/kernel_path_branched.h
@@ -480,6 +480,12 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
/* Setup and evaluate shader. */
shader_setup_from_ray(kg, &sd, &isect, &ray);
+
+ /* Skip most work for volume bounding surface. */
+#ifdef __VOLUME__
+ if(!(sd.flag & SD_HAS_ONLY_VOLUME)) {
+#endif
+
shader_eval_surface(kg, &sd, &state, state.flag);
shader_merge_closures(&sd);
@@ -533,37 +539,46 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
}
#endif /* __SUBSURFACE__ */
- if(!(sd.flag & SD_HAS_ONLY_VOLUME)) {
- PathState hit_state = state;
+ PathState hit_state = state;
#ifdef __EMISSION__
- /* direct light */
- if(kernel_data.integrator.use_direct_light) {
- int all = (kernel_data.integrator.sample_all_lights_direct) ||
- (state.flag & PATH_RAY_SHADOW_CATCHER);
- kernel_branched_path_surface_connect_light(kg,
- &sd, emission_sd, &hit_state, throughput, 1.0f, L, all);
- }
+ /* direct light */
+ if(kernel_data.integrator.use_direct_light) {
+ int all = (kernel_data.integrator.sample_all_lights_direct) ||
+ (state.flag & PATH_RAY_SHADOW_CATCHER);
+ kernel_branched_path_surface_connect_light(kg,
+ &sd, emission_sd, &hit_state, throughput, 1.0f, L, all);
+ }
#endif /* __EMISSION__ */
- /* indirect light */
- kernel_branched_path_surface_indirect_light(kg,
- &sd, &indirect_sd, emission_sd, throughput, 1.0f, &hit_state, L);
+ /* indirect light */
+ kernel_branched_path_surface_indirect_light(kg,
+ &sd, &indirect_sd, emission_sd, throughput, 1.0f, &hit_state, L);
- /* continue in case of transparency */
- throughput *= shader_bsdf_transparency(kg, &sd);
+ /* continue in case of transparency */
+ throughput *= shader_bsdf_transparency(kg, &sd);
- if(is_zero(throughput))
- break;
- }
+ if(is_zero(throughput))
+ break;
/* Update Path State */
path_state_next(kg, &state, LABEL_TRANSPARENT);
+#ifdef __VOLUME__
+ }
+ else {
+ /* For volume bounding meshes we pass through without counting transparent
+ * bounces, only sanity check in case self intersection gets us stuck. */
+ state.volume_bounds_bounce++;
+ if (state.volume_bounds_bounce > VOLUME_BOUNDS_MAX) {
+ break;
+ }
+ }
+#endif
+
ray.P = ray_offset(sd.P, -sd.Ng);
ray.t -= sd.ray_length; /* clipping works through transparent */
-
#ifdef __RAY_DIFFERENTIALS__
ray.dP = sd.dP;
ray.dD.dx = -sd.dI.dx;
diff --git a/intern/cycles/kernel/kernel_path_state.h b/intern/cycles/kernel/kernel_path_state.h
index 15d81fcddf4..ff7d1307a6c 100644
--- a/intern/cycles/kernel/kernel_path_state.h
+++ b/intern/cycles/kernel/kernel_path_state.h
@@ -55,6 +55,7 @@ ccl_device_inline void path_state_init(KernelGlobals *kg,
#ifdef __VOLUME__
state->volume_bounce = 0;
+ state->volume_bounds_bounce = 0;
if(kernel_data.integrator.use_volumes) {
/* Initialize volume stack with volume we are inside of. */
diff --git a/intern/cycles/kernel/kernel_path_surface.h b/intern/cycles/kernel/kernel_path_surface.h
index 7b566b01b04..bca346d5ee0 100644
--- a/intern/cycles/kernel/kernel_path_surface.h
+++ b/intern/cycles/kernel/kernel_path_surface.h
@@ -329,10 +329,12 @@ ccl_device bool kernel_path_surface_bounce(KernelGlobals *kg,
}
#ifdef __VOLUME__
else if(sd->flag & SD_HAS_ONLY_VOLUME) {
- /* no surface shader but have a volume shader? act transparent */
-
- /* update path state, count as transparent */
- path_state_next(kg, state, LABEL_TRANSPARENT);
+ /* For volume bounding meshes we pass through without counting transparent
+ * bounces, only sanity check in case self intersection gets us stuck. */
+ state->volume_bounds_bounce++;
+ if (state->volume_bounds_bounce > VOLUME_BOUNDS_MAX) {
+ return false;
+ }
if(state->bounce == 0)
ray->t -= sd->ray_length; /* clipping works through transparent */
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index d967edca75d..2a437cdbdc6 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -49,6 +49,8 @@ CCL_NAMESPACE_BEGIN
#define BSSRDF_MAX_BOUNCES 256
#define LOCAL_MAX_HITS 4
+#define VOLUME_BOUNDS_MAX 1024
+
#define BECKMANN_TABLE_SIZE 256
#define SHADER_NONE (~0)
@@ -1107,6 +1109,7 @@ typedef struct PathState {
/* volume rendering */
#ifdef __VOLUME__
int volume_bounce;
+ int volume_bounds_bounce;
uint rng_congruential;
VolumeStack volume_stack[VOLUME_STACK_SIZE];
#endif
@@ -1497,8 +1500,10 @@ enum RayState {
RAY_ACTIVE,
/* Denotes ray has completed processing all samples and is inactive. */
RAY_INACTIVE,
- /* Denoted ray has exited path-iteration and needs to update output buffer. */
+ /* Denotes ray has exited path-iteration and needs to update output buffer. */
RAY_UPDATE_BUFFER,
+ /* Denotes ray needs to skip most surface shader work. */
+ RAY_HAS_ONLY_VOLUME,
/* Donotes ray has hit background */
RAY_HIT_BACKGROUND,
/* Denotes ray has to be regenerated */
diff --git a/intern/cycles/kernel/split/kernel_next_iteration_setup.h b/intern/cycles/kernel/split/kernel_next_iteration_setup.h
index 81024f0cf99..8092419e796 100644
--- a/intern/cycles/kernel/split/kernel_next_iteration_setup.h
+++ b/intern/cycles/kernel/split/kernel_next_iteration_setup.h
@@ -53,39 +53,52 @@ ccl_device_inline void kernel_split_branched_indirect_light_init(KernelGlobals *
ADD_RAY_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_LIGHT_INDIRECT);
}
-ccl_device void kernel_split_branched_indirect_light_end(KernelGlobals *kg, int ray_index)
+ccl_device void kernel_split_branched_transparent_bounce(KernelGlobals *kg, int ray_index)
{
- kernel_split_branched_path_indirect_loop_end(kg, ray_index);
-
ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
ShaderData *sd = kernel_split_sd(sd, ray_index);
ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
- /* continue in case of transparency */
- *throughput *= shader_bsdf_transparency(kg, sd);
+# ifdef __VOLUME__
+ if(!(sd->flag & SD_HAS_ONLY_VOLUME)) {
+# endif
+ /* continue in case of transparency */
+ *throughput *= shader_bsdf_transparency(kg, sd);
+
+ if(is_zero(*throughput)) {
+ kernel_split_path_end(kg, ray_index);
+ return;
+ }
- if(is_zero(*throughput)) {
- kernel_split_path_end(kg, ray_index);
- }
- else {
/* Update Path State */
path_state_next(kg, state, LABEL_TRANSPARENT);
+# ifdef __VOLUME__
+ }
+ else {
+ /* For volume bounding meshes we pass through without counting transparent
+ * bounces, only sanity check in case self intersection gets us stuck. */
+ state->volume_bounds_bounce++;
+ if (state->volume_bounds_bounce > VOLUME_BOUNDS_MAX) {
+ kernel_split_path_end(kg, ray_index);
+ return;
+ }
+ }
+# endif
- ray->P = ray_offset(sd->P, -sd->Ng);
- ray->t -= sd->ray_length; /* clipping works through transparent */
+ ray->P = ray_offset(sd->P, -sd->Ng);
+ ray->t -= sd->ray_length; /* clipping works through transparent */
# ifdef __RAY_DIFFERENTIALS__
- ray->dP = sd->dP;
- ray->dD.dx = -sd->dI.dx;
- ray->dD.dy = -sd->dI.dy;
+ ray->dP = sd->dP;
+ ray->dD.dx = -sd->dI.dx;
+ ray->dD.dy = -sd->dI.dy;
# endif /* __RAY_DIFFERENTIALS__ */
# ifdef __VOLUME__
- /* enter/exit volume */
- kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
+ /* enter/exit volume */
+ kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
# endif /* __VOLUME__ */
- }
}
#endif /* __BRANCHED_PATH__ */
@@ -121,6 +134,13 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg,
ccl_global char *ray_state = kernel_split_state.ray_state;
+# ifdef __VOLUME__
+ /* Reactivate only volume rays here, most surface work was skipped. */
+ if(IS_STATE(ray_state, ray_index, RAY_HAS_ONLY_VOLUME)) {
+ ASSIGN_RAY_STATE(ray_state, ray_index, RAY_ACTIVE);
+ }
+# endif
+
bool active = IS_STATE(ray_state, ray_index, RAY_ACTIVE);
if(active) {
ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
@@ -138,6 +158,9 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg,
}
#ifdef __BRANCHED_PATH__
}
+ else if(sd->flag & SD_HAS_ONLY_VOLUME) {
+ kernel_split_branched_transparent_bounce(kg, ray_index);
+ }
else {
kernel_split_branched_indirect_light_init(kg, ray_index);
@@ -151,7 +174,8 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg,
ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
}
else {
- kernel_split_branched_indirect_light_end(kg, ray_index);
+ kernel_split_branched_path_indirect_loop_end(kg, ray_index);
+ kernel_split_branched_transparent_bounce(kg, ray_index);
}
}
#endif /* __BRANCHED_PATH__ */
@@ -196,7 +220,8 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg,
ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
}
else {
- kernel_split_branched_indirect_light_end(kg, ray_index);
+ kernel_split_branched_path_indirect_loop_end(kg, ray_index);
+ kernel_split_branched_transparent_bounce(kg, ray_index);
}
}
diff --git a/intern/cycles/kernel/split/kernel_queue_enqueue.h b/intern/cycles/kernel/split/kernel_queue_enqueue.h
index 66ce2dfb6f1..df67fabab19 100644
--- a/intern/cycles/kernel/split/kernel_queue_enqueue.h
+++ b/intern/cycles/kernel/split/kernel_queue_enqueue.h
@@ -56,6 +56,7 @@ ccl_device void kernel_queue_enqueue(KernelGlobals *kg,
queue_number = QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS;
}
else if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE) ||
+ IS_STATE(kernel_split_state.ray_state, ray_index, RAY_HAS_ONLY_VOLUME) ||
IS_STATE(kernel_split_state.ray_state, ray_index, RAY_REGENERATED)) {
queue_number = QUEUE_ACTIVE_AND_REGENERATED_RAYS;
}
diff --git a/intern/cycles/kernel/split/kernel_shader_setup.h b/intern/cycles/kernel/split/kernel_shader_setup.h
index 9d428ee8139..ea3ec2ec83f 100644
--- a/intern/cycles/kernel/split/kernel_shader_setup.h
+++ b/intern/cycles/kernel/split/kernel_shader_setup.h
@@ -59,12 +59,20 @@ ccl_device void kernel_shader_setup(KernelGlobals *kg,
if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE)) {
Intersection isect = kernel_split_state.isect[ray_index];
Ray ray = kernel_split_state.ray[ray_index];
+ ShaderData *sd = kernel_split_sd(sd, ray_index);
shader_setup_from_ray(kg,
- kernel_split_sd(sd, ray_index),
+ sd,
&isect,
&ray);
+
+#ifdef __VOLUME__
+ if(sd->flag & SD_HAS_ONLY_VOLUME) {
+ ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_HAS_ONLY_VOLUME);
+ }
+#endif
}
+
}
CCL_NAMESPACE_END
diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c
index 42d152cc7de..7023e44d289 100644
--- a/source/blender/gpu/intern/gpu_select.c
+++ b/source/blender/gpu/intern/gpu_select.c
@@ -150,29 +150,6 @@ bool GPU_select_load_id(uint id)
}
/**
- * Needed when GL context of #GPU_select_end
- * can't be used to finalize selection operations
- * (because of context changes).
- */
-void GPU_select_finalize(void)
-{
- if (!g_select_state.select_is_active)
- return;
-
- switch (g_select_state.algorithm) {
- case ALGO_GL_LEGACY:
- case ALGO_GL_QUERY:
- {
- break;
- }
- default: /* ALGO_GL_PICK */
- {
- gpu_select_pick_finalize();
- }
- }
-}
-
-/**
* Cleanup and flush selection results to buffer.
* Return number of hits and hits in buffer.
* if \a dopass is true, we will do a second pass with occlusion queries to get the closest hit.
diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c
index 9aff708d32a..4aef80934ad 100644
--- a/source/blender/gpu/intern/gpu_select_pick.c
+++ b/source/blender/gpu/intern/gpu_select_pick.c
@@ -257,7 +257,6 @@ typedef struct GPUPickState {
/* Set after first draw */
bool is_init;
- bool is_finalized;
uint prev_id;
} gl;
@@ -368,7 +367,6 @@ void gpu_select_pick_begin(
#endif
ps->gl.is_init = false;
- ps->gl.is_finalized = false;
ps->gl.prev_id = 0;
}
else {
@@ -529,20 +527,6 @@ bool gpu_select_pick_load_id(uint id)
return true;
}
- /**
- * (Optional), call before 'gpu_select_pick_end' if GL context is not kept.
- * is not compatible with regular select case.
- * */
-void gpu_select_pick_finalize(void)
-{
- GPUPickState *ps = &g_pick_state;
- if (ps->gl.is_init) {
- /* force finishing last pass */
- gpu_select_pick_load_id(ps->gl.prev_id);
- }
- ps->gl.is_finalized = true;
-}
-
uint gpu_select_pick_end(void)
{
GPUPickState *ps = &g_pick_state;
@@ -552,10 +536,10 @@ uint gpu_select_pick_end(void)
#endif
if (ps->is_cached == false) {
- if (ps->gl.is_finalized == false) {
- gpu_select_pick_finalize();
+ if (ps->gl.is_init) {
+ /* force finishing last pass */
+ gpu_select_pick_load_id(ps->gl.prev_id);
}
-
gpuPopAttrib();
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
diff --git a/source/blender/gpu/intern/gpu_select_private.h b/source/blender/gpu/intern/gpu_select_private.h
index 8368aaa9edc..8935bd7b253 100644
--- a/source/blender/gpu/intern/gpu_select_private.h
+++ b/source/blender/gpu/intern/gpu_select_private.h
@@ -35,7 +35,6 @@
/* gpu_select_pick */
void gpu_select_pick_begin(unsigned int (*buffer)[4], unsigned int bufsize, const rcti *input, char mode);
bool gpu_select_pick_load_id(unsigned int id);
-void gpu_select_pick_finalize(void);
unsigned int gpu_select_pick_end(void);
void gpu_select_pick_cache_begin(void);