blender/intern/cycles/session/buffers.h

190 lines
5.6 KiB
C++

/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: Apache-2.0 */
#ifndef __BUFFERS_H__
#define __BUFFERS_H__
#include "device/memory.h"
#include "graph/node.h"
#include "scene/pass.h"
#include "kernel/types.h"
#include "util/half.h"
#include "util/string.h"
#include "util/thread.h"
#include "util/types.h"
CCL_NAMESPACE_BEGIN
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;
ustring lightgroup;
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 && lightgroup == other.lightgroup &&
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). */
/* NOTE: Is not a real scene node. Using Node API for ease of (de)serialization. */
class BufferParams : public Node {
public:
NODE_DECLARE
/* Width/height of the physical buffer. */
int width = 0;
int height = 0;
/* Windows defines which part of the buffers is visible. The part outside of the window is
* considered an "overscan".
*
* Window X and Y are relative to the position of the buffer in the full buffer. */
int window_x = 0;
int window_y = 0;
int window_width = 0;
int window_height = 0;
/* 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;
/* Runtime fields, only valid after `update_passes()` or `update_offset_stride()`. */
int offset = -1, stride = -1;
/* Runtime fields, only valid after `update_passes()`. */
int pass_stride = -1;
/* Properties which are used for accessing buffer pixels outside of scene graph. */
vector<BufferPass> passes;
ustring layer;
ustring view;
int samples = 0;
float exposure = 1.0f;
bool use_approximate_shadow_catcher = false;
bool use_transparent_background = false;
BufferParams();
BufferParams(BufferParams &&other) noexcept = default;
BufferParams(const BufferParams &other) = default;
BufferParams &operator=(BufferParams &&other) = default;
BufferParams &operator=(const BufferParams &other) = default;
~BufferParams() = default;
/* 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 strides which are stored outside
* of the passes. */
void update_passes();
void update_passes(const vector<Pass *> &scene_passes);
/* Returns PASS_UNUSED if there is no such pass in the buffer. */
int get_pass_offset(PassType type, PassMode mode = PassMode::NOISY) const;
/* 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;
/* 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;
void update_offset_stride();
bool modified(const BufferParams &other) const;
protected:
void reset_pass_offset();
/* Multiplied 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 Buffers */
class RenderBuffers {
public:
/* buffer parameters */
BufferParams params;
/* float buffer */
device_vector<float> buffer;
explicit RenderBuffers(Device *device);
~RenderBuffers();
void reset(const BufferParams &params);
void zero();
bool copy_from_device();
void copy_to_device();
};
/* Copy denoised passes form source to destination.
*
* Buffer parameters are provided explicitly, allowing to copy pixels 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__ */