440ee8c8264ee9c7c99086e81ed4a06a0c25d77b
[blender.git] / source / blender / draw / engines / eevee / eevee_lightcache.c
1 /*
2  * Copyright 2016, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Blender Institute
19  *
20  */
21
22 /** \file eevee_lightcache.c
23  *  \ingroup draw_engine
24  *
25  * Eevee's indirect lighting cache.
26  */
27
28 #include "DRW_render.h"
29
30 #include "BKE_global.h"
31 #include "BKE_blender.h"
32
33 #include "BLI_threads.h"
34
35 #include "DEG_depsgraph_build.h"
36 #include "DEG_depsgraph_query.h"
37
38 #include "BKE_object.h"
39
40 #include "DNA_collection_types.h"
41 #include "DNA_lightprobe_types.h"
42
43 #include "PIL_time.h"
44
45 #include "eevee_lightcache.h"
46 #include "eevee_private.h"
47
48 #include "GPU_context.h"
49
50 #include "WM_api.h"
51 #include "WM_types.h"
52
53 #include "wm_window.h"
54
55 /* Rounded to nearest PowerOfTwo */
56 #if defined(IRRADIANCE_SH_L2)
57 #define IRRADIANCE_SAMPLE_SIZE_X 4 /* 3 in reality */
58 #define IRRADIANCE_SAMPLE_SIZE_Y 4 /* 3 in reality */
59 #elif defined(IRRADIANCE_CUBEMAP)
60 #define IRRADIANCE_SAMPLE_SIZE_X 8
61 #define IRRADIANCE_SAMPLE_SIZE_Y 8
62 #elif defined(IRRADIANCE_HL2)
63 #define IRRADIANCE_SAMPLE_SIZE_X 4 /* 3 in reality */
64 #define IRRADIANCE_SAMPLE_SIZE_Y 2
65 #endif
66
67 #ifdef IRRADIANCE_SH_L2
68 /* we need a signed format for Spherical Harmonics */
69 #  define IRRADIANCE_FORMAT GPU_RGBA16F
70 #else
71 #  define IRRADIANCE_FORMAT GPU_RGBA8
72 #endif
73
74 #define IRRADIANCE_MAX_POOL_LAYER 256 /* OpenGL 3.3 core requirement, can be extended but it's already very big */
75 #define IRRADIANCE_MAX_POOL_SIZE 1024
76 #define MAX_IRRADIANCE_SAMPLES \
77         (IRRADIANCE_MAX_POOL_SIZE / IRRADIANCE_SAMPLE_SIZE_X) * \
78         (IRRADIANCE_MAX_POOL_SIZE / IRRADIANCE_SAMPLE_SIZE_Y)
79
80 /* TODO should be replace by a more elegant alternative. */
81 extern void DRW_opengl_context_enable(void);
82 extern void DRW_opengl_context_disable(void);
83
84 extern void DRW_opengl_render_context_enable(void *re_gl_context);
85 extern void DRW_opengl_render_context_disable(void *re_gl_context);
86 extern void DRW_gawain_render_context_enable(void *re_gpu_context);
87 extern void DRW_gawain_render_context_disable(void *re_gpu_context);
88
89 typedef struct EEVEE_LightBake {
90         Depsgraph *depsgraph;
91         ViewLayer *view_layer;
92         ViewLayer *view_layer_input;
93         LightCache *lcache;
94         Scene *scene;
95         struct Main *bmain;
96         EEVEE_ViewLayerData *sldata;
97
98         LightProbe **probe;              /* Current probe being rendered. */
99         GPUTexture *rt_color;            /* Target cube color texture. */
100         GPUTexture *rt_depth;            /* Target cube depth texture. */
101         GPUFrameBuffer *rt_fb[6];        /* Target cube framebuffers. */
102         GPUFrameBuffer *store_fb;        /* Storage framebuffer. */
103         int rt_res;                      /* Cube render target resolution. */
104
105         /* Shared */
106         int layer;                       /* Target layer to store the data to. */
107         float samples_ct, invsamples_ct; /* Sample count for the convolution. */
108         float lod_factor;                /* Sampling bias during convolution step. */
109         float lod_max;                   /* Max cubemap LOD to sample when convolving. */
110         int cube_len, grid_len;          /* Number of probes to render + world probe. */
111
112         /* Irradiance grid */
113         EEVEE_LightGrid *grid;           /* Current probe being rendered (UBO data). */
114         int irr_cube_res;                /* Target cubemap at MIP 0. */
115         int irr_size[3];                 /* Size of the irradiance texture. */
116         int total_irr_samples;           /* Total for all grids */
117         int grid_sample;                 /* Nth sample of the current grid being rendered. */
118         int grid_sample_len;             /* Total number of samples for the current grid. */
119         int grid_curr;                   /* Nth grid in the cache being rendered. */
120         int bounce_curr, bounce_len;     /* The current light bounce being evaluated. */
121         float vis_res;                   /* Resolution of the Visibility shadowmap. */
122         GPUTexture *grid_prev;           /* Result of previous light bounce. */
123         LightProbe **grid_prb;           /* Pointer to the id.data of the probe object. */
124
125         /* Reflection probe */
126         EEVEE_LightProbe *cube;          /* Current probe being rendered (UBO data). */
127         int ref_cube_res;                /* Target cubemap at MIP 0. */
128         int cube_offset;                 /* Index of the current cube. */
129         LightProbe **cube_prb;           /* Pointer to the id.data of the probe object. */
130
131         /* Dummy Textures */
132         struct GPUTexture *dummy_color, *dummy_depth;
133         struct GPUTexture *dummy_layer_color;
134
135         int total, done; /* to compute progress */
136         short *stop, *do_update;
137         float *progress;
138
139         bool resource_only;              /* For only handling the resources. */
140         bool own_resources;
141         bool own_light_cache;            /* If the lightcache was created for baking, it's first owned by the baker. */
142         int delay;                       /* ms. delay the start of the baking to not slowdown interactions (TODO remove) */
143
144         void *gl_context, *gpu_context;  /* If running in parallel (in a separate thread), use this context. */
145
146         ThreadMutex *mutex;
147 } EEVEE_LightBake;
148
149 /* -------------------------------------------------------------------- */
150
151 /** \name Light Cache
152  * \{ */
153
154 /* Return memory footprint in bytes. */
155 static uint eevee_lightcache_memsize_get(LightCache *lcache)
156 {
157         uint size = 0;
158         if (lcache->grid_tx.data) {
159                 size += MEM_allocN_len(lcache->grid_tx.data);
160         }
161         if (lcache->cube_tx.data) {
162                 size += MEM_allocN_len(lcache->cube_tx.data);
163                 for (int mip = 0; mip < lcache->mips_len; ++mip) {
164                         size += MEM_allocN_len(lcache->cube_mips[mip].data);
165                 }
166         }
167         return size;
168 }
169
170 static int eevee_lightcache_irradiance_sample_count(LightCache *lcache)
171 {
172         int total_irr_samples = 0;
173
174         for (int i = 1; i < lcache->grid_len; ++i) {
175                 EEVEE_LightGrid *egrid = lcache->grid_data + i;
176                 total_irr_samples += egrid->resolution[0] * egrid->resolution[1] * egrid->resolution[2];
177         }
178         return total_irr_samples;
179 }
180
181 void EEVEE_lightcache_info_update(SceneEEVEE *eevee)
182 {
183         LightCache *lcache = eevee->light_cache;
184
185         if (lcache != NULL) {
186                 if (lcache->flag & LIGHTCACHE_BAKING) {
187                         BLI_strncpy(eevee->light_cache_info, IFACE_("Baking light cache"), sizeof(eevee->light_cache_info));
188                         return;
189                 }
190
191                 char formatted_mem[15];
192                 BLI_str_format_byte_unit(formatted_mem, eevee_lightcache_memsize_get(lcache), true);
193
194                 int irr_samples = eevee_lightcache_irradiance_sample_count(lcache);
195
196                 BLI_snprintf(eevee->light_cache_info, sizeof(eevee->light_cache_info), IFACE_("%d Ref. Cubemaps, %d Irr. Samples (%s in memory)"), lcache->cube_len - 1, irr_samples, formatted_mem);
197         }
198         else {
199                 BLI_strncpy(eevee->light_cache_info, IFACE_("No light cache in this scene"), sizeof(eevee->light_cache_info));
200         }
201 }
202
203 static void irradiance_pool_size_get(int visibility_size, int total_samples, int r_size[3])
204 {
205         /* Compute how many irradiance samples we can store per visibility sample. */
206         int irr_per_vis = (visibility_size / IRRADIANCE_SAMPLE_SIZE_X) *
207                           (visibility_size / IRRADIANCE_SAMPLE_SIZE_Y);
208
209         /* The irradiance itself take one layer, hence the +1 */
210         int layer_ct = MIN2(irr_per_vis + 1, IRRADIANCE_MAX_POOL_LAYER);
211
212         int texel_ct = (int)ceilf((float)total_samples / (float)(layer_ct - 1));
213         r_size[0] = visibility_size * max_ii(1, min_ii(texel_ct, (IRRADIANCE_MAX_POOL_SIZE / visibility_size)));
214         r_size[1] = visibility_size * max_ii(1, (texel_ct / (IRRADIANCE_MAX_POOL_SIZE / visibility_size)));
215         r_size[2] = layer_ct;
216 }
217
218 static bool EEVEE_lightcache_validate(
219         const LightCache *light_cache,
220         const int cube_len,
221         const int cube_res,
222         const int grid_len,
223         const int irr_size[3])
224 {
225         if (light_cache) {
226                 /* See if we need the same amount of texture space. */
227                 if ((irr_size[0] == light_cache->grid_tx.tex_size[0]) &&
228                     (irr_size[1] == light_cache->grid_tx.tex_size[1]) &&
229                     (irr_size[2] == light_cache->grid_tx.tex_size[2]) &&
230                     (grid_len == light_cache->grid_len))
231                 {
232                         int mip_len = (int)(floorf(log2f(cube_res)) - MIN_CUBE_LOD_LEVEL);
233                         if ((cube_res == light_cache->cube_tx.tex_size[0]) &&
234                             (cube_len == light_cache->cube_tx.tex_size[2]) &&
235                             (mip_len  == light_cache->mips_len))
236                         {
237                                 return true;
238                         }
239                 }
240         }
241         return false;
242 }
243
244 LightCache *EEVEE_lightcache_create(
245         const int grid_len,
246         const int cube_len,
247         const int cube_size,
248         const int vis_size,
249         const int irr_size[3])
250 {
251         LightCache *light_cache = MEM_callocN(sizeof(LightCache), "LightCache");
252
253         light_cache->cube_data = MEM_callocN(sizeof(EEVEE_LightProbe) * cube_len, "EEVEE_LightProbe");
254         light_cache->grid_data = MEM_callocN(sizeof(EEVEE_LightGrid) * grid_len, "EEVEE_LightGrid");
255
256         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);
257         light_cache->grid_tx.tex_size[0] = irr_size[0];
258         light_cache->grid_tx.tex_size[1] = irr_size[1];
259         light_cache->grid_tx.tex_size[2] = irr_size[2];
260
261         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);
262         light_cache->cube_tx.tex_size[0] = cube_size;
263         light_cache->cube_tx.tex_size[1] = cube_size;
264         light_cache->cube_tx.tex_size[2] = cube_len;
265
266         light_cache->mips_len = (int)(floorf(log2f(cube_size)) - MIN_CUBE_LOD_LEVEL);
267         light_cache->vis_res = vis_size;
268         light_cache->ref_res = cube_size;
269
270         light_cache->cube_mips = MEM_callocN(sizeof(LightCacheTexture) * light_cache->mips_len, "LightCacheTexture");
271
272         for (int mip = 0; mip < light_cache->mips_len; ++mip) {
273                 GPU_texture_get_mipmap_size(light_cache->cube_tx.tex, mip + 1, light_cache->cube_mips[mip].tex_size);
274         }
275
276         light_cache->flag = LIGHTCACHE_UPDATE_WORLD | LIGHTCACHE_UPDATE_CUBE | LIGHTCACHE_UPDATE_GRID;
277
278         return light_cache;
279 }
280
281 void EEVEE_lightcache_load(LightCache *lcache)
282 {
283         if (lcache->grid_tx.tex == NULL && lcache->grid_tx.data) {
284                 lcache->grid_tx.tex = GPU_texture_create_nD(lcache->grid_tx.tex_size[0],
285                                                             lcache->grid_tx.tex_size[1],
286                                                             lcache->grid_tx.tex_size[2],
287                                                             2,
288                                                             lcache->grid_tx.data,
289                                                             IRRADIANCE_FORMAT,
290                                                             GPU_DATA_UNSIGNED_BYTE,
291                                                             0,
292                                                             false,
293                                                             NULL);
294                 GPU_texture_bind(lcache->grid_tx.tex, 0);
295                 GPU_texture_filter_mode(lcache->grid_tx.tex, true);
296                 GPU_texture_unbind(lcache->grid_tx.tex);
297         }
298
299         if (lcache->cube_tx.tex == NULL && lcache->cube_tx.data) {
300                 lcache->cube_tx.tex = GPU_texture_create_nD(lcache->cube_tx.tex_size[0],
301                                                             lcache->cube_tx.tex_size[1],
302                                                             lcache->cube_tx.tex_size[2],
303                                                             2,
304                                                             lcache->cube_tx.data,
305                                                             GPU_R11F_G11F_B10F,
306                                                             GPU_DATA_10_11_11_REV,
307                                                             0,
308                                                             false,
309                                                             NULL);
310                 GPU_texture_bind(lcache->cube_tx.tex, 0);
311                 GPU_texture_mipmap_mode(lcache->cube_tx.tex, true, true);
312                 for (int mip = 0; mip < lcache->mips_len; ++mip) {
313                         GPU_texture_add_mipmap(lcache->cube_tx.tex, GPU_DATA_10_11_11_REV, mip + 1, lcache->cube_mips[mip].data);
314                 }
315                 GPU_texture_unbind(lcache->cube_tx.tex);
316         }
317 }
318
319 static void eevee_lightbake_readback_irradiance(LightCache *lcache)
320 {
321         MEM_SAFE_FREE(lcache->grid_tx.data);
322         lcache->grid_tx.data = GPU_texture_read(lcache->grid_tx.tex, GPU_DATA_UNSIGNED_BYTE, 0);
323         lcache->grid_tx.data_type = LIGHTCACHETEX_BYTE;
324         lcache->grid_tx.components = 4;
325 }
326
327 static void eevee_lightbake_readback_reflections(LightCache *lcache)
328 {
329         MEM_SAFE_FREE(lcache->cube_tx.data);
330         lcache->cube_tx.data = GPU_texture_read(lcache->cube_tx.tex, GPU_DATA_10_11_11_REV, 0);
331         lcache->cube_tx.data_type = LIGHTCACHETEX_UINT;
332         lcache->cube_tx.components = 1;
333
334         for (int mip = 0; mip < lcache->mips_len; ++mip) {
335                 LightCacheTexture *cube_mip = lcache->cube_mips + mip;
336                 MEM_SAFE_FREE(cube_mip->data);
337                 GPU_texture_get_mipmap_size(lcache->cube_tx.tex, mip + 1, cube_mip->tex_size);
338
339                 cube_mip->data = GPU_texture_read(lcache->cube_tx.tex, GPU_DATA_10_11_11_REV, mip + 1);
340                 cube_mip->data_type = LIGHTCACHETEX_UINT;
341                 cube_mip->components = 1;
342         }
343 }
344
345 void EEVEE_lightcache_free(LightCache *lcache)
346 {
347         DRW_TEXTURE_FREE_SAFE(lcache->cube_tx.tex);
348         MEM_SAFE_FREE(lcache->cube_tx.data);
349         DRW_TEXTURE_FREE_SAFE(lcache->grid_tx.tex);
350         MEM_SAFE_FREE(lcache->grid_tx.data);
351
352         if (lcache->cube_mips) {
353                 for (int i = 0; i < lcache->mips_len; ++i) {
354                         MEM_SAFE_FREE(lcache->cube_mips[i].data);
355                 }
356                 MEM_SAFE_FREE(lcache->cube_mips);
357         }
358
359         MEM_SAFE_FREE(lcache->cube_data);
360         MEM_SAFE_FREE(lcache->grid_data);
361         MEM_freeN(lcache);
362 }
363
364 /** \} */
365
366
367 /* -------------------------------------------------------------------- */
368
369 /** \name Light Bake Context
370  * \{ */
371
372 static void eevee_lightbake_context_enable(EEVEE_LightBake *lbake)
373 {
374         if (lbake->gl_context) {
375                 DRW_opengl_render_context_enable(lbake->gl_context);
376                 if (lbake->gpu_context == NULL) {
377                         lbake->gpu_context = GPU_context_create();
378                 }
379                 DRW_gawain_render_context_enable(lbake->gpu_context);
380         }
381         else {
382                 DRW_opengl_context_enable();
383         }
384 }
385
386 static void eevee_lightbake_context_disable(EEVEE_LightBake *lbake)
387 {
388         if (lbake->gl_context) {
389                 DRW_gawain_render_context_disable(lbake->gpu_context);
390                 DRW_opengl_render_context_disable(lbake->gl_context);
391         }
392         else {
393                 DRW_opengl_context_disable();
394         }
395 }
396
397 /** \} */
398
399
400 /* -------------------------------------------------------------------- */
401
402 /** \name Light Bake Job
403  * \{ */
404
405 static void eevee_lightbake_count_probes(EEVEE_LightBake *lbake)
406 {
407         Depsgraph *depsgraph = lbake->depsgraph;
408
409         /* At least one of each for the world */
410         lbake->grid_len = lbake->cube_len = lbake->total_irr_samples = 1;
411
412         DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
413         {
414                 const int ob_visibility = BKE_object_visibility(ob, DAG_EVAL_RENDER);
415                 if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
416                         continue;
417                 }
418
419                 if (ob->type == OB_LIGHTPROBE) {
420                         LightProbe *prb = (LightProbe *)ob->data;
421
422                         if (prb->type == LIGHTPROBE_TYPE_GRID) {
423                                 lbake->total_irr_samples += prb->grid_resolution_x * prb->grid_resolution_y * prb->grid_resolution_z;
424                                 lbake->grid_len++;
425                         }
426                         else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
427                                 lbake->cube_len++;
428                         }
429                 }
430         }
431         DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
432 }
433
434 static void eevee_lightbake_create_render_target(EEVEE_LightBake *lbake, int rt_res)
435 {
436         lbake->rt_depth = DRW_texture_create_cube(rt_res, GPU_DEPTH_COMPONENT24, 0, NULL);
437         lbake->rt_color = DRW_texture_create_cube(rt_res, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
438
439         for (int i = 0; i < 6; ++i) {
440                 GPU_framebuffer_ensure_config(&lbake->rt_fb[i], {
441                         GPU_ATTACHMENT_TEXTURE_CUBEFACE(lbake->rt_depth, i),
442                         GPU_ATTACHMENT_TEXTURE_CUBEFACE(lbake->rt_color, i)
443                 });
444         }
445
446         GPU_framebuffer_ensure_config(&lbake->store_fb, {
447                 GPU_ATTACHMENT_NONE,
448                 GPU_ATTACHMENT_NONE
449         });
450 }
451
452 static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
453 {
454         Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
455         SceneEEVEE *eevee = &scene_eval->eevee;
456
457         lbake->bounce_len   = eevee->gi_diffuse_bounces;
458         lbake->vis_res      = eevee->gi_visibility_resolution;
459         lbake->rt_res       = eevee->gi_cubemap_resolution;
460
461         irradiance_pool_size_get(lbake->vis_res, lbake->total_irr_samples, lbake->irr_size);
462
463         lbake->ref_cube_res = OCTAHEDRAL_SIZE_FROM_CUBESIZE(lbake->rt_res);
464
465         lbake->cube_prb = MEM_callocN(sizeof(LightProbe *) * lbake->cube_len, "EEVEE Cube visgroup ptr");
466         lbake->grid_prb = MEM_callocN(sizeof(LightProbe *) * lbake->grid_len, "EEVEE Grid visgroup ptr");
467
468         lbake->grid_prev = DRW_texture_create_2D_array(lbake->irr_size[0], lbake->irr_size[1], lbake->irr_size[2],
469                                                        IRRADIANCE_FORMAT, DRW_TEX_FILTER, NULL);
470
471         /* Ensure Light Cache is ready to accept new data. If not recreate one.
472          * WARNING: All the following must be threadsafe. It's currently protected
473          * by the DRW mutex. */
474         lbake->lcache = eevee->light_cache;
475
476         /* TODO validate irradiance and reflection cache independently... */
477         if (!EEVEE_lightcache_validate(
478                     lbake->lcache, lbake->cube_len, lbake->ref_cube_res, lbake->grid_len, lbake->irr_size))
479         {
480                 eevee->light_cache = lbake->lcache = NULL;
481         }
482
483         if (lbake->lcache == NULL) {
484                 lbake->lcache = EEVEE_lightcache_create(
485                         lbake->grid_len,
486                         lbake->cube_len,
487                         lbake->ref_cube_res,
488                         lbake->vis_res,
489                         lbake->irr_size);
490                 lbake->lcache->flag = LIGHTCACHE_UPDATE_WORLD | LIGHTCACHE_UPDATE_CUBE | LIGHTCACHE_UPDATE_GRID;
491                 lbake->lcache->vis_res = lbake->vis_res;
492                 lbake->own_light_cache = true;
493
494                 eevee->light_cache = lbake->lcache;
495         }
496
497         EEVEE_lightcache_load(eevee->light_cache);
498
499         lbake->lcache->flag |= LIGHTCACHE_BAKING;
500         lbake->lcache->cube_len = 1;
501 }
502
503 wmJob *EEVEE_lightbake_job_create(
504         struct wmWindowManager *wm, struct wmWindow *win, struct Main *bmain,
505         struct ViewLayer *view_layer, struct Scene *scene, int delay)
506 {
507         EEVEE_LightBake *lbake = NULL;
508
509         /* only one render job at a time */
510         if (WM_jobs_test(wm, scene, WM_JOB_TYPE_RENDER))
511                 return NULL;
512
513         wmJob *wm_job = WM_jobs_get(wm, win, scene, "Bake Lighting",
514                                     WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, WM_JOB_TYPE_LIGHT_BAKE);
515
516         /* If job exists do not recreate context and depsgraph. */
517         EEVEE_LightBake *old_lbake = (EEVEE_LightBake *)WM_jobs_customdata_get(wm_job);
518
519         if (old_lbake && (old_lbake->view_layer_input == view_layer) && (old_lbake->bmain == bmain)) {
520                 lbake = MEM_callocN(sizeof(EEVEE_LightBake), "EEVEE_LightBake");
521                 /* Cannot reuse depsgraph for now because we cannot get the update from the
522                  * main database directly. TODO reuse depsgraph and only update positions. */
523                 /* lbake->depsgraph = old_lbake->depsgraph; */
524                 lbake->depsgraph = DEG_graph_new(scene, view_layer, DAG_EVAL_RENDER);
525
526                 lbake->mutex = BLI_mutex_alloc();
527
528                 BLI_mutex_lock(old_lbake->mutex);
529                 old_lbake->own_resources = false;
530
531                 lbake->scene = scene;
532                 lbake->bmain = bmain;
533                 lbake->view_layer_input = view_layer;
534                 lbake->gl_context = old_lbake->gl_context;
535                 lbake->own_resources = true;
536                 lbake->delay = delay;
537
538                 if (lbake->gl_context == NULL) {
539                         lbake->gl_context = WM_opengl_context_create();
540                         wm_window_reset_drawable();
541                 }
542
543                 if (old_lbake->stop != NULL) {
544                         *old_lbake->stop = 1;
545                 }
546                 BLI_mutex_unlock(old_lbake->mutex);
547         }
548         else {
549                 lbake = EEVEE_lightbake_job_data_alloc(bmain, view_layer, scene, true);
550                 lbake->delay = delay;
551         }
552
553         WM_jobs_customdata_set(wm_job, lbake, EEVEE_lightbake_job_data_free);
554         WM_jobs_timer(wm_job, 0.4, NC_SCENE | NA_EDITED, 0);
555         WM_jobs_callbacks(wm_job, EEVEE_lightbake_job, NULL, EEVEE_lightbake_update, EEVEE_lightbake_update);
556
557         G.is_break = false;
558
559         return wm_job;
560 }
561
562 /* MUST run on the main thread. */
563 void *EEVEE_lightbake_job_data_alloc(
564         struct Main *bmain, struct ViewLayer *view_layer, struct Scene *scene, bool run_as_job)
565 {
566         BLI_assert(BLI_thread_is_main());
567
568         EEVEE_LightBake *lbake = MEM_callocN(sizeof(EEVEE_LightBake), "EEVEE_LightBake");
569
570         lbake->depsgraph = DEG_graph_new(scene, view_layer, DAG_EVAL_RENDER);
571         lbake->scene = scene;
572         lbake->bmain = bmain;
573         lbake->view_layer_input = view_layer;
574         lbake->own_resources = true;
575         lbake->own_light_cache = false;
576         lbake->mutex = BLI_mutex_alloc();
577
578         if (run_as_job) {
579                 lbake->gl_context = WM_opengl_context_create();
580                 wm_window_reset_drawable();
581         }
582
583         return lbake;
584 }
585
586 void EEVEE_lightbake_job_data_free(void *custom_data)
587 {
588         EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
589
590
591
592         /* TODO reuse depsgraph. */
593         /* if (lbake->own_resources) { */
594                 DEG_graph_free(lbake->depsgraph);
595         /* } */
596
597         MEM_SAFE_FREE(lbake->cube_prb);
598         MEM_SAFE_FREE(lbake->grid_prb);
599
600         BLI_mutex_free(lbake->mutex);
601
602         MEM_freeN(lbake);
603 }
604
605 static void eevee_lightbake_delete_resources(EEVEE_LightBake *lbake)
606 {
607         if (!lbake->resource_only) {
608                 BLI_mutex_lock(lbake->mutex);
609         }
610
611         if (lbake->gl_context) {
612                 DRW_opengl_render_context_enable(lbake->gl_context);
613                 DRW_gawain_render_context_enable(lbake->gpu_context);
614         }
615         else if (!lbake->resource_only) {
616                 DRW_opengl_context_enable();
617         }
618
619         /* XXX Free the resources contained in the viewlayer data
620          * to be able to free the context before deleting the depsgraph.  */
621         if (lbake->sldata) {
622                 EEVEE_view_layer_data_free(lbake->sldata);
623         }
624
625         DRW_TEXTURE_FREE_SAFE(lbake->rt_depth);
626         DRW_TEXTURE_FREE_SAFE(lbake->rt_color);
627         DRW_TEXTURE_FREE_SAFE(lbake->grid_prev);
628         GPU_FRAMEBUFFER_FREE_SAFE(lbake->store_fb);
629         for (int i = 0; i < 6; ++i) {
630                 GPU_FRAMEBUFFER_FREE_SAFE(lbake->rt_fb[i]);
631         }
632
633         if (lbake->gpu_context) {
634                 DRW_gawain_render_context_disable(lbake->gpu_context);
635                 DRW_gawain_render_context_enable(lbake->gpu_context);
636                 GPU_context_discard(lbake->gpu_context);
637         }
638
639         if (lbake->gl_context && lbake->own_resources) {
640                 /* Delete the baking context. */
641                 DRW_opengl_render_context_disable(lbake->gl_context);
642                 WM_opengl_context_dispose(lbake->gl_context);
643                 lbake->gpu_context = NULL;
644                 lbake->gl_context = NULL;
645         }
646         else if (lbake->gl_context) {
647                 DRW_opengl_render_context_disable(lbake->gl_context);
648         }
649         else if (!lbake->resource_only) {
650                 DRW_opengl_context_disable();
651         }
652
653         if (!lbake->resource_only) {
654                 BLI_mutex_unlock(lbake->mutex);
655         }
656 }
657
658 /* Cache as in draw cache not light cache. */
659 static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lbake)
660 {
661         EEVEE_TextureList *txl = vedata->txl;
662         EEVEE_StorageList *stl = vedata->stl;
663         EEVEE_FramebufferList *fbl = vedata->fbl;
664         EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
665         Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
666         lbake->sldata = sldata;
667
668         /* Disable all effects BUT high bitdepth shadows. */
669         scene_eval->eevee.flag &= SCE_EEVEE_SHADOW_HIGH_BITDEPTH;
670         scene_eval->eevee.taa_samples = 1;
671         scene_eval->eevee.gi_irradiance_smoothing = 0.0f;
672
673         stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
674         stl->g_data->background_alpha = 1.0f;
675
676         /* XXX TODO remove this. This is in order to make the init functions work. */
677         DRWMatrixState dummy_mats = {{{{{0}}}}};
678         DRW_viewport_matrix_override_set_all(&dummy_mats);
679
680         if (sldata->common_ubo == NULL) {
681                 sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data), &sldata->common_data);
682         }
683         if (sldata->clip_ubo == NULL) {
684                 sldata->clip_ubo = DRW_uniformbuffer_create(sizeof(sldata->clip_data), &sldata->clip_data);
685         }
686
687         /* HACK: set txl->color but unset it before Draw Manager frees it. */
688         txl->color = lbake->rt_color;
689         int viewport_size[2] = {
690                 GPU_texture_width(txl->color),
691                 GPU_texture_height(txl->color)
692         };
693         DRW_render_viewport_size_set(viewport_size);
694
695         EEVEE_effects_init(sldata, vedata, NULL, true);
696         EEVEE_materials_init(sldata, stl, fbl);
697         EEVEE_lights_init(sldata);
698         EEVEE_lightprobes_init(sldata, vedata);
699
700         EEVEE_effects_cache_init(sldata, vedata);
701         EEVEE_materials_cache_init(sldata, vedata);
702         EEVEE_lights_cache_init(sldata, vedata);
703         EEVEE_lightprobes_cache_init(sldata, vedata);
704
705         EEVEE_lightbake_cache_init(sldata, vedata, lbake->rt_color, lbake->rt_depth);
706
707         if (lbake->probe) {
708                 EEVEE_LightProbesInfo *pinfo = sldata->probes;
709                 LightProbe *prb = *lbake->probe;
710                 pinfo->vis_data.collection = prb->visibility_grp;
711                 pinfo->vis_data.invert = prb->flag & LIGHTPROBE_FLAG_INVERT_GROUP;
712                 pinfo->vis_data.cached = false;
713         }
714         DRW_render_object_iter(vedata, NULL, lbake->depsgraph, EEVEE_render_cache);
715
716         EEVEE_materials_cache_finish(vedata);
717         EEVEE_lights_cache_finish(sldata, vedata);
718         EEVEE_lightprobes_cache_finish(sldata, vedata);
719
720         txl->color = NULL;
721
722         DRW_render_instance_buffer_finish();
723         DRW_hair_update();
724 }
725
726 static void eevee_lightbake_copy_irradiance(EEVEE_LightBake *lbake, LightCache *lcache)
727 {
728         DRW_TEXTURE_FREE_SAFE(lbake->grid_prev);
729
730         /* Copy texture by reading back and reuploading it. */
731         float *tex = GPU_texture_read(lcache->grid_tx.tex, GPU_DATA_FLOAT, 0);
732         lbake->grid_prev = DRW_texture_create_2D_array(lbake->irr_size[0], lbake->irr_size[1], lbake->irr_size[2],
733                                                        IRRADIANCE_FORMAT, DRW_TEX_FILTER, tex);
734
735         MEM_freeN(tex);
736 }
737
738 static void eevee_lightbake_render_world_sample(void *ved, void *user_data)
739 {
740         EEVEE_Data *vedata = (EEVEE_Data *)ved;
741         EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
742         EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
743         Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
744         LightCache *lcache = scene_eval->eevee.light_cache;
745         float clamp = scene_eval->eevee.gi_glossy_clamp;
746         float filter_quality = scene_eval->eevee.gi_filter_quality;
747
748         /* TODO do this once for the whole bake when we have independent DRWManagers. */
749         eevee_lightbake_cache_create(vedata, lbake);
750
751         sldata->common_data.ray_type = EEVEE_RAY_GLOSSY;
752         sldata->common_data.ray_depth = 1;
753         DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
754         EEVEE_lightbake_render_world(sldata, vedata, lbake->rt_fb);
755         EEVEE_lightbake_filter_glossy(sldata, vedata, lbake->rt_color, lbake->store_fb, 0, 1.0f, lcache->mips_len, filter_quality, clamp);
756
757         sldata->common_data.ray_type = EEVEE_RAY_DIFFUSE;
758         sldata->common_data.ray_depth = 1;
759         DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
760         EEVEE_lightbake_render_world(sldata, vedata, lbake->rt_fb);
761         EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake->rt_color, lbake->store_fb, 0, 1.0f);
762
763         /* Clear the cache to avoid white values in the grid. */
764         GPU_framebuffer_texture_attach(lbake->store_fb, lbake->grid_prev, 0, 0);
765         GPU_framebuffer_bind(lbake->store_fb);
766         /* Clear to 1.0f for visibility. */
767         GPU_framebuffer_clear_color(lbake->store_fb, ((float[4]){1.0f, 1.0f, 1.0f, 1.0f}));
768         DRW_draw_pass(vedata->psl->probe_grid_fill);
769
770         SWAP(GPUTexture *, lbake->grid_prev, lcache->grid_tx.tex);
771
772         /* Make a copy for later. */
773         eevee_lightbake_copy_irradiance(lbake, lcache);
774
775         lcache->cube_len = 1;
776         lcache->grid_len = lbake->grid_len;
777
778         lcache->flag |= LIGHTCACHE_CUBE_READY | LIGHTCACHE_GRID_READY;
779         lcache->flag &= ~LIGHTCACHE_UPDATE_WORLD;
780 }
781
782 static void cell_id_to_grid_loc(EEVEE_LightGrid *egrid, int cell_idx, int r_local_cell[3])
783 {
784         /* Keep in sync with lightprobe_grid_display_vert */
785         r_local_cell[2] = cell_idx % egrid->resolution[2];
786         r_local_cell[1] = (cell_idx / egrid->resolution[2]) % egrid->resolution[1];
787         r_local_cell[0] = cell_idx / (egrid->resolution[2] * egrid->resolution[1]);
788 }
789
790 static void compute_cell_id(
791         EEVEE_LightGrid *egrid, LightProbe *probe,
792         int cell_idx, int *r_final_idx, int r_local_cell[3], int *r_stride)
793 {
794         const int cell_count = probe->grid_resolution_x * probe->grid_resolution_y * probe->grid_resolution_z;
795
796         /* Add one for level 0 */
797         int max_lvl = (int)floorf(log2f((float)MAX3(probe->grid_resolution_x,
798                                                     probe->grid_resolution_y,
799                                                     probe->grid_resolution_z)));
800
801         int visited_cells = 0;
802         *r_stride = 0;
803         *r_final_idx = 0;
804         r_local_cell[0] = r_local_cell[1] = r_local_cell[2] = 0;
805         for (int lvl = max_lvl; lvl >= 0; --lvl) {
806                 *r_stride = 1 << lvl;
807                 int prev_stride = *r_stride << 1;
808                 for (int i = 0; i < cell_count; ++i) {
809                         *r_final_idx = i;
810                         cell_id_to_grid_loc(egrid, *r_final_idx, r_local_cell);
811                         if (((r_local_cell[0] % *r_stride) == 0) &&
812                             ((r_local_cell[1] % *r_stride) == 0) &&
813                             ((r_local_cell[2] % *r_stride) == 0))
814                         {
815                                 if (!(((r_local_cell[0] % prev_stride) == 0) &&
816                                       ((r_local_cell[1] % prev_stride) == 0) &&
817                                       ((r_local_cell[2] % prev_stride) == 0)) ||
818                                       ((i == 0) && (lvl == max_lvl)))
819                                 {
820                                         if (visited_cells == cell_idx) {
821                                                 return;
822                                         }
823                                         else {
824                                                 visited_cells++;
825                                         }
826                                 }
827                         }
828                 }
829         }
830
831         BLI_assert(0);
832 }
833
834 static void grid_loc_to_world_loc(EEVEE_LightGrid *egrid, int local_cell[3], float r_pos[3])
835 {
836         copy_v3_v3(r_pos, egrid->corner);
837         madd_v3_v3fl(r_pos, egrid->increment_x, local_cell[0]);
838         madd_v3_v3fl(r_pos, egrid->increment_y, local_cell[1]);
839         madd_v3_v3fl(r_pos, egrid->increment_z, local_cell[2]);
840 }
841
842 static void eevee_lightbake_render_grid_sample(void *ved, void *user_data)
843 {
844         EEVEE_Data *vedata = (EEVEE_Data *)ved;
845         EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
846         EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
847         EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
848         EEVEE_LightGrid *egrid = lbake->grid;
849         LightProbe *prb = *lbake->probe;
850         Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
851         LightCache *lcache = scene_eval->eevee.light_cache;
852         int grid_loc[3], sample_id, sample_offset, stride;
853         float pos[3];
854         const bool is_last_bounce_sample = ((egrid->offset + lbake->grid_sample) == (lbake->total_irr_samples - 1));
855
856         /* No bias for rendering the probe. */
857         egrid->level_bias = 1.0f;
858
859         /* Use the previous bounce for rendering this bounce. */
860         SWAP(GPUTexture *, lbake->grid_prev, lcache->grid_tx.tex);
861
862         /* TODO do this once for the whole bake when we have independent DRWManagers.
863          * Warning: Some of the things above require this. */
864         eevee_lightbake_cache_create(vedata, lbake);
865
866         /* Compute sample position */
867         compute_cell_id(egrid, prb, lbake->grid_sample, &sample_id, grid_loc, &stride);
868         sample_offset = egrid->offset + sample_id;
869
870         grid_loc_to_world_loc(egrid, grid_loc, pos);
871
872         /* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
873         common_data->spec_toggle = false;
874         common_data->prb_num_planar = 0;
875         common_data->prb_num_render_cube = 0;
876         common_data->ray_type = EEVEE_RAY_DIFFUSE;
877         common_data->ray_depth = lbake->bounce_curr + 1;
878         if (lbake->bounce_curr == 0) {
879                 common_data->prb_num_render_grid = 0;
880         }
881         DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
882
883         EEVEE_lightbake_render_scene(sldata, vedata, lbake->rt_fb, pos, prb->clipsta, prb->clipend);
884
885         /* Restore before filtering. */
886         SWAP(GPUTexture *, lbake->grid_prev, lcache->grid_tx.tex);
887
888         EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake->rt_color, lbake->store_fb, sample_offset, prb->intensity);
889
890         if (lbake->bounce_curr == 0) {
891                 /* We only need to filter the visibility for the first bounce. */
892                 EEVEE_lightbake_filter_visibility(sldata, vedata, lbake->rt_depth, lbake->store_fb, sample_offset,
893                                                   prb->clipsta, prb->clipend, egrid->visibility_range,
894                                                   prb->vis_blur, lbake->vis_res);
895         }
896
897         /* Update level for progressive update. */
898         if (is_last_bounce_sample) {
899                 egrid->level_bias = 1.0f;
900         }
901         else if (lbake->bounce_curr == 0) {
902                 egrid->level_bias = (float)(stride << 1);
903         }
904
905         /* Only run this for the last sample of a bounce. */
906         if (is_last_bounce_sample) {
907                 eevee_lightbake_copy_irradiance(lbake, lcache);
908         }
909
910         /* If it is the last sample grid sample (and last bounce). */
911         if ((lbake->bounce_curr == lbake->bounce_len - 1) &&
912             (lbake->grid_curr == lbake->grid_len - 1) &&
913             (lbake->grid_sample == lbake->grid_sample_len - 1))
914         {
915                 lcache->flag &= ~LIGHTCACHE_UPDATE_GRID;
916         }
917 }
918
919 static void eevee_lightbake_render_probe_sample(void *ved, void *user_data)
920 {
921         EEVEE_Data *vedata = (EEVEE_Data *)ved;
922         EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
923         EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
924         EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
925         Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
926         LightCache *lcache = scene_eval->eevee.light_cache;
927         EEVEE_LightProbe *eprobe = lbake->cube;
928         LightProbe *prb = *lbake->probe;
929         float clamp = scene_eval->eevee.gi_glossy_clamp;
930         float filter_quality = scene_eval->eevee.gi_filter_quality;
931
932         /* TODO do this once for the whole bake when we have independent DRWManagers. */
933         eevee_lightbake_cache_create(vedata, lbake);
934
935         /* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
936         common_data->spec_toggle = false;
937         common_data->prb_num_planar = 0;
938         common_data->prb_num_render_cube = 0;
939         common_data->ray_type = EEVEE_RAY_GLOSSY;
940         common_data->ray_depth = 1;
941         DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
942
943         EEVEE_lightbake_render_scene(sldata, vedata, lbake->rt_fb, eprobe->position, prb->clipsta, prb->clipend);
944         EEVEE_lightbake_filter_glossy(
945                 sldata, vedata, lbake->rt_color, lbake->store_fb, lbake->cube_offset, prb->intensity,
946                 lcache->mips_len, filter_quality, clamp);
947
948         lcache->cube_len += 1;
949
950         /* If it's the last probe. */
951         if (lbake->cube_offset == lbake->cube_len - 1) {
952                 lcache->flag &= ~LIGHTCACHE_UPDATE_CUBE;
953         }
954 }
955
956 static float eevee_lightbake_grid_influence_volume(EEVEE_LightGrid *grid)
957 {
958         return mat4_to_scale(grid->mat);
959 }
960
961 static float eevee_lightbake_cube_influence_volume(EEVEE_LightProbe *eprb)
962 {
963         return mat4_to_scale(eprb->attenuationmat);
964 }
965
966 static bool eevee_lightbake_grid_comp(EEVEE_LightGrid *grid_a, EEVEE_LightGrid *grid_b)
967 {
968         float vol_a = eevee_lightbake_grid_influence_volume(grid_a);
969         float vol_b = eevee_lightbake_grid_influence_volume(grid_b);
970         return (vol_a < vol_b);
971 }
972
973 static bool eevee_lightbake_cube_comp(EEVEE_LightProbe *prb_a, EEVEE_LightProbe *prb_b)
974 {
975         float vol_a = eevee_lightbake_cube_influence_volume(prb_a);
976         float vol_b = eevee_lightbake_cube_influence_volume(prb_b);
977         return (vol_a < vol_b);
978 }
979
980 #define SORT_PROBE(elems_type, prbs, elems, elems_len, comp_fn) \
981 { \
982         bool sorted = false; \
983         while (!sorted) { \
984                 sorted = true; \
985                 for (int i = 0; i < (elems_len) - 1; ++i) { \
986                         if ((comp_fn)((elems) + i, (elems) + i+1)) { \
987                                 SWAP(elems_type, (elems)[i], (elems)[i+1]); \
988                                 SWAP(LightProbe *, (prbs)[i], (prbs)[i+1]); \
989                                 sorted = false; \
990                         } \
991                 } \
992         } \
993 }
994
995 static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
996 {
997         Depsgraph *depsgraph = lbake->depsgraph;
998         Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
999         LightCache *lcache = scene_eval->eevee.light_cache;
1000
1001         /* At least one for the world */
1002         int grid_len = 1;
1003         int cube_len = 1;
1004         int total_irr_samples = 1;
1005
1006         /* Convert all lightprobes to tight UBO data from all lightprobes in the scene.
1007          * This allows a large number of probe to be precomputed (even dupli ones). */
1008         DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
1009         {
1010                 const int ob_visibility = BKE_object_visibility(ob, DAG_EVAL_RENDER);
1011                 if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
1012                         continue;
1013                 }
1014
1015                 if (ob->type == OB_LIGHTPROBE) {
1016                         LightProbe *prb = (LightProbe *)ob->data;
1017
1018                         if (prb->type == LIGHTPROBE_TYPE_GRID) {
1019                                 lbake->grid_prb[grid_len] = prb;
1020                                 EEVEE_LightGrid *egrid = &lcache->grid_data[grid_len++];
1021                                 EEVEE_lightprobes_grid_data_from_object(ob, egrid, &total_irr_samples);
1022                         }
1023                         else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
1024                                 lbake->cube_prb[cube_len] = prb;
1025                                 EEVEE_LightProbe *eprobe = &lcache->cube_data[cube_len++];
1026                                 EEVEE_lightprobes_cube_data_from_object(ob, eprobe);
1027                         }
1028                 }
1029         }
1030         DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
1031
1032         SORT_PROBE(EEVEE_LightGrid, lbake->grid_prb + 1, lcache->grid_data + 1, lbake->grid_len - 1, eevee_lightbake_grid_comp);
1033         SORT_PROBE(EEVEE_LightProbe, lbake->cube_prb + 1, lcache->cube_data + 1, lbake->cube_len - 1, eevee_lightbake_cube_comp);
1034
1035         lbake->total = lbake->total_irr_samples * lbake->bounce_len + lbake->cube_len;
1036         lbake->done = 0;
1037 }
1038
1039 void EEVEE_lightbake_update(void *custom_data)
1040 {
1041         EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
1042         Scene *scene_orig = lbake->scene;
1043
1044         /* If a new lightcache was created, free the old one and reference the new. */
1045         if (lbake->lcache && scene_orig->eevee.light_cache != lbake->lcache) {
1046                 if (scene_orig->eevee.light_cache != NULL) {
1047                         EEVEE_lightcache_free(scene_orig->eevee.light_cache);
1048                 }
1049                 scene_orig->eevee.light_cache = lbake->lcache;
1050                 lbake->own_light_cache = false;
1051         }
1052
1053         EEVEE_lightcache_info_update(&lbake->scene->eevee);
1054
1055         DEG_id_tag_update(&scene_orig->id, ID_RECALC_COPY_ON_WRITE);
1056 }
1057
1058 static bool lightbake_do_sample(EEVEE_LightBake *lbake, void (*render_callback)(void *ved, void *user_data))
1059 {
1060         if (G.is_break == true || *lbake->stop) {
1061                 return false;
1062         }
1063
1064         Depsgraph *depsgraph = lbake->depsgraph;
1065
1066         /* TODO: make DRW manager instanciable (and only lock on drawing) */
1067         eevee_lightbake_context_enable(lbake);
1068         DRW_custom_pipeline(&draw_engine_eevee_type, depsgraph, render_callback, lbake);
1069         lbake->done += 1;
1070         *lbake->progress = lbake->done / (float)lbake->total;
1071         *lbake->do_update = 1;
1072         eevee_lightbake_context_disable(lbake);
1073
1074         return true;
1075 }
1076
1077 void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float *progress)
1078 {
1079         EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
1080         Depsgraph *depsgraph = lbake->depsgraph;
1081         int frame = 0; /* TODO make it user param. */
1082
1083         DEG_graph_relations_update(depsgraph, lbake->bmain, lbake->scene, lbake->view_layer_input);
1084         DEG_evaluate_on_framechange(lbake->bmain, depsgraph, frame);
1085
1086         lbake->view_layer = DEG_get_evaluated_view_layer(depsgraph);
1087         lbake->stop = stop;
1088         lbake->do_update = do_update;
1089         lbake->progress = progress;
1090
1091         /* Count lightprobes */
1092         eevee_lightbake_count_probes(lbake);
1093
1094         /* We need to create the FBOs in the right context.
1095          * We cannot do it in the main thread. */
1096         eevee_lightbake_context_enable(lbake);
1097         eevee_lightbake_create_resources(lbake);
1098         eevee_lightbake_create_render_target(lbake, lbake->rt_res);
1099         eevee_lightbake_context_disable(lbake);
1100
1101         /* Gather all probes data */
1102         eevee_lightbake_gather_probes(lbake);
1103
1104         LightCache *lcache = lbake->lcache;
1105
1106         /* HACK: Sleep to delay the first rendering operation
1107          * that causes a small freeze (caused by VBO generation)
1108          * because this step is locking at this moment. */
1109         /* TODO remove this. */
1110         if (lbake->delay) {
1111                 PIL_sleep_ms(lbake->delay);
1112         }
1113
1114         /* Render world irradiance and reflection first */
1115         if (lcache->flag & LIGHTCACHE_UPDATE_WORLD) {
1116                 lbake->probe = NULL;
1117                 lightbake_do_sample(lbake, eevee_lightbake_render_world_sample);
1118         }
1119
1120         /* Render irradiance grids */
1121         if (lcache->flag & LIGHTCACHE_UPDATE_GRID) {
1122                 for (lbake->bounce_curr = 0; lbake->bounce_curr < lbake->bounce_len; ++lbake->bounce_curr) {
1123                         /* Bypass world, start at 1. */
1124                         lbake->probe = lbake->grid_prb + 1;
1125                         lbake->grid = lcache->grid_data + 1;
1126                         for (lbake->grid_curr = 1;
1127                              lbake->grid_curr < lbake->grid_len;
1128                              ++lbake->grid_curr, ++lbake->probe, ++lbake->grid)
1129                         {
1130                                 LightProbe *prb = *lbake->probe;
1131                                 lbake->grid_sample_len = prb->grid_resolution_x *
1132                                                          prb->grid_resolution_y *
1133                                                          prb->grid_resolution_z;
1134                                 for (lbake->grid_sample = 0;
1135                                      lbake->grid_sample < lbake->grid_sample_len;
1136                                      ++lbake->grid_sample)
1137                                 {
1138                                         lightbake_do_sample(lbake, eevee_lightbake_render_grid_sample);
1139                                 }
1140                         }
1141                 }
1142         }
1143
1144         /* Render reflections */
1145         if (lcache->flag & LIGHTCACHE_UPDATE_CUBE) {
1146                 /* Bypass world, start at 1. */
1147                 lbake->probe = lbake->cube_prb + 1;
1148                 lbake->cube = lcache->cube_data + 1;
1149                 for (lbake->cube_offset = 1;
1150                      lbake->cube_offset < lbake->cube_len;
1151                      ++lbake->cube_offset, ++lbake->probe, ++lbake->cube)
1152                 {
1153                         lightbake_do_sample(lbake, eevee_lightbake_render_probe_sample);
1154                 }
1155         }
1156
1157         /* Read the resulting lighting data to save it to file/disk. */
1158         eevee_lightbake_context_enable(lbake);
1159         eevee_lightbake_readback_irradiance(lcache);
1160         eevee_lightbake_readback_reflections(lcache);
1161         eevee_lightbake_context_disable(lbake);
1162
1163         lcache->flag |=  LIGHTCACHE_BAKED;
1164         lcache->flag &= ~LIGHTCACHE_BAKING;
1165
1166         /* Assume that if lbake->gl_context is NULL
1167          * we are not running in this in a job, so update
1168          * the scene lightcache pointer before deleting it. */
1169         if (lbake->gl_context == NULL) {
1170                 BLI_assert(BLI_thread_is_main());
1171                 EEVEE_lightbake_update(lbake);
1172         }
1173
1174         eevee_lightbake_delete_resources(lbake);
1175 }
1176
1177 /* This is to update the world irradiance and reflection contribution from
1178  * within the viewport drawing (does not have the overhead of a full light cache rebuild.) */
1179 void EEVEE_lightbake_update_world_quick(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, const Scene *scene)
1180 {
1181         LightCache *lcache = vedata->stl->g_data->light_cache;
1182         float clamp = scene->eevee.gi_glossy_clamp;
1183         float filter_quality = scene->eevee.gi_filter_quality;
1184
1185         EEVEE_LightBake lbake = {
1186                 .resource_only = true
1187         };
1188
1189         /* Create resources. */
1190         eevee_lightbake_create_render_target(&lbake, scene->eevee.gi_cubemap_resolution);
1191
1192         EEVEE_lightbake_cache_init(sldata, vedata, lbake.rt_color, lbake.rt_depth);
1193
1194         sldata->common_data.ray_type = EEVEE_RAY_GLOSSY;
1195         sldata->common_data.ray_depth = 1;
1196         DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
1197         EEVEE_lightbake_render_world(sldata, vedata, lbake.rt_fb);
1198         EEVEE_lightbake_filter_glossy(sldata, vedata, lbake.rt_color, lbake.store_fb, 0, 1.0f, lcache->mips_len,
1199                                       filter_quality, clamp);
1200
1201         sldata->common_data.ray_type = EEVEE_RAY_DIFFUSE;
1202         sldata->common_data.ray_depth = 1;
1203         DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
1204         EEVEE_lightbake_render_world(sldata, vedata, lbake.rt_fb);
1205         EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake.rt_color, lbake.store_fb, 0, 1.0f);
1206
1207         /* Don't hide grids if they are already rendered. */
1208         lcache->grid_len = max_ii(1, lcache->grid_len);
1209         lcache->cube_len = 1;
1210
1211         lcache->flag |= LIGHTCACHE_CUBE_READY | LIGHTCACHE_GRID_READY;
1212         lcache->flag &= ~LIGHTCACHE_UPDATE_WORLD;
1213
1214         eevee_lightbake_delete_resources(&lbake);
1215 }
1216
1217 /** \} */