[Bf-blender-cvs] [007d3074fab] temp-eeveelightcache: Eevee: Move cache creation to main thread

Clément Foucault noreply at git.blender.org
Fri Jun 22 17:46:23 CEST 2018


Commit: 007d3074fab68629e20a6596b363476a7fc4ab5d
Author: Clément Foucault
Date:   Wed Jun 20 11:59:41 2018 +0200
Branches: temp-eeveelightcache
https://developer.blender.org/rB007d3074fab68629e20a6596b363476a7fc4ab5d

Eevee: Move cache creation to main thread

This fix freeing hazard and use after free.

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

M	source/blender/draw/engines/eevee/eevee_lightcache.c
M	source/blender/draw/engines/eevee/eevee_materials.c

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

diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 1e0d64c2124..dac79c413e5 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -104,6 +104,7 @@ typedef struct EEVEE_LightBake {
 	int irr_cube_res;                /* Target cubemap at MIP 0. */
 	int irr_size[3];                 /* Size of the irradiance texture. */
 	int total_irr_samples;           /* Total for all grids */
+	int grid_sample;                 /* Nth sample of the current grid being rendered. */
 	int bounce_curr, bounce_count;   /* The current light bounce being evaluated. */
 	float vis_range, vis_blur;       /* Sample Visibility compression and bluring. */
 	float vis_res;                   /* Resolution of the Visibility shadowmap. */
@@ -203,39 +204,64 @@ void EEVEE_lightcache_free(EEVEE_LightCache *lcache)
 
 /* -------------------------------------------------------------------- */
 
-/** \name Light Bake Job
+/** \name Light Bake Context
  * \{ */
 
-void *EEVEE_lightbake_job_data_alloc(struct Main *bmain, struct ViewLayer *view_layer, struct Scene *scene, bool run_as_job)
+static void eevee_lightbake_context_enable(EEVEE_LightBake *lbake)
 {
-	EEVEE_LightBake *lbake = MEM_callocN(sizeof(EEVEE_LightBake), "EEVEE_LightBake");
-
-	lbake->depsgraph = DEG_graph_new(scene, view_layer, DAG_EVAL_RENDER);
-	lbake->scene = scene;
-	lbake->bmain = bmain;
+	if (lbake->gl_context) {
+		DRW_opengl_render_context_enable(lbake->gl_context);
+		if (lbake->gwn_context == NULL) {
+			lbake->gwn_context = GWN_context_create();
+		}
+		DRW_gawain_render_context_enable(lbake->gwn_context);
+	}
+	else {
+		DRW_opengl_context_enable();
+	}
+}
 
-	if (run_as_job) {
-		lbake->gl_context = WM_opengl_context_create();
+static void eevee_lightbake_context_disable(EEVEE_LightBake *lbake)
+{
+	if (lbake->gl_context) {
+		DRW_opengl_render_context_disable(lbake->gl_context);
+		DRW_gawain_render_context_disable(lbake->gwn_context);
 	}
+	else {
+		DRW_opengl_context_disable();
+	}
+}
 
-    DEG_graph_relations_update(lbake->depsgraph, bmain, scene, view_layer);
+/** \} */
 
-	int frame = 0; /* TODO make it user param. */
-	DEG_evaluate_on_framechange(lbake->bmain, lbake->depsgraph, frame);
 
-	return lbake;
-}
+/* -------------------------------------------------------------------- */
 
-void EEVEE_lightbake_job_data_free(void *custom_data)
+/** \name Light Bake Job
+ * \{ */
+
+static void eevee_lightbake_count_probes(EEVEE_LightBake *lbake)
 {
-	EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
+	Depsgraph *depsgraph = lbake->depsgraph;
 
-	DEG_graph_free(lbake->depsgraph);
+	/* At least one of each for the world */
+	lbake->grid_count = lbake->cube_count = lbake->total_irr_samples = 1;
 
-	MEM_SAFE_FREE(lbake->cube_prb);
-	MEM_SAFE_FREE(lbake->grid_prb);
+	DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
+	{
+		if (ob->type == OB_LIGHTPROBE) {
+			LightProbe *prb = (LightProbe *)ob->data;
 
-	MEM_freeN(lbake);
+			if (prb->type == LIGHTPROBE_TYPE_GRID) {
+				lbake->total_irr_samples += prb->grid_resolution_x * prb->grid_resolution_y * prb->grid_resolution_z;
+				lbake->grid_count++;
+			}
+			else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
+				lbake->cube_count++;
+			}
+		}
+	}
+	DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
 }
 
 static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
