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:
authorPatrick Mours <pmours@nvidia.com>2019-08-25 19:11:41 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2019-08-26 11:26:53 +0300
commitfd52dc58ddea642b7162b01538c0c6c48abb0507 (patch)
tree21df79cee59c14c0cada5c4bc49da3824d4c8a4b /intern/cycles/kernel/kernel_light.h
parentf491c23f1e104998752380b930307e7abc4597b3 (diff)
Cycles: GPU code generation optimizations for direct lighting
Use a single loop to iterate over all lights, reducing divergence and amount of code to generate. Moving ray intersection calls out of conditionals will also help the Optix compiler. Ref D5363
Diffstat (limited to 'intern/cycles/kernel/kernel_light.h')
-rw-r--r--intern/cycles/kernel/kernel_light.h61
1 files changed, 34 insertions, 27 deletions
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 758e91159b6..ce908ce0fe2 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -1076,7 +1076,7 @@ ccl_device int light_distribution_sample(KernelGlobals *kg, float *randu)
int len = kernel_data.integrator.num_distribution + 1;
float r = *randu;
- while (len > 0) {
+ do {
int half_len = len >> 1;
int middle = first + half_len;
@@ -1087,7 +1087,7 @@ ccl_device int light_distribution_sample(KernelGlobals *kg, float *randu)
first = middle + 1;
len = len - half_len - 1;
}
- }
+ } while (len > 0);
/* Clamping should not be needed but float rounding errors seem to
* make this fail on rare occasions. */
@@ -1104,42 +1104,49 @@ ccl_device int light_distribution_sample(KernelGlobals *kg, float *randu)
/* Generic Light */
-ccl_device bool light_select_reached_max_bounces(KernelGlobals *kg, int index, int bounce)
+ccl_device_inline bool light_select_reached_max_bounces(KernelGlobals *kg, int index, int bounce)
{
return (bounce > kernel_tex_fetch(__lights, index).max_bounces);
}
-ccl_device_noinline bool light_sample(
- KernelGlobals *kg, float randu, float randv, float time, float3 P, int bounce, LightSample *ls)
+ccl_device_noinline bool light_sample(KernelGlobals *kg,
+ int lamp,
+ float randu,
+ float randv,
+ float time,
+ float3 P,
+ int bounce,
+ LightSample *ls)
{
- /* sample index */
- int index = light_distribution_sample(kg, &randu);
-
- /* fetch light data */
- const ccl_global KernelLightDistribution *kdistribution = &kernel_tex_fetch(__light_distribution,
- index);
- int prim = kdistribution->prim;
-
- if (prim >= 0) {
- int object = kdistribution->mesh_light.object_id;
- int shader_flag = kdistribution->mesh_light.shader_flag;
+ if (lamp < 0) {
+ /* sample index */
+ int index = light_distribution_sample(kg, &randu);
+
+ /* fetch light data */
+ const ccl_global KernelLightDistribution *kdistribution = &kernel_tex_fetch(
+ __light_distribution, index);
+ int prim = kdistribution->prim;
+
+ if (prim >= 0) {
+ int object = kdistribution->mesh_light.object_id;
+ int shader_flag = kdistribution->mesh_light.shader_flag;
+
+ triangle_light_sample(kg, prim, object, randu, randv, time, ls, P);
+ ls->shader |= shader_flag;
+ return (ls->pdf > 0.0f);
+ }
- triangle_light_sample(kg, prim, object, randu, randv, time, ls, P);
- ls->shader |= shader_flag;
- return (ls->pdf > 0.0f);
+ lamp = -prim - 1;
}
- else {
- int lamp = -prim - 1;
- if (UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) {
- return false;
- }
-
- return lamp_light_sample(kg, lamp, randu, randv, P, ls);
+ if (UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) {
+ return false;
}
+
+ return lamp_light_sample(kg, lamp, randu, randv, P, ls);
}
-ccl_device int light_select_num_samples(KernelGlobals *kg, int index)
+ccl_device_inline int light_select_num_samples(KernelGlobals *kg, int index)
{
return kernel_tex_fetch(__lights, index).samples;
}