[Bf-blender-cvs] [60e2e1058d6] temp-eeveelightcache: Eevee: LightCache: Write LightCache to File

Clément Foucault noreply at git.blender.org
Thu Jun 28 15:55:16 CEST 2018


Commit: 60e2e1058d6faf51fd95849440c9d8b5bcea2391
Author: Clément Foucault
Date:   Thu Jun 28 15:53:01 2018 +0200
Branches: temp-eeveelightcache
https://developer.blender.org/rB60e2e1058d6faf51fd95849440c9d8b5bcea2391

Eevee: LightCache: Write LightCache to File

This patch does a few things for it to work.
- It port some eevee's struct to DNA for them to be saved in the file.
- Readback the result of the lightcache baking and store it in the scene
  struct.

For small scenes, it's okayish to keep the data around in memory but a
better approach would be to save it to disk.

A standard reflection probe is more than 6 MB of data.
Diffuse irradiance grids are relatively small compared to this.

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

M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.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_lookdev.c
M	source/blender/draw/engines/eevee/eevee_materials.c
M	source/blender/draw/engines/eevee/eevee_private.h
M	source/blender/draw/engines/eevee/eevee_screen_raytrace.c
M	source/blender/draw/engines/eevee/eevee_volumes.c
M	source/blender/makesdna/DNA_lightprobe_types.h
M	source/blender/makesdna/DNA_scene_types.h

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

diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 15b0589e8c4..196ab40b1f1 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1649,7 +1649,7 @@ void blo_make_scene_pointer_map(FileData *fd, Main *oldmain)
 
 	for (; sce; sce = sce->id.next) {
 		if (sce->eevee.light_cache) {
-			struct EEVEE_LightCache *light_cache = sce->eevee.light_cache;
+			struct LightCache *light_cache = sce->eevee.light_cache;
 			oldnewmap_insert(fd->scenemap, light_cache, light_cache, 0);
 		}
 	}
@@ -5827,6 +5827,41 @@ static void lib_link_sequence_modifiers(FileData *fd, Scene *scene, ListBase *lb
 	}
 }
 
+static void direct_link_lightcache_texture(FileData *fd, LightCacheTexture *lctex)
+{
+	lctex->tex = NULL;
+
+	if (lctex->data) {
+		lctex->data = newdataadr(fd, lctex->data);
+		if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
+			int data_size = lctex->components * lctex->tex_size[0] * lctex->tex_size[1] * lctex->tex_size[2];
+
+			if (lctex->data_type == LIGHTCACHETEX_FLOAT) {
+				BLI_endian_switch_float_array((float *)lctex->data, data_size * sizeof(float));
+			}
+			else if (lctex->data_type == LIGHTCACHETEX_UINT) {
+				BLI_endian_switch_uint32_array((unsigned int *)lctex->data, data_size * sizeof(unsigned int));
+			}
+		}
+	}
+}
+
+static void direct_link_lightcache(FileData *fd, LightCache *cache)
+{
+	direct_link_lightcache_texture(fd, &cache->cube_tx);
+	direct_link_lightcache_texture(fd, &cache->grid_tx);
+
+	if (cache->cube_mips) {
+		cache->cube_mips = newdataadr(fd, cache->cube_mips);
+		for (int i = 0; i < cache->mips_len; ++i) {
+			direct_link_lightcache_texture(fd, &cache->cube_mips[i]);
+		}
+	}
+
+	cache->cube_data = newdataadr(fd, cache->cube_data);
+	cache->grid_data = newdataadr(fd, cache->grid_data);
+}
+
 /* check for cyclic set-scene,
  * libs can cause this case which is normally prevented, see (T#####) */
 #define USE_SETSCENE_CHECK
@@ -6370,8 +6405,18 @@ static void direct_link_scene(FileData *fd, Scene *sce)
 		direct_link_view_layer(fd, view_layer);
 	}
 
