Files
test2/source/blender/draw/intern/draw_view_data.hh
Omar Emara 57ff2969b8 Compositor: Support multi-pass compositing for EEVEE
This patch adds support for multi-pass compositing for EEVEE. This is
done by copying the passes used by the compositor node tree to the DRW
view data, which can then be accessed by the viewport compositor.

The viewport compositor will fallback to the viewport texture or an
invalid output of the passes were not initialized, this is currently the
case for any render engine that is not EEVEE.

A future optimization that we can do is eliminate the film pass copy
shaders and only copy the data that EEVEE rendered, which can be a
subset of the viewport for border rendering. This is not done at the
moment because not all engines support passes at the moment, so the
compositor expects full viewport passes.

Depends on: #123685, #123817, #123815.

Pull Request: https://projects.blender.org/blender/blender/pulls/123378
2024-07-23 10:15:13 +02:00

142 lines
4.4 KiB
C++

/* SPDX-FileCopyrightText: 2021 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup draw
*
* Engine data
* Structure containing each draw engine instance data.
*/
#pragma once
#define GPU_INFO_SIZE 512 /* IMA_MAX_RENDER_TEXT_SIZE */
namespace blender::draw {
class TextureFromPool;
} // namespace blender::draw
struct DRWPass;
struct DRWTextStore;
struct DRWRegisteredDrawEngine;
struct DrawEngineType;
struct GPUViewport;
/* NOTE: these structs are only here for reading the actual lists from the engine.
* The actual length of them is stored in a ViewportEngineData_Info.
* The length of 1 is just here to avoid compiler warning. */
struct FramebufferList {
GPUFrameBuffer *framebuffers[1];
};
struct TextureList {
GPUTexture *textures[1];
};
struct PassList {
DRWPass *passes[1];
};
/* Stores custom structs from the engine that have been MEM_(m/c)allocN'ed. */
struct StorageList {
void *storage[1];
};
struct ViewportEngineData {
/* Not owning pointer to the draw engine. */
DRWRegisteredDrawEngine *engine_type;
FramebufferList *fbl;
TextureList *txl;
PassList *psl;
StorageList *stl;
/**
* \brief Memory block that can be freely used by the draw engine.
* When used the draw engine must implement #DrawEngineType.instance_free callback.
*/
void *instance_data;
char info[GPU_INFO_SIZE];
/* we may want to put this elsewhere */
DRWTextStore *text_draw_cache;
/* Profiling data */
double init_time;
double render_time;
double background_time;
};
struct ViewportEngineData_Info {
int fbl_len;
int txl_len;
int psl_len;
int stl_len;
};
/* Buffer and textures used by the viewport by default */
struct DefaultFramebufferList {
GPUFrameBuffer *default_fb;
GPUFrameBuffer *overlay_fb;
GPUFrameBuffer *in_front_fb;
GPUFrameBuffer *color_only_fb;
GPUFrameBuffer *depth_only_fb;
GPUFrameBuffer *overlay_only_fb;
};
struct DefaultTextureList {
GPUTexture *color;
GPUTexture *color_overlay;
GPUTexture *depth;
GPUTexture *depth_in_front;
};
struct DRWViewData;
/**
* Creates a view data with all possible engines type for this view.
*
* `engine_types` contains #DRWRegisteredDrawEngine.
*/
DRWViewData *DRW_view_data_create(ListBase *engine_types);
void DRW_view_data_free(DRWViewData *view_data);
/* Returns a TextureFromPool stored in the given view data for the pass identified by the given
* pass name. Engines should call call this function for each of the passes needed by the viewport
* compositor in every redraw, then it should allocate the texture and write the pass data to it.
* The texture should cover the entire viewport. */
blender::draw::TextureFromPool &DRW_view_data_pass_texture_get(DRWViewData *view_data,
const char *pass_name);
void DRW_view_data_default_lists_from_viewport(DRWViewData *view_data, GPUViewport *viewport);
void DRW_view_data_texture_list_size_validate(DRWViewData *view_data, const int size[2]);
ViewportEngineData *DRW_view_data_engine_data_get_ensure(DRWViewData *view_data,
DrawEngineType *engine_type_);
void DRW_view_data_use_engine(DRWViewData *view_data, DrawEngineType *engine_type);
void DRW_view_data_reset(DRWViewData *view_data);
void DRW_view_data_free_unused(DRWViewData *view_data);
void DRW_view_data_engines_view_update(DRWViewData *view_data);
double *DRW_view_data_cache_time_get(DRWViewData *view_data);
DefaultFramebufferList *DRW_view_data_default_framebuffer_list_get(DRWViewData *view_data);
DefaultTextureList *DRW_view_data_default_texture_list_get(DRWViewData *view_data);
struct DRWEngineIterator {
int id, end;
ViewportEngineData **engines;
};
/* Iterate over used engines of this view_data. */
void DRW_view_data_enabled_engine_iter_begin(DRWEngineIterator *iterator, DRWViewData *view_data);
ViewportEngineData *DRW_view_data_enabled_engine_iter_step(DRWEngineIterator *iterator);
#define DRW_ENABLED_ENGINE_ITER(view_data_, engine_, data_) \
DRWEngineIterator iterator; \
ViewportEngineData *data_; \
DrawEngineType *engine_; \
DRW_view_data_enabled_engine_iter_begin(&iterator, view_data_); \
/* WATCH Comma operator trickery ahead! This tests engine_ == nullptr. */ \
while ((data_ = DRW_view_data_enabled_engine_iter_step(&iterator), \
engine_ = (data_ != nullptr) ? (DrawEngineType *)data_->engine_type->draw_engine : \
nullptr))