@@ -290,6 +316,8 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
 	if (lcache == NULL) {
 		lcache = EEVEE_lightcache_create(lbake->grid_count, lbake->cube_count, lbake->ref_cube_res, lbake->irr_size);
 		scene_orig->eevee.light_cache = lcache;
+
+		DEG_id_tag_update(&scene_orig->id, DEG_TAG_COPY_ON_WRITE);
 	}
 
 	/* Share light cache with the evaluated (baking) layer and the original layer.
@@ -297,6 +325,48 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
 	scene_eval->eevee.light_cache = lcache;
 }
 
+/* MUST run on the main thread. */
+void *EEVEE_lightbake_job_data_alloc(struct Main *bmain, struct ViewLayer *view_layer, struct Scene *scene, bool run_as_job)
+{
+	EEVEE_LightBake *lbake = MEM_callocN(sizeof(EEVEE_LightBake), "EEVEE_LightBake");
+
+	lbake->depsgraph = DEG_graph_new(scene, view_layer, DAG_EVAL_RENDER);
+	lbake->scene = scene;
+	lbake->bmain = bmain;
+
+	if (run_as_job) {
+		lbake->gl_context = WM_opengl_context_create();
+	}
+
+    DEG_graph_relations_update(lbake->depsgraph, bmain, scene, view_layer);
+
+	int frame = 0; /* TODO make it user param. */
+	DEG_evaluate_on_framechange(lbake->bmain, lbake->depsgraph, frame);
+
+	/* The following needs to run on the main thread. */
+
+	/* Count lightprobes */
+	eevee_lightbake_count_probes(lbake);
+
+	DRW_opengl_context_enable();
+	eevee_lightbake_create_resources(lbake);
+	DRW_opengl_context_disable();
+
+	return lbake;
+}
+
+void EEVEE_lightbake_job_data_free(void *custom_data)
+{
+	EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
+
+	DEG_graph_free(lbake->depsgraph);
+
+	MEM_SAFE_FREE(lbake->cube_prb);
+	MEM_SAFE_FREE(lbake->grid_prb);
+
+	MEM_freeN(lbake);
+}
+
 static void eevee_lightbake_delete_resources(EEVEE_LightBake *lbake)
 {
 	if (lbake->gl_context) {
@@ -330,31 +400,6 @@ static void eevee_lightbake_delete_resources(EEVEE_LightBake *lbake)
 	}
 }
 
-static void eevee_lightbake_context_enable(EEVEE_LightBake *lbake)
-{
-	if (lbake->gl_context) {
-		DRW_opengl_render_context_enable(lbake->gl_context);
-		if (lbake->gwn_context == NULL) {
-			lbake->gwn_context = GWN_context_create();
-		}
-		DRW_gawain_render_context_enable(lbake->gwn_context);
-	}
-	else {
-		DRW_opengl_context_enable();
-	}
-}
-
-static void eevee_lightbake_context_disable(EEVEE_LightBake *lbake)
-{
-	if (lbake->gl_context) {
-		DRW_opengl_render_context_disable(lbake->gl_context);
-		DRW_gawain_render_context_disable(lbake->gwn_context);
-	}
-	else {
-		DRW_opengl_context_disable();
-	}
-}
-
 /* Cache as in draw cache not light cache. */
 static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lbake)
 {
@@ -395,6 +440,7 @@ static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lb
 
 	DRW_render_instance_buffer_finish();
 }