-	if (fd->scenemap) sce->eevee.light_cache = newsceadr(fd, sce->eevee.light_cache);
-	else sce->eevee.light_cache = NULL;
+	if (fd->memfile) {
+		/* If it's undo try to recover the cache. */
+		if (fd->scenemap) sce->eevee.light_cache = newsceadr(fd, sce->eevee.light_cache);
+		else sce->eevee.light_cache = NULL;
+	}
+	else {
+		/* else read the cache from file. */
+		if (sce->eevee.light_cache) {
+			sce->eevee.light_cache = newdataadr(fd, sce->eevee.light_cache);
+			direct_link_lightcache(fd, sce->eevee.light_cache);
+		}
+	}
 
 	sce->layer_properties = newdataadr(fd, sce->layer_properties);
 	IDP_DirectLinkGroup_OrFree(&sce->layer_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 1a33b9440b5..f3e7252258b 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -2468,6 +2468,36 @@ static void write_view_layer(WriteData *wd, ViewLayer *view_layer)
 	write_layer_collections(wd, &view_layer->layer_collections);
 }
 
+static void write_lightcache_texture(WriteData *wd, LightCacheTexture *tex)
+{
+	if (tex->data) {
+		size_t data_size = tex->components * tex->tex_size[0] * tex->tex_size[1] * tex->tex_size[2];
+		if (tex->data_type == LIGHTCACHETEX_FLOAT) {
+			data_size *= sizeof(float);
+		}
+		else if (tex->data_type == LIGHTCACHETEX_UINT) {
+			data_size *= sizeof(unsigned int);
+		}
+		writedata(wd, DATA, data_size, tex->data);
+	}
+}
+
+static void write_lightcache(WriteData *wd, LightCache *cache)
+{
+	write_lightcache_texture(wd, &cache->grid_tx);
+	write_lightcache_texture(wd, &cache->cube_tx);
+
+	if (cache->cube_mips) {
+		writestruct(wd, DATA, LightCacheTexture, cache->mips_len, cache->cube_mips);
+		for (int i = 0; i < cache->mips_len; ++i) {
+			write_lightcache_texture(wd, &cache->cube_mips[i]);
+		}
+	}
+
+	writestruct(wd, DATA, LightGridCache,    cache->grid_len, cache->grid_data);
+	writestruct(wd, DATA, LightProbeCache,   cache->cube_len, cache->cube_data);
+}
+
 static void write_scene(WriteData *wd, Scene *sce)
 {
 	/* write LibData */
@@ -2663,6 +2693,12 @@ static void write_scene(WriteData *wd, Scene *sce)
 		write_collection_nolib(wd, sce->master_collection);
 	}
 
