Proper implementation of compositor support for Draw Manager

We need to move the render result logic outside the render engine code.

It makes no sense for Eevee/Clay/... to have to re-implement the render resilt
creation logic. Beside the original implementation really got it wrong, by
ignoring the different render layers needed for the final render.

Finally, there is no need to re-create the logic for views. So this was also
fixed.

Note 1: This will break still if the depsgraph of the needed view layers is not
updated / created. We need to address this separately. For now if users want
to test this, just show each view layer in the viewport at least once.

Note 2: We are still getting depsgraph from scene and creating if needed.
`BKE_scene_get_depsgraph(scene, view_layer, true);` according to Sergey we need
to move the render depsgraph for the Render struct instead. I will do it
separately as well.
This commit is contained in:
Dalai Felinto 2018-02-20 10:14:23 -03:00
parent a16c0ebc59
commit c14925bddf
5 changed files with 50 additions and 49 deletions

View File

@ -377,14 +377,15 @@ static void eevee_id_update(void *vedata, ID *id)
}
}
static void eevee_render_to_image(void *vedata, struct RenderEngine *engine, struct Depsgraph *depsgraph)
static void eevee_render_to_image(void *vedata, RenderEngine *engine, struct RenderResult *render_result, struct RenderLayer *render_layer)
{
EEVEE_render_init(vedata, engine, depsgraph);
const DRWContextState *draw_ctx = DRW_context_state_get();
EEVEE_render_init(vedata, engine, draw_ctx->depsgraph);
DRW_render_object_iter(vedata, engine, depsgraph, EEVEE_render_cache);
DRW_render_object_iter(vedata, engine, draw_ctx->depsgraph, EEVEE_render_cache);
/* Actually do the rendering. */
EEVEE_render_draw(vedata, engine, depsgraph);
EEVEE_render_draw(vedata, engine, render_result, render_layer);
}
static void eevee_engine_free(void)

View File

@ -29,6 +29,8 @@
struct Object;
struct EEVEE_BoundSphere;
struct EEVEE_ShadowCasterBuffer;
struct RenderLayer;
struct RenderResult;
extern struct DrawEngineType draw_engine_eevee_type;
@ -886,7 +888,7 @@ void EEVEE_effects_free(void);
/* eevee_render.c */
void EEVEE_render_init(EEVEE_Data *vedata, struct RenderEngine *engine, struct Depsgraph *depsgraph);
void EEVEE_render_cache(void *vedata, struct Object *ob, struct RenderEngine *engine, struct Depsgraph *depsgraph);
void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct Depsgraph *depsgraph);
void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct RenderResult *render_result, struct RenderLayer *render_layer);
void EEVEE_render_update_passes(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer);
/* Shadow Matrix */

View File