+
 static void eevee_lightbake_render_world(void *ved, void *user_data)
 {
 	EEVEE_Data *vedata = (EEVEE_Data *)ved;
@@ -425,62 +471,56 @@ static void eevee_lightbake_render_grid_sample(void *ved, void *user_data)
 {
 	EEVEE_Data *vedata = (EEVEE_Data *)ved;
 	EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
+	EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
 	EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
+	EEVEE_LightGrid *egrid = lbake->grid;
+	LightProbe *prb = *lbake->probe;
 
 	/* TODO do this once for the whole bake when we have independant DRWManagers. */
 	eevee_lightbake_cache_create(vedata, lbake);
 
 	/* Compute sample position */
-	/* ... */
-
-	/* Disable specular. */
-	/* ... */
-
-	EEVEE_lightbake_render_scene(sldata, vedata, lbake->rt_fb, (float[3]){0.0f}, 1.0f, 10.0f);
-	EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake->rt_color, lbake->store_fb, 0, 1.0f);
-	EEVEE_lightbake_filter_visibility(sldata, vedata, lbake->rt_depth, lbake->store_fb, 0, 1.0f, 10.0f, 9.0f, 1.0f, 32);
+	float pos[3];
+	copy_v3_v3(pos, egrid->corner);
+	madd_v3_v3fl(pos, egrid->increment_x, lbake->grid_sample % prb->grid_resolution_x);
+	madd_v3_v3fl(pos, egrid->increment_y, lbake->grid_sample / prb->grid_resolution_x);
+	madd_v3_v3fl(pos, egrid->increment_z, lbake->grid_sample / (prb->grid_resolution_x * prb->grid_resolution_y));
+
+	/* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
+	common_data->spec_toggle = false;
+	common_data->prb_num_planar = 0;
+	common_data->prb_num_render_cube = 0;
+	common_data->prb_num_render_grid = 0;
+	DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
+
+	int sample_offset = egrid->offset + lbake->grid_sample;
+	EEVEE_lightbake_render_scene(sldata, vedata, lbake->rt_fb, pos, prb->clipsta, prb->clipend);
+	EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake->rt_color, lbake->store_fb, sample_offset, prb->intensity);
+	EEVEE_lightbake_filter_visibility(sldata, vedata, lbake->rt_depth, lbake->store_fb, sample_offset,
+	                                  prb->clipsta, prb->clipend, egrid->visibility_range,
+	                                  prb->vis_blur, lbake->vis_res);
 }
 
 static void eevee_lightbake_render_probe(void *ved, void *user_data)
 {
 	EEVEE_Data *vedata = (EEVEE_Data *)ved;
 	EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
+	EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
 	EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
 
 	/* TODO do this once for the whole bake when we have independant DRWManagers. */
 	eevee_lightbake_cache_create(vedata, lbake);
 
-	/* Disable specular. */
-	/* ... */
+	/* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
+	common_data->spec_toggle = false;
+	common_data->prb_num_planar = 0;
+	common_data->prb_num_render_cube = 0;
+	DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
 
 	EEVEE_lightbake_render_scene(sldata, vedata, lbake->rt_fb, (float[3]){0.0f}, 1.0f, 10.0f);
 	EEVEE_lightbake_filter_glossy(sldata, vedata, lbake->rt_color, lbake->store_fb, 0, 1.0);
 }
 
-static void eevee_lightbake_count_probes(EEVEE_LightBake *lbake)
-{
-	Depsgraph *depsgraph = lbake->depsgraph;
-
-	/* At least one of each for the world */
-	lbake->grid_count = lbake->cube_count = lbake->total_irr_samples = 1;
-
-	DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
-	{
-		if (ob->type == OB_LIGHTPROBE) {
-			LightProbe *prb = (LightProbe *)ob->data;
-
-			if (prb->type == LIGHTPROBE_TYPE_GRID) {
-				lbake->total_irr_samples += prb->grid_resolution_x * prb->grid_resolution_y * prb->grid_resolution_z;
-				lbake->grid_count++;
-			}
-			else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
-				lbake->cube_count++;
-			}
-		}
-	}
-	DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
-}
-
 static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
 {
 	Depsgraph *depsgraph = lb

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list