Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/engines/eevee/eevee_lightcache.c')
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.c158
1 files changed, 122 insertions, 36 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 2b11a608bd0..35a45cc97f4 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -42,6 +42,7 @@
#include "eevee_private.h"
#include "GPU_context.h"
+#include "GPU_extensions.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -195,6 +196,16 @@ static uint eevee_lightcache_memsize_get(LightCache *lcache)
return size;
}
+static bool eevee_lightcache_version_check(LightCache *lcache)
+{
+ switch (lcache->type) {
+ case LIGHTCACHE_TYPE_STATIC:
+ return lcache->version == LIGHTCACHE_STATIC_VERSION;
+ default:
+ return false;
+ }
+}
+
static int eevee_lightcache_irradiance_sample_count(LightCache *lcache)
{
int total_irr_samples = 0;
@@ -208,9 +219,23 @@ static int eevee_lightcache_irradiance_sample_count(LightCache *lcache)
void EEVEE_lightcache_info_update(SceneEEVEE *eevee)
{
- LightCache *lcache = eevee->light_cache;
+ LightCache *lcache = eevee->light_cache_data;
if (lcache != NULL) {
+ if (!eevee_lightcache_version_check(lcache)) {
+ BLI_strncpy(eevee->light_cache_info,
+ TIP_("Incompatible Light cache version, please bake again"),
+ sizeof(eevee->light_cache_info));
+ return;
+ }
+
+ if (lcache->cube_tx.tex_size[2] > GPU_max_texture_layers()) {
+ BLI_strncpy(eevee->light_cache_info,
+ TIP_("Error: Light cache is too big for your GPU to be loaded"),
+ sizeof(eevee->light_cache_info));
+ return;
+ }
+
if (lcache->flag & LIGHTCACHE_BAKING) {
BLI_strncpy(
eevee->light_cache_info, TIP_("Baking light cache"), sizeof(eevee->light_cache_info));
@@ -266,8 +291,8 @@ static bool EEVEE_lightcache_validate(const LightCache *light_cache,
(irr_size[2] == light_cache->grid_tx.tex_size[2]) && (grid_len == light_cache->grid_len)) {
int mip_len = log2_floor_u(cube_res) - MIN_CUBE_LOD_LEVEL;
if ((cube_res == light_cache->cube_tx.tex_size[0]) &&
- (cube_len == light_cache->cube_tx.tex_size[2]) && (cube_len == light_cache->cube_len) &&
- (mip_len == light_cache->mips_len)) {
+ (cube_len == light_cache->cube_tx.tex_size[2] / 6) &&
+ (cube_len == light_cache->cube_len) && (mip_len == light_cache->mips_len)) {
return true;
}
}
@@ -283,6 +308,9 @@ LightCache *EEVEE_lightcache_create(const int grid_len,
{
LightCache *light_cache = MEM_callocN(sizeof(LightCache), "LightCache");
+ light_cache->version = LIGHTCACHE_STATIC_VERSION;
+ light_cache->type = LIGHTCACHE_TYPE_STATIC;
+
light_cache->cube_data = MEM_callocN(sizeof(EEVEE_LightProbe) * cube_len, "EEVEE_LightProbe");
light_cache->grid_data = MEM_callocN(sizeof(EEVEE_LightGrid) * grid_len, "EEVEE_LightGrid");
@@ -292,13 +320,26 @@ LightCache *EEVEE_lightcache_create(const int grid_len,
light_cache->grid_tx.tex_size[1] = irr_size[1];
light_cache->grid_tx.tex_size[2] = irr_size[2];
- light_cache->cube_tx.tex = DRW_texture_create_2d_array(
- cube_size, cube_size, cube_len, GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
+ int mips_len = log2_floor_u(cube_size) - MIN_CUBE_LOD_LEVEL;
+
+ if (GPU_arb_texture_cube_map_array_is_supported()) {
+ light_cache->cube_tx.tex = DRW_texture_create_cube_array(
+ cube_size, cube_len, GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
+ }
+ else {
+ light_cache->cube_tx.tex = DRW_texture_create_2d_array(cube_size,
+ cube_size,
+ cube_len * 6,
+ GPU_R11F_G11F_B10F,
+ DRW_TEX_FILTER | DRW_TEX_MIPMAP,
+ NULL);
+ }
+
light_cache->cube_tx.tex_size[0] = cube_size;
light_cache->cube_tx.tex_size[1] = cube_size;
- light_cache->cube_tx.tex_size[2] = cube_len;
+ light_cache->cube_tx.tex_size[2] = cube_len * 6;
- light_cache->mips_len = log2_floor_u(cube_size) - MIN_CUBE_LOD_LEVEL;
+ light_cache->mips_len = mips_len;
light_cache->vis_res = vis_size;
light_cache->ref_res = cube_size;
@@ -315,9 +356,19 @@ LightCache *EEVEE_lightcache_create(const int grid_len,
return light_cache;
}
-void EEVEE_lightcache_load(LightCache *lcache)
+static bool eevee_lightcache_static_load(LightCache *lcache)
{
- if (lcache->grid_tx.tex == NULL && lcache->grid_tx.data) {
+ /* We use fallback if a texture is not setup and there is no data to restore it. */
+ if ((!lcache->grid_tx.tex && !lcache->grid_tx.data) ||
+ (!lcache->cube_tx.tex && !lcache->cube_tx.data)) {
+ return false;
+ }
+ /* If cache is too big for this GPU. */
+ if (lcache->cube_tx.tex_size[2] > GPU_max_texture_layers()) {
+ return false;
+ }
+
+ if (lcache->grid_tx.tex == NULL) {
lcache->grid_tx.tex = GPU_texture_create_nD(lcache->grid_tx.tex_size[0],
lcache->grid_tx.tex_size[1],
lcache->grid_tx.tex_size[2],
@@ -333,17 +384,28 @@ void EEVEE_lightcache_load(LightCache *lcache)
GPU_texture_unbind(lcache->grid_tx.tex);
}
- if (lcache->cube_tx.tex == NULL && lcache->cube_tx.data) {
- lcache->cube_tx.tex = GPU_texture_create_nD(lcache->cube_tx.tex_size[0],
- lcache->cube_tx.tex_size[1],
- lcache->cube_tx.tex_size[2],
- 2,
- lcache->cube_tx.data,
- GPU_R11F_G11F_B10F,
- GPU_DATA_10_11_11_REV,
- 0,
- false,
- NULL);
+ if (lcache->cube_tx.tex == NULL) {
+ if (GPU_arb_texture_cube_map_array_is_supported()) {
+ lcache->cube_tx.tex = GPU_texture_cube_create(lcache->cube_tx.tex_size[0],
+ lcache->cube_tx.tex_size[2] / 6,
+ lcache->cube_tx.data,
+ GPU_R11F_G11F_B10F,
+ GPU_DATA_10_11_11_REV,
+ NULL);
+ }
+ else {
+ lcache->cube_tx.tex = GPU_texture_create_nD(lcache->cube_tx.tex_size[0],
+ lcache->cube_tx.tex_size[1],
+ lcache->cube_tx.tex_size[2],
+ 2,
+ lcache->cube_tx.data,
+ GPU_R11F_G11F_B10F,
+ GPU_DATA_10_11_11_REV,
+ 0,
+ false,
+ NULL);
+ }
+
GPU_texture_bind(lcache->cube_tx.tex, 0);
GPU_texture_mipmap_mode(lcache->cube_tx.tex, true, true);
for (int mip = 0; mip < lcache->mips_len; mip++) {
@@ -352,6 +414,25 @@ void EEVEE_lightcache_load(LightCache *lcache)
}
GPU_texture_unbind(lcache->cube_tx.tex);
}
+ return true;
+}
+
+bool EEVEE_lightcache_load(LightCache *lcache)
+{
+ if (lcache == NULL) {
+ return false;
+ }
+
+ if (!eevee_lightcache_version_check(lcache)) {
+ return false;
+ }
+
+ switch (lcache->type) {
+ case LIGHTCACHE_TYPE_STATIC:
+ return eevee_lightcache_static_load(lcache);
+ default:
+ return false;
+ }
}
static void eevee_lightbake_readback_irradiance(LightCache *lcache)
@@ -457,7 +538,7 @@ static void eevee_lightbake_count_probes(EEVEE_LightBake *lbake)
prb->grid_resolution_z;
lbake->grid_len++;
}
- else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
+ else if (prb->type == LIGHTPROBE_TYPE_CUBE && lbake->cube_len < EEVEE_PROBE_MAX) {
lbake->cube_len++;
}
}
@@ -491,8 +572,7 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
irradiance_pool_size_get(lbake->vis_res, lbake->total_irr_samples, lbake->irr_size);
- lbake->ref_cube_res = octahedral_size_from_cubesize(lbake->rt_res);
-
+ lbake->ref_cube_res = lbake->rt_res;
lbake->cube_prb = MEM_callocN(sizeof(LightProbe *) * lbake->cube_len, "EEVEE Cube visgroup ptr");
lbake->grid_prb = MEM_callocN(sizeof(LightProbe *) * lbake->grid_len, "EEVEE Grid visgroup ptr");
@@ -506,12 +586,12 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
/* Ensure Light Cache is ready to accept new data. If not recreate one.
* WARNING: All the following must be threadsafe. It's currently protected
* by the DRW mutex. */
- lbake->lcache = eevee->light_cache;
+ lbake->lcache = eevee->light_cache_data;
/* TODO validate irradiance and reflection cache independently... */
if (!EEVEE_lightcache_validate(
lbake->lcache, lbake->cube_len, lbake->ref_cube_res, lbake->grid_len, lbake->irr_size)) {
- eevee->light_cache = lbake->lcache = NULL;
+ eevee->light_cache_data = lbake->lcache = NULL;
}
if (lbake->lcache == NULL) {
@@ -522,10 +602,10 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
lbake->lcache->vis_res = lbake->vis_res;
lbake->own_light_cache = true;
- eevee->light_cache = lbake->lcache;
+ eevee->light_cache_data = lbake->lcache;
}
- EEVEE_lightcache_load(eevee->light_cache);
+ EEVEE_lightcache_load(eevee->light_cache_data);
lbake->lcache->flag |= LIGHTCACHE_BAKING;
lbake->lcache->cube_len = 1;
@@ -804,7 +884,7 @@ static void eevee_lightbake_render_world_sample(void *ved, void *user_data)
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
- LightCache *lcache = scene_eval->eevee.light_cache;
+ LightCache *lcache = scene_eval->eevee.light_cache_data;
float clamp = scene_eval->eevee.gi_glossy_clamp;
float filter_quality = scene_eval->eevee.gi_filter_quality;
@@ -920,7 +1000,7 @@ static void eevee_lightbake_render_grid_sample(void *ved, void *user_data)
EEVEE_LightGrid *egrid = lbake->grid;
LightProbe *prb = *lbake->probe;
Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
- LightCache *lcache = scene_eval->eevee.light_cache;
+ LightCache *lcache = scene_eval->eevee.light_cache_data;
int grid_loc[3], sample_id, sample_offset, stride;
float pos[3];
const bool is_last_bounce_sample = ((egrid->offset + lbake->grid_sample) ==
@@ -1002,7 +1082,7 @@ static void eevee_lightbake_render_probe_sample(void *ved, void *user_data)
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
- LightCache *lcache = scene_eval->eevee.light_cache;
+ LightCache *lcache = scene_eval->eevee.light_cache_data;
EEVEE_LightProbe *eprobe = lbake->cube;
LightProbe *prb = *lbake->probe;
float clamp = scene_eval->eevee.gi_glossy_clamp;
@@ -1083,7 +1163,7 @@ static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
{
Depsgraph *depsgraph = lbake->depsgraph;
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
- LightCache *lcache = scene_eval->eevee.light_cache;
+ LightCache *lcache = scene_eval->eevee.light_cache_data;
/* At least one for the world */
int grid_len = 1;
@@ -1106,7 +1186,7 @@ static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
EEVEE_LightGrid *egrid = &lcache->grid_data[grid_len++];
EEVEE_lightprobes_grid_data_from_object(ob, egrid, &total_irr_samples);
}
- else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
+ else if (prb->type == LIGHTPROBE_TYPE_CUBE && cube_len < EEVEE_PROBE_MAX) {
lbake->cube_prb[cube_len] = prb;
EEVEE_LightProbe *eprobe = &lcache->cube_data[cube_len++];
EEVEE_lightprobes_cube_data_from_object(ob, eprobe);
@@ -1136,11 +1216,11 @@ void EEVEE_lightbake_update(void *custom_data)
Scene *scene_orig = lbake->scene;
/* If a new lightcache was created, free the old one and reference the new. */
- if (lbake->lcache && scene_orig->eevee.light_cache != lbake->lcache) {
- if (scene_orig->eevee.light_cache != NULL) {
- EEVEE_lightcache_free(scene_orig->eevee.light_cache);
+ if (lbake->lcache && scene_orig->eevee.light_cache_data != lbake->lcache) {
+ if (scene_orig->eevee.light_cache_data != NULL) {
+ EEVEE_lightcache_free(scene_orig->eevee.light_cache_data);
}
- scene_orig->eevee.light_cache = lbake->lcache;
+ scene_orig->eevee.light_cache_data = lbake->lcache;
lbake->own_light_cache = false;
}
@@ -1182,6 +1262,12 @@ void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float
lbake->do_update = do_update;
lbake->progress = progress;
+ if (G.background) {
+ /* Make sure to init GL capabilities before counting probes. */
+ eevee_lightbake_context_enable(lbake);
+ eevee_lightbake_context_disable(lbake);
+ }
+
/* Count lightprobes */
eevee_lightbake_count_probes(lbake);