[Bf-blender-cvs] [7778a1a0a12] blender2.7: Cycles: optimization for constant background colors.

Brecht Van Lommel noreply at git.blender.org
Sun Mar 17 12:05:27 CET 2019


Commit: 7778a1a0a12fc026dc5bcc2c195b9460d1c77b53
Author: Brecht Van Lommel
Date:   Tue Feb 19 17:44:58 2019 +0100
Branches: blender2.7
https://developer.blender.org/rB7778a1a0a12fc026dc5bcc2c195b9460d1c77b53

Cycles: optimization for constant background colors.

Skip shader evaluation then, as we already do for lights. Less than
1% faster in my tests, but might as well be consistent for both.

===================================================================

M	intern/cycles/kernel/kernel_bake.h
M	intern/cycles/kernel/kernel_emission.h
M	intern/cycles/kernel/kernel_shader.h
M	intern/cycles/render/shader.cpp

===================================================================

diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index 920b10086c5..37c163f2538 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -351,7 +351,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
 				out = make_float3(roughness, roughness, roughness);
 			}
 			else {
-				out = shader_emissive_eval(kg, &sd);
+				out = shader_emissive_eval(&sd);
 			}
 			break;
 		}
@@ -475,8 +475,9 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
 			shader_setup_from_background(kg, &sd, &ray);
 
 			/* evaluate */
-			int flag = 0; /* we can't know which type of BSDF this is for */
-			out = shader_eval_background(kg, &sd, &state, flag);
+			int path_flag = 0; /* we can't know which type of BSDF this is for */
+			shader_eval_surface(kg, &sd, &state, path_flag | PATH_RAY_EMISSION);
+			out = shader_background_eval(&sd);
 			break;
 		}
 		default:
