Draw: Reuse GPUViewport when doing viewport render animations

Allows supporting motion blur for EEVEE-Next viewport render animations.
It should also provide a slight performance improvement.

Pull Request: https://projects.blender.org/blender/blender/pulls/116199
This commit is contained in:
Miguel Pozo 2023-12-19 16:12:30 +01:00
parent 17acedf965
commit b1e83f8323
9 changed files with 35 additions and 2 deletions

View File

@ -29,6 +29,7 @@ typedef struct ImBuf *(*SequencerDrawView)(struct Depsgraph *depsgraph,
int alpha_mode, int alpha_mode,
const char *viewname, const char *viewname,
struct GPUOffScreen *ofs, struct GPUOffScreen *ofs,
struct GPUViewport *viewport,
char err_out[256]); char err_out[256]);
extern SequencerDrawView sequencer_view3d_fn; extern SequencerDrawView sequencer_view3d_fn;

View File

@ -68,6 +68,9 @@ void ED_view3d_draw_offscreen_simple(Depsgraph *depsgraph,
* *
* \param ofs: Optional off-screen buffer, can be NULL. * \param ofs: Optional off-screen buffer, can be NULL.
* (avoids re-creating when doing multiple GL renders). * (avoids re-creating when doing multiple GL renders).
* \param viewport: Optional viewport data, can be NULL.
* (avoids re-creating when doing multiple GL renders,
* allows keeping track of state across frames).
*/ */
ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph, ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
Scene *scene, Scene *scene,
@ -81,12 +84,16 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
const char *viewname, const char *viewname,
bool restore_rv3d_mats, bool restore_rv3d_mats,
GPUOffScreen *ofs, GPUOffScreen *ofs,
GPUViewport *viewport,
char err_out[256]); char err_out[256]);
/** /**
* Creates own fake 3d views (wrapping #ED_view3d_draw_offscreen_imbuf) * Creates own fake 3d views (wrapping #ED_view3d_draw_offscreen_imbuf)
* *
* \param ofs: Optional off-screen buffer can be NULL. * \param ofs: Optional off-screen buffer can be NULL.
* (avoids re-creating when doing multiple GL renders). * (avoids re-creating when doing multiple GL renders).
* \param viewport: Optional viewport data, can be NULL.
* (avoids re-creating when doing multiple GL renders,
* allows keeping track of state across frames).
* *
* \note used by the sequencer * \note used by the sequencer
*/ */
@ -102,4 +109,5 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph,
int alpha_mode, int alpha_mode,
const char *viewname, const char *viewname,
GPUOffScreen *ofs, GPUOffScreen *ofs,
GPUViewport *viewport,
char err_out[256]); char err_out[256]);

View File

@ -71,6 +71,7 @@
#include "GPU_framebuffer.h" #include "GPU_framebuffer.h"
#include "GPU_matrix.h" #include "GPU_matrix.h"
#include "GPU_viewport.h"
#include "render_intern.hh" #include "render_intern.hh"
@ -115,6 +116,8 @@ struct OGLRender {
int sizex, sizey; int sizex, sizey;
int write_still; int write_still;
GPUViewport *viewport;
ReportList *reports; ReportList *reports;
bMovieHandle *mh; bMovieHandle *mh;
int cfrao, nfra; int cfrao, nfra;
@ -348,6 +351,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
viewname, viewname,
true, true,
oglrender->ofs, oglrender->ofs,
oglrender->viewport,
err_out); err_out);
/* for stamp only */ /* for stamp only */
@ -368,6 +372,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
alpha_mode, alpha_mode,
viewname, viewname,
oglrender->ofs, oglrender->ofs,
oglrender->viewport,
err_out); err_out);
camera = scene->camera; camera = scene->camera;
} }
@ -469,6 +474,7 @@ static void screen_opengl_render_apply(const bContext *C, OGLRender *oglrender)
for (view_id = 0; view_id < oglrender->views_len; view_id++) { for (view_id = 0; view_id < oglrender->views_len; view_id++) {
context.view_id = view_id; context.view_id = view_id;
context.gpu_offscreen = oglrender->ofs; context.gpu_offscreen = oglrender->ofs;
context.gpu_viewport = oglrender->viewport;
oglrender->seq_data.ibufs_arr[view_id] = SEQ_render_give_ibuf( oglrender->seq_data.ibufs_arr[view_id] = SEQ_render_give_ibuf(
&context, scene->r.cfra, chanshown); &context, scene->r.cfra, chanshown);
} }
@ -759,6 +765,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
oglrender->ofs = ofs; oglrender->ofs = ofs;
oglrender->sizex = sizex; oglrender->sizex = sizex;
oglrender->sizey = sizey; oglrender->sizey = sizey;
oglrender->viewport = GPU_viewport_create();
oglrender->bmain = CTX_data_main(C); oglrender->bmain = CTX_data_main(C);
oglrender->scene = scene; oglrender->scene = scene;
oglrender->workspace = workspace; oglrender->workspace = workspace;
@ -921,6 +928,7 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
DRW_gpu_context_enable(); DRW_gpu_context_enable();
GPU_offscreen_free(oglrender->ofs); GPU_offscreen_free(oglrender->ofs);
GPU_viewport_free(oglrender->viewport);
DRW_gpu_context_disable(); DRW_gpu_context_disable();
if (oglrender->is_sequencer) { if (oglrender->is_sequencer) {

View File

@ -890,6 +890,7 @@ static void object_preview_render(IconPreview *preview, IconPreviewSize *preview
R_ALPHAPREMUL, R_ALPHAPREMUL,
nullptr, nullptr,
nullptr, nullptr,
nullptr,
err_out); err_out);
/* TODO: color-management? */ /* TODO: color-management? */
@ -1025,6 +1026,7 @@ static void action_preview_render(IconPreview *preview, IconPreviewSize *preview
R_ADDSKY, R_ADDSKY,
nullptr, nullptr,
nullptr, nullptr,
nullptr,
err_out); err_out);
action_preview_render_cleanup(preview, pose_backup); action_preview_render_cleanup(preview, pose_backup);

