diff options
Diffstat (limited to 'intern/cycles/render/buffers.h')
-rw-r--r-- | intern/cycles/render/buffers.h | 256 |
1 files changed, 121 insertions, 135 deletions
diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h index 4ffc628bb52..c048234167d 100644 --- a/intern/cycles/render/buffers.h +++ b/intern/cycles/render/buffers.h @@ -18,8 +18,8 @@ #define __BUFFERS_H__ #include "device/device_memory.h" - -#include "render/film.h" +#include "graph/node.h" +#include "render/pass.h" #include "kernel/kernel_types.h" @@ -34,170 +34,156 @@ class Device; struct DeviceDrawParams; struct float4; +/* NOTE: Is not a real scene node. Using Node API for ease of (de)serialization. */ +class BufferPass : public Node { + public: + NODE_DECLARE + + PassType type = PASS_NONE; + PassMode mode = PassMode::NOISY; + ustring name; + bool include_albedo = false; + + int offset = -1; + + BufferPass(); + explicit BufferPass(const Pass *scene_pass); + + BufferPass(BufferPass &&other) noexcept = default; + BufferPass(const BufferPass &other) = default; + + BufferPass &operator=(BufferPass &&other) = default; + BufferPass &operator=(const BufferPass &other) = default; + + ~BufferPass() = default; + + PassInfo get_info() const; + + inline bool operator==(const BufferPass &other) const + { + return type == other.type && mode == other.mode && name == other.name && + include_albedo == other.include_albedo && offset == other.offset; + } + inline bool operator!=(const BufferPass &other) const + { + return !(*this == other); + } +}; + /* Buffer Parameters * Size of render buffer and how it fits in the full image (border render). */ -class BufferParams { +/* NOTE: Is not a real scene node. Using Node API for ease of (de)serialization. */ +class BufferParams : public Node { public: - /* width/height of the physical buffer */ - int width; - int height; - - /* offset into and width/height of the full buffer */ - int full_x; - int full_y; - int full_width; - int full_height; - - /* passes */ - vector<Pass> passes; - bool denoising_data_pass; - /* If only some light path types should be target, an additional pass is needed. */ - bool denoising_clean_pass; - /* When we're prefiltering the passes during rendering, we need to keep both the - * original and the prefiltered data around because neighboring tiles might still - * need the original data. */ - bool denoising_prefiltered_pass; - - /* functions */ - BufferParams(); + NODE_DECLARE - void get_offset_stride(int &offset, int &stride); - bool modified(const BufferParams ¶ms); - int get_passes_size(); - int get_denoising_offset(); - int get_denoising_prefiltered_offset(); -}; + /* Width/height of the physical buffer. */ + int width = 0; + int height = 0; -/* Render Buffers */ + /* Offset into and width/height of the full buffer. */ + int full_x = 0; + int full_y = 0; + int full_width = 0; + int full_height = 0; -class RenderBuffers { - public: - /* buffer parameters */ - BufferParams params; + /* Runtime fields, only valid after `update_passes()` or `update_offset_stride()`. */ + int offset = -1, stride = -1; - /* float buffer */ - device_vector<float> buffer; - bool map_neighbor_copied; - double render_time; + /* Runtime fields, only valid after `update_passes()`. */ + int pass_stride = -1; - explicit RenderBuffers(Device *device); - ~RenderBuffers(); + /* Properties which are used for accessing buffer pixels outside of scene graph. */ + vector<BufferPass> passes; + ustring layer; + ustring view; + float exposure = 1.0f; + bool use_approximate_shadow_catcher = false; + bool use_transparent_background = false; - void reset(BufferParams ¶ms); - void zero(); + BufferParams(); - bool copy_from_device(); - bool get_pass_rect( - const string &name, float exposure, int sample, int components, float *pixels); - bool get_denoising_pass_rect( - int offset, float exposure, int sample, int components, float *pixels); - bool set_pass_rect(PassType type, int components, float *pixels, int samples); -}; + BufferParams(BufferParams &&other) noexcept = default; + BufferParams(const BufferParams &other) = default; -/* Display Buffer - * - * The buffer used for drawing during render, filled by converting the render - * buffers to byte of half float storage */ + BufferParams &operator=(BufferParams &&other) = default; + BufferParams &operator=(const BufferParams &other) = default; -class DisplayBuffer { - public: - /* buffer parameters */ - BufferParams params; - /* dimensions for how much of the buffer is actually ready for display. - * with progressive render we can be using only a subset of the buffer. - * if these are zero, it means nothing can be drawn yet */ - int draw_width, draw_height; - /* draw alpha channel? */ - bool transparent; - /* use half float? */ - bool half_float; - /* byte buffer for converted result */ - device_pixels<uchar4> rgba_byte; - device_pixels<half4> rgba_half; - - DisplayBuffer(Device *device, bool linear = false); - ~DisplayBuffer(); - - void reset(BufferParams ¶ms); - - void draw_set(int width, int height); - void draw(Device *device, const DeviceDrawParams &draw_params); - bool draw_ready(); -}; + ~BufferParams() = default; -/* Render Tile - * Rendering task on a buffer */ + /* Pre-calculate all fields which depends on the passes. + * + * When the scene passes are given, the buffer passes will be created from them and stored in + * this params, and then params are updated for those passes. + * The `update_passes()` without parameters updates offsets and stries which are stored outside + * of the passes. */ + void update_passes(); + void update_passes(const vector<Pass *> &scene_passes); -class RenderTile { - public: - typedef enum { PATH_TRACE = (1 << 0), BAKE = (1 << 1), DENOISE = (1 << 2) } Task; + /* Returns PASS_UNUSED if there is no such pass in the buffer. */ + int get_pass_offset(PassType type, PassMode mode = PassMode::NOISY) const; - Task task; - int x, y, w, h; - int start_sample; - int num_samples; - int sample; - int resolution; - int offset; - int stride; - int tile_index; + /* Returns nullptr if pass with given name does not exist. */ + const BufferPass *find_pass(string_view name) const; + const BufferPass *find_pass(PassType type, PassMode mode = PassMode::NOISY) const; - device_ptr buffer; - int device_size; + /* Get display pass from its name. + * Will do special logic to replace combined pass with shadow catcher matte. */ + const BufferPass *get_actual_display_pass(PassType type, PassMode mode = PassMode::NOISY) const; + const BufferPass *get_actual_display_pass(const BufferPass *pass) const; - typedef enum { NO_STEALING = 0, CAN_BE_STOLEN = 1, WAS_STOLEN = 2 } StealingState; - StealingState stealing_state; + void update_offset_stride(); - RenderBuffers *buffers; + bool modified(const BufferParams &other) const; - RenderTile(); + protected: + void reset_pass_offset(); - int4 bounds() const - { - return make_int4(x, /* xmin */ - y, /* ymin */ - x + w, /* xmax */ - y + h); /* ymax */ - } + /* Multipled by 2 to be able to store noisy and denoised pass types. */ + static constexpr int kNumPassOffsets = PASS_NUM * 2; + + /* Indexed by an index derived from pass type and mode, indicates offset of the corresponding + * pass in the buffer. + * If there are multiple passes with same type and mode contains lowest offset of all of them. */ + int pass_offset_[kNumPassOffsets]; }; -/* Render Tile Neighbors - * Set of neighboring tiles used for denoising. Tile order: - * 0 1 2 - * 3 4 5 - * 6 7 8 */ +/* Render Buffers */ -class RenderTileNeighbors { +class RenderBuffers { public: - static const int SIZE = 9; - static const int CENTER = 4; + /* buffer parameters */ + BufferParams params; - RenderTile tiles[SIZE]; - RenderTile target; + /* float buffer */ + device_vector<float> buffer; - RenderTileNeighbors(const RenderTile ¢er) - { - tiles[CENTER] = center; - } + explicit RenderBuffers(Device *device); + ~RenderBuffers(); - int4 bounds() const - { - return make_int4(tiles[3].x, /* xmin */ - tiles[1].y, /* ymin */ - tiles[5].x + tiles[5].w, /* xmax */ - tiles[7].y + tiles[7].h); /* ymax */ - } + void reset(const BufferParams ¶ms); + void zero(); - void set_bounds_from_center() - { - tiles[3].x = tiles[CENTER].x; - tiles[1].y = tiles[CENTER].y; - tiles[5].x = tiles[CENTER].x + tiles[CENTER].w; - tiles[7].y = tiles[CENTER].y + tiles[CENTER].h; - } + bool copy_from_device(); + void copy_to_device(); }; +/* Copy denoised passes form source to destination. + * + * Buffer parameters are provided explicitly, allowing to copy pixelks between render buffers which + * content corresponds to a render result at a non-unit resolution divider. + * + * `src_offset` allows to offset source pixel index which is used when a fraction of the source + * buffer is to be copied. + * + * Copy happens of the number of pixels in the destination. */ +void render_buffers_host_copy_denoised(RenderBuffers *dst, + const BufferParams &dst_params, + const RenderBuffers *src, + const BufferParams &src_params, + const size_t src_offset = 0); + CCL_NAMESPACE_END #endif /* __BUFFERS_H__ */ |