diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-08-20 08:50:15 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-08-20 08:50:15 +0300 |
commit | 74974881491d0a8140de5f67421b04a6584ca3d8 (patch) | |
tree | 48415c6929cb179fc303e4619bc5f231c544d268 | |
parent | 64c7cf203627d5fc02c03e2a74de197ded36e129 (diff) | |
parent | 46cf33bf0146946ed05756a9b8bfa1318538f020 (diff) |
Merge branch 'master' into blender2.8
45 files changed, 450 insertions, 394 deletions
diff --git a/intern/cycles/kernel/bvh/bvh_traversal.h b/intern/cycles/kernel/bvh/bvh_traversal.h index ae8f54821f2..bdf43dcac18 100644 --- a/intern/cycles/kernel/bvh/bvh_traversal.h +++ b/intern/cycles/kernel/bvh/bvh_traversal.h @@ -244,14 +244,14 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, { /* shadow ray early termination */ #if defined(__KERNEL_SSE2__) - if(visibility & PATH_RAY_SHADOW_OPAQUE) + if(!(visibility & (PATH_RAY_ALL_VISIBILITY - PATH_RAY_SHADOW_OPAQUE))) return true; tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t); # if BVH_FEATURE(BVH_HAIR) tfar = ssef(isect->t); # endif #else - if(visibility & PATH_RAY_SHADOW_OPAQUE) + if(!(visibility & (PATH_RAY_ALL_VISIBILITY - PATH_RAY_SHADOW_OPAQUE))) return true; #endif } @@ -274,14 +274,14 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, { /* shadow ray early termination */ # if defined(__KERNEL_SSE2__) - if(visibility & PATH_RAY_SHADOW_OPAQUE) + if(!(visibility & (PATH_RAY_ALL_VISIBILITY - PATH_RAY_SHADOW_OPAQUE))) return true; tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t); # if BVH_FEATURE(BVH_HAIR) tfar = ssef(isect->t); # endif # else - if(visibility & PATH_RAY_SHADOW_OPAQUE) + if(!(visibility & (PATH_RAY_ALL_VISIBILITY - PATH_RAY_SHADOW_OPAQUE))) return true; # endif } @@ -328,14 +328,14 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(hit) { /* shadow ray early termination */ # if defined(__KERNEL_SSE2__) - if(visibility & PATH_RAY_SHADOW_OPAQUE) + if(!(visibility & (PATH_RAY_ALL_VISIBILITY - PATH_RAY_SHADOW_OPAQUE))) return true; tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t); # if BVH_FEATURE(BVH_HAIR) tfar = ssef(isect->t); # endif # else - if(visibility & PATH_RAY_SHADOW_OPAQUE) + if(!(visibility & (PATH_RAY_ALL_VISIBILITY - PATH_RAY_SHADOW_OPAQUE))) return true; # endif } diff --git a/intern/cycles/kernel/bvh/qbvh_traversal.h b/intern/cycles/kernel/bvh/qbvh_traversal.h index 335a4afd47a..3ee3bf57899 100644 --- a/intern/cycles/kernel/bvh/qbvh_traversal.h +++ b/intern/cycles/kernel/bvh/qbvh_traversal.h @@ -340,7 +340,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, prim_addr)) { tfar = ssef(isect->t); /* Shadow ray early termination. */ - if(visibility & PATH_RAY_SHADOW_OPAQUE) { + if(!(visibility & (PATH_RAY_ALL_VISIBILITY - PATH_RAY_SHADOW_OPAQUE))) { return true; } } @@ -362,7 +362,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, prim_addr)) { tfar = ssef(isect->t); /* Shadow ray early termination. */ - if(visibility & PATH_RAY_SHADOW_OPAQUE) { + if(!(visibility & (PATH_RAY_ALL_VISIBILITY - PATH_RAY_SHADOW_OPAQUE))) { return true; } } @@ -409,7 +409,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(hit) { tfar = ssef(isect->t); /* Shadow ray early termination. */ - if(visibility & PATH_RAY_SHADOW_OPAQUE) { + if(!(visibility & (PATH_RAY_ALL_VISIBILITY - PATH_RAY_SHADOW_OPAQUE))) { return true; } } diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h index f18d145f7cf..ea30ee9c139 100644 --- a/intern/cycles/kernel/kernel_bake.h +++ b/intern/cycles/kernel/kernel_bake.h @@ -21,7 +21,7 @@ CCL_NAMESPACE_BEGIN ccl_device_inline void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, - RNG rng, + uint rng_hash, int pass_filter, int sample) { @@ -48,11 +48,11 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg, path_radiance_init(&L_sample, kernel_data.film.use_light_pass); /* init path state */ - path_state_init(kg, &emission_sd, &state, &rng, sample, NULL); + path_state_init(kg, &emission_sd, &state, rng_hash, sample, NULL); /* evaluate surface shader */ - float rbsdf = path_state_rng_1D(kg, &rng, &state, PRNG_BSDF); - shader_eval_surface(kg, sd, &rng, &state, rbsdf, state.flag, SHADER_CONTEXT_MAIN); + float rbsdf = path_state_rng_1D(kg, &state, PRNG_BSDF); + shader_eval_surface(kg, sd, &state, rbsdf, state.flag, SHADER_CONTEXT_MAIN); /* TODO, disable more closures we don't need besides transparent */ shader_bsdf_disable_transparency(kg, sd); @@ -64,7 +64,7 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg, /* sample ambient occlusion */ if(pass_filter & BAKE_FILTER_AO) { - kernel_path_ao(kg, sd, &emission_sd, &L_sample, &state, &rng, throughput, shader_bsdf_alpha(kg, sd)); + kernel_path_ao(kg, sd, &emission_sd, &L_sample, &state, throughput, shader_bsdf_alpha(kg, sd)); } /* sample emission */ @@ -86,7 +86,6 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg, &emission_sd, &L_sample, &state, - &rng, &ray, &throughput, &ss_indirect)) @@ -101,7 +100,6 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg, kernel_path_indirect(kg, &indirect_sd, &emission_sd, - &rng, &ray, throughput, state.num_samples, @@ -116,14 +114,14 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg, /* sample light and BSDF */ if(!is_sss_sample && (pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT))) { - kernel_path_surface_connect_light(kg, &rng, sd, &emission_sd, throughput, &state, &L_sample); + kernel_path_surface_connect_light(kg, sd, &emission_sd, throughput, &state, &L_sample); - if(kernel_path_surface_bounce(kg, &rng, sd, &throughput, &state, &L_sample, &ray)) { + if(kernel_path_surface_bounce(kg, sd, &throughput, &state, &L_sample, &ray)) { #ifdef __LAMP_MIS__ state.ray_t = 0.0f; #endif /* compute indirect light */ - kernel_path_indirect(kg, &indirect_sd, &emission_sd, &rng, &ray, throughput, 1, &state, &L_sample); + kernel_path_indirect(kg, &indirect_sd, &emission_sd, &ray, throughput, 1, &state, &L_sample); /* sum and reset indirect light pass variables for the next samples */ path_radiance_sum_indirect(&L_sample); @@ -137,7 +135,7 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg, /* sample ambient occlusion */ if(pass_filter & BAKE_FILTER_AO) { - kernel_branched_path_ao(kg, sd, &emission_sd, &L_sample, &state, &rng, throughput); + kernel_branched_path_ao(kg, sd, &emission_sd, &L_sample, &state, throughput); } /* sample emission */ @@ -151,7 +149,7 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg, if((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) { /* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */ kernel_branched_path_subsurface_scatter(kg, sd, &indirect_sd, - &emission_sd, &L_sample, &state, &rng, &ray, throughput); + &emission_sd, &L_sample, &state, &ray, throughput); } #endif @@ -161,13 +159,13 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg, /* direct light */ if(kernel_data.integrator.use_direct_light) { int all = kernel_data.integrator.sample_all_lights_direct; - kernel_branched_path_surface_connect_light(kg, &rng, + kernel_branched_path_surface_connect_light(kg, sd, &emission_sd, &state, throughput, 1.0f, &L_sample, all); } #endif /* indirect light */ - kernel_branched_path_surface_indirect_light(kg, &rng, + kernel_branched_path_surface_indirect_light(kg, sd, &indirect_sd, &emission_sd, throughput, 1.0f, &state, &L_sample); } } @@ -225,7 +223,6 @@ ccl_device_inline float3 kernel_bake_shader_bsdf(KernelGlobals *kg, ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg, ShaderData *sd, - RNG *rng, PathState *state, float3 direct, float3 indirect, @@ -245,12 +242,12 @@ ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg, } else { /* surface color of the pass only */ - shader_eval_surface(kg, sd, rng, state, 0.0f, 0, SHADER_CONTEXT_MAIN); + shader_eval_surface(kg, sd, state, 0.0f, 0, SHADER_CONTEXT_MAIN); return kernel_bake_shader_bsdf(kg, sd, type); } } else { - shader_eval_surface(kg, sd, rng, state, 0.0f, 0, SHADER_CONTEXT_MAIN); + shader_eval_surface(kg, sd, state, 0.0f, 0, SHADER_CONTEXT_MAIN); color = kernel_bake_shader_bsdf(kg, sd, type); } @@ -292,14 +289,14 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, int num_samples = kernel_data.integrator.aa_samples; /* random number generator */ - RNG rng = cmj_hash(offset + i, kernel_data.integrator.seed); + uint rng_hash = cmj_hash(offset + i, kernel_data.integrator.seed); float filter_x, filter_y; if(sample == 0) { filter_x = filter_y = 0.5f; } else { - path_rng_2D(kg, &rng, sample, num_samples, PRNG_FILTER_U, &filter_x, &filter_y); + path_rng_2D(kg, rng_hash, sample, num_samples, PRNG_FILTER_U, &filter_x, &filter_y); } /* subpixel u/v offset */ @@ -335,14 +332,14 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, /* light passes if we need more than color */ if(pass_filter & ~BAKE_FILTER_COLOR) - compute_light_pass(kg, &sd, &L, rng, pass_filter, sample); + compute_light_pass(kg, &sd, &L, rng_hash, pass_filter, sample); switch(type) { /* data passes */ case SHADER_EVAL_NORMAL: { if((sd.flag & SD_HAS_BUMP)) { - shader_eval_surface(kg, &sd, &rng, &state, 0.f, 0, SHADER_CONTEXT_MAIN); + shader_eval_surface(kg, &sd, &state, 0.f, 0, SHADER_CONTEXT_MAIN); } /* compression: normal = (2 * color) - 1 */ @@ -356,7 +353,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, } case SHADER_EVAL_EMISSION: { - shader_eval_surface(kg, &sd, &rng, &state, 0.f, 0, SHADER_CONTEXT_EMISSION); + shader_eval_surface(kg, &sd, &state, 0.f, 0, SHADER_CONTEXT_EMISSION); out = shader_emissive_eval(kg, &sd); break; } @@ -409,7 +406,6 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, { out = kernel_bake_evaluate_direct_indirect(kg, &sd, - &rng, &state, L.direct_diffuse, L.indirect_diffuse, @@ -421,7 +417,6 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, { out = kernel_bake_evaluate_direct_indirect(kg, &sd, - &rng, &state, L.direct_glossy, L.indirect_glossy, @@ -433,7 +428,6 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, { out = kernel_bake_evaluate_direct_indirect(kg, &sd, - &rng, &state, L.direct_transmission, L.indirect_transmission, @@ -446,7 +440,6 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, #ifdef __SUBSURFACE__ out = kernel_bake_evaluate_direct_indirect(kg, &sd, - &rng, &state, L.direct_subsurface, L.indirect_subsurface, diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index 36ae9702227..df63124ae5c 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -72,7 +72,7 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, /* no path flag, we're evaluating this for all closures. that's weak but * we'd have to do multiple evaluations otherwise */ path_state_modify_bounce(state, true); - shader_eval_surface(kg, emission_sd, NULL, state, 0.0f, 0, SHADER_CONTEXT_EMISSION); + shader_eval_surface(kg, emission_sd, state, 0.0f, 0, SHADER_CONTEXT_EMISSION); path_state_modify_bounce(state, false); /* evaluate emissive closure */ diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index c454228eab5..5fc64b2b11b 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -55,14 +55,13 @@ ccl_device_noinline void kernel_path_ao(KernelGlobals *kg, ShaderData *emission_sd, PathRadiance *L, ccl_addr_space PathState *state, - RNG *rng, float3 throughput, float3 ao_alpha) { /* todo: solve correlation */ float bsdf_u, bsdf_v; - path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v); + path_state_rng_2D(kg, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v); float ao_factor = kernel_data.background.ao_factor; float3 ao_N; @@ -101,7 +100,6 @@ ccl_device_noinline void kernel_path_ao(KernelGlobals *kg, ccl_device void kernel_path_indirect(KernelGlobals *kg, ShaderData *sd, ShaderData *emission_sd, - RNG *rng, Ray *ray, float3 throughput, int num_samples, @@ -200,7 +198,6 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, /* direct light sampling */ kernel_branched_path_volume_connect_light(kg, - rng, sd, emission_sd, throughput, @@ -213,8 +210,8 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, /* indirect sample. if we use distance sampling and take just * one sample for direct and indirect light, we could share * this computation, but makes code a bit complex */ - float rphase = path_state_rng_1D_for_decision(kg, rng, state, PRNG_PHASE); - float rscatter = path_state_rng_1D_for_decision(kg, rng, state, PRNG_SCATTER_DISTANCE); + float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE); + float rscatter = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE); result = kernel_volume_decoupled_scatter(kg, state, @@ -233,7 +230,6 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, if(result == VOLUME_PATH_SCATTERED) { if(kernel_path_volume_bounce(kg, - rng, sd, &throughput, state, @@ -255,13 +251,12 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, { /* integrate along volume segment with distance sampling */ VolumeIntegrateResult result = kernel_volume_integrate( - kg, state, sd, &volume_ray, L, &throughput, rng, heterogeneous); + kg, state, sd, &volume_ray, L, &throughput, heterogeneous); # ifdef __VOLUME_SCATTER__ if(result == VOLUME_PATH_SCATTERED) { /* direct lighting */ kernel_path_volume_connect_light(kg, - rng, sd, emission_sd, throughput, @@ -270,7 +265,6 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, /* indirect light bounce */ if(kernel_path_volume_bounce(kg, - rng, sd, &throughput, state, @@ -309,8 +303,8 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, sd, &isect, ray); - float rbsdf = path_state_rng_1D_for_decision(kg, rng, state, PRNG_BSDF); - shader_eval_surface(kg, sd, rng, state, rbsdf, state->flag, SHADER_CONTEXT_INDIRECT); + float rbsdf = path_state_rng_1D_for_decision(kg, state, PRNG_BSDF); + shader_eval_surface(kg, sd, state, rbsdf, state->flag, SHADER_CONTEXT_INDIRECT); #ifdef __BRANCHED_PATH__ shader_merge_closures(sd); #endif /* __BRANCHED_PATH__ */ @@ -360,7 +354,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, break; } else if(probability != 1.0f) { - float terminate = path_state_rng_1D_for_decision(kg, rng, state, PRNG_TERMINATE); + float terminate = path_state_rng_1D_for_decision(kg, state, PRNG_TERMINATE); if(terminate >= probability) break; @@ -373,7 +367,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, #ifdef __AO__ /* ambient occlusion */ if(kernel_data.integrator.use_ambient_occlusion || (sd->flag & SD_AO)) { - kernel_path_ao(kg, sd, emission_sd, L, state, rng, throughput, make_float3(0.0f, 0.0f, 0.0f)); + kernel_path_ao(kg, sd, emission_sd, L, state, throughput, make_float3(0.0f, 0.0f, 0.0f)); } #endif /* __AO__ */ @@ -389,11 +383,10 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, /* do bssrdf scatter step if we picked a bssrdf closure */ if(sc) { - uint lcg_state = lcg_state_init(rng, state->rng_offset, state->sample, 0x68bc21eb); + uint lcg_state = lcg_state_init(state, 0x68bc21eb); float bssrdf_u, bssrdf_v; path_state_rng_2D(kg, - rng, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); @@ -414,7 +407,6 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, int all = (kernel_data.integrator.sample_all_lights_indirect) || (state->flag & PATH_RAY_SHADOW_CATCHER); kernel_branched_path_surface_connect_light(kg, - rng, sd, emission_sd, state, @@ -425,7 +417,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, } #endif /* defined(__EMISSION__) */ - if(!kernel_path_surface_bounce(kg, rng, sd, &throughput, state, L, ray)) + if(!kernel_path_surface_bounce(kg, sd, &throughput, state, L, ray)) break; } } @@ -433,7 +425,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, #endif /* defined(__BRANCHED_PATH__) || defined(__BAKING__) */ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg, - RNG *rng, + uint rng_hash, int sample, Ray ray, ccl_global float *buffer, @@ -451,7 +443,7 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg, ShaderData emission_sd; PathState state; - path_state_init(kg, &emission_sd, &state, rng, sample, &ray); + path_state_init(kg, &emission_sd, &state, rng_hash, sample, &ray); #ifdef __SUBSURFACE__ SubsurfaceIndirectRays ss_indirect; @@ -478,7 +470,7 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg, } extmax = kernel_data.curve.maximum_width; - lcg_state = lcg_state_init(rng, state.rng_offset, state.sample, 0x51633e2d); + lcg_state = lcg_state_init(&state, 0x51633e2d); } if(state.bounce > kernel_data.integrator.ao_bounces) { @@ -558,15 +550,15 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg, int all = false; /* direct light sampling */ - kernel_branched_path_volume_connect_light(kg, rng, &sd, + kernel_branched_path_volume_connect_light(kg, &sd, &emission_sd, throughput, &state, L, all, &volume_ray, &volume_segment); /* indirect sample. if we use distance sampling and take just * one sample for direct and indirect light, we could share * this computation, but makes code a bit complex */ - float rphase = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_PHASE); - float rscatter = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_SCATTER_DISTANCE); + float rphase = path_state_rng_1D_for_decision(kg, &state, PRNG_PHASE); + float rscatter = path_state_rng_1D_for_decision(kg, &state, PRNG_SCATTER_DISTANCE); result = kernel_volume_decoupled_scatter(kg, &state, &volume_ray, &sd, &throughput, @@ -577,7 +569,7 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg, kernel_volume_decoupled_free(kg, &volume_segment); if(result == VOLUME_PATH_SCATTERED) { - if(kernel_path_volume_bounce(kg, rng, &sd, &throughput, &state, L, &ray)) + if(kernel_path_volume_bounce(kg, &sd, &throughput, &state, L, &ray)) continue; else break; @@ -591,15 +583,15 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg, { /* integrate along volume segment with distance sampling */ VolumeIntegrateResult result = kernel_volume_integrate( - kg, &state, &sd, &volume_ray, L, &throughput, rng, heterogeneous); + kg, &state, &sd, &volume_ray, L, &throughput, heterogeneous); # ifdef __VOLUME_SCATTER__ if(result == VOLUME_PATH_SCATTERED) { /* direct lighting */ - kernel_path_volume_connect_light(kg, rng, &sd, &emission_sd, throughput, &state, L); + kernel_path_volume_connect_light(kg, &sd, &emission_sd, throughput, &state, L); /* indirect light bounce */ - if(kernel_path_volume_bounce(kg, rng, &sd, &throughput, &state, L, &ray)) + if(kernel_path_volume_bounce(kg, &sd, &throughput, &state, L, &ray)) continue; else break; @@ -634,8 +626,8 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg, /* setup shading */ shader_setup_from_ray(kg, &sd, &isect, &ray); - float rbsdf = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_BSDF); - shader_eval_surface(kg, &sd, rng, &state, rbsdf, state.flag, SHADER_CONTEXT_MAIN); + float rbsdf = path_state_rng_1D_for_decision(kg, &state, PRNG_BSDF); + shader_eval_surface(kg, &sd, &state, rbsdf, state.flag, SHADER_CONTEXT_MAIN); #ifdef __SHADOW_TRICKS__ if((sd.object_flag & SD_OBJECT_SHADOW_CATCHER)) { @@ -713,7 +705,7 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg, break; } else if(probability != 1.0f) { - float terminate = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_TERMINATE); + float terminate = path_state_rng_1D_for_decision(kg, &state, PRNG_TERMINATE); if(terminate >= probability) break; @@ -725,7 +717,7 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg, #ifdef __AO__ /* ambient occlusion */ if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { - kernel_path_ao(kg, &sd, &emission_sd, L, &state, rng, throughput, shader_bsdf_alpha(kg, &sd)); + kernel_path_ao(kg, &sd, &emission_sd, L, &state, throughput, shader_bsdf_alpha(kg, &sd)); } #endif /* __AO__ */ @@ -738,7 +730,6 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg, &emission_sd, L, &state, - rng, &ray, &throughput, &ss_indirect)) @@ -749,10 +740,10 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg, #endif /* __SUBSURFACE__ */ /* direct lighting */ - kernel_path_surface_connect_light(kg, rng, &sd, &emission_sd, throughput, &state, L); + kernel_path_surface_connect_light(kg, &sd, &emission_sd, throughput, &state, L); /* compute direct lighting and next bounce */ - if(!kernel_path_surface_bounce(kg, rng, &sd, &throughput, &state, L, &ray)) + if(!kernel_path_surface_bounce(kg, &sd, &throughput, &state, L, &ray)) break; } @@ -793,17 +784,17 @@ ccl_device void kernel_path_trace(KernelGlobals *kg, buffer += index*pass_stride; /* initialize random numbers and ray */ - RNG rng; + uint rng_hash; Ray ray; - kernel_path_trace_setup(kg, rng_state, sample, x, y, &rng, &ray); + kernel_path_trace_setup(kg, rng_state, sample, x, y, &rng_hash, &ray); /* integrate */ PathRadiance L; bool is_shadow_catcher; if(ray.t != 0.0f) { - kernel_path_integrate(kg, &rng, sample, ray, buffer, &L, &is_shadow_catcher); + kernel_path_integrate(kg, rng_hash, sample, ray, buffer, &L, &is_shadow_catcher); kernel_write_result(kg, buffer, sample, &L, is_shadow_catcher); } else { diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h index abc291bc7e3..bce8d361b62 100644 --- a/intern/cycles/kernel/kernel_path_branched.h +++ b/intern/cycles/kernel/kernel_path_branched.h @@ -23,7 +23,6 @@ ccl_device_inline void kernel_branched_path_ao(KernelGlobals *kg, ShaderData *emission_sd, PathRadiance *L, ccl_addr_space PathState *state, - RNG *rng, float3 throughput) { int num_samples = kernel_data.integrator.ao_samples; @@ -35,7 +34,7 @@ ccl_device_inline void kernel_branched_path_ao(KernelGlobals *kg, for(int j = 0; j < num_samples; j++) { float bsdf_u, bsdf_v; - path_branched_rng_2D(kg, rng, state, j, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v); + path_branched_rng_2D(kg, state->rng_hash, state, j, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v); float3 ao_D; float ao_pdf; @@ -69,7 +68,7 @@ ccl_device_inline void kernel_branched_path_ao(KernelGlobals *kg, /* bounce off surface and integrate indirect light */ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGlobals *kg, - RNG *rng, ShaderData *sd, ShaderData *indirect_sd, ShaderData *emission_sd, + ShaderData *sd, ShaderData *indirect_sd, ShaderData *emission_sd, float3 throughput, float num_samples_adjust, PathState *state, PathRadiance *L) { float sum_sample_weight = 0.0f; @@ -113,7 +112,6 @@ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGloba num_samples = ceil_to_int(num_samples_adjust*num_samples); float num_samples_inv = num_samples_adjust/num_samples; - RNG bsdf_rng = cmj_hash(*rng, i); for(int j = 0; j < num_samples; j++) { PathState ps = *state; @@ -123,8 +121,9 @@ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGloba float shadow_transparency = L->shadow_transparency; #endif + ps.rng_hash = cmj_hash(state->rng_hash, i); + if(!kernel_branched_path_surface_bounce(kg, - &bsdf_rng, sd, sc, j, @@ -138,10 +137,11 @@ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGloba continue; } + ps.rng_hash = state->rng_hash; + kernel_path_indirect(kg, indirect_sd, emission_sd, - rng, &bsdf_ray, tp*num_samples_inv, num_samples, @@ -167,7 +167,6 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg, ShaderData *emission_sd, PathRadiance *L, PathState *state, - RNG *rng, Ray *ray, float3 throughput) { @@ -178,17 +177,17 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg, continue; /* set up random number generator */ - uint lcg_state = lcg_state_init(rng, state->rng_offset, state->sample, 0x68bc21eb); + uint lcg_state = lcg_state_init(state, 0x68bc21eb); int num_samples = kernel_data.integrator.subsurface_samples; float num_samples_inv = 1.0f/num_samples; - RNG bssrdf_rng = cmj_hash(*rng, i); + uint bssrdf_rng_hash = cmj_hash(state->rng_hash, i); /* do subsurface scatter step with copy of shader data, this will * replace the BSSRDF with a diffuse BSDF closure */ for(int j = 0; j < num_samples; j++) { SubsurfaceIntersection ss_isect; float bssrdf_u, bssrdf_v; - path_branched_rng_2D(kg, &bssrdf_rng, state, j, num_samples, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); + path_branched_rng_2D(kg, bssrdf_rng_hash, state, j, num_samples, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); int num_hits = subsurface_scatter_multi_intersect(kg, &ss_isect, sd, @@ -241,7 +240,6 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg, (state->flag & PATH_RAY_SHADOW_CATCHER); kernel_branched_path_surface_connect_light( kg, - rng, &bssrdf_sd, emission_sd, &hit_state, @@ -255,7 +253,6 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg, /* indirect light */ kernel_branched_path_surface_indirect_light( kg, - rng, &bssrdf_sd, indirect_sd, emission_sd, @@ -270,7 +267,7 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg, #endif /* __SUBSURFACE__ */ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, - RNG *rng, + uint rng_hash, int sample, Ray ray, ccl_global float *buffer, @@ -288,7 +285,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, ShaderData emission_sd, indirect_sd; PathState state; - path_state_init(kg, &emission_sd, &state, rng, sample, &ray); + path_state_init(kg, &emission_sd, &state, rng_hash, sample, &ray); /* Main Loop * Here we only handle transparency intersections from the camera ray. @@ -311,7 +308,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, } extmax = kernel_data.curve.maximum_width; - lcg_state = lcg_state_init(rng, state.rng_offset, state.sample, 0x51633e2d); + lcg_state = lcg_state_init(&state, 0x51633e2d); } bool hit = scene_intersect(kg, ray, visibility, &isect, &lcg_state, difl, extmax); @@ -354,7 +351,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, int all = kernel_data.integrator.sample_all_lights_direct; - kernel_branched_path_volume_connect_light(kg, rng, &sd, + kernel_branched_path_volume_connect_light(kg, &sd, &emission_sd, throughput, &state, L, all, &volume_ray, &volume_segment); @@ -373,8 +370,8 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, /* scatter sample. if we use distance sampling and take just one * sample for direct and indirect light, we could share this * computation, but makes code a bit complex */ - float rphase = path_state_rng_1D_for_decision(kg, rng, &ps, PRNG_PHASE); - float rscatter = path_state_rng_1D_for_decision(kg, rng, &ps, PRNG_SCATTER_DISTANCE); + float rphase = path_state_rng_1D_for_decision(kg, &ps, PRNG_PHASE); + float rscatter = path_state_rng_1D_for_decision(kg, &ps, PRNG_SCATTER_DISTANCE); VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg, &ps, &pray, &sd, &tp, rphase, rscatter, &volume_segment, NULL, false); @@ -383,7 +380,6 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, kernel_assert(result == VOLUME_PATH_SCATTERED); if(kernel_path_volume_bounce(kg, - rng, &sd, &tp, &ps, @@ -393,7 +389,6 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, kernel_path_indirect(kg, &indirect_sd, &emission_sd, - rng, &pray, tp*num_samples_inv, num_samples, @@ -432,16 +427,15 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, path_state_branch(&ps, j, num_samples); VolumeIntegrateResult result = kernel_volume_integrate( - kg, &ps, &sd, &volume_ray, L, &tp, rng, heterogeneous); + kg, &ps, &sd, &volume_ray, L, &tp, heterogeneous); #ifdef __VOLUME_SCATTER__ if(result == VOLUME_PATH_SCATTERED) { /* todo: support equiangular, MIS and all light sampling. * alternatively get decoupled ray marching working on the GPU */ - kernel_path_volume_connect_light(kg, rng, &sd, &emission_sd, tp, &state, L); + kernel_path_volume_connect_light(kg, &sd, &emission_sd, tp, &state, L); if(kernel_path_volume_bounce(kg, - rng, &sd, &tp, &ps, @@ -451,7 +445,6 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, kernel_path_indirect(kg, &indirect_sd, &emission_sd, - rng, &pray, tp, num_samples, @@ -495,7 +488,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, /* setup shading */ shader_setup_from_ray(kg, &sd, &isect, &ray); - shader_eval_surface(kg, &sd, rng, &state, 0.0f, state.flag, SHADER_CONTEXT_MAIN); + shader_eval_surface(kg, &sd, &state, 0.0f, state.flag, SHADER_CONTEXT_MAIN); shader_merge_closures(&sd); #ifdef __SHADOW_TRICKS__ @@ -558,7 +551,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, break; } else if(probability != 1.0f) { - float terminate = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_TERMINATE); + float terminate = path_state_rng_1D_for_decision(kg, &state, PRNG_TERMINATE); if(terminate >= probability) break; @@ -572,7 +565,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, #ifdef __AO__ /* ambient occlusion */ if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { - kernel_branched_path_ao(kg, &sd, &emission_sd, L, &state, rng, throughput); + kernel_branched_path_ao(kg, &sd, &emission_sd, L, &state, throughput); } #endif /* __AO__ */ @@ -580,7 +573,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, /* bssrdf scatter to a different location on the same object */ if(sd.flag & SD_BSSRDF) { kernel_branched_path_subsurface_scatter(kg, &sd, &indirect_sd, &emission_sd, - L, &state, rng, &ray, throughput); + L, &state, &ray, throughput); } #endif /* __SUBSURFACE__ */ @@ -592,13 +585,13 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, 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, rng, + 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, rng, + kernel_branched_path_surface_indirect_light(kg, &sd, &indirect_sd, &emission_sd, throughput, 1.0f, &hit_state, L); /* continue in case of transparency */ @@ -645,17 +638,17 @@ ccl_device void kernel_branched_path_trace(KernelGlobals *kg, buffer += index*pass_stride; /* initialize random numbers and ray */ - RNG rng; + uint rng_hash; Ray ray; - kernel_path_trace_setup(kg, rng_state, sample, x, y, &rng, &ray); + kernel_path_trace_setup(kg, rng_state, sample, x, y, &rng_hash, &ray); /* integrate */ PathRadiance L; bool is_shadow_catcher; if(ray.t != 0.0f) { - kernel_branched_path_integrate(kg, &rng, sample, ray, buffer, &L, &is_shadow_catcher); + kernel_branched_path_integrate(kg, rng_hash, sample, ray, buffer, &L, &is_shadow_catcher); kernel_write_result(kg, buffer, sample, &L, is_shadow_catcher); } else { diff --git a/intern/cycles/kernel/kernel_path_common.h b/intern/cycles/kernel/kernel_path_common.h index 82f83deb595..54dd278a185 100644 --- a/intern/cycles/kernel/kernel_path_common.h +++ b/intern/cycles/kernel/kernel_path_common.h @@ -22,7 +22,7 @@ ccl_device_inline void kernel_path_trace_setup(KernelGlobals *kg, ccl_global uint *rng_state, int sample, int x, int y, - RNG *rng, + uint *rng_hash, ccl_addr_space Ray *ray) { float filter_u; @@ -34,20 +34,20 @@ ccl_device_inline void kernel_path_trace_setup(KernelGlobals *kg, *rng_state = hash_int_2d(x, y); } - path_rng_init(kg, rng_state, sample, num_samples, rng, x, y, &filter_u, &filter_v); + path_rng_init(kg, rng_state, sample, num_samples, rng_hash, x, y, &filter_u, &filter_v); /* sample camera ray */ float lens_u = 0.0f, lens_v = 0.0f; if(kernel_data.cam.aperturesize > 0.0f) - path_rng_2D(kg, rng, sample, num_samples, PRNG_LENS_U, &lens_u, &lens_v); + path_rng_2D(kg, *rng_hash, sample, num_samples, PRNG_LENS_U, &lens_u, &lens_v); float time = 0.0f; #ifdef __CAMERA_MOTION__ if(kernel_data.cam.shuttertime != -1.0f) - time = path_rng_1D(kg, rng, sample, num_samples, PRNG_TIME); + time = path_rng_1D(kg, *rng_hash, sample, num_samples, PRNG_TIME); #endif camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, time, ray); diff --git a/intern/cycles/kernel/kernel_path_state.h b/intern/cycles/kernel/kernel_path_state.h index 28582de979d..b539224db31 100644 --- a/intern/cycles/kernel/kernel_path_state.h +++ b/intern/cycles/kernel/kernel_path_state.h @@ -19,12 +19,13 @@ CCL_NAMESPACE_BEGIN ccl_device_inline void path_state_init(KernelGlobals *kg, ShaderData *stack_sd, ccl_addr_space PathState *state, - RNG *rng, + uint rng_hash, int sample, ccl_addr_space Ray *ray) { state->flag = PATH_RAY_CAMERA|PATH_RAY_MIS_SKIP; + state->rng_hash = rng_hash; state->rng_offset = PRNG_BASE_NUM; state->sample = sample; state->num_samples = kernel_data.integrator.aa_samples; @@ -58,7 +59,7 @@ ccl_device_inline void path_state_init(KernelGlobals *kg, /* Initialize volume stack with volume we are inside of. */ kernel_volume_stack_init(kg, stack_sd, state, ray, state->volume_stack); /* Seed RNG for cases where we can't use stratified samples .*/ - state->rng_congruential = lcg_init(*rng + sample*0x51633e2d); + state->rng_congruential = lcg_init(rng_hash + sample*0x51633e2d); } else { state->volume_stack[0].shader = SHADER_NONE; diff --git a/intern/cycles/kernel/kernel_path_subsurface.h b/intern/cycles/kernel/kernel_path_subsurface.h index 10b568ac3dd..5fce5ed59d2 100644 --- a/intern/cycles/kernel/kernel_path_subsurface.h +++ b/intern/cycles/kernel/kernel_path_subsurface.h @@ -28,7 +28,6 @@ bool kernel_path_subsurface_scatter( ShaderData *emission_sd, PathRadiance *L, ccl_addr_space PathState *state, - RNG *rng, ccl_addr_space Ray *ray, ccl_addr_space float3 *throughput, ccl_addr_space SubsurfaceIndirectRays *ss_indirect) @@ -47,11 +46,11 @@ bool kernel_path_subsurface_scatter( */ kernel_assert(!ss_indirect->tracing); - uint lcg_state = lcg_state_init(rng, state->rng_offset, state->sample, 0x68bc21eb); + uint lcg_state = lcg_state_init(state, 0x68bc21eb); SubsurfaceIntersection ss_isect; float bssrdf_u, bssrdf_v; - path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); + path_state_rng_2D(kg, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); int num_hits = subsurface_scatter_multi_intersect(kg, &ss_isect, sd, @@ -94,10 +93,9 @@ bool kernel_path_subsurface_scatter( hit_L->direct_throughput = L->direct_throughput; path_radiance_copy_indirect(hit_L, L); - kernel_path_surface_connect_light(kg, rng, sd, emission_sd, *hit_tp, state, hit_L); + kernel_path_surface_connect_light(kg, sd, emission_sd, *hit_tp, state, hit_L); if(kernel_path_surface_bounce(kg, - rng, sd, hit_tp, hit_state, diff --git a/intern/cycles/kernel/kernel_path_surface.h b/intern/cycles/kernel/kernel_path_surface.h index dcb577e176f..3d10736e90c 100644 --- a/intern/cycles/kernel/kernel_path_surface.h +++ b/intern/cycles/kernel/kernel_path_surface.h @@ -20,7 +20,6 @@ CCL_NAMESPACE_BEGIN /* branched path tracing: connect path directly to position on one or more lights and add it to L */ ccl_device_noinline void kernel_branched_path_surface_connect_light( KernelGlobals *kg, - RNG *rng, ShaderData *sd, ShaderData *emission_sd, ccl_addr_space PathState *state, @@ -50,12 +49,12 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light( int num_samples = ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i)); float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights); - RNG lamp_rng = cmj_hash(*rng, i); + uint lamp_rng_hash = cmj_hash(state->rng_hash, i); for(int j = 0; j < num_samples; j++) { float light_u, light_v; - path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); - float terminate = path_branched_rng_light_termination(kg, &lamp_rng, state, j, num_samples); + path_branched_rng_2D(kg, lamp_rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); + float terminate = path_branched_rng_light_termination(kg, lamp_rng_hash, state, j, num_samples); LightSample ls; if(lamp_light_sample(kg, i, light_u, light_v, sd->P, &ls)) { @@ -86,10 +85,10 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light( float num_samples_inv = num_samples_adjust/num_samples; for(int j = 0; j < num_samples; j++) { - float light_t = path_branched_rng_1D(kg, rng, state, j, num_samples, PRNG_LIGHT); + float light_t = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_LIGHT); float light_u, light_v; - path_branched_rng_2D(kg, rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); - float terminate = path_branched_rng_light_termination(kg, rng, state, j, num_samples); + path_branched_rng_2D(kg, state->rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); + float terminate = path_branched_rng_light_termination(kg, state->rng_hash, state, j, num_samples); /* only sample triangle lights */ if(kernel_data.integrator.num_all_lights) @@ -119,10 +118,10 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light( } else { /* sample one light at random */ - float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT); + float light_t = path_state_rng_1D(kg, state, PRNG_LIGHT); float light_u, light_v; - path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v); - float terminate = path_state_rng_light_termination(kg, rng, state); + path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v); + float terminate = path_state_rng_light_termination(kg, state); LightSample ls; if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) { @@ -147,7 +146,6 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light( /* branched path tracing: bounce off or through surface to with new direction stored in ray */ ccl_device bool kernel_branched_path_surface_bounce( KernelGlobals *kg, - RNG *rng, ShaderData *sd, const ShaderClosure *sc, int sample, @@ -164,7 +162,7 @@ ccl_device bool kernel_branched_path_surface_bounce( float3 bsdf_omega_in; differential3 bsdf_domega_in; float bsdf_u, bsdf_v; - path_branched_rng_2D(kg, rng, state, sample, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v); + path_branched_rng_2D(kg, state->rng_hash, state, sample, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v); int label; label = shader_bsdf_sample_closure(kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval, @@ -217,7 +215,7 @@ ccl_device bool kernel_branched_path_surface_bounce( #endif /* path tracing: connect path directly to position on a light and add it to L */ -ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, RNG *rng, +ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, ShaderData *sd, ShaderData *emission_sd, float3 throughput, ccl_addr_space PathState *state, PathRadiance *L) { @@ -228,7 +226,6 @@ ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, RNG #ifdef __SHADOW_TRICKS__ if(state->flag & PATH_RAY_SHADOW_CATCHER) { kernel_branched_path_surface_connect_light(kg, - rng, sd, emission_sd, state, @@ -241,9 +238,9 @@ ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, RNG #endif /* sample illumination from lights to find path contribution */ - float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT); + float light_t = path_state_rng_1D(kg, state, PRNG_LIGHT); float light_u, light_v; - path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v); + path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v); Ray light_ray; BsdfEval L_light; @@ -255,7 +252,7 @@ ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, RNG LightSample ls; if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) { - float terminate = path_state_rng_light_termination(kg, rng, state); + float terminate = path_state_rng_light_termination(kg, state); if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { /* trace shadow ray */ float3 shadow; @@ -274,7 +271,6 @@ ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, RNG /* path tracing: bounce off or through surface to with new direction stored in ray */ ccl_device bool kernel_path_surface_bounce(KernelGlobals *kg, - RNG *rng, ShaderData *sd, ccl_addr_space float3 *throughput, ccl_addr_space PathState *state, @@ -289,7 +285,7 @@ ccl_device bool kernel_path_surface_bounce(KernelGlobals *kg, float3 bsdf_omega_in; differential3 bsdf_domega_in; float bsdf_u, bsdf_v; - path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v); + path_state_rng_2D(kg, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v); int label; label = shader_bsdf_sample(kg, sd, bsdf_u, bsdf_v, &bsdf_eval, diff --git a/intern/cycles/kernel/kernel_path_volume.h b/intern/cycles/kernel/kernel_path_volume.h index dcedf51e479..3661432f0b7 100644 --- a/intern/cycles/kernel/kernel_path_volume.h +++ b/intern/cycles/kernel/kernel_path_volume.h @@ -20,7 +20,6 @@ CCL_NAMESPACE_BEGIN ccl_device_inline void kernel_path_volume_connect_light( KernelGlobals *kg, - RNG *rng, ShaderData *sd, ShaderData *emission_sd, float3 throughput, @@ -32,9 +31,9 @@ ccl_device_inline void kernel_path_volume_connect_light( return; /* sample illumination from lights to find path contribution */ - float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT); + float light_t = path_state_rng_1D(kg, state, PRNG_LIGHT); float light_u, light_v; - path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v); + path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v); Ray light_ray; BsdfEval L_light; @@ -48,7 +47,7 @@ ccl_device_inline void kernel_path_volume_connect_light( if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) { - float terminate = path_state_rng_light_termination(kg, rng, state); + float terminate = path_state_rng_light_termination(kg, state); if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { /* trace shadow ray */ float3 shadow; @@ -69,7 +68,6 @@ ccl_device #endif bool kernel_path_volume_bounce( KernelGlobals *kg, - RNG *rng, ShaderData *sd, ccl_addr_space float3 *throughput, ccl_addr_space PathState *state, @@ -82,7 +80,7 @@ bool kernel_path_volume_bounce( float3 phase_omega_in; differential3 phase_domega_in; float phase_u, phase_v; - path_state_rng_2D(kg, rng, state, PRNG_PHASE_U, &phase_u, &phase_v); + path_state_rng_2D(kg, state, PRNG_PHASE_U, &phase_u, &phase_v); int label; label = shader_volume_phase_sample(kg, sd, phase_u, phase_v, &phase_eval, @@ -120,7 +118,6 @@ bool kernel_path_volume_bounce( #ifndef __SPLIT_KERNEL__ ccl_device void kernel_branched_path_volume_connect_light( KernelGlobals *kg, - RNG *rng, ShaderData *sd, ShaderData *emission_sd, float3 throughput, @@ -150,12 +147,12 @@ ccl_device void kernel_branched_path_volume_connect_light( int num_samples = light_select_num_samples(kg, i); float num_samples_inv = 1.0f/(num_samples*kernel_data.integrator.num_all_lights); - RNG lamp_rng = cmj_hash(*rng, i); + uint lamp_rng_hash = cmj_hash(state->rng_hash, i); for(int j = 0; j < num_samples; j++) { /* sample random position on given light */ float light_u, light_v; - path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); + path_branched_rng_2D(kg, lamp_rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); LightSample ls; lamp_light_sample(kg, i, light_u, light_v, ray->P, &ls); @@ -163,8 +160,8 @@ ccl_device void kernel_branched_path_volume_connect_light( float3 tp = throughput; /* sample position on volume segment */ - float rphase = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_PHASE); - float rscatter = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_SCATTER_DISTANCE); + float rphase = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE); + float rscatter = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE); VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg, state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false); @@ -177,7 +174,7 @@ ccl_device void kernel_branched_path_volume_connect_light( if(kernel_data.integrator.pdf_triangles != 0.0f) ls.pdf *= 2.0f; - float terminate = path_branched_rng_light_termination(kg, rng, state, j, num_samples); + float terminate = path_branched_rng_light_termination(kg, state->rng_hash, state, j, num_samples); if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { /* trace shadow ray */ float3 shadow; @@ -198,9 +195,9 @@ ccl_device void kernel_branched_path_volume_connect_light( for(int j = 0; j < num_samples; j++) { /* sample random position on random triangle */ - float light_t = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_LIGHT); + float light_t = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_LIGHT); float light_u, light_v; - path_branched_rng_2D(kg, rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); + path_branched_rng_2D(kg, state->rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); /* only sample triangle lights */ if(kernel_data.integrator.num_all_lights) @@ -212,8 +209,8 @@ ccl_device void kernel_branched_path_volume_connect_light( float3 tp = throughput; /* sample position on volume segment */ - float rphase = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_PHASE); - float rscatter = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_SCATTER_DISTANCE); + float rphase = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE); + float rscatter = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE); VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg, state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false); @@ -226,7 +223,7 @@ ccl_device void kernel_branched_path_volume_connect_light( if(kernel_data.integrator.num_all_lights) ls.pdf *= 2.0f; - float terminate = path_branched_rng_light_termination(kg, rng, state, j, num_samples); + float terminate = path_branched_rng_light_termination(kg, state->rng_hash, state, j, num_samples); if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { /* trace shadow ray */ float3 shadow; @@ -242,9 +239,9 @@ ccl_device void kernel_branched_path_volume_connect_light( } else { /* sample random position on random light */ - float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT); + float light_t = path_state_rng_1D(kg, state, PRNG_LIGHT); float light_u, light_v; - path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v); + path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v); LightSample ls; light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, state->bounce, &ls); @@ -252,8 +249,8 @@ ccl_device void kernel_branched_path_volume_connect_light( float3 tp = throughput; /* sample position on volume segment */ - float rphase = path_state_rng_1D_for_decision(kg, rng, state, PRNG_PHASE); - float rscatter = path_state_rng_1D_for_decision(kg, rng, state, PRNG_SCATTER_DISTANCE); + float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE); + float rscatter = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE); VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg, state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false); @@ -264,7 +261,7 @@ ccl_device void kernel_branched_path_volume_connect_light( /* todo: split up light_sample so we don't have to call it again with new position */ if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) { /* sample random light */ - float terminate = path_state_rng_light_termination(kg, rng, state); + float terminate = path_state_rng_light_termination(kg, state); if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { /* trace shadow ray */ float3 shadow; diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h index 073011ace31..459333f9807 100644 --- a/intern/cycles/kernel/kernel_random.h +++ b/intern/cycles/kernel/kernel_random.h @@ -52,7 +52,7 @@ ccl_device uint sobol_dimension(KernelGlobals *kg, int index, int dimension) ccl_device_forceinline float path_rng_1D(KernelGlobals *kg, - RNG *rng, + uint rng_hash, int sample, int num_samples, int dimension) { @@ -66,7 +66,7 @@ ccl_device_forceinline float path_rng_1D(KernelGlobals *kg, # endif { /* Correlated multi-jitter. */ - int p = *rng + dimension; + int p = rng_hash + dimension; return cmj_sample_1D(sample, num_samples, p); } #endif @@ -82,7 +82,7 @@ ccl_device_forceinline float path_rng_1D(KernelGlobals *kg, /* Hash rng with dimension to solve correlation issues. * See T38710, T50116. */ - RNG tmp_rng = cmj_hash_simple(dimension, *rng); + uint tmp_rng = cmj_hash_simple(dimension, rng_hash); shift = tmp_rng * (1.0f/(float)0xFFFFFFFF); return r + shift - floorf(r + shift); @@ -90,7 +90,7 @@ ccl_device_forceinline float path_rng_1D(KernelGlobals *kg, } ccl_device_forceinline void path_rng_2D(KernelGlobals *kg, - RNG *rng, + uint rng_hash, int sample, int num_samples, int dimension, float *fx, float *fy) @@ -107,7 +107,7 @@ ccl_device_forceinline void path_rng_2D(KernelGlobals *kg, # endif { /* Correlated multi-jitter. */ - int p = *rng + dimension; + int p = rng_hash + dimension; cmj_sample_2D(sample, num_samples, p, fx, fy); return; } @@ -115,24 +115,24 @@ ccl_device_forceinline void path_rng_2D(KernelGlobals *kg, #ifdef __SOBOL__ /* Sobol. */ - *fx = path_rng_1D(kg, rng, sample, num_samples, dimension); - *fy = path_rng_1D(kg, rng, sample, num_samples, dimension + 1); + *fx = path_rng_1D(kg, rng_hash, sample, num_samples, dimension); + *fy = path_rng_1D(kg, rng_hash, sample, num_samples, dimension + 1); #endif } ccl_device_inline void path_rng_init(KernelGlobals *kg, ccl_global uint *rng_state, int sample, int num_samples, - RNG *rng, + uint *rng_hash, int x, int y, float *fx, float *fy) { /* load state */ - *rng = *rng_state; - *rng ^= kernel_data.integrator.seed; + *rng_hash = *rng_state; + *rng_hash ^= kernel_data.integrator.seed; #ifdef __DEBUG_CORRELATION__ - srand48(*rng + sample); + srand48(*rng_hash + sample); #endif if(sample == 0) { @@ -140,7 +140,7 @@ ccl_device_inline void path_rng_init(KernelGlobals *kg, *fy = 0.5f; } else { - path_rng_2D(kg, rng, sample, num_samples, PRNG_FILTER_U, fx, fy); + path_rng_2D(kg, *rng_hash, sample, num_samples, PRNG_FILTER_U, fx, fy); } } @@ -177,19 +177,17 @@ ccl_device uint lcg_init(uint seed) */ ccl_device_inline float path_state_rng_1D(KernelGlobals *kg, - RNG *rng, const ccl_addr_space PathState *state, int dimension) { return path_rng_1D(kg, - rng, + state->rng_hash, state->sample, state->num_samples, state->rng_offset + dimension); } ccl_device_inline float path_state_rng_1D_for_decision( KernelGlobals *kg, - RNG *rng, const ccl_addr_space PathState *state, int dimension) { @@ -202,19 +200,18 @@ ccl_device_inline float path_state_rng_1D_for_decision( * the same decision. */ const int rng_offset = state->rng_offset + state->transparent_bounce * PRNG_BOUNCE_NUM; return path_rng_1D(kg, - rng, + state->rng_hash, state->sample, state->num_samples, rng_offset + dimension); } ccl_device_inline void path_state_rng_2D(KernelGlobals *kg, - RNG *rng, const ccl_addr_space PathState *state, int dimension, float *fx, float *fy) { path_rng_2D(kg, - rng, + state->rng_hash, state->sample, state->num_samples, state->rng_offset + dimension, fx, fy); @@ -222,14 +219,14 @@ ccl_device_inline void path_state_rng_2D(KernelGlobals *kg, ccl_device_inline float path_branched_rng_1D( KernelGlobals *kg, - RNG *rng, + uint rng_hash, const ccl_addr_space PathState *state, int branch, int num_branches, int dimension) { return path_rng_1D(kg, - rng, + rng_hash, state->sample * num_branches + branch, state->num_samples * num_branches, state->rng_offset + dimension); @@ -237,7 +234,7 @@ ccl_device_inline float path_branched_rng_1D( ccl_device_inline float path_branched_rng_1D_for_decision( KernelGlobals *kg, - RNG *rng, + uint rng_hash, const ccl_addr_space PathState *state, int branch, int num_branches, @@ -245,7 +242,7 @@ ccl_device_inline float path_branched_rng_1D_for_decision( { const int rng_offset = state->rng_offset + state->transparent_bounce * PRNG_BOUNCE_NUM; return path_rng_1D(kg, - rng, + rng_hash, state->sample * num_branches + branch, state->num_samples * num_branches, rng_offset + dimension); @@ -253,7 +250,7 @@ ccl_device_inline float path_branched_rng_1D_for_decision( ccl_device_inline void path_branched_rng_2D( KernelGlobals *kg, - RNG *rng, + uint rng_hash, const ccl_addr_space PathState *state, int branch, int num_branches, @@ -261,7 +258,7 @@ ccl_device_inline void path_branched_rng_2D( float *fx, float *fy) { path_rng_2D(kg, - rng, + rng_hash, state->sample * num_branches + branch, state->num_samples * num_branches, state->rng_offset + dimension, @@ -273,25 +270,24 @@ ccl_device_inline void path_branched_rng_2D( */ ccl_device_inline float path_state_rng_light_termination( KernelGlobals *kg, - RNG *rng, const ccl_addr_space PathState *state) { if(kernel_data.integrator.light_inv_rr_threshold > 0.0f) { - return path_state_rng_1D_for_decision(kg, rng, state, PRNG_LIGHT_TERMINATE); + return path_state_rng_1D_for_decision(kg, state, PRNG_LIGHT_TERMINATE); } return 0.0f; } ccl_device_inline float path_branched_rng_light_termination( KernelGlobals *kg, - RNG *rng, + uint rng_hash, const ccl_addr_space PathState *state, int branch, int num_branches) { if(kernel_data.integrator.light_inv_rr_threshold > 0.0f) { return path_branched_rng_1D_for_decision(kg, - rng, + rng_hash, state, branch, num_branches, @@ -311,12 +307,10 @@ ccl_device_inline void path_state_branch(ccl_addr_space PathState *state, state->num_samples = state->num_samples*num_branches; } -ccl_device_inline uint lcg_state_init(RNG *rng, - int rng_offset, - int sample, +ccl_device_inline uint lcg_state_init(ccl_addr_space PathState *state, uint scramble) { - return lcg_init(*rng + rng_offset + sample*scramble); + return lcg_init(state->rng_hash + state->rng_offset + state->sample*scramble); } ccl_device float lcg_step_float_addrspace(ccl_addr_space uint *rng) diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index f553599a2e4..01ba6d86f0b 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -863,7 +863,7 @@ ccl_device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd) /* Surface Evaluation */ -ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd, RNG *rng, +ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd, ccl_addr_space PathState *state, float randb, int path_flag, ShaderContext ctx) { sd->num_closure = 0; @@ -887,8 +887,8 @@ ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd, RNG *rng, #endif } - if(rng && (sd->flag & SD_BSDF_NEEDS_LCG)) { - sd->lcg_state = lcg_state_init(rng, state->rng_offset, state->sample, 0xb4bc3953); + if(sd->flag & SD_BSDF_NEEDS_LCG) { + sd->lcg_state = lcg_state_init(state, 0xb4bc3953); } } diff --git a/intern/cycles/kernel/kernel_shadow.h b/intern/cycles/kernel/kernel_shadow.h index 10e9083551e..e9ce4ddc7bf 100644 --- a/intern/cycles/kernel/kernel_shadow.h +++ b/intern/cycles/kernel/kernel_shadow.h @@ -49,7 +49,6 @@ ccl_device_forceinline bool shadow_handle_transparent_isect( path_state_modify_bounce(state, true); shader_eval_surface(kg, shadow_sd, - NULL, state, 0.0f, PATH_RAY_SHADOW, diff --git a/intern/cycles/kernel/kernel_subsurface.h b/intern/cycles/kernel/kernel_subsurface.h index 6475d4b66fd..f2c5e5298c4 100644 --- a/intern/cycles/kernel/kernel_subsurface.h +++ b/intern/cycles/kernel/kernel_subsurface.h @@ -219,7 +219,7 @@ ccl_device void subsurface_color_bump_blur(KernelGlobals *kg, if(bump || texture_blur > 0.0f) { /* average color and normal at incoming point */ - shader_eval_surface(kg, sd, NULL, state, 0.0f, state_flag, SHADER_CONTEXT_SSS); + shader_eval_surface(kg, sd, state, 0.0f, state_flag, SHADER_CONTEXT_SSS); float3 in_color = shader_bssrdf_sum(sd, (bump)? N: NULL, NULL); /* we simply divide out the average color and multiply with the average @@ -243,7 +243,7 @@ ccl_device_inline int subsurface_scatter_multi_intersect( SubsurfaceIntersection *ss_isect, ShaderData *sd, ShaderClosure *sc, - RNG *lcg_state, + uint *lcg_state, float disk_u, float disk_v, bool all) diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index f1b82eee352..58371c56267 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -242,10 +242,6 @@ CCL_NAMESPACE_BEGIN # undef __DENOISING_FEATURES__ #endif -/* Random Numbers */ - -typedef uint RNG; - /* Shader Evaluation */ typedef enum ShaderEvalType { @@ -1023,6 +1019,7 @@ typedef struct PathState { int flag; /* random number generator state */ + uint rng_hash; /* per pixel hash */ int rng_offset; /* dimension offset */ int sample; /* path sample number */ int num_samples; /* total number of times this path will be sampled */ @@ -1048,7 +1045,7 @@ typedef struct PathState { /* volume rendering */ #ifdef __VOLUME__ int volume_bounce; - RNG rng_congruential; + uint rng_congruential; VolumeStack volume_stack[VOLUME_STACK_SIZE]; #endif } PathState; diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h index 1e472aaf51a..8dcfe7f5145 100644 --- a/intern/cycles/kernel/kernel_volume.h +++ b/intern/cycles/kernel/kernel_volume.h @@ -360,7 +360,6 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous( ShaderData *sd, PathRadiance *L, ccl_addr_space float3 *throughput, - RNG *rng, bool probalistic_scatter) { VolumeShaderCoefficients coeff; @@ -380,13 +379,13 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous( /* pick random color channel, we use the Veach one-sample * model with balance heuristic for the channels */ - float rphase = path_state_rng_1D_for_decision(kg, rng, state, PRNG_PHASE); + float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE); int channel = (int)(rphase*3.0f); sd->randb_closure = rphase*3.0f - channel; /* decide if we will hit or miss */ bool scatter = true; - float xi = path_state_rng_1D_for_decision(kg, rng, state, PRNG_SCATTER_DISTANCE); + float xi = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE); if(probalistic_scatter) { float sample_sigma_t = kernel_volume_channel_get(sigma_t, channel); @@ -468,8 +467,7 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance( Ray *ray, ShaderData *sd, PathRadiance *L, - ccl_addr_space float3 *throughput, - RNG *rng) + ccl_addr_space float3 *throughput) { float3 tp = *throughput; const float tp_eps = 1e-6f; /* todo: this is likely not the right value */ @@ -485,8 +483,8 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance( /* pick random color channel, we use the Veach one-sample * model with balance heuristic for the channels */ - float xi = path_state_rng_1D_for_decision(kg, rng, state, PRNG_SCATTER_DISTANCE); - float rphase = path_state_rng_1D_for_decision(kg, rng, state, PRNG_PHASE); + float xi = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE); + float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE); int channel = (int)(rphase*3.0f); sd->randb_closure = rphase*3.0f - channel; bool has_scatter = false; @@ -610,15 +608,14 @@ ccl_device_noinline VolumeIntegrateResult kernel_volume_integrate( Ray *ray, PathRadiance *L, ccl_addr_space float3 *throughput, - RNG *rng, bool heterogeneous) { shader_setup_from_volume(kg, sd, ray); if(heterogeneous) - return kernel_volume_integrate_heterogeneous_distance(kg, state, ray, sd, L, throughput, rng); + return kernel_volume_integrate_heterogeneous_distance(kg, state, ray, sd, L, throughput); else - return kernel_volume_integrate_homogeneous(kg, state, ray, sd, L, throughput, rng, true); + return kernel_volume_integrate_homogeneous(kg, state, ray, sd, L, throughput, true); } #ifndef __SPLIT_KERNEL__ diff --git a/intern/cycles/kernel/split/kernel_branched.h b/intern/cycles/kernel/split/kernel_branched.h index e2762a85fc8..9fe4ec18e9e 100644 --- a/intern/cycles/kernel/split/kernel_branched.h +++ b/intern/cycles/kernel/split/kernel_branched.h @@ -110,7 +110,6 @@ ccl_device_noinline bool kernel_split_branched_path_surface_indirect_light_iter( SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index]; ShaderData *sd = saved_sd; - RNG rng = kernel_split_state.rng[ray_index]; PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; float3 throughput = branched_state->throughput; ccl_global PathState *ps = &kernel_split_state.path_state[ray_index]; @@ -157,20 +156,20 @@ ccl_device_noinline bool kernel_split_branched_path_surface_indirect_light_iter( num_samples = ceil_to_int(num_samples_adjust*num_samples); float num_samples_inv = num_samples_adjust/num_samples; - RNG bsdf_rng = cmj_hash(rng, i); for(int j = branched_state->next_sample; j < num_samples; j++) { if(reset_path_state) { *ps = branched_state->path_state; } + ps->rng_hash = cmj_hash(branched_state->path_state.rng_hash, i); + ccl_global float3 *tp = &kernel_split_state.throughput[ray_index]; *tp = throughput; ccl_global Ray *bsdf_ray = &kernel_split_state.ray[ray_index]; if(!kernel_branched_path_surface_bounce(kg, - &bsdf_rng, sd, sc, j, @@ -184,6 +183,8 @@ ccl_device_noinline bool kernel_split_branched_path_surface_indirect_light_iter( continue; } + ps->rng_hash = branched_state->path_state.rng_hash; + /* update state for next iteration */ branched_state->next_closure = i; branched_state->next_sample = j+1; diff --git a/intern/cycles/kernel/split/kernel_buffer_update.h b/intern/cycles/kernel/split/kernel_buffer_update.h index 6aa0d6948d0..de0c4160ca0 100644 --- a/intern/cycles/kernel/split/kernel_buffer_update.h +++ b/intern/cycles/kernel/split/kernel_buffer_update.h @@ -83,7 +83,6 @@ ccl_device void kernel_buffer_update(KernelGlobals *kg, PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; ccl_global Ray *ray = &kernel_split_state.ray[ray_index]; ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index]; - RNG rng = kernel_split_state.rng[ray_index]; ccl_global float *buffer = kernel_split_params.buffer; unsigned int work_index; @@ -135,7 +134,8 @@ ccl_device void kernel_buffer_update(KernelGlobals *kg, buffer += (kernel_split_params.offset + pixel_x + pixel_y*stride) * kernel_data.film.pass_stride; /* Initialize random numbers and ray. */ - kernel_path_trace_setup(kg, rng_state, sample, pixel_x, pixel_y, &rng, ray); + uint rng_hash; + kernel_path_trace_setup(kg, rng_state, sample, pixel_x, pixel_y, &rng_hash, ray); if(ray->t != 0.0f) { /* Initialize throughput, path radiance, Ray, PathState; @@ -143,7 +143,7 @@ ccl_device void kernel_buffer_update(KernelGlobals *kg, */ *throughput = make_float3(1.0f, 1.0f, 1.0f); path_radiance_init(L, kernel_data.film.use_light_pass); - path_state_init(kg, &kernel_split_state.sd_DL_shadow[ray_index], state, &rng, sample, ray); + path_state_init(kg, &kernel_split_state.sd_DL_shadow[ray_index], state, rng_hash, sample, ray); #ifdef __SUBSURFACE__ kernel_path_subsurface_init_indirect(&kernel_split_state.ss_rays[ray_index]); #endif @@ -160,7 +160,6 @@ ccl_device void kernel_buffer_update(KernelGlobals *kg, } } } - kernel_split_state.rng[ray_index] = rng; #ifndef __COMPUTE_DEVICE_GPU__ } diff --git a/intern/cycles/kernel/split/kernel_direct_lighting.h b/intern/cycles/kernel/split/kernel_direct_lighting.h index 3336c968a44..8e3f7555550 100644 --- a/intern/cycles/kernel/split/kernel_direct_lighting.h +++ b/intern/cycles/kernel/split/kernel_direct_lighting.h @@ -62,8 +62,6 @@ ccl_device void kernel_direct_lighting(KernelGlobals *kg, /* direct lighting */ #ifdef __EMISSION__ - RNG rng = kernel_split_state.rng[ray_index]; - bool flag = (kernel_data.integrator.use_direct_light && (sd->flag & SD_BSDF_HAS_EVAL)); @@ -83,10 +81,10 @@ ccl_device void kernel_direct_lighting(KernelGlobals *kg, if(flag) { /* Sample illumination from lights to find path contribution. */ - float light_t = path_state_rng_1D(kg, &rng, state, PRNG_LIGHT); + float light_t = path_state_rng_1D(kg, state, PRNG_LIGHT); float light_u, light_v; - path_state_rng_2D(kg, &rng, state, PRNG_LIGHT_U, &light_u, &light_v); - float terminate = path_state_rng_light_termination(kg, &rng, state); + path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v); + float terminate = path_state_rng_light_termination(kg, state); LightSample ls; if(light_sample(kg, @@ -115,7 +113,6 @@ ccl_device void kernel_direct_lighting(KernelGlobals *kg, } } } - kernel_split_state.rng[ray_index] = rng; #endif /* __EMISSION__ */ } diff --git a/intern/cycles/kernel/split/kernel_do_volume.h b/intern/cycles/kernel/split/kernel_do_volume.h index 9f8dd2392d9..478d83d633e 100644 --- a/intern/cycles/kernel/split/kernel_do_volume.h +++ b/intern/cycles/kernel/split/kernel_do_volume.h @@ -30,7 +30,6 @@ ccl_device_noinline bool kernel_split_branched_path_volume_indirect_light_iter(K SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index]; ShaderData *sd = &kernel_split_state.sd[ray_index]; - RNG rng = kernel_split_state.rng[ray_index]; PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index]; @@ -58,15 +57,15 @@ ccl_device_noinline bool kernel_split_branched_path_volume_indirect_light_iter(K /* integrate along volume segment with distance sampling */ VolumeIntegrateResult result = kernel_volume_integrate( - kg, ps, sd, &volume_ray, L, tp, &rng, heterogeneous); + kg, ps, sd, &volume_ray, L, tp, heterogeneous); # ifdef __VOLUME_SCATTER__ if(result == VOLUME_PATH_SCATTERED) { /* direct lighting */ - kernel_path_volume_connect_light(kg, &rng, sd, emission_sd, *tp, &branched_state->path_state, L); + kernel_path_volume_connect_light(kg, sd, emission_sd, *tp, &branched_state->path_state, L); /* indirect light bounce */ - if(!kernel_path_volume_bounce(kg, &rng, sd, tp, ps, L, pray)) { + if(!kernel_path_volume_bounce(kg, sd, tp, ps, L, pray)) { continue; } @@ -141,7 +140,6 @@ ccl_device void kernel_do_volume(KernelGlobals *kg) IS_STATE(ray_state, ray_index, RAY_HIT_BACKGROUND)) { ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index]; ccl_global Ray *ray = &kernel_split_state.ray[ray_index]; - RNG rng = kernel_split_state.rng[ray_index]; ccl_global Intersection *isect = &kernel_split_state.isect[ray_index]; ShaderData *sd = &kernel_split_state.sd[ray_index]; ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index]; @@ -165,15 +163,15 @@ ccl_device void kernel_do_volume(KernelGlobals *kg) { /* integrate along volume segment with distance sampling */ VolumeIntegrateResult result = kernel_volume_integrate( - kg, state, sd, &volume_ray, L, throughput, &rng, heterogeneous); + kg, state, sd, &volume_ray, L, throughput, heterogeneous); # ifdef __VOLUME_SCATTER__ if(result == VOLUME_PATH_SCATTERED) { /* direct lighting */ - kernel_path_volume_connect_light(kg, &rng, sd, emission_sd, *throughput, state, L); + kernel_path_volume_connect_light(kg, sd, emission_sd, *throughput, state, L); /* indirect light bounce */ - if(kernel_path_volume_bounce(kg, &rng, sd, throughput, state, L, ray)) { + if(kernel_path_volume_bounce(kg, sd, throughput, state, L, ray)) { ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED); } else { @@ -194,8 +192,6 @@ ccl_device void kernel_do_volume(KernelGlobals *kg) } # endif /* __BRANCHED_PATH__ */ } - - kernel_split_state.rng[ray_index] = rng; } # ifdef __BRANCHED_PATH__ diff --git a/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h b/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h index 95f57fbff57..3fc45afbd92 100644 --- a/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h +++ b/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h @@ -100,7 +100,6 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao( unsigned int tile_y; unsigned int sample; - RNG rng = kernel_split_state.rng[ray_index]; ccl_global PathState *state = 0x0; float3 throughput; @@ -247,7 +246,7 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao( if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) { if(probability != 1.0f) { - float terminate = path_state_rng_1D_for_decision(kg, &rng, state, PRNG_TERMINATE); + float terminate = path_state_rng_1D_for_decision(kg, state, PRNG_TERMINATE); if(terminate >= probability) { kernel_split_path_end(kg, ray_index); } @@ -269,8 +268,6 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao( } #endif /* __AO__ */ - kernel_split_state.rng[ray_index] = rng; - #ifndef __COMPUTE_DEVICE_GPU__ } #endif diff --git a/intern/cycles/kernel/split/kernel_next_iteration_setup.h b/intern/cycles/kernel/split/kernel_next_iteration_setup.h index 7758e35fd32..4e0c966cca9 100644 --- a/intern/cycles/kernel/split/kernel_next_iteration_setup.h +++ b/intern/cycles/kernel/split/kernel_next_iteration_setup.h @@ -126,7 +126,6 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg, if(active) { ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index]; ccl_global Ray *ray = &kernel_split_state.ray[ray_index]; - RNG rng = kernel_split_state.rng[ray_index]; ShaderData *sd = &kernel_split_state.sd[ray_index]; ccl_global PathState *state = &kernel_split_state.path_state[ray_index]; PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; @@ -135,7 +134,7 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg, if(!kernel_data.integrator.branched || IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) { #endif /* Compute direct lighting and next bounce. */ - if(!kernel_path_surface_bounce(kg, &rng, sd, throughput, state, L, ray)) { + if(!kernel_path_surface_bounce(kg, sd, throughput, state, L, ray)) { kernel_split_path_end(kg, ray_index); } #ifdef __BRANCHED_PATH__ @@ -157,8 +156,6 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg, } } #endif /* __BRANCHED_PATH__ */ - - kernel_split_state.rng[ray_index] = rng; } /* Enqueue RAY_UPDATE_BUFFER rays. */ diff --git a/intern/cycles/kernel/split/kernel_path_init.h b/intern/cycles/kernel/split/kernel_path_init.h index 8315b0b2bd3..8b70df16d2a 100644 --- a/intern/cycles/kernel/split/kernel_path_init.h +++ b/intern/cycles/kernel/split/kernel_path_init.h @@ -60,14 +60,14 @@ ccl_device void kernel_path_init(KernelGlobals *kg) { ccl_global float *buffer = kernel_split_params.buffer; buffer += (kernel_split_params.offset + pixel_x + pixel_y * kernel_split_params.stride) * kernel_data.film.pass_stride; - RNG rng = kernel_split_state.rng[ray_index]; + uint rng_hash; /* Initialize random numbers and ray. */ kernel_path_trace_setup(kg, rng_state, my_sample, pixel_x, pixel_y, - &rng, + &rng_hash, &kernel_split_state.ray[ray_index]); if(kernel_split_state.ray[ray_index].t != 0.0f) { @@ -79,7 +79,7 @@ ccl_device void kernel_path_init(KernelGlobals *kg) { path_state_init(kg, &kernel_split_state.sd_DL_shadow[ray_index], &kernel_split_state.path_state[ray_index], - &rng, + rng_hash, my_sample, &kernel_split_state.ray[ray_index]); #ifdef __SUBSURFACE__ @@ -93,7 +93,6 @@ ccl_device void kernel_path_init(KernelGlobals *kg) { kernel_write_pass_float4(buffer, my_sample, L_rad); ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_TO_REGENERATE); } - kernel_split_state.rng[ray_index] = rng; } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/split/kernel_scene_intersect.h b/intern/cycles/kernel/split/kernel_scene_intersect.h index 5c6d90eecc4..d0afd39ef29 100644 --- a/intern/cycles/kernel/split/kernel_scene_intersect.h +++ b/intern/cycles/kernel/split/kernel_scene_intersect.h @@ -74,7 +74,6 @@ ccl_device void kernel_scene_intersect(KernelGlobals *kg) #ifdef __HAIR__ float difl = 0.0f, extmax = 0.0f; uint lcg_state = 0; - RNG rng = kernel_split_state.rng[ray_index]; if(kernel_data.bvh.have_curves) { if((kernel_data.cam.resolution == 1) && (state.flag & PATH_RAY_CAMERA)) { @@ -84,7 +83,7 @@ ccl_device void kernel_scene_intersect(KernelGlobals *kg) } extmax = kernel_data.curve.maximum_width; - lcg_state = lcg_state_init(&rng, state.rng_offset, state.sample, 0x51633e2d); + lcg_state = lcg_state_init(&state, 0x51633e2d); } bool hit = scene_intersect(kg, ray, visibility, &isect, &lcg_state, difl, extmax); diff --git a/intern/cycles/kernel/split/kernel_shader_eval.h b/intern/cycles/kernel/split/kernel_shader_eval.h index 2801b32f285..d0fa29ef3f8 100644 --- a/intern/cycles/kernel/split/kernel_shader_eval.h +++ b/intern/cycles/kernel/split/kernel_shader_eval.h @@ -48,18 +48,17 @@ ccl_device void kernel_shader_eval(KernelGlobals *kg) ccl_global char *ray_state = kernel_split_state.ray_state; if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) { - RNG rng = kernel_split_state.rng[ray_index]; ccl_global PathState *state = &kernel_split_state.path_state[ray_index]; #ifndef __BRANCHED_PATH__ - float rbsdf = path_state_rng_1D_for_decision(kg, &rng, state, PRNG_BSDF); - shader_eval_surface(kg, &kernel_split_state.sd[ray_index], &rng, state, rbsdf, state->flag, SHADER_CONTEXT_MAIN); + float rbsdf = path_state_rng_1D_for_decision(kg, state, PRNG_BSDF); + shader_eval_surface(kg, &kernel_split_state.sd[ray_index], state, rbsdf, state->flag, SHADER_CONTEXT_MAIN); #else ShaderContext ctx = SHADER_CONTEXT_MAIN; float rbsdf = 0.0f; if(!kernel_data.integrator.branched || IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) { - rbsdf = path_state_rng_1D_for_decision(kg, &rng, state, PRNG_BSDF); + rbsdf = path_state_rng_1D_for_decision(kg, state, PRNG_BSDF); } @@ -67,11 +66,9 @@ ccl_device void kernel_shader_eval(KernelGlobals *kg) ctx = SHADER_CONTEXT_INDIRECT; } - shader_eval_surface(kg, &kernel_split_state.sd[ray_index], &rng, state, rbsdf, state->flag, ctx); + shader_eval_surface(kg, &kernel_split_state.sd[ray_index], state, rbsdf, state->flag, ctx); shader_merge_closures(&kernel_split_state.sd[ray_index]); #endif /* __BRANCHED_PATH__ */ - - kernel_split_state.rng[ray_index] = rng; } } diff --git a/intern/cycles/kernel/split/kernel_shadow_blocked_ao.h b/intern/cycles/kernel/split/kernel_shadow_blocked_ao.h index 474286285a9..79aa2c9435b 100644 --- a/intern/cycles/kernel/split/kernel_shadow_blocked_ao.h +++ b/intern/cycles/kernel/split/kernel_shadow_blocked_ao.h @@ -37,21 +37,18 @@ ccl_device void kernel_shadow_blocked_ao(KernelGlobals *kg) ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index]; PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; ccl_global PathState *state = &kernel_split_state.path_state[ray_index]; - RNG rng = kernel_split_state.rng[ray_index]; float3 throughput = kernel_split_state.throughput[ray_index]; #ifdef __BRANCHED_PATH__ if(!kernel_data.integrator.branched || IS_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_INDIRECT)) { #endif - kernel_path_ao(kg, sd, emission_sd, L, state, &rng, throughput, shader_bsdf_alpha(kg, sd)); + kernel_path_ao(kg, sd, emission_sd, L, state, throughput, shader_bsdf_alpha(kg, sd)); #ifdef __BRANCHED_PATH__ } else { - kernel_branched_path_ao(kg, sd, emission_sd, L, state, &rng, throughput); + kernel_branched_path_ao(kg, sd, emission_sd, L, state, throughput); } #endif - - kernel_split_state.rng[ray_index] = rng; } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/split/kernel_shadow_blocked_dl.h b/intern/cycles/kernel/split/kernel_shadow_blocked_dl.h index 78e61709b01..50c9acec4ee 100644 --- a/intern/cycles/kernel/split/kernel_shadow_blocked_dl.h +++ b/intern/cycles/kernel/split/kernel_shadow_blocked_dl.h @@ -45,7 +45,6 @@ ccl_device void kernel_shadow_blocked_dl(KernelGlobals *kg) PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; ShaderData *sd = &kernel_split_state.sd[ray_index]; float3 throughput = kernel_split_state.throughput[ray_index]; - RNG rng = kernel_split_state.rng[ray_index]; BsdfEval L_light = kernel_split_state.bsdf_eval[ray_index]; ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index]; @@ -75,7 +74,6 @@ ccl_device void kernel_shadow_blocked_dl(KernelGlobals *kg) if(use_branched) { kernel_branched_path_surface_connect_light(kg, - &rng, sd, emission_sd, state, @@ -103,8 +101,6 @@ ccl_device void kernel_shadow_blocked_dl(KernelGlobals *kg) path_radiance_accum_total_light(L, state, throughput, &L_light); } } - - kernel_split_state.rng[ray_index] = rng; } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/split/kernel_split_data_types.h b/intern/cycles/kernel/split/kernel_split_data_types.h index 4f32c68d630..3eae884d479 100644 --- a/intern/cycles/kernel/split/kernel_split_data_types.h +++ b/intern/cycles/kernel/split/kernel_split_data_types.h @@ -114,7 +114,6 @@ typedef ccl_global struct SplitBranchedState { #endif /* __VOLUME__ */ #define SPLIT_DATA_ENTRIES \ - SPLIT_DATA_ENTRY(ccl_global RNG, rng, 1) \ SPLIT_DATA_ENTRY(ccl_global float3, throughput, 1) \ SPLIT_DATA_ENTRY(PathRadiance, path_radiance, 1) \ SPLIT_DATA_ENTRY(ccl_global Ray, ray, 1) \ @@ -133,7 +132,6 @@ typedef ccl_global struct SplitBranchedState { /* entries to be copied to inactive rays when sharing branched samples (TODO: which are actually needed?) */ #define SPLIT_DATA_ENTRIES_BRANCHED_SHARED \ - SPLIT_DATA_ENTRY(ccl_global RNG, rng, 1) \ SPLIT_DATA_ENTRY(ccl_global float3, throughput, 1) \ SPLIT_DATA_ENTRY(PathRadiance, path_radiance, 1) \ SPLIT_DATA_ENTRY(ccl_global Ray, ray, 1) \ diff --git a/intern/cycles/kernel/split/kernel_subsurface_scatter.h b/intern/cycles/kernel/split/kernel_subsurface_scatter.h index d5083b23f80..76d198abc8a 100644 --- a/intern/cycles/kernel/split/kernel_subsurface_scatter.h +++ b/intern/cycles/kernel/split/kernel_subsurface_scatter.h @@ -38,7 +38,6 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index]; ShaderData *sd = &branched_state->sd; - RNG rng = kernel_split_state.rng[ray_index]; PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index]; @@ -52,14 +51,12 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it if(branched_state->ss_next_sample == 0 && branched_state->next_hit == 0 && branched_state->next_closure == 0 && branched_state->next_sample == 0) { - branched_state->lcg_state = lcg_state_init(&rng, - branched_state->path_state.rng_offset, - branched_state->path_state.sample, + branched_state->lcg_state = lcg_state_init(&branched_state->path_state, 0x68bc21eb); } int num_samples = kernel_data.integrator.subsurface_samples; float num_samples_inv = 1.0f/num_samples; - RNG bssrdf_rng = cmj_hash(rng, i); + uint bssrdf_rng_hash = cmj_hash(branched_state->path_state.rng_hash, i); /* do subsurface scatter step with copy of shader data, this will * replace the BSSRDF with a diffuse BSDF closure */ @@ -67,7 +64,7 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it ccl_global SubsurfaceIntersection *ss_isect = &branched_state->ss_isect; float bssrdf_u, bssrdf_v; path_branched_rng_2D(kg, - &bssrdf_rng, + bssrdf_rng_hash, &branched_state->path_state, j, num_samples, @@ -77,7 +74,7 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it /* intersection is expensive so avoid doing multiple times for the same input */ if(branched_state->next_hit == 0 && branched_state->next_closure == 0 && branched_state->next_sample == 0) { - RNG lcg_state = branched_state->lcg_state; + uint lcg_state = branched_state->lcg_state; SubsurfaceIntersection ss_isect_private; branched_state->num_hits = subsurface_scatter_multi_intersect(kg, @@ -152,7 +149,6 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it int all = (kernel_data.integrator.sample_all_lights_direct) || (branched_state->path_state.flag & PATH_RAY_SHADOW_CATCHER); kernel_branched_path_surface_connect_light(kg, - &rng, bssrdf_sd, emission_sd, hit_state, @@ -229,7 +225,6 @@ ccl_device void kernel_subsurface_scatter(KernelGlobals *kg) if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) { ccl_global PathState *state = &kernel_split_state.path_state[ray_index]; PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; - RNG rng = kernel_split_state.rng[ray_index]; ccl_global Ray *ray = &kernel_split_state.ray[ray_index]; ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index]; ccl_global SubsurfaceIndirectRays *ss_indirect = &kernel_split_state.ss_rays[ray_index]; @@ -246,7 +241,6 @@ ccl_device void kernel_subsurface_scatter(KernelGlobals *kg) emission_sd, L, state, - &rng, ray, throughput, ss_indirect)) @@ -264,10 +258,9 @@ ccl_device void kernel_subsurface_scatter(KernelGlobals *kg) /* do bssrdf scatter step if we picked a bssrdf closure */ if(sc) { - uint lcg_state = lcg_state_init(&rng, state->rng_offset, state->sample, 0x68bc21eb); + uint lcg_state = lcg_state_init(state, 0x68bc21eb); float bssrdf_u, bssrdf_v; path_state_rng_2D(kg, - &rng, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); @@ -290,7 +283,6 @@ ccl_device void kernel_subsurface_scatter(KernelGlobals *kg) } #endif } - kernel_split_state.rng[ray_index] = rng; } # ifdef __BRANCHED_PATH__ @@ -5,6 +5,7 @@ setlocal EnableDelayedExpansion setlocal ENABLEEXTENSIONS set BLENDER_DIR=%~dp0 set BLENDER_DIR_NOSPACES=%BLENDER_DIR: =% +for %%X in (svn.exe) do (set HAS_SVN=%%~$PATH:X) if not "%BLENDER_DIR%"=="%BLENDER_DIR_NOSPACES%" ( echo There are spaces detected in the build path "%BLENDER_DIR%", this is currently not supported, exiting.... goto EOF @@ -17,6 +18,9 @@ set BUILD_CMAKE_ARGS= set BUILD_ARCH= set BUILD_VS_VER= set BUILD_VS_YEAR= +set BUILD_VS_LIBDIRPOST= +set BUILD_VS_LIBDIR= +set BUILD_VS_SVNDIR= set BUILD_NGE= set KEY_NAME= set MSBUILD_PLATFORM= @@ -74,12 +78,15 @@ if NOT "%1" == "" ( ) else if "%1" == "2017" ( set BUILD_VS_VER=15 set BUILD_VS_YEAR=2017 + set BUILD_VS_LIBDIRPOST=vc14 ) else if "%1" == "2015" ( set BUILD_VS_VER=14 set BUILD_VS_YEAR=2015 + set BUILD_VS_LIBDIRPOST=vc14 ) else if "%1" == "2013" ( set BUILD_VS_VER=12 set BUILD_VS_YEAR=2013 + set BUILD_VS_LIBDIRPOST=vc12 ) else if "%1" == "packagename" ( set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -DCPACK_OVERRIDE_PACKAGENAME="%2" shift /1 @@ -130,6 +137,7 @@ if "%BUILD_ARCH%"=="" ( if "%BUILD_VS_VER%"=="" ( set BUILD_VS_VER=12 set BUILD_VS_YEAR=2013 + set BUILD_VS_LIBDIRPOST=vc12 ) if "%BUILD_ARCH%"=="x64" ( @@ -183,6 +191,7 @@ if %ERRORLEVEL% NEQ 0 ( echo Visual Studio 2013 not found, trying Visual Studio 2015. set BUILD_VS_VER=14 set BUILD_VS_YEAR=2015 + set BUILD_VS_LIBDIRPOST=vc14 goto DetectMSVC ) else ( echo Error: "MSBuild" command not in the PATH. @@ -204,11 +213,36 @@ if %ERRORLEVEL% NEQ 0 ( echo You must have CMake installed and added to your PATH, aborting! goto EOF ) -if NOT EXIST %BLENDER_DIR%..\lib\nul ( - echo Error: Path to libraries not found "%BLENDER_DIR%..\lib\" - echo This is needed for building, aborting! - goto EOF + +if "%BUILD_ARCH%"=="x64" ( + set BUILD_VS_SVNDIR=win64_%BUILD_VS_LIBDIRPOST% + ) else if "%BUILD_ARCH%"=="x86" ( + set BUILD_VS_SVNDIR=windows_%BUILD_VS_LIBDIRPOST% +) +set BUILD_VS_LIBDIR="%BLENDER_DIR%..\lib\%BUILD_VS_SVNDIR%" + +if NOT EXIST %BUILD_VS_LIBDIR% ( + rem libs not found, but svn is on the system + if not "%HAS_SVN%"=="" ( + echo. + echo The required external libraries in %BUILD_VS_LIBDIR% are missing + echo. + set /p GetLibs= "Would you like to download them? (y/n)" + if /I "!GetLibs!"=="Y" ( + echo. + echo Downloading %BUILD_VS_SVNDIR% libraries, please wait. + echo. + svn checkout https://svn.blender.org/svnroot/bf-blender/trunk/lib/%BUILD_VS_SVNDIR% %BUILD_VS_LIBDIR% + ) + ) ) + +if NOT EXIST %BUILD_VS_LIBDIR% ( + echo Error: Path to libraries not found "%BUILD_VS_LIBDIR%" + echo This is needed for building, aborting! + goto EOF +) + if "%TARGET%"=="" ( echo Error: Convenience target not set echo This is required for building, aborting! diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c index 8f287918a4a..b8ff0588581 100644 --- a/source/blender/python/bmesh/bmesh_py_ops_call.c +++ b/source/blender/python/bmesh/bmesh_py_ops_call.c @@ -44,6 +44,7 @@ #include "bmesh_py_types.h" #include "../generic/python_utildefines.h" +#include "../generic/py_capi_utils.h" static int bpy_bm_op_as_py_error(BMesh *bm) { @@ -152,11 +153,9 @@ static int bpy_slot_from_py( switch (slot->slot_type) { case BMO_OP_SLOT_BOOL: { - int param; + const int param = PyC_Long_AsBool(value); - param = PyLong_AsLong(value); - - if (param < 0) { + if (param == -1) { PyErr_Format(PyExc_TypeError, "%.200s: keyword \"%.200s\" expected True/False or 0/1, not %.200s", opname, slot_name, Py_TYPE(value)->tp_name); @@ -170,23 +169,16 @@ static int bpy_slot_from_py( } case BMO_OP_SLOT_INT: { - int overflow; - long param = PyLong_AsLongAndOverflow(value, &overflow); - if (overflow || (param > INT_MAX) || (param < INT_MIN)) { - PyErr_Format(PyExc_ValueError, - "%.200s: keyword \"%.200s\" value not in 'int' range " - "(" STRINGIFY(INT_MIN) ", " STRINGIFY(INT_MAX) ")", - opname, slot_name, Py_TYPE(value)->tp_name); - return -1; - } - else if (param == -1 && PyErr_Occurred()) { + const int param = PyC_Long_AsI32(value); + + if (param == -1 && PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, "%.200s: keyword \"%.200s\" expected an int, not %.200s", opname, slot_name, Py_TYPE(value)->tp_name); return -1; } else { - BMO_SLOT_AS_INT(slot) = (int)param; + BMO_SLOT_AS_INT(slot) = param; } break; } @@ -209,25 +201,18 @@ static int bpy_slot_from_py( /* XXX - BMesh operator design is crappy here, operator slot should define matrix size, * not the caller! */ unsigned short size; - if (!MatrixObject_Check(value)) { - PyErr_Format(PyExc_TypeError, - "%.200s: keyword \"%.200s\" expected a Matrix, not %.200s", - opname, slot_name, Py_TYPE(value)->tp_name); + MatrixObject *pymat; + if (!Matrix_ParseAny(value, &pymat)) { return -1; } - else if (BaseMath_ReadCallback((MatrixObject *)value) == -1) { - return -1; - } - else if (((size = ((MatrixObject *)value)->num_col) != ((MatrixObject *)value)->num_row) || - (ELEM(size, 3, 4) == false)) - { + if ((size = (pymat->num_col) != pymat->num_row) || (!ELEM(size, 3, 4))) { PyErr_Format(PyExc_TypeError, "%.200s: keyword \"%.200s\" expected a 3x3 or 4x4 matrix Matrix", opname, slot_name); return -1; } - BMO_slot_mat_set(bmop, bmop->slots_in, slot_name, ((MatrixObject *)value)->matrix, size); + BMO_slot_mat_set(bmop, bmop->slots_in, slot_name, pymat->matrix, size); break; } case BMO_OP_SLOT_VEC: @@ -436,7 +421,7 @@ static int bpy_slot_from_py( return -1; /* error is set in bpy_slot_from_py_elem_check() */ } - value_i = PyLong_AsLong(arg_value); + value_i = PyC_Long_AsI32(arg_value); if (value_i == -1 && PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, @@ -466,7 +451,7 @@ static int bpy_slot_from_py( return -1; /* error is set in bpy_slot_from_py_elem_check() */ } - value_i = PyLong_AsLong(arg_value); + value_i = PyC_Long_AsI32(arg_value); if (value_i == -1 && PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index bfd0898f064..cf5aecc40f3 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -125,25 +125,19 @@ static int bpy_bm_elem_hflag_set(BPy_BMElem *self, PyObject *value, void *flag) BPY_BM_CHECK_INT(self); - param = PyLong_AsLong(value); - - if ((unsigned int)param <= 1) { - if (hflag == BM_ELEM_SELECT) - BM_elem_select_set(self->bm, self->ele, param); - else - BM_elem_flag_set(self->ele, hflag, param); + if ((param = PyC_Long_AsBool(value)) == -1) { + return -1; + } - return 0; + if (hflag == BM_ELEM_SELECT) { + BM_elem_select_set(self->bm, self->ele, param); } else { - PyErr_Format(PyExc_TypeError, - "expected True/False or 0/1, not %.200s", - Py_TYPE(value)->tp_name); - return -1; + BM_elem_flag_set(self->ele, hflag, param); } + return -1; } - PyDoc_STRVAR(bpy_bm_elem_index_doc, "Index of this element.\n" "\n" @@ -170,21 +164,17 @@ static int bpy_bm_elem_index_set(BPy_BMElem *self, PyObject *value, void *UNUSED BPY_BM_CHECK_INT(self); - param = PyLong_AsLong(value); - - if (param == -1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "expected an int type"); + if (((param = PyC_Long_AsI32(value)) == -1) && PyErr_Occurred()) { + /* error is set */ return -1; } - else { - BM_elem_index_set(self->ele, param); /* set_dirty! */ - /* when setting the index assume its set invalid */ - self->bm->elem_index_dirty |= self->ele->head.htype; + BM_elem_index_set(self->ele, param); /* set_dirty! */ - return 0; - } + /* when setting the index assume its set invalid */ + self->bm->elem_index_dirty |= self->ele->head.htype; + + return 0; } /* type specific get/sets @@ -507,14 +497,12 @@ static int bpy_bmface_material_index_set(BPy_BMFace *self, PyObject *value) BPY_BM_CHECK_INT(self); - param = PyLong_AsLong(value); - - if (param == -1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "expected an int type"); + if (((param = PyC_Long_AsI32(value)) == -1) && PyErr_Occurred()) { + /* error is set */ return -1; } - else if ((param < 0) || (param > MAXMAT)) { + + if ((param < 0) || (param > MAXMAT)) { /* normally we clamp but in this case raise an error */ PyErr_SetString(PyExc_ValueError, "material index outside of usable range (0 - 32766)"); @@ -1117,15 +1105,16 @@ static PyObject *bpy_bmesh_select_flush(BPy_BMesh *self, PyObject *value) BPY_BM_CHECK_OBJ(self); - param = PyLong_AsLong(value); - if (param != false && param != true) { - PyErr_SetString(PyExc_TypeError, - "expected a boolean type 0/1"); + if ((param = PyC_Long_AsBool(value)) == -1) { return NULL; } - if (param) BM_mesh_select_flush(self->bm); - else BM_mesh_deselect_flush(self->bm); + if (param) { + BM_mesh_select_flush(self->bm); + } + else { + BM_mesh_deselect_flush(self->bm); + } Py_RETURN_NONE; } @@ -1305,10 +1294,7 @@ static PyObject *bpy_bm_elem_select_set(BPy_BMElem *self, PyObject *value) BPY_BM_CHECK_OBJ(self); - param = PyLong_AsLong(value); - if (param != false && param != true) { - PyErr_SetString(PyExc_TypeError, - "expected a boolean type 0/1"); + if ((param = PyC_Long_AsBool(value)) == -1) { return NULL; } @@ -1333,10 +1319,7 @@ static PyObject *bpy_bm_elem_hide_set(BPy_BMElem *self, PyObject *value) BPY_BM_CHECK_OBJ(self); - param = PyLong_AsLong(value); - if (param != false && param != true) { - PyErr_SetString(PyExc_TypeError, - "expected a boolean type 0/1"); + if ((param = PyC_Long_AsBool(value)) == -1) { return NULL; } diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c index 532f85f87d7..e2241ade7f0 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c @@ -43,6 +43,7 @@ #include "../mathutils/mathutils.h" #include "../generic/python_utildefines.h" +#include "../generic/py_capi_utils.h" #include "BKE_customdata.h" @@ -1070,9 +1071,9 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj case CD_PROP_INT: case CD_FACEMAP: { - int tmp_val = PyLong_AsLong(py_value); + int tmp_val = PyC_Long_AsI32(py_value); if (UNLIKELY(tmp_val == -1 && PyErr_Occurred())) { - PyErr_Format(PyExc_TypeError, "expected an int, not a %.200s", Py_TYPE(py_value)->tp_name); + /* error is set */ ret = -1; } else { diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c index f6926e8437d..574aef3d54f 100644 --- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c @@ -45,6 +45,7 @@ #include "bmesh_py_types_meshdata.h" +#include "../generic/py_capi_utils.h" #include "../generic/python_utildefines.h" /* Mesh Loop UV @@ -98,7 +99,7 @@ static int bpy_bmloopuv_flag_set(BPy_BMLoopUV *self, PyObject *value, void *flag { const int flag = GET_INT_FROM_POINTER(flag_p); - switch (PyLong_AsLong(value)) { + switch (PyC_Long_AsBool(value)) { case true: self->data->flag |= flag; return 0; @@ -106,8 +107,7 @@ static int bpy_bmloopuv_flag_set(BPy_BMLoopUV *self, PyObject *value, void *flag self->data->flag &= ~flag; return 0; default: - PyErr_SetString(PyExc_TypeError, - "expected a boolean type 0/1"); + /* error is set */ return -1; } } @@ -207,7 +207,7 @@ static int bpy_bmvertskin_flag_set(BPy_BMVertSkin *self, PyObject *value, void * { const int flag = GET_INT_FROM_POINTER(flag_p); - switch (PyLong_AsLong(value)) { + switch (PyC_Long_AsBool(value)) { case true: self->data->flag |= flag; return 0; @@ -215,8 +215,7 @@ static int bpy_bmvertskin_flag_set(BPy_BMVertSkin *self, PyObject *value, void * self->data->flag &= ~flag; return 0; default: - PyErr_SetString(PyExc_TypeError, - "expected a boolean type 0/1"); + /* error is set */ return -1; } } diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c index 5d6a7c578a2..1153e0176df 100644 --- a/source/blender/python/generic/idprop_py_api.c +++ b/source/blender/python/generic/idprop_py_api.c @@ -386,7 +386,7 @@ static IDProperty *idp_from_PyFloat(const char *name, PyObject *ob) static IDProperty *idp_from_PyLong(const char *name, PyObject *ob) { IDPropertyTemplate val = {0}; - val.i = _PyLong_AsInt(ob); + val.i = PyC_Long_AsI32(ob); if (val.i == -1 && PyErr_Occurred()) { return NULL; } @@ -499,7 +499,7 @@ static IDProperty *idp_from_PySequence_Fast(const char *name, PyObject *ob) prop_data = IDP_Array(prop); for (i = 0; i < val.array.len; i++) { item = ob_seq_fast_items[i]; - if (((prop_data[i] = _PyLong_AsInt(item)) == -1) && PyErr_Occurred()) { + if (((prop_data[i] = PyC_Long_AsI32(item)) == -1) && PyErr_Occurred()) { return NULL; } } @@ -1337,7 +1337,7 @@ static int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *value) } case IDP_INT: { - const int i = _PyLong_AsInt(value); + const int i = PyC_Long_AsI32(value); if (i == -1 && PyErr_Occurred()) { return -1; } diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index 861e2dbb0df..abc2da9e4c7 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -85,7 +85,7 @@ int PyC_AsArray_FAST( /* could use is_double for 'long int' but no use now */ int *array_int = array; for (i = 0; i < length; i++) { - array_int[i] = PyLong_AsLong(value_fast_items[i]); + array_int[i] = PyC_Long_AsI32(value_fast_items[i]); } } else if (type == &PyBool_Type) { @@ -203,6 +203,8 @@ void PyC_List_Fill(PyObject *list, PyObject *value) /** * Use with PyArg_ParseTuple's "O&" formatting. + * + * \see #PyC_Long_AsBool for a similar function to use outside of argument parsing. */ int PyC_ParseBool(PyObject *o, void *p) { @@ -1115,3 +1117,101 @@ bool PyC_RunString_AsString(const char *expr, const char *filename, char **r_val } #endif /* #ifndef MATH_STANDALONE */ + +/* -------------------------------------------------------------------- */ + +/** \name Int Conversion + * + * \note Python doesn't provide overflow checks for specific bit-widths. + * + * \{ */ + +/* Compiler optimizes out redundant checks. */ +#ifdef __GNUC__ +# pragma warning(push) +# pragma GCC diagnostic ignored "-Wtype-limits" +#endif + +/** + * Don't use `bool` return type, so -1 can be used as an error value. + */ +int PyC_Long_AsBool(PyObject *value) +{ + int test = _PyLong_AsInt(value); + if (UNLIKELY((uint)test > 1)) { + PyErr_SetString(PyExc_TypeError, + "Python number not a bool (0/1)"); + return -1; + } + return test; +} + +int8_t PyC_Long_AsI8(PyObject *value) +{ + int test = _PyLong_AsInt(value); + if (UNLIKELY(test < INT8_MIN || test > INT8_MAX)) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C int8"); + return -1; + } + return (int8_t)test; +} + +int16_t PyC_Long_AsI16(PyObject *value) +{ + int test = _PyLong_AsInt(value); + if (UNLIKELY(test < INT16_MIN || test > INT16_MAX)) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C int16"); + return -1; + } + return (int16_t)test; +} + +/* Inlined in header: + * PyC_Long_AsI32 + * PyC_Long_AsI64 + */ + +uint8_t PyC_Long_AsU8(PyObject *value) +{ + ulong test = PyLong_AsUnsignedLong(value); + if (UNLIKELY(test > UINT8_MAX)) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C uint8"); + return (uint8_t)-1; + } + return (uint8_t)test; +} + +uint16_t PyC_Long_AsU16(PyObject *value) +{ + ulong test = PyLong_AsUnsignedLong(value); + if (UNLIKELY(test > UINT16_MAX)) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C uint16"); + return (uint16_t)-1; + } + return (uint16_t)test; +} + +uint32_t PyC_Long_AsU32(PyObject *value) +{ + ulong test = PyLong_AsUnsignedLong(value); + if (UNLIKELY(test > UINT32_MAX)) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C uint32"); + return (uint32_t)-1; + } + return (uint32_t)test; +} + +/* Inlined in header: + * PyC_Long_AsU64 + */ + +#ifdef __GNUC__ +# pragma warning(pop) +#endif + +/** \} */ diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h index 3f89e1d82a0..322e67f486d 100644 --- a/source/blender/python/generic/py_capi_utils.h +++ b/source/blender/python/generic/py_capi_utils.h @@ -85,4 +85,26 @@ bool PyC_RunString_AsString(const char *expr, const char *filename, char **r_val int PyC_ParseBool(PyObject *o, void *p); + +/* Integer parsing (with overflow checks), -1 on error. */ +int PyC_Long_AsBool(PyObject *value); +int8_t PyC_Long_AsI8(PyObject *value); +int16_t PyC_Long_AsI16(PyObject *value); +#if 0 /* inline */ +int32_t PyC_Long_AsI32(PyObject *value); +int64_t PyC_Long_AsI64(PyObject *value); +#endif + +uint8_t PyC_Long_AsU8(PyObject *value); +uint16_t PyC_Long_AsU16(PyObject *value); +uint32_t PyC_Long_AsU32(PyObject *value); +#if 0 /* inline */ +uint64_t PyC_Long_AsU64(PyObject *value); +#endif + +/* inline so type signatures match as expected */ +BLI_INLINE int32_t PyC_Long_AsI32(PyObject *value) { return (int32_t)_PyLong_AsInt(value); } +BLI_INLINE int64_t PyC_Long_AsI64(PyObject *value) { return (int64_t)PyLong_AsLongLong(value); } +BLI_INLINE uint64_t PyC_Long_AsU64(PyObject *value) { return (uint64_t)PyLong_AsUnsignedLongLong(value); } + #endif /* __PY_CAPI_UTILS_H__ */ diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index e47bf21f04b..3693e2d22a0 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -292,7 +292,7 @@ static PyObject *bpy_app_debug_value_get(PyObject *UNUSED(self), void *UNUSED(cl static int bpy_app_debug_value_set(PyObject *UNUSED(self), PyObject *value, void *UNUSED(closure)) { - int param = PyLong_AsLong(value); + int param = PyC_Long_AsI32(value); if (param == -1 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "bpy.app.debug_value can only be set to a whole number"); diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 362c0281b36..611d70b8ed8 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -320,7 +320,7 @@ static int bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p value = false; } else { - value = PyLong_AsLong(ret); + value = PyC_Long_AsI32(ret); if (value == -1 && PyErr_Occurred()) { printf_func_error(py_func); @@ -599,7 +599,7 @@ static int bpy_prop_int_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) value = 0.0f; } else { - value = PyLong_AsLong(ret); + value = PyC_Long_AsI32(ret); if (value == -1 && PyErr_Occurred()) { printf_func_error(py_func); @@ -1249,7 +1249,7 @@ static int bpy_prop_enum_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop value = RNA_property_enum_get_default(ptr, prop); } else { - value = PyLong_AsLong(ret); + value = PyC_Long_AsI32(ret); if (value == -1 && PyErr_Occurred()) { printf_func_error(py_func); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 91ddec53909..fccffc7829c 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1643,7 +1643,7 @@ static int pyrna_py_to_prop( param = PyObject_IsTrue(value); } else { - param = PyLong_AsLong(value); + param = PyC_Long_AsI32(value); if (UNLIKELY(param & ~1)) { /* only accept 0/1 */ param = -1; /* error out below */ @@ -2088,10 +2088,10 @@ static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, P switch (RNA_property_type(prop)) { case PROP_BOOLEAN: { - int param = PyLong_AsLong(value); + int param = PyC_Long_AsBool(value); - if (param < 0 || param > 1) { - PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1"); + if (param == -1) { + /* error is set */ ret = -1; } else { @@ -2101,7 +2101,7 @@ static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, P } case PROP_INT: { - int param = PyLong_AsLong(value); + int param = PyC_Long_AsI32(value); if (param == -1 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "expected an int type"); ret = -1; @@ -2721,7 +2721,7 @@ static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return NULL; - return pyrna_prop_array_subscript_int(self, PyLong_AsLong(key)); + return pyrna_prop_array_subscript_int(self, i); } else if (PySlice_Check(key)) { Py_ssize_t step = 1; diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c index 38931cd85de..3e147d29c90 100644 --- a/source/blender/python/intern/bpy_rna_array.c +++ b/source/blender/python/intern/bpy_rna_array.c @@ -38,6 +38,8 @@ #include "RNA_access.h" +#include "../generic/py_capi_utils.h" + #define USE_MATHUTILS #ifdef USE_MATHUTILS @@ -550,7 +552,7 @@ static void py_to_float(const struct ItemConvertArgData *arg, PyObject *py, char static void py_to_int(const struct ItemConvertArgData *arg, PyObject *py, char *data) { const int *range = arg->int_data.range; - int value = (int)PyLong_AsLong(py); + int value = PyC_Long_AsI32(py); CLAMP(value, range[0], range[1]); *(int *)data = value; } diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c index afc8a30a6b5..f9cc9b5b409 100644 --- a/source/blender/python/mathutils/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -32,6 +32,8 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "../generic/py_capi_utils.h" + #ifndef MATH_STANDALONE # include "BLI_dynstr.h" #endif @@ -403,7 +405,7 @@ static PyObject *Vector_resize(VectorObject *self, PyObject *value) return NULL; } - if ((size = PyLong_AsLong(value)) == -1) { + if ((size = PyC_Long_AsI32(value)) == -1) { PyErr_SetString(PyExc_TypeError, "Vector.resize(size): " "expected size argument to be an integer"); diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c index bc3cd0bf416..8162f8e9d0c 100644 --- a/source/blender/python/mathutils/mathutils_bvhtree.c +++ b/source/blender/python/mathutils/mathutils_bvhtree.c @@ -761,7 +761,7 @@ static PyObject *C_BVHTree_FromPolygons(PyObject *UNUSED(cls), PyObject *args, P py_tricoords_fast_items = PySequence_Fast_ITEMS(py_tricoords_fast); for (j = 0; j < 3; j++) { - tri[j] = (unsigned int)_PyLong_AsInt(py_tricoords_fast_items[j]); + tri[j] = PyC_Long_AsU32(py_tricoords_fast_items[j]); if (UNLIKELY(tri[j] >= (unsigned int)coords_len)) { PyErr_Format(PyExc_ValueError, "%s: index %d must be less than %d", @@ -812,7 +812,7 @@ static PyObject *C_BVHTree_FromPolygons(PyObject *UNUSED(cls), PyObject *args, P p_plink_prev = &plink->next; for (j = 0; j < py_tricoords_len; j++) { - plink->poly[j] = (unsigned int)_PyLong_AsInt(py_tricoords_fast_items[j]); + plink->poly[j] = PyC_Long_AsU32(py_tricoords_fast_items[j]); if (UNLIKELY(plink->poly[j] >= (unsigned int)coords_len)) { PyErr_Format(PyExc_ValueError, "%s: index %d must be less than %d", diff --git a/tests/python/cycles_render_tests.py b/tests/python/cycles_render_tests.py index 77bee4953ba..d4e796f35ae 100755 --- a/tests/python/cycles_render_tests.py +++ b/tests/python/cycles_render_tests.py @@ -5,6 +5,7 @@ import argparse import glob import os import pathlib +import shlex import shutil import subprocess import sys @@ -52,38 +53,44 @@ def render_file(filepath): dirname = os.path.dirname(filepath) basedir = os.path.dirname(dirname) subject = os.path.basename(dirname) + + custom_args = os.getenv('CYCLESTEST_ARGS') + custom_args = shlex.split(custom_args) if custom_args else [] + + # OSL and GPU examples + # custom_args += ["--python-expr", "import bpy; bpy.context.scene.cycles.shading_system = True"] + # custom_args += ["--python-expr", "import bpy; bpy.context.scene.cycles.device = 'GPU'"] + if subject == 'opengl': - command = ( + command = [ BLENDER, "--window-geometry", "0", "0", "1", "1", "-noaudio", "--factory-startup", "--enable-autoexec", filepath, - "-E", "CYCLES", - # Run with OSL enabled - # "--python-expr", "import bpy; bpy.context.scene.cycles.shading_system = True", + "-E", "CYCLES"] + command += custom_args + command += [ "-o", TEMP_FILE_MASK, "-F", "PNG", '--python', os.path.join(basedir, "util", - "render_opengl.py") - ) + "render_opengl.py")] else: - command = ( + command = [ BLENDER, "--background", "-noaudio", "--factory-startup", "--enable-autoexec", filepath, - "-E", "CYCLES", - # Run with OSL enabled - # "--python-expr", "import bpy; bpy.context.scene.cycles.shading_system = True", + "-E", "CYCLES"] + command += custom_args + command += [ "-o", TEMP_FILE_MASK, "-F", "PNG", - "-f", "1", - ) + "-f", "1"] try: output = subprocess.check_output(command) if VERBOSE: |