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
path: root/source
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2020-08-04 20:52:18 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-08-05 03:26:44 +0300
commit6be8b6af4006e088ac4a2cd8c1adc8f18c04035b (patch)
treeb1fdd6632646e8cc87015294b6a394087ee54583 /source
parentd1b3da697d814bcb35a718d2d7c660bd2120cb4b (diff)
EEVEE: LightCache: Prevent crash when using a lightcache too big
Some implementation have different maximum texture size. This patch avoid crash when texture allocation fails when: - trying to bake a lightcache too big for the OpenGL imeplementaion. - loading a cache from file that is too big for the OpenGL imeplementation.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.c55
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c9
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h3
-rw-r--r--source/blender/draw/intern/draw_manager_texture.c6
-rw-r--r--source/blender/editors/render/render_shading.c5
-rw-r--r--source/blender/makesdna/DNA_lightprobe_types.h6
7 files changed, 73 insertions, 12 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 9f5e474e479..4abf37e66bc 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6048,6 +6048,7 @@ static void direct_link_lightcache_texture(BlendDataReader *reader, LightCacheTe
static void direct_link_lightcache(BlendDataReader *reader, LightCache *cache)
{
+ cache->flag &= ~LIGHTCACHE_NOT_USABLE;
direct_link_lightcache_texture(reader, &cache->cube_tx);
direct_link_lightcache_texture(reader, &cache->grid_tx);
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 78fcd28eb5d..92bb9227e13 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -228,7 +228,14 @@ void EEVEE_lightcache_info_update(SceneEEVEE *eevee)
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"),
+ TIP_("Error: Light cache is too big for the GPU to be loaded"),
+ sizeof(eevee->light_cache_info));
+ return;
+ }
+
+ if (lcache->flag & LIGHTCACHE_INVALID) {
+ BLI_strncpy(eevee->light_cache_info,
+ TIP_("Error: Light cache dimensions not supported by the GPU"),
sizeof(eevee->light_cache_info));
return;
}
@@ -281,7 +288,7 @@ static bool EEVEE_lightcache_validate(const LightCache *light_cache,
const int grid_len,
const int irr_size[3])
{
- if (light_cache) {
+ if (light_cache && !(light_cache->flag & LIGHTCACHE_INVALID)) {
/* See if we need the same amount of texture space. */
if ((irr_size[0] == light_cache->grid_tx.tex_size[0]) &&
(irr_size[1] == light_cache->grid_tx.tex_size[1]) &&
@@ -343,12 +350,18 @@ LightCache *EEVEE_lightcache_create(const int grid_len,
light_cache->cube_mips = MEM_callocN(sizeof(LightCacheTexture) * light_cache->mips_len,
"LightCacheTexture");
- for (int mip = 0; mip < light_cache->mips_len; mip++) {
- GPU_texture_get_mipmap_size(
- light_cache->cube_tx.tex, mip + 1, light_cache->cube_mips[mip].tex_size);
+ if (light_cache->grid_tx.tex == NULL || light_cache->cube_tx.tex == NULL) {
+ /* We could not create the requested textures size. Stop baking and do not use the cache. */
+ light_cache->flag = LIGHTCACHE_INVALID;
}
+ else {
+ light_cache->flag = LIGHTCACHE_UPDATE_WORLD | LIGHTCACHE_UPDATE_CUBE | LIGHTCACHE_UPDATE_GRID;
- light_cache->flag = LIGHTCACHE_UPDATE_WORLD | LIGHTCACHE_UPDATE_CUBE | LIGHTCACHE_UPDATE_GRID;
+ for (int mip = 0; mip < light_cache->mips_len; mip++) {
+ GPU_texture_get_mipmap_size(
+ light_cache->cube_tx.tex, mip + 1, light_cache->cube_mips[mip].tex_size);
+ }
+ }
return light_cache;
}
@@ -376,6 +389,12 @@ static bool eevee_lightcache_static_load(LightCache *lcache)
0,
false,
NULL);
+
+ if (lcache->grid_tx.tex == NULL) {
+ lcache->flag |= LIGHTCACHE_NOT_USABLE;
+ return false;
+ }
+
GPU_texture_filter_mode(lcache->grid_tx.tex, true);
}
@@ -401,6 +420,11 @@ static bool eevee_lightcache_static_load(LightCache *lcache)
NULL);
}
+ if (lcache->cube_tx.tex == NULL) {
+ lcache->flag |= LIGHTCACHE_NOT_USABLE;
+ return false;
+ }
+
for (int mip = 0; mip < lcache->mips_len; mip++) {
GPU_texture_add_mipmap(
lcache->cube_tx.tex, GPU_DATA_10_11_11_REV, mip + 1, lcache->cube_mips[mip].data);
@@ -420,6 +444,10 @@ bool EEVEE_lightcache_load(LightCache *lcache)
return false;
}
+ if (lcache->flag & (LIGHTCACHE_INVALID | LIGHTCACHE_NOT_USABLE)) {
+ return false;
+ }
+
switch (lcache->type) {
case LIGHTCACHE_TYPE_STATIC:
return eevee_lightcache_static_load(lcache);
@@ -590,9 +618,7 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
if (lbake->lcache == NULL) {
lbake->lcache = EEVEE_lightcache_create(
lbake->grid_len, lbake->cube_len, lbake->ref_cube_res, lbake->vis_res, lbake->irr_size);
- lbake->lcache->flag = LIGHTCACHE_UPDATE_WORLD | LIGHTCACHE_UPDATE_CUBE |
- LIGHTCACHE_UPDATE_GRID;
- lbake->lcache->vis_res = lbake->vis_res;
+
lbake->own_light_cache = true;
eevee->light_cache_data = lbake->lcache;
@@ -1269,6 +1295,17 @@ void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float
* We cannot do it in the main thread. */
eevee_lightbake_context_enable(lbake);
eevee_lightbake_create_resources(lbake);
+
+ /* Resource allocation can fail. Early exit in this case. */
+ if (lbake->lcache->flag & LIGHTCACHE_INVALID) {
+ *lbake->stop = 1;
+ *lbake->do_update = 1;
+ lbake->lcache->flag &= ~LIGHTCACHE_BAKING;
+ eevee_lightbake_context_disable(lbake);
+ eevee_lightbake_delete_resources(lbake);
+ return;
+ }
+
eevee_lightbake_create_render_target(lbake, lbake->rt_res);
eevee_lightbake_context_disable(lbake);
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index 72187dc29eb..a2f7686619f 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -23,6 +23,7 @@
#include "DRW_render.h"
#include "BLI_rand.h"
+#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
#include "DNA_image_types.h"
@@ -161,6 +162,7 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
+ vedata->info[0] = '\0';
if (!e_data.hammersley) {
EEVEE_shaders_lightprobe_shaders_init();
@@ -176,6 +178,13 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
stl->g_data->light_cache = scene_eval->eevee.light_cache_data;
}
else {
+ if (scene_eval->eevee.light_cache_data &&
+ (scene_eval->eevee.light_cache_data->flag & LIGHTCACHE_NOT_USABLE)) {
+ /* Error message info. */
+ BLI_snprintf(
+ vedata->info, sizeof(vedata->info), "Error: LightCache cannot be loaded on this GPU");
+ }
+
if (!sldata->fallback_lightcache) {
#if defined(IRRADIANCE_SH_L2)
int grid_res = 4;
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 81a50d36e17..51831e5506d 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -29,6 +29,8 @@
#include "DNA_lightprobe_types.h"
+#include "GPU_viewport.h"
+
#include "BKE_camera.h"
struct EEVEE_ShadowCasterBuffer;
@@ -891,6 +893,7 @@ typedef struct EEVEE_Data {
EEVEE_TextureList *txl;
EEVEE_PassList *psl;
EEVEE_StorageList *stl;
+ char info[GPU_INFO_SIZE];
} EEVEE_Data;
typedef struct EEVEE_PrivateData {
diff --git a/source/blender/draw/intern/draw_manager_texture.c b/source/blender/draw/intern/draw_manager_texture.c
index 77b0462303d..b94a6db3bad 100644
--- a/source/blender/draw/intern/draw_manager_texture.c
+++ b/source/blender/draw/intern/draw_manager_texture.c
@@ -61,6 +61,10 @@ static bool drw_texture_format_supports_framebuffer(eGPUTextureFormat format)
void drw_texture_set_parameters(GPUTexture *tex, DRWTextureFlag flags)
{
+ if (tex == NULL) {
+ return;
+ }
+
if (flags & DRW_TEX_MIPMAP) {
GPU_texture_mipmap_mode(tex, true, flags & DRW_TEX_FILTER);
GPU_texture_bind(tex, 0);
@@ -119,7 +123,6 @@ GPUTexture *DRW_texture_create_cube(int w,
{
GPUTexture *tex = GPU_texture_create_cube(w, format, fpixels, NULL);
drw_texture_set_parameters(tex, flags);
-
return tex;
}
@@ -128,7 +131,6 @@ GPUTexture *DRW_texture_create_cube_array(
{
GPUTexture *tex = GPU_texture_create_cube_array(w, d, format, fpixels, NULL);
drw_texture_set_parameters(tex, flags);
-
return tex;
}
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 536252f5003..711f89b9fda 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -945,6 +945,11 @@ static int light_cache_bake_modal(bContext *C, wmOperator *op, const wmEvent *ev
/* no running blender, remove handler and pass through */
if (0 == WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER)) {
+ LightCache *lcache = scene->eevee.light_cache_data;
+ if (lcache && (lcache->flag & LIGHTCACHE_INVALID)) {
+ BKE_report(op->reports, RPT_ERROR, "Lightcache cannot allocate resources");
+ return OPERATOR_CANCELLED;
+ }
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
}
diff --git a/source/blender/makesdna/DNA_lightprobe_types.h b/source/blender/makesdna/DNA_lightprobe_types.h
index 5ddfedfed2d..c8d091bd074 100644
--- a/source/blender/makesdna/DNA_lightprobe_types.h
+++ b/source/blender/makesdna/DNA_lightprobe_types.h
@@ -150,7 +150,7 @@ BLI_STATIC_ASSERT_ALIGN(LightGridCache, 16)
typedef struct LightCacheTexture {
struct GPUTexture *tex;
- /* Copy of GPU datas to create GPUTextures on file read. */
+ /** Copy of GPU datas to create GPUTextures on file read. */
char *data;
int tex_size[3];
char data_type;
@@ -204,6 +204,10 @@ enum {
LIGHTCACHE_UPDATE_GRID = (1 << 5),
LIGHTCACHE_UPDATE_WORLD = (1 << 6),
LIGHTCACHE_UPDATE_AUTO = (1 << 7),
+ /** Invalid means we tried to alloc it but failed. */
+ LIGHTCACHE_INVALID = (1 << 8),
+ /** The data present in the cache is valid but unusable on this GPU. */
+ LIGHTCACHE_NOT_USABLE = (1 << 9),
};
/* EEVEE_LightCacheTexture->data_type */