View File

@ -6329,6 +6329,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
nullptr, nullptr,
false, false,
nullptr, nullptr,
nullptr,
err_out); err_out);
if (!ibuf) { if (!ibuf) {

View File

@ -1753,6 +1753,10 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph,
view3d_main_region_setup_offscreen(depsgraph, scene, v3d, region, viewmat, winmat); view3d_main_region_setup_offscreen(depsgraph, scene, v3d, region, viewmat, winmat);
} }
if (viewport) {
GPU_viewport_tag_update(viewport);
}
/* main drawing call */ /* main drawing call */
DRW_draw_render_loop_offscreen(depsgraph, DRW_draw_render_loop_offscreen(depsgraph,
engine_type, engine_type,
@ -1905,8 +1909,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
int alpha_mode, int alpha_mode,
const char *viewname, const char *viewname,
const bool restore_rv3d_mats, const bool restore_rv3d_mats,
/* output vars */
GPUOffScreen *ofs, GPUOffScreen *ofs,
GPUViewport *viewport,
/* output vars */
char err_out[256]) char err_out[256])
{ {
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata); RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
@ -2024,7 +2029,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
do_color_management, do_color_management,
restore_rv3d_mats, restore_rv3d_mats,
ofs, ofs,
nullptr); viewport);
if (ibuf->float_buffer.data) { if (ibuf->float_buffer.data) {
GPU_offscreen_read_color(ofs, GPU_DATA_FLOAT, ibuf->float_buffer.data); GPU_offscreen_read_color(ofs, GPU_DATA_FLOAT, ibuf->float_buffer.data);
@ -2065,6 +2070,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph,
int alpha_mode, int alpha_mode,
const char *viewname, const char *viewname,
GPUOffScreen *ofs, GPUOffScreen *ofs,
GPUViewport *viewport,
char err_out[256]) char err_out[256])
{ {
View3D v3d = blender::dna::shallow_zero_initialize(); View3D v3d = blender::dna::shallow_zero_initialize();
@ -2159,6 +2165,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph,
viewname, viewname,
true, true,
ofs, ofs,
viewport,
err_out); err_out);
} }

View File

@ -12,6 +12,7 @@
struct Depsgraph; struct Depsgraph;
struct GPUOffScreen; struct GPUOffScreen;
struct GPUViewport;
struct ImBuf; struct ImBuf;
struct ListBase; struct ListBase;
struct Main; struct Main;
@ -45,6 +46,7 @@ struct SeqRenderData {
/* special case for OpenGL render */ /* special case for OpenGL render */
GPUOffScreen *gpu_offscreen; GPUOffScreen *gpu_offscreen;
GPUViewport *gpu_viewport;
// int gpu_samples; // int gpu_samples;
// bool gpu_full_samples; // bool gpu_full_samples;
}; };

View File

@ -238,6 +238,7 @@ void SEQ_render_new_render_data(Main *bmain,
r_context->is_proxy_render = false; r_context->is_proxy_render = false;
r_context->view_id = 0; r_context->view_id = 0;
r_context->gpu_offscreen = nullptr; r_context->gpu_offscreen = nullptr;
r_context->gpu_viewport = nullptr;
r_context->task_id = SEQ_TASK_MAIN_RENDER; r_context->task_id = SEQ_TASK_MAIN_RENDER;
r_context->is_prefetch_render = false; r_context->is_prefetch_render = false;
} }
@ -1534,6 +1535,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context,
scene->r.alphamode, scene->r.alphamode,
viewname, viewname,
context->gpu_offscreen, context->gpu_offscreen,
context->gpu_viewport,
err_out); err_out);
if (ibuf == nullptr) { if (ibuf == nullptr) {
fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out); fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out);

View File

@ -1797,6 +1797,7 @@ static ImBuf *blend_file_thumb_from_camera(const bContext *C,
R_ALPHAPREMUL, R_ALPHAPREMUL,
nullptr, nullptr,
nullptr, nullptr,
nullptr,
err_out); err_out);
} }
else { else {
@ -1812,6 +1813,7 @@ static ImBuf *blend_file_thumb_from_camera(const bContext *C,
nullptr, nullptr,
true, true,
nullptr, nullptr,
nullptr,
err_out); err_out);
} }