[Bf-blender-cvs] [6d0d237be37] temp-eeveelightcache: Eevee: LightCache: Add auto update when lightprobe are being modified

Clément Foucault noreply at git.blender.org
Mon Jul 9 23:03:34 CEST 2018


Commit: 6d0d237be37bfe36255f61ccd9817005148d4475
Author: Clément Foucault
Date:   Sat Jul 7 12:58:46 2018 +0200
Branches: temp-eeveelightcache
https://developer.blender.org/rB6d0d237be37bfe36255f61ccd9817005148d4475

Eevee: LightCache: Add auto update when lightprobe are being modified

One draw back is that there is a significant overhead caused by creating
the batches for the new depsgraph. Caching the depsgraph between subsequent
update is not possible right now because we cannot update it. This is to be
adressed in the future.

There is no option to disable auto update right now.

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

M	source/blender/draw/engines/eevee/eevee_data.c
M	source/blender/draw/engines/eevee/eevee_engine.c
M	source/blender/draw/engines/eevee/eevee_lightcache.c
M	source/blender/draw/engines/eevee/eevee_lightcache.h
M	source/blender/draw/engines/eevee/eevee_lightprobes.c
M	source/blender/draw/engines/eevee/eevee_private.h
M	source/blender/draw/intern/draw_manager.c
M	source/blender/editors/render/render_shading.c
M	source/blender/editors/space_view3d/space_view3d.c
M	source/blender/windowmanager/WM_types.h

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

diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c
index 74bb7a17eb7..96e784b524c 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -131,15 +131,7 @@ EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob)
 static void eevee_lightprobe_data_init(DrawData *dd)
 {
 	EEVEE_LightProbeEngineData *ped = (EEVEE_LightProbeEngineData *)dd;
-	ped->need_full_update = true;
-	ped->need_update = true;
-}
-
-static void eevee_lightprobe_data_free(DrawData *dd)
-{
-	EEVEE_LightProbeEngineData *ped = (EEVEE_LightProbeEngineData *)dd;
-
-	BLI_freelistN(&ped->captured_object_list);
+	ped->need_update = false;
 }
 
 EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob)
@@ -159,7 +151,7 @@ EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob)
 	        &draw_engine_eevee_type,
 	        sizeof(EEVEE_LightProbeEngineData),
 	        eevee_lightprobe_data_init,