@ -152,10 +152,9 @@ void EEVEE_render_cache(
}
static void eevee_render_result_combined(
RenderResult *rr, const char *viewname,
RenderResult *rr, RenderLayer *rl, const char *viewname,
EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
{
RenderLayer *rl = rr->layers.first;
RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname);
DRW_framebuffer_bind(vedata->stl->effects->final_fb);
@ -163,7 +162,7 @@ static void eevee_render_result_combined(
}
static void eevee_render_result_subsurface(
RenderResult *rr, const char *viewname,
RenderResult *rr, RenderLayer *rl, const char *viewname,
EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
{
const DRWContextState *draw_ctx = DRW_context_state_get();
@ -175,7 +174,6 @@ static void eevee_render_result_subsurface(
}
if ((view_layer->passflag & SCE_PASS_SUBSURFACE_COLOR) != 0) {
RenderLayer *rl = rr->layers.first;
RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_COLOR, viewname);
IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
@ -191,7 +189,6 @@ static void eevee_render_result_subsurface(
}
if ((view_layer->passflag & SCE_PASS_SUBSURFACE_DIRECT) != 0) {
RenderLayer *rl = rr->layers.first;
RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_DIRECT, viewname);
IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
@ -213,7 +210,7 @@ static void eevee_render_result_subsurface(
}
static void eevee_render_result_normal(
RenderResult *rr, const char *viewname,
RenderResult *rr, RenderLayer *rl, const char *viewname,
EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
{
const DRWContextState *draw_ctx = DRW_context_state_get();
@ -226,7 +223,6 @@ static void eevee_render_result_normal(
return;
if ((view_layer->passflag & SCE_PASS_NORMAL) != 0) {
RenderLayer *rl = rr->layers.first;
RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_NORMAL, viewname);
DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 3, 1, rp->rect);
@ -255,7 +251,7 @@ static void eevee_render_result_normal(
}
static void eevee_render_result_z(
RenderResult *rr, const char *viewname,
RenderResult *rr, RenderLayer *rl, const char *viewname,
EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
@ -269,7 +265,6 @@ static void eevee_render_result_z(
return;
if ((view_layer->passflag & SCE_PASS_Z) != 0) {
RenderLayer *rl = rr->layers.first;
RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname);
DRW_framebuffer_read_depth(rr->xof, rr->yof, rr->rectx, rr->recty, rp->rect);
@ -295,14 +290,13 @@ static void eevee_render_result_z(
}
static void eevee_render_result_mist(
RenderResult *rr, const char *viewname,
RenderResult *rr, RenderLayer *rl, const char *viewname,
EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
{
const DRWContextState *draw_ctx = DRW_context_state_get();
ViewLayer *view_layer = draw_ctx->view_layer;
if ((view_layer->passflag & SCE_PASS_MIST) != 0) {
RenderLayer *rl = rr->layers.first;
RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_MIST, viewname);
IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
@ -319,7 +313,7 @@ static void eevee_render_result_mist(
}
static void eevee_render_result_occlusion(
RenderResult *rr, const char *viewname,
RenderResult *rr, RenderLayer *rl, const char *viewname,
EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
{
const DRWContextState *draw_ctx = DRW_context_state_get();
@ -331,7 +325,6 @@ static void eevee_render_result_occlusion(
}
if ((view_layer->passflag & SCE_PASS_AO) != 0) {
RenderLayer *rl = rr->layers.first;
RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_AO, viewname);
IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
@ -375,10 +368,11 @@ static void eevee_render_draw_background(EEVEE_Data *vedata)
DRW_framebuffer_bind(fbl->main);
}
void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct Depsgraph *UNUSED(depsgraph))
void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderResult *rr, RenderLayer *rl)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
ViewLayer *view_layer = draw_ctx->view_layer;
const char *viewname = RE_GetActiveRenderView(engine->re);
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_FramebufferList *fbl = vedata->fbl;
@ -412,12 +406,6 @@ void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct D
EEVEE_occlusion_output_init(sldata, vedata);
}
/* Init render result. */
const char *viewname = RE_GetActiveRenderView(engine->re);
const float *render_size = DRW_viewport_size_get();
RenderResult *rr = RE_engine_begin_result(engine, 0, 0, (int)render_size[0], (int)render_size[1], NULL, viewname);
IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
unsigned int render_samples = BKE_collection_engine_property_value_get_int(props, "taa_render_samples");
@ -482,7 +470,7 @@ void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct D
/* Occlusion output */
EEVEE_occlusion_output_accumulate(sldata, vedata);
/* Result NORMAL */
eevee_render_result_normal(rr, viewname, vedata, sldata);
eevee_render_result_normal(rr, rl, viewname, vedata, sldata);
/* Volumetrics Resolve Opaque */
EEVEE_volumes_resolve(sldata, vedata);
/* Mist output */
@ -490,17 +478,15 @@ void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct D
/* Transparent */
DRW_draw_pass(psl->transparent_pass);
/* Result Z */
eevee_render_result_z(rr, viewname, vedata, sldata);
eevee_render_result_z(rr, rl, viewname, vedata, sldata);
/* Post Process */
EEVEE_draw_effects(sldata, vedata);
}
eevee_render_result_combined(rr, viewname, vedata, sldata);
eevee_render_result_subsurface(rr, viewname, vedata, sldata);
eevee_render_result_mist(rr, viewname, vedata, sldata);
eevee_render_result_occlusion(rr, viewname, vedata, sldata);
RE_engine_end_result(engine, rr, false, false, false);
eevee_render_result_combined(rr, rl, viewname, vedata, sldata);
eevee_render_result_subsurface(rr, rl, viewname, vedata, sldata);
eevee_render_result_mist(rr, rl, viewname, vedata, sldata);
eevee_render_result_occlusion(rr, rl, viewname, vedata, sldata);
}
void EEVEE_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)

View File

@ -140,7 +140,7 @@ typedef struct DrawEngineType {
void (*view_update)(void *vedata);
void (*id_update)(void *vedata, struct ID *id);
void (*render_to_image)(void *vedata, struct RenderEngine *engine, struct Depsgraph *graph);
void (*render_to_image)(void *vedata, struct RenderEngine *engine, struct RenderResult *result, struct RenderLayer *layer);
} DrawEngineType;
#ifndef __DRW_ENGINE_H__

View File

@ -3606,14 +3606,13 @@ void DRW_draw_render_loop_offscreen(
GPU_offscreen_bind(ofs, false);
}
void DRW_render_to_image(RenderEngine *re, struct Depsgraph *depsgraph)
void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
RenderEngineType *engine_type = re->type;
RenderEngineType *engine_type = engine->type;
DrawEngineType *draw_engine_type = engine_type->draw_engine;
RenderData *r = &scene->r;
Render *render = re->re;
Render *render = engine->re;
const EvaluationContext *eval_ctx = RE_GetEvalCtx(render);
/* Reset before using it. */
@ -3623,7 +3622,7 @@ void DRW_render_to_image(RenderEngine *re, struct Depsgraph *depsgraph)
DST.options.draw_background = scene->r.alphamode == R_ADDSKY;
DST.draw_ctx = (DRWContextState){
NULL, NULL, NULL, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, eval_ctx->object_mode, NULL,
NULL, NULL, NULL, scene, NULL, NULL, engine_type, depsgraph, eval_ctx->object_mode, NULL,
};
drw_context_state_init();
@ -3640,21 +3639,34 @@ void DRW_render_to_image(RenderEngine *re, struct Depsgraph *depsgraph)
glDisable(GL_SCISSOR_TEST);
glViewport(0, 0, size[0], size[1]);
if ((r->scemode & R_MULTIVIEW) != 0) {
for (SceneRenderView *srv = r->views.first; srv; srv = srv->next) {
if (BKE_scene_multiview_is_render_view_active(r, srv) == false)
continue;
/* Main rendering loop. */
RE_SetActiveRenderView(render, srv->name);
/* Init render result. */
const float *render_size = DRW_viewport_size_get();
RenderResult *render_result = RE_engine_begin_result(engine, 0, 0, (int)render_size[0], (int)render_size[1], NULL, NULL);
engine_type->draw_engine->render_to_image(data, re, depsgraph);
for (RenderView *render_view = render_result->views.first;
render_view != NULL;
render_view = render_view->next)
{
RE_SetActiveRenderView(render, render_view->name);
for (RenderLayer *render_layer = render_result->layers.first;
render_layer != NULL;
render_layer = render_layer->next)
{
ViewLayer *view_layer = BLI_findstring(&scene->view_layers, render_layer->name, offsetof(ViewLayer, name));
DST.draw_ctx.view_layer = view_layer;
/* TODO(dfelinto/sergey) we should not get depsgraph from scene.
* For rendering depsgraph is to be owned by Render. */
DST.draw_ctx.depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
engine_type->draw_engine->render_to_image(data, engine, render_result, render_layer);
DST.buffer_finish_called = false;
}
}
else {
engine_type->draw_engine->render_to_image(data, re, depsgraph);
}
DST.buffer_finish_called = false;
RE_engine_end_result(engine, render_result, false, false, false);
/* TODO grease pencil */