+	/* Eevee Lightcache */
+	if (sce->eevee.light_cache && !wd->use_memfile) {
+		writestruct(wd, DATA, LightCache, 1, sce->eevee.light_cache);
+		write_lightcache(wd, sce->eevee.light_cache);
+	}
+
 	/* Freed on doversion. */
 	BLI_assert(sce->layer_properties == NULL);
 }
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index ae76e13b2c2..c4b673ddabf 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -388,7 +388,7 @@ static void eevee_id_object_update(void *UNUSED(vedata), Object *object)
 static void eevee_id_world_update(void *vedata, World *wo)
 {
 	EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
-	EEVEE_LightCache *lcache = stl->g_data->light_cache;
+	LightCache *lcache = stl->g_data->light_cache;
 
 	EEVEE_WorldEngineData *wedata = EEVEE_world_data_ensure(wo);
 
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index f87257cd634..c449f6a0894 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -97,7 +97,7 @@ typedef struct EEVEE_LightBake {
 	float samples_ct, invsamples_ct; /* Sample count for the convolution. */
 	float lod_factor;                /* Sampling bias during convolution step. */
 	float lod_max;                   /* Max cubemap LOD to sample when convolving. */
-	int cube_count, grid_count;      /* Number of probes to render + world probe. */
+	int cube_len, grid_len;          /* Number of probes to render + world probe. */
 
 	/* Irradiance grid */
 	EEVEE_LightGrid *grid;           /* Current probe being rendered (UBO data). */
@@ -154,19 +154,19 @@ static void irradiance_pool_size_get(int visibility_size, int total_samples, int
 }
 
 static bool EEVEE_lightcache_validate(
-        const EEVEE_LightCache *light_cache,
-        const int cube_count,
+        const LightCache *light_cache,
+        const int cube_len,
         const int cube_res,
         const int irr_size[3])
 {
 	if (light_cache) {
 		/* See if we need the same amount of texture space. */
-		if ((irr_size[0] == GPU_texture_width(light_cache->grid_tx)) &&
-		    (irr_size[1] == GPU_texture_height(light_cache->grid_tx)) &&
-		    (irr_size[2] == GPU_texture_layers(light_cache->grid_tx)))
+		if ((irr_size[0] == light_cache->grid_tx.tex_size[0]) &&
+		    (irr_size[1] == light_cache->grid_tx.tex_size[1]) &&
+		    (irr_size[2] == light_cache->grid_tx.tex_size[2]))
 		{
-			if ((cube_res == GPU_texture_width(light_cache->cube_tx)) &&
-			    (cube_count == GPU_texture_layers(light_cache->cube_tx))) {
+			if ((cube_res == light_cache->grid_tx.tex_size[0]) &&
+			    (cube_len == light_cache->grid_tx.tex_size[2])) {
 				return true;
 			}
 		}
@@ -174,28 +174,118 @@ static bool EEVEE_lightcache_validate(
 	return false;
 }
 
-EEVEE_LightCache *EEVEE_lightcache_create(
-        const int grid_count,
-        const int cube_count,
+LightCache *EEVEE_lightcache_create(
+        const int grid_len,
+        const int cube_len,
         const int cube_size,
+        const int vis_size,
         const int irr_size[3])
 {
-	EEVEE_LightCache *light_cache = MEM_callocN(sizeof(EEVEE_LightCache), "EEVEE_LightCache");
+	LightCache *light_cache = MEM_callocN(sizeof(LightCache), "LightCache");
 
-	light_cache->cube_data = MEM_callocN(sizeof(EEVEE_LightProbe) * cube_count, "EEVEE_LightProbe");
-	light_cache->grid_data = MEM_callocN(sizeof(EEVEE_LightGrid) * grid_count, "EEVEE_LightGrid");
+	light_cache->cube_data = MEM_callocN(sizeof(EEVEE_LightProbe) * cube_len, "EEVEE_LightProbe");
+	light_cache->grid_data = MEM_callocN(sizeof(EEVEE_LightGrid) * grid_len, "EEVEE_LightGrid");
+
+	light_cache->grid_tx.tex = DRW_texture_create_2D_array(irr_size[0], irr_size[1], irr_size[2], IRRADIANCE_FORMAT, DRW_TEX_FILTER, NULL);
+	light_cache->grid_tx.tex_size[0] = irr_size[0];
+	light_cache->grid_tx.tex_size[1] = irr_size[1];
+	light_cache->grid_tx.tex_size[2] = irr_size[2];
+
+	light_cache->cube_tx.tex = DRW_texture_create_2D_array(cube_size, cube_size, cube_len, GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
+	light_cache->cube_tx.tex_size[0] = cube_size;
+	light_cache->cube_tx.tex_size[1] = cube_size;
+	light_cache->cube_tx.tex_size[2] = cube_len;
+
+	light_cache->mips_len = (int)(floorf(log2f(cube_size)) - MIN_CUBE_LOD_LEVEL);
+	light_cache->vis_res = vis_size;
+	light_cache->ref_res = cube_size;
+
+	light_cache->cube_mips = MEM_callocN(sizeof(LightCacheTexture) * light_cache->mips_len, "LightCacheTexture");
+
+	for (int mip = 0; mip < light_cache->mips_len; ++mip) {
+		GPU_texture_get_mipmap_size(light_cache->cube_tx.tex, mip, light_cache->cube_mips[mip].tex_size);
+	}
 
-	light_cache->grid_tx = DRW_texture_create_2D_array(irr_size[0], irr_size[1], irr_size[2], IRRADIANCE_FORMAT, DRW_TEX_FILTER, NULL);
-	light_cache->cube_tx = DRW_texture_create_2D_array(cube_size, cube_size, cube_count, GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
 	light_cache->flag = LIGHTCACHE_UPDATE_WORLD | LIGHTCACHE_UPDATE_CUBE | LIGHTCACHE_UPDATE_GRID;
 
 	return light_cache;
 }
 
-void EEVEE_lightcache_free(EEVEE_LightCache *lcache)
+void EEVEE_lightcache_load(LightCache *lcache)
+{
+	if (lcache->grid_tx.tex == NULL && lcache->grid_tx.data) {
+		lcache->grid_tx.tex = GPU_texture_create_nD(lcache->grid_tx.tex_size[0],
+		                                            lcache->grid_tx.tex_size[1],
+		                                            lcache->grid_tx.tex_size[2],
+		                                            2,
+		                                            lcache->grid_tx.data,
+		                                            IRRADIANCE_FORMAT,
+		                             

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list