@@ -554,8 +555,9 @@ ccl_device void kernel_background_evaluate(KernelGlobals *kg,
 	shader_setup_from_background(kg, &sd, &ray);
 
 	/* evaluate */
-	int flag = 0; /* we can't know which type of BSDF this is for */
-	float3 color = shader_eval_background(kg, &sd, &state, flag);
+	int path_flag = 0; /* we can't know which type of BSDF this is for */
+	shader_eval_surface(kg, &sd, &state, path_flag | PATH_RAY_EMISSION);
+	float3 color = shader_background_eval(&sd);
 
 	/* write output */
 	output[i] += make_float4(color.x, color.y, color.z, 0.0f);
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index 302bb047647..9c47d1ca7be 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -29,43 +29,36 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg,
 	/* setup shading at emitter */
 	float3 eval;
 
-	int shader_flag = kernel_tex_fetch(__shaders, (ls->shader & SHADER_MASK)).flags;
-
-#ifdef __BACKGROUND_MIS__
-	if(ls->type == LIGHT_BACKGROUND) {
-		Ray ray;
-		ray.D = ls->D;
-		ray.P = ls->P;
-		ray.t = 1.0f;
-		ray.time = time;
-		ray.dP = differential3_zero();
-		ray.dD = dI;
-
-		shader_setup_from_background(kg, emission_sd, &ray);
-
-		path_state_modify_bounce(state, true);
-		eval = shader_eval_background(kg, emission_sd, state, 0);
-		path_state_modify_bounce(state, false);
-	}
-	else
-#endif
-	if(shader_flag & SD_HAS_CONSTANT_EMISSION)
-	{
-		eval.x = kernel_tex_fetch(__shaders, (ls->shader & SHADER_MASK)).constant_emission[0];
-		eval.y = kernel_tex_fetch(__shaders, (ls->shader & SHADER_MASK)).constant_emission[1];
-		eval.z = kernel_tex_fetch(__shaders, (ls->shader & SHADER_MASK)).constant_emission[2];
+	if(shader_constant_emission_eval(kg, ls->shader, &eval)) {
 		if((ls->prim != PRIM_NONE) && dot(ls->Ng, I) < 0.0f) {
 			ls->Ng = -ls->Ng;
 		}
 	}
-	else
-	{
-		shader_setup_from_sample(kg, emission_sd,
-		                         ls->P, ls->Ng, I,
-		                         ls->shader, ls->object, ls->prim,
-		                         ls->u, ls->v, t, time, false, ls->lamp);
+	else {
+		/* Setup shader data and call shader_eval_surface once, better
+		 * for GPU coherence and compile times. */
+#ifdef __BACKGROUND_MIS__
+		if(ls->type == LIGHT_BACKGROUND) {
+			Ray ray;
+			ray.D = ls->D;
+			ray.P = ls->P;
+			ray.t = 1.0f;
+			ray.time = time;
+			ray.dP = differential3_zero();
+			ray.dD = dI;
+
+			shader_setup_from_background(kg, emission_sd, &ray);
+		}
+		else
+#endif
+		{
+			shader_setup_from_sample(kg, emission_sd,
+			                         ls->P, ls->Ng, I,
+			                         ls->shader, ls->object, ls->prim,
+			                         ls->u, ls->v, t, time, false, ls->lamp);
 
-		ls->Ng = emission_sd->Ng;
+			ls->Ng = emission_sd->Ng;
+		}
 
 		/* No proper path flag, we're evaluating this for all closures. that's
 		 * weak but we'd have to do multiple evaluations otherwise. */
@@ -73,8 +66,16 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg,
 		shader_eval_surface(kg, emission_sd, state, PATH_RAY_EMISSION);
 		path_state_modify_bounce(state, false);
 
-		/* Evaluate emissive closure. */
-		eval = shader_emissive_eval(kg, emission_sd);
+		/* Evaluate closures. */
+#ifdef __BACKGROUND_MIS__
+		if (ls->type == LIGHT_BACKGROUND) {
+			eval = shader_background_eval(emission_sd);
+		}
+		else
+#endif
+		{
+			eval = shader_emissive_eval(emission_sd);
+		}
 	}
 
 	eval *= ls->eval_fac;
@@ -201,7 +202,7 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg,
 ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf)
 {
 	/* evaluate emissive closure */
-	float3 L = shader_emissive_eval(kg, sd);
+	float3 L = shader_emissive_eval(sd);
 
 #ifdef __HAIR__
 	if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) && (sd->type & PRIMITIVE_ALL_TRIANGLE))
@@ -294,7 +295,7 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg,
 #ifdef __BACKGROUND__
 	int shader = kernel_data.background.surface_shader;
 
-	/* use visibility flag to skip lights */
+	/* Use visibility flag to skip lights. */
 	if(shader & SHADER_EXCLUDE_ANY) {
 		if(((shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
 		   ((shader & SHADER_EXCLUDE_GLOSSY) &&
@@ -305,20 +306,27 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg,
 			return make_float3(0.0f, 0.0f, 0.0f);
 	}
 
-	/* evaluate background closure */
+
+	/* Evaluate background shader. */
+	float3 L;
+	if(!shader_constant_emission_eval(kg, shader, &L)) {
 #  ifdef __SPLIT_KERNEL__
-	Ray priv_ray = *ray;
-	shader_setup_from_background(kg, emission_sd, &priv_ray);
+		Ray priv_ray = *ray;
+		shader_setup_from_background(kg, emission_sd, &priv_ray);
 #  else
-	shader_setup_from_background(kg, emission_sd, ray);
+		shader_setup_from_background(kg, emission_sd, ray);
 #  endif
 
-	path_state_modify_bounce(state, true);
-	float3 L = shader_eval_background(kg, emission_sd, state, state->flag);
-	path_state_modify_bounce(state, false);
+		path_state_modify_bounce(state, true);
+		shader_eval_surface(kg, emission_sd, state, PATH_RAY_EMISSION);
+		path_state_modify_bounce(state, false);
+
+		L = shader_background_eval(emission_sd);
+	}
 
+	/* Background MIS weights. */
 #ifdef __BACKGROUND_MIS__
-	/* check if background light exists or if we should skip pdf */
+	/* Check if background light exists or if we should skip pdf. */
 	int res_x = kernel_data.integrator.pdf_background_res_x;
 
 	if(!(state->flag & PATH_RAY_MIS_SKIP) && res_x) {
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index afb9ff11c10..eff792ec53d 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -984,9 +984,40 @@ ccl_device float3 shader_bssrdf_sum(ShaderData *sd, float3 *N_, float *texture_b
 }
 #endif  /* __SUBSURFACE__ */
 
+/* Constant emission optimization */
+
+ccl_device bool shader_constant_emission_eval(KernelGlobals *kg, int shader, float3 *eval)
+{
+	int shader_index = shader & SHADER_MASK;
+	int shader_flag = kernel_tex_fetch(__shaders, shader_index).flags;
+
+	if (shader_flag & SD_HAS_CONSTANT_EMISSION) {
+		*eval = make_float3(
+			kernel_tex_fetch(__shaders, shader_index).constant_emission[0],
+			kernel_tex_fetch(__shaders, shader_index).constant_emission[1],
+			kernel_tex_fetch(__shaders, shader_index).constant_emission[2]);
+
+		return true;
+	}
+
+	return false;
+}
+
+/* Background */
+
+ccl_device float3 shader_background_eval(ShaderData *sd)
+{
+	if(sd->flag & SD_EMISSION) {
+		return sd->closure_emission_background;
+	}
+	else {
+		return make_float3(0.0f, 0.0f, 0.0f);
+	}
+}
+
 /* Emission */
 
-ccl_device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
+ccl_device float3 shader_emissive_eval(ShaderData *sd)
 {
 	if(sd->flag & SD_EMISSION) {
 		return emissive_simple_eval(sd->Ng, sd->I) * sd->closure_emission_background;
@@ -1034,20 +1065,32 @@ ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
 	sd->num_closure_left = max_closures;
 
 #ifdef __OSL__
-	if(kg->osl)
-		OSLShader::eval_surface(kg, sd, state, path_flag);
+	if(kg->osl) {
+		if (sd->object == OBJECT_NONE) {
+			OSLShader::eval_background(kg, sd, state, path_flag);
+		}
+		else {
+			OSLShader::eval_surface(kg, sd, state, path_flag);
+		}
+	}
 	else
 #endif
 	{
 #ifdef __SVM__
 		svm_eval_nodes(kg, sd, state, SHADER_TYPE_SURFACE, path_flag);
 #else
-		DiffuseBsdf *bsdf = (DiffuseBsdf*)bsdf_alloc(sd,
-		                                             sizeof(DiffuseBsdf),
-		                                             make_float3(0.8f, 0.8f, 0.8f));
-		if(bsdf != NULL) {
-			bsdf->N = sd->N;
-			sd->flag |= bsdf_diffuse_setup(bsdf);
+		if(sd->object == OBJECT_NONE) {
+			sd->closure_emission_background = make_float3(0.8f, 0.8f, 0.8f);
+			sd->flag |= SD_EMISSION;
+		}
+		else {
+			DiffuseBsdf *bsdf = (DiffuseBsdf*)bsdf_alloc(sd,
+			                                             sizeof(DiffuseBsdf),
+			                                             make_float3(0.8f, 0.8f, 0.8f));
+			if(bsdf != NULL) {
+				bsdf->N = sd->N;
+				sd->flag |= bsdf_diffuse_setup(bsdf);
+			}
 		}
 #endif
 	}
@@ -1057,36 +1100,6 @@ ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
 	}
 }
 
-/* Background Evaluation */
-
-ccl_device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd,
-	ccl_addr_space PathState *state, int path_flag)
-{
-	sd->num_closure = 0;
-	sd->num_closure_left = 0;
-
-#ifdef __SVM__
-#  ifdef __OSL__
-	if(kg->osl) {
-		OSLShader::eval_background(kg, sd, state, path_flag);
-	}
-	else
-#  endif  /* __OSL__ */
-	{
-		svm_eval_nodes(kg, sd, state, SHADER_TYPE_SURFACE, path_flag);
-	}
-
-	if(sd->flag & SD_EMISSION) {
-		return sd->closure_emission_background;
-	}
-	else {
-		return make_float3(0.0f, 0.0f, 0.0f);
-	}
-#else  /* __SVM__ */
-	return make_float3(0.8f, 0.8f, 0.8f);
-#endif  /* __SVM__ */
-}
-
 /* Volume */
 
 #ifdef __VOLUME__
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 9f256a665cd..0f40ab7b15f 100644
--- a/intern/cycles/render/shader.

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list