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