-	        eevee_lightprobe_data_free);
+	        NULL);
 }
 
 /* Lamp data. */
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index c4b673ddabf..6d68e609f03 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -367,10 +367,9 @@ static void eevee_view_update(void *vedata)
 
 static void eevee_id_object_update(void *UNUSED(vedata), Object *object)
 {
-	/* This is a bit mask of components which update is to be ignored. */
 	EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(object);
 	if (ped != NULL && ped->dd.recalc != 0) {
-		ped->need_full_update = true;
+		ped->need_update = (ped->dd.recalc & (ID_RECALC_TRANSFORM | ID_RECALC_COPY_ON_WRITE)) != 0;
 		ped->dd.recalc = 0;
 	}
 	EEVEE_LampEngineData *led = EEVEE_lamp_data_get(object);
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 219297d6c83..89f21b02dcd 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -30,6 +30,8 @@
 #include "BKE_global.h"
 #include "BKE_blender.h"
 
+#include "BLI_threads.h"
+
 #include "DEG_depsgraph_build.h"
 #include "DEG_depsgraph_query.h"
 
@@ -44,6 +46,9 @@
 #include "../../../intern/gawain/gawain/gwn_context.h"
 
 #include "WM_api.h"
+#include "WM_types.h"
+
+#include "wm_window.h"
 
 /* Rounded to nearest PowerOfTwo */
 #if defined(IRRADIANCE_SH_L2)
@@ -82,6 +87,8 @@ extern void DRW_gawain_render_context_disable(void *re_gwn_context);
 typedef struct EEVEE_LightBake {
 	Depsgraph *depsgraph;
 	ViewLayer *view_layer;
+	ViewLayer *view_layer_input;
+	LightCache *lcache;
 	Scene *scene;
 	struct Main *bmain;
 
@@ -105,7 +112,8 @@ typedef struct EEVEE_LightBake {
 	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. */
+	int grid_curr;                   /* Nth grid in the cache being rendered. */
+	int bounce_curr, bounce_len;     /* The current light bounce being evaluated. */
 	float vis_range, vis_blur;       /* Sample Visibility compression and bluring. */
 	float vis_res;                   /* Resolution of the Visibility shadowmap. */
 	GPUTexture *grid_prev;           /* Result of previous light bounce. */
@@ -129,6 +137,8 @@ typedef struct EEVEE_LightBake {
 	float *progress;
 
 	bool resource_only;              /* For only handling the resources. */
+	bool own_resources;
+	int delay;                       /* ms. delay the start of the baking to not slowdown interactions (TODO remove) */
 
 	void *gl_context, *gwn_context;  /* If running in parallel (in a separate thread), use this context. */
 } EEVEE_LightBake;
@@ -242,7 +252,6 @@ void EEVEE_lightcache_load(LightCache *lcache)
 		                                            NULL);
 		GPU_texture_bind(lcache->cube_tx.tex, 0);
 		GPU_texture_mipmap_mode(lcache->cube_tx.tex, true, true);
-		GPU_texture_generate_mipmap(lcache->cube_tx.tex);
 		for (int mip = 0; mip < lcache->mips_len; ++mip) {
 			GPU_texture_add_mipmap(lcache->cube_tx.tex, GPU_DATA_10_11_11_REV, mip + 1, lcache->cube_mips[mip].data);
 		}
@@ -378,10 +387,9 @@ static void eevee_lightbake_create_render_target(EEVEE_LightBake *lbake, int rt_
 static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
 {
 	Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
-	Scene *scene_orig = lbake->scene;
-	const SceneEEVEE *eevee = &scene_eval->eevee;
+	SceneEEVEE *eevee = &scene_eval->eevee;
 
-	lbake->bounce_count = eevee->gi_diffuse_bounces;
+	lbake->bounce_len   = eevee->gi_diffuse_bounces;
 	lbake->vis_res      = eevee->gi_visibility_resolution;
 	lbake->rt_res       = eevee->gi_cubemap_resolution;
 
@@ -398,62 +406,98 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
 	/* Ensure Light Cache is ready to accept new data. If not recreate one.
 	 * WARNING: All the following must be threadsafe. It's currently protected
 	 * by the DRW mutex. */
-	LightCache *lcache = scene_orig->eevee.light_cache;
+	lbake->lcache = eevee->light_cache;
 
 	/* TODO validate irradiance and reflection cache independantly... */
-	if (lcache != NULL &&
-	    !EEVEE_lightcache_validate(lcache, lbake->cube_len, lbake->ref_cube_res, lbake->irr_size))
+	if (lbake->lcache != NULL &&
+	    !EEVEE_lightcache_validate(lbake->lcache, lbake->cube_len, lbake->ref_cube_res, lbake->irr_size))
 	{
-		EEVEE_lightcache_free(lcache);
-		scene_orig->eevee.light_cache = lcache = NULL;
+		eevee->light_cache = lbake->lcache = NULL;
 	}
 
-	if (lcache == NULL) {
-		lcache = EEVEE_lightcache_create(lbake->grid_len,
-		                                 lbake->cube_len,
-		                                 lbake->ref_cube_res,
-		                                 lbake->vis_res,
-		                                 lbake->irr_size);
-		scene_orig->eevee.light_cache = lcache;
+	if (lbake->lcache == NULL) {
+		lbake->lcache = EEVEE_lightcache_create(lbake->grid_len,
+		                                        lbake->cube_len,
+		                                        lbake->ref_cube_res,
+		                                        lbake->vis_res,
+		                                        lbake->irr_size);
+		eevee->light_cache = lbake->lcache;
+	}
+
+	lbake->lcache->vis_res = lbake->vis_res;
+	lbake->lcache->flag = LIGHTCACHE_UPDATE_WORLD | LIGHTCACHE_UPDATE_CUBE | LIGHTCACHE_UPDATE_GRID | LIGHTCACHE_BAKING;
+}
+
+wmJob *EEVEE_lightbake_job_create(
+        struct wmWindowManager *wm, struct wmWindow *win, struct Main *bmain,
+        struct ViewLayer *view_layer, struct Scene *scene, int delay)
+{
+	EEVEE_LightBake *lbake = NULL;
+
+	/* only one render job at a time */
+	if (WM_jobs_test(wm, scene, WM_JOB_TYPE_RENDER))
+		return NULL;
+
+	wmJob *wm_job = WM_jobs_get(wm, win, scene, "Bake Lighting",
+	                            WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, WM_JOB_TYPE_LIGHT_BAKE);
+
+	/* If job exists do not recreate context and depsgraph. */
+	EEVEE_LightBake *old_lbake = (EEVEE_LightBake *)WM_jobs_customdata_get(wm_job);
+
+	if (old_lbake && (old_lbake->view_layer_input == view_layer) && (old_lbake->bmain == bmain)) {
+		lbake = MEM_callocN(sizeof(EEVEE_LightBake), "EEVEE_LightBake");
+		/* Cannot reuse depsgraph for now because we cannot get the update from the
+		 * main database directly. TODO reuse depsgraph and only update positions. */
+		/* lbake->depsgraph = old_lbake->depsgraph; */
+		lbake->depsgraph = DEG_graph_new(scene, view_layer, DAG_EVAL_RENDER);
+
+		lbake->scene = scene;
+		lbake->bmain = bmain;
+		lbake->view_layer_input = view_layer;
+		lbake->gl_context = old_lbake->gl_context;
+		lbake->gwn_context = old_lbake->gwn_context;
+		lbake->own_resources = true;
+		lbake->delay = delay;
+
+		old_lbake->own_resources = false;
 
-		DEG_id_tag_update(&scene_orig->id, DEG_TAG_COPY_ON_WRITE);
+		if (old_lbake->stop != NULL) {
+			*old_lbake->stop = 1;
+		}
+	}
+	else {
+		lbake = EEVEE_lightbake_job_data_alloc(bmain, view_layer, scene, true);
+		lbake->delay = delay;
 	}
 
-	lcache->vis_res = lbake->vis_res;
+	WM_jobs_customdata_set(wm_job, lbake, EEVEE_lightbake_job_data_free);
+	WM_jobs_timer(wm_job, 0.4, NC_SCENE | NA_EDITED, 0);
+	WM_jobs_callbacks(wm_job, EEVEE_lightbake_job, NULL, EEVEE_lightbake_update, EEVEE_lightbake_update);
 
-	lcache->flag = LIGHTCACHE_UPDATE_WORLD | LIGHTCACHE_UPDATE_CUBE | LIGHTCACHE_UPDATE_GRID | LIGHTCACHE_BAKING;
+	G.is_break = false;
 
-	/* Share light cache with the evaluated (baking) layer and the original layer.
-	 * This avoid full scene re-evaluation by depsgraph. */
-	scene_eval->eevee.light_cache = lcache;
+	return wm_job;
 }
 
 /* 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)
+void *EEVEE_lightbake_job_data_alloc(
+        struct Main *bmain, struct ViewLayer *view_layer, struct Scene *scene, bool run_as_job)
 {
+	BLI_assert(BLI_thread_is_main());
+
 	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;
+	lbake->view_layer_input = view_layer;
+	lbake->own_resources = true;
 
 	if (run_as_job) {
 		lbake->gl_context = WM_opengl_context_create();
+		wm_window_reset_drawable();
 	}
 
-    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);
-
-	/* Count lightprobes */
-	eevee_lightbake_count_probes(lbake);
-
-	DRW_opengl_context_enable();
-	/* This function needs to run on the main thread. */
-	eevee_lightbake_create_resources(lbake);
-	DRW_opengl_context_disable();
-
 	return lbake;
 }
 
@@ -461,7 +505,10 @@ void EEVEE_lightbake_job_data_free(void *custom_data)
 {
 	EEVEE_Li

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list