Fix T78452 EEVEE: Motion Blur: Crash when using camera switching
This was caused by the ViewLayer being freed with all its engine data.
This commit is contained in:
parent
3dcaca93a0
commit
4f59e4bddc
Notes:
blender-bot
2023-02-14 05:25:44 +01:00
Referenced by commit 58909abc68
, EEVEE: Render: Fix regression caused by previous Motion blur fix
Referenced by issue #79970, Camera Animation Breaks EEVEE Motion Blur (Two Steps or More)
Referenced by issue #79672, Motion blur steps value incorrectly changes shutter duration and affects AA quality
Referenced by issue #79630, Crop and transparent in render
Referenced by issue #79533, Crash when opening file
Referenced by issue #78452, crash while switching camera in animation rendering (only when motion blur is on in eevee render settings )
|
@ -237,6 +237,11 @@ EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void)
|
|||
return (EEVEE_ViewLayerData *)DRW_view_layer_engine_data_get(&draw_engine_eevee_type);
|
||||
}
|
||||
|
||||
static void eevee_view_layer_init(EEVEE_ViewLayerData *sldata)
|
||||
{
|
||||
sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data), NULL);
|
||||
}
|
||||
|
||||
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_layer)
|
||||
{
|
||||
EEVEE_ViewLayerData **sldata = (EEVEE_ViewLayerData **)DRW_view_layer_engine_data_ensure_ex(
|
||||
|
@ -244,6 +249,7 @@ EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_laye
|
|||
|
||||
if (*sldata == NULL) {
|
||||
*sldata = MEM_callocN(sizeof(**sldata), "EEVEE_ViewLayerData");
|
||||
eevee_view_layer_init(*sldata);
|
||||
}
|
||||
|
||||
return *sldata;
|
||||
|
@ -256,6 +262,7 @@ EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void)
|
|||
|
||||
if (*sldata == NULL) {
|
||||
*sldata = MEM_callocN(sizeof(**sldata), "EEVEE_ViewLayerData");
|
||||
eevee_view_layer_init(*sldata);
|
||||
}
|
||||
|
||||
return *sldata;
|
||||
|
|
|
@ -79,11 +79,6 @@ static void eevee_engine_init(void *ved)
|
|||
GPU_framebuffer_ensure_config(&fbl->main_color_fb,
|
||||
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->color)});
|
||||
|
||||
if (sldata->common_ubo == NULL) {
|
||||
sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data),
|
||||
&sldata->common_data);
|
||||
}
|
||||
|
||||
/* `EEVEE_renderpasses_init` will set the active render passes used by `EEVEE_effects_init`.
|
||||
* `EEVEE_effects_init` needs to go second for TAA. */
|
||||
EEVEE_renderpasses_init(vedata);
|
||||
|
@ -459,6 +454,8 @@ static void eevee_render_to_image(void *vedata,
|
|||
}
|
||||
EEVEE_PrivateData *g_data = ved->stl->g_data;
|
||||
|
||||
EEVEE_render_modules_init(vedata, engine, depsgraph);
|
||||
|
||||
int initial_frame = CFRA;
|
||||
int steps = max_ii(1, scene->eevee.motion_blur_steps);
|
||||
int time_steps_tot = (do_motion_blur) ? steps : 1;
|
||||
|
@ -481,9 +478,10 @@ static void eevee_render_to_image(void *vedata,
|
|||
}
|
||||
else {
|
||||
EEVEE_motion_blur_step_set(ved, MB_PREV);
|
||||
RE_engine_frame_set(engine, floorf(time_prev), fractf(time_prev));
|
||||
DRW_render_set_time(engine, depsgraph, floorf(time_prev), fractf(time_prev));
|
||||
EEVEE_render_modules_init(vedata, engine, depsgraph);
|
||||
sldata = EEVEE_view_layer_data_ensure();
|
||||
|
||||
EEVEE_render_view_sync(vedata, engine, depsgraph);
|
||||
EEVEE_render_cache_init(sldata, vedata);
|
||||
|
||||
DRW_render_object_iter(vedata, engine, depsgraph, EEVEE_render_cache);
|
||||
|
@ -497,9 +495,10 @@ static void eevee_render_to_image(void *vedata,
|
|||
/* Next motion step. */
|
||||
if (do_motion_blur_fx) {
|
||||
EEVEE_motion_blur_step_set(ved, MB_NEXT);
|
||||
RE_engine_frame_set(engine, floorf(time_next), fractf(time_next));
|
||||
DRW_render_set_time(engine, depsgraph, floorf(time_next), fractf(time_next));
|
||||
EEVEE_render_modules_init(vedata, engine, depsgraph);
|
||||
sldata = EEVEE_view_layer_data_ensure();
|
||||
|
||||
EEVEE_render_view_sync(vedata, engine, depsgraph);
|
||||
EEVEE_render_cache_init(sldata, vedata);
|
||||
|
||||
DRW_render_object_iter(vedata, engine, depsgraph, EEVEE_render_cache);
|
||||
|
@ -513,10 +512,11 @@ static void eevee_render_to_image(void *vedata,
|
|||
{
|
||||
if (do_motion_blur) {
|
||||
EEVEE_motion_blur_step_set(ved, MB_CURR);
|
||||
RE_engine_frame_set(engine, floorf(time_curr), fractf(time_curr));
|
||||
DRW_render_set_time(engine, depsgraph, floorf(time_curr), fractf(time_curr));
|
||||
EEVEE_render_modules_init(vedata, engine, depsgraph);
|
||||
sldata = EEVEE_view_layer_data_ensure();
|
||||
}
|
||||
|
||||
EEVEE_render_view_sync(vedata, engine, depsgraph);
|
||||
EEVEE_render_cache_init(sldata, vedata);
|
||||
|
||||
DRW_render_object_iter(vedata, engine, depsgraph, EEVEE_render_cache);
|
||||
|
|
|
@ -861,11 +861,6 @@ static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lb
|
|||
DRW_view_set_active(view);
|
||||
}
|
||||
|
||||
if (sldata->common_ubo == NULL) {
|
||||
sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data),
|
||||
&sldata->common_data);
|
||||
}
|
||||
|
||||
/* HACK: set txl->color but unset it before Draw Manager frees it. */
|
||||
txl->color = lbake->rt_color;
|
||||
int viewport_size[2] = {
|
||||
|
|
|
@ -1285,6 +1285,9 @@ bool EEVEE_render_init(EEVEE_Data *vedata,
|
|||
void EEVEE_render_view_sync(EEVEE_Data *vedata,
|
||||
struct RenderEngine *engine,
|
||||
struct Depsgraph *depsgraph);
|
||||
void EEVEE_render_modules_init(EEVEE_Data *vedata,
|
||||
struct RenderEngine *engine,
|
||||
struct Depsgraph *depsgraph);
|
||||
void EEVEE_render_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
||||
void EEVEE_render_cache(void *vedata,
|
||||
struct Object *ob,
|
||||
|
|
|
@ -47,17 +47,13 @@
|
|||
#include "eevee_private.h"
|
||||
|
||||
/* Return true if init properly. */
|
||||
bool EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *depsgraph)
|
||||
bool EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *UNUSED(depsgraph))
|
||||
{
|
||||
EEVEE_Data *vedata = (EEVEE_Data *)ved;
|
||||
EEVEE_StorageList *stl = vedata->stl;
|
||||
EEVEE_TextureList *txl = vedata->txl;
|
||||
EEVEE_FramebufferList *fbl = vedata->fbl;
|
||||
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
|
||||
Scene *scene = DEG_get_evaluated_scene(depsgraph);
|
||||
const float *size_orig = DRW_viewport_size_get();
|
||||
float size_final[2];
|
||||
float camtexcofac[4];
|
||||
|
||||
/* Init default FB and render targets:
|
||||
* In render mode the default framebuffer is not generated
|
||||
|
@ -75,25 +71,6 @@ bool EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
|
|||
g_data->valid_double_buffer = 0;
|
||||
copy_v2_v2(g_data->size_orig, size_orig);
|
||||
|
||||
if (scene->eevee.flag & SCE_EEVEE_OVERSCAN) {
|
||||
g_data->overscan = scene->eevee.overscan / 100.0f;
|
||||
g_data->overscan_pixels = roundf(max_ff(size_orig[0], size_orig[1]) * g_data->overscan);
|
||||
|
||||
madd_v2_v2v2fl(size_final, size_orig, (float[2]){2.0f, 2.0f}, g_data->overscan_pixels);
|
||||
|
||||
camtexcofac[0] = size_final[0] / size_orig[0];
|
||||
camtexcofac[1] = size_final[1] / size_orig[1];
|
||||
|
||||
camtexcofac[2] = -camtexcofac[0] * g_data->overscan_pixels / size_final[0];
|
||||
camtexcofac[3] = -camtexcofac[1] * g_data->overscan_pixels / size_final[1];
|
||||
}
|
||||
else {
|
||||
copy_v2_v2(size_final, size_orig);
|
||||
g_data->overscan = 0.0f;
|
||||
g_data->overscan_pixels = 0.0f;
|
||||
copy_v4_fl4(camtexcofac, 1.0f, 1.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
int final_res[2] = {size_orig[0] + g_data->overscan_pixels * 2.0f,
|
||||
size_orig[1] + g_data->overscan_pixels * 2.0f};
|
||||
|
||||
|
@ -125,19 +102,19 @@ bool EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
|
|||
GPU_framebuffer_ensure_config(&fbl->main_color_fb,
|
||||
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->color)});
|
||||
|
||||
/* Alloc common ubo data. */
|
||||
if (sldata->common_ubo == NULL) {
|
||||
sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data),
|
||||
&sldata->common_data);
|
||||
}
|
||||
|
||||
EEVEE_render_view_sync(vedata, engine, depsgraph);
|
||||
return true;
|
||||
}
|
||||
|
||||
void EEVEE_render_modules_init(EEVEE_Data *vedata,
|
||||
RenderEngine *engine,
|
||||
struct Depsgraph *depsgraph)
|
||||
{
|
||||
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
|
||||
EEVEE_StorageList *stl = vedata->stl;
|
||||
EEVEE_FramebufferList *fbl = vedata->fbl;
|
||||
/* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */
|
||||
struct Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
|
||||
|
||||
DRWView *view = (DRWView *)DRW_view_default_get();
|
||||
DRW_view_camtexco_set(view, camtexcofac);
|
||||
EEVEE_render_view_sync(vedata, engine, depsgraph);
|
||||
|
||||
/* `EEVEE_renderpasses_init` will set the active render passes used by `EEVEE_effects_init`.
|
||||
* `EEVEE_effects_init` needs to go second for TAA. */
|
||||
|
@ -146,13 +123,14 @@ bool EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
|
|||
EEVEE_materials_init(sldata, vedata, stl, fbl);
|
||||
EEVEE_shadows_init(sldata);
|
||||
EEVEE_lightprobes_init(sldata, vedata);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EEVEE_render_view_sync(EEVEE_Data *vedata, RenderEngine *engine, struct Depsgraph *depsgraph)
|
||||
{
|
||||
EEVEE_PrivateData *g_data = vedata->stl->g_data;
|
||||
Scene *scene = DEG_get_evaluated_scene(depsgraph);
|
||||
const float *size_orig = DRW_viewport_size_get();
|
||||
float size_final[2];
|
||||
|
||||
/* Set the pers & view matrix. */
|
||||
float winmat[4][4], viewmat[4][4], viewinv[4][4];
|
||||
|
@ -169,10 +147,33 @@ void EEVEE_render_view_sync(EEVEE_Data *vedata, RenderEngine *engine, struct Dep
|
|||
DRW_view_reset();
|
||||
DRW_view_default_set(view);
|
||||
DRW_view_set_active(view);
|
||||
|
||||
float camtexcofac[4];
|
||||
if (scene->eevee.flag & SCE_EEVEE_OVERSCAN) {
|
||||
g_data->overscan = scene->eevee.overscan / 100.0f;
|
||||
g_data->overscan_pixels = roundf(max_ff(size_orig[0], size_orig[1]) * g_data->overscan);
|
||||
|
||||
madd_v2_v2v2fl(size_final, size_orig, (float[2]){2.0f, 2.0f}, g_data->overscan_pixels);
|
||||
|
||||
camtexcofac[0] = size_final[0] / size_orig[0];
|
||||
camtexcofac[1] = size_final[1] / size_orig[1];
|
||||
|
||||
camtexcofac[2] = -camtexcofac[0] * g_data->overscan_pixels / size_final[0];
|
||||
camtexcofac[3] = -camtexcofac[1] * g_data->overscan_pixels / size_final[1];
|
||||
}
|
||||
else {
|
||||
copy_v2_v2(size_final, size_orig);
|
||||
g_data->overscan = 0.0f;
|
||||
g_data->overscan_pixels = 0.0f;
|
||||
copy_v4_fl4(camtexcofac, 1.0f, 1.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
DRW_view_camtexco_set(view, camtexcofac);
|
||||
}
|
||||
|
||||
void EEVEE_render_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
||||
{
|
||||
EEVEE_view_layer_data_ensure();
|
||||
EEVEE_bloom_cache_init(sldata, vedata);
|
||||
EEVEE_depth_of_field_cache_init(sldata, vedata);
|
||||
EEVEE_effects_cache_init(sldata, vedata);
|
||||
|
|
|
@ -632,6 +632,10 @@ void DRW_render_object_iter(void *vedata,
|
|||
struct RenderEngine *engine,
|
||||
struct Depsgraph *depsgraph));
|
||||
void DRW_render_instance_buffer_finish(void);
|
||||
void DRW_render_set_time(struct RenderEngine *engine,
|
||||
struct Depsgraph *depsgraph,
|
||||
int frame,
|
||||
float subframe);
|
||||
void DRW_render_viewport_size_set(const int size[2]);
|
||||
|
||||
void DRW_custom_pipeline(DrawEngineType *draw_engine_type,
|
||||
|
|
|
@ -1953,6 +1953,14 @@ void DRW_render_instance_buffer_finish(void)
|
|||
drw_resource_buffer_finish(DST.vmempool);
|
||||
}
|
||||
|
||||
/* WARNING: Changing frame might free the ViewLayerEngineData */
|
||||
void DRW_render_set_time(RenderEngine *engine, Depsgraph *depsgraph, int frame, float subframe)
|
||||
{
|
||||
RE_engine_frame_set(engine, frame, subframe);
|
||||
DST.draw_ctx.scene = DEG_get_evaluated_scene(depsgraph);
|
||||
DST.draw_ctx.view_layer = DEG_get_evaluated_view_layer(depsgraph);
|
||||
}
|
||||
|
||||
/**
|
||||
* object mode select-loop, see: ED_view3d_draw_select_loop (legacy drawing).
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue