Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/render/buffers.h
| Show All 17 Lines | |||||
| #define __BUFFERS_H__ | #define __BUFFERS_H__ | ||||
| #include "device/device_memory.h" | #include "device/device_memory.h" | ||||
| #include "render/film.h" | #include "render/film.h" | ||||
| #include "kernel/kernel_types.h" | #include "kernel/kernel_types.h" | ||||
| #include "util/util_api.h" | |||||
| #include "util/util_half.h" | #include "util/util_half.h" | ||||
| #include "util/util_string.h" | #include "util/util_string.h" | ||||
| #include "util/util_thread.h" | #include "util/util_thread.h" | ||||
| #include "util/util_types.h" | #include "util/util_types.h" | ||||
| struct TileInfo; | |||||
| CCL_NAMESPACE_BEGIN | CCL_NAMESPACE_BEGIN | ||||
| class Device; | class Device; | ||||
| class DeviceTask; | |||||
| struct DeviceDrawParams; | struct DeviceDrawParams; | ||||
| struct float4; | struct float4; | ||||
| /* Buffer Parameters | /* Buffer Parameters | ||||
| * Size of render buffer and how it fits in the full image (border render). */ | * Size of render buffer and how it fits in the full image (border render). */ | ||||
| class BufferParams { | class BufferParams { | ||||
| public: | |||||
| /* width/height of the physical buffer */ | /* width/height of the physical buffer */ | ||||
| int width; | GET_SET(int, width) | ||||
| int height; | GET_SET(int, height) | ||||
| /* offset into and width/height of the full buffer */ | /* offset into and width/height of the full buffer */ | ||||
| int full_x; | GET_SET(int, full_x) | ||||
| int full_y; | GET_SET(int, full_y) | ||||
| int full_width; | GET_SET(int, full_width) | ||||
| int full_height; | GET_SET(int, full_height) | ||||
| /* passes */ | /* passes */ | ||||
| vector<Pass> passes; | GET_SET(vector<Pass>, passes) | ||||
| bool denoising_data_pass; | GET_SET(bool, denoising_data_pass) | ||||
| /* If only some light path types should be target, an additional pass is needed. */ | /* If only some light path types should be target, an additional pass is needed. */ | ||||
| bool denoising_clean_pass; | GET_SET(bool, denoising_clean_pass) | ||||
| /* When we're prefiltering the passes during rendering, we need to keep both the | /* 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 | * original and the prefiltered data around because neighboring tiles might still | ||||
| * need the original data. */ | * need the original data. */ | ||||
| bool denoising_prefiltered_pass; | GET_SET(bool, denoising_prefiltered_pass) | ||||
| public: | |||||
| /* functions */ | /* functions */ | ||||
| BufferParams(); | BufferParams(); | ||||
| void get_offset_stride(int &offset, int &stride); | void get_offset_stride(int &offset, int &stride); | ||||
| bool modified(const BufferParams ¶ms); | bool modified(const BufferParams ¶ms); | ||||
| int get_passes_size(); | int get_passes_size(); | ||||
| int get_denoising_offset(); | int get_denoising_offset(); | ||||
| int get_denoising_prefiltered_offset(); | int get_denoising_prefiltered_offset(); | ||||
| }; | }; | ||||
| /* Render Buffers */ | /* Render Buffers */ | ||||
| class RenderBuffers { | class RenderBuffers { | ||||
| public: | |||||
| /* buffer parameters */ | /* buffer parameters */ | ||||
| BufferParams params; | GET_SET(BufferParams, params) | ||||
| /* float buffer */ | /* float buffer */ | ||||
| device_vector<float> buffer; | GET(device_vector<float>, buffer) | ||||
| bool map_neighbor_copied; | GET_SET(bool, map_neighbor_copied) | ||||
| double render_time; | GET_SET(double, render_time) | ||||
| public: | |||||
| explicit RenderBuffers(Device *device); | explicit RenderBuffers(Device *device); | ||||
| ~RenderBuffers(); | ~RenderBuffers(); | ||||
| void reset(BufferParams ¶ms); | void reset(BufferParams ¶ms); | ||||
| void zero(); | void zero(); | ||||
| bool copy_from_device(); | bool copy_from_device(); | ||||
| bool get_pass_rect( | bool get_pass_rect( | ||||
| const string &name, float exposure, int sample, int components, float *pixels); | const string &name, float exposure, int sample, int components, float *pixels); | ||||
| bool get_denoising_pass_rect( | bool get_denoising_pass_rect( | ||||
| int offset, float exposure, int sample, int components, float *pixels); | int offset, float exposure, int sample, int components, float *pixels); | ||||
| bool set_pass_rect(PassType type, int components, float *pixels, int samples); | bool set_pass_rect(PassType type, int components, float *pixels, int samples); | ||||
| }; | }; | ||||
| /* Display Buffer | /* Display Buffer | ||||
| * | * | ||||
| * The buffer used for drawing during render, filled by converting the render | * The buffer used for drawing during render, filled by converting the render | ||||
| * buffers to byte of half float storage */ | * buffers to byte of half float storage */ | ||||
| class DisplayBuffer { | class DisplayBuffer { | ||||
| public: | |||||
| /* buffer parameters */ | /* buffer parameters */ | ||||
| BufferParams params; | GET_SET(BufferParams, params) | ||||
| /* dimensions for how much of the buffer is actually ready for display. | /* 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. | * with progressive render we can be using only a subset of the buffer. | ||||
| * if these are zero, it means nothing can be drawn yet */ | * if these are zero, it means nothing can be drawn yet */ | ||||
| int draw_width, draw_height; | GET_SET(int, draw_width) | ||||
| GET_SET(int, draw_height) | |||||
| /* draw alpha channel? */ | /* draw alpha channel? */ | ||||
| bool transparent; | GET_SET(bool, transparent) | ||||
| /* use half float? */ | /* use half float? */ | ||||
| bool half_float; | GET_SET(bool, half_float) | ||||
| /* byte buffer for converted result */ | /* byte buffer for converted result */ | ||||
| device_pixels<uchar4> rgba_byte; | GET(device_pixels<uchar4>, rgba_byte) | ||||
| device_pixels<half4> rgba_half; | GET(device_pixels<half4>, rgba_half) | ||||
| public: | |||||
| DisplayBuffer(Device *device, bool linear = false); | DisplayBuffer(Device *device, bool linear = false); | ||||
| ~DisplayBuffer(); | ~DisplayBuffer(); | ||||
| void reset(BufferParams ¶ms); | void reset(BufferParams ¶ms); | ||||
| void draw_set(int width, int height); | void draw_set(int width, int height); | ||||
| void draw(Device *device, const DeviceDrawParams &draw_params); | void draw(Device *device, const DeviceDrawParams &draw_params); | ||||
| bool draw_ready(); | bool draw_ready(); | ||||
| }; | }; | ||||
| /* Render Tile | /* Render Tile | ||||
| * Rendering task on a buffer */ | * Rendering task on a buffer */ | ||||
| class RenderTile { | class RenderTile { | ||||
| public: | public: | ||||
| typedef enum { PATH_TRACE = (1 << 0), BAKE = (1 << 1), DENOISE = (1 << 2) } Task; | typedef enum { PATH_TRACE = (1 << 0), BAKE = (1 << 1), DENOISE = (1 << 2) } Task; | ||||
| typedef enum { NO_STEALING = 0, CAN_BE_STOLEN = 1, WAS_STOLEN = 2 } StealingState; | |||||
| Task task; | GET_SET(Task, task) | ||||
| int x, y, w, h; | GET_SET(int, x) | ||||
| int start_sample; | GET_SET(int, y) | ||||
| int num_samples; | GET_SET(int, w) | ||||
| int sample; | GET_SET(int, h) | ||||
| int resolution; | GET_SET(int, start_sample) | ||||
| int offset; | GET_SET(int, num_samples) | ||||
| int stride; | GET_SET(int, sample) | ||||
| int tile_index; | GET_SET(int, resolution) | ||||
| GET_SET(int, offset) | |||||
| GET_SET(int, stride) | |||||
| GET_SET(int, tile_index) | |||||
| device_ptr buffer; | GET_SET(device_ptr, buffer) | ||||
| int device_size; | GET_SET(int, device_size) | ||||
| typedef enum { NO_STEALING = 0, CAN_BE_STOLEN = 1, WAS_STOLEN = 2 } StealingState; | GET_SET(StealingState, stealing_state) | ||||
| StealingState stealing_state; | |||||
| RenderBuffers *buffers; | GET_SET(RenderBuffers *, buffers) | ||||
| public: | |||||
| RenderTile(); | RenderTile(); | ||||
| int4 bounds() const | int4 bounds() const | ||||
| { | { | ||||
| return make_int4(x, /* xmin */ | return make_int4(x, /* xmin */ | ||||
| y, /* ymin */ | y, /* ymin */ | ||||
| x + w, /* xmax */ | x + w, /* xmax */ | ||||
| y + h); /* ymax */ | y + h); /* ymax */ | ||||
| } | } | ||||
| /* Create a WorkTile from this RenderTile. */ | |||||
| WorkTile work_tile() const; | |||||
| /* Create a RenderTile from a DeviceTask, the set_sample parameter controls | |||||
| * whether to inherit the current sample from the task. */ | |||||
| static RenderTile from_device_task(const DeviceTask &task, bool set_sample); | |||||
| }; | }; | ||||
| /* Render Tile Neighbors | /* Render Tile Neighbors | ||||
| * Set of neighboring tiles used for denoising. Tile order: | * Set of neighboring tiles used for denoising. Tile order: | ||||
| * 0 1 2 | * 0 1 2 | ||||
| * 3 4 5 | * 3 4 5 | ||||
| * 6 7 8 */ | * 6 7 8 */ | ||||
| class RenderTileNeighbors { | class RenderTileNeighbors { | ||||
| public: | public: | ||||
| static const int SIZE = 9; | static const int SIZE = 9; | ||||
| static const int CENTER = 4; | static const int CENTER = 4; | ||||
| RenderTile tiles[SIZE]; | /* cannot use a template in a macro */ | ||||
| RenderTile target; | using RenderTileArray = std::array<RenderTile, SIZE>; | ||||
| GET(RenderTileArray, tiles) | |||||
| GET_SET(RenderTile, target) | |||||
| public: | |||||
| RenderTileNeighbors(const RenderTile ¢er) | RenderTileNeighbors(const RenderTile ¢er) | ||||
| { | { | ||||
| tiles[CENTER] = center; | tiles[CENTER] = center; | ||||
| } | } | ||||
| int4 bounds() const | int4 bounds() const | ||||
| { | { | ||||
| return make_int4(tiles[3].x, /* xmin */ | return make_int4(tiles[3].get_x(), /* xmin */ | ||||
| tiles[1].y, /* ymin */ | tiles[1].get_y(), /* ymin */ | ||||
| tiles[5].x + tiles[5].w, /* xmax */ | tiles[5].get_x() + tiles[5].get_w(), /* xmax */ | ||||
| tiles[7].y + tiles[7].h); /* ymax */ | tiles[7].get_y() + tiles[7].get_h()); /* ymax */ | ||||
| } | } | ||||
| void set_bounds_from_center() | void set_bounds_from_center() | ||||
| { | { | ||||
| tiles[3].x = tiles[CENTER].x; | tiles[3].set_x(tiles[CENTER].get_x()); | ||||
| tiles[1].y = tiles[CENTER].y; | tiles[1].set_y(tiles[CENTER].get_y()); | ||||
| tiles[5].x = tiles[CENTER].x + tiles[CENTER].w; | tiles[5].set_x(tiles[CENTER].get_x() + tiles[CENTER].get_w()); | ||||
| tiles[7].y = tiles[CENTER].y + tiles[CENTER].h; | tiles[7].set_y(tiles[CENTER].get_y() + tiles[CENTER].get_h()); | ||||
| } | } | ||||
| void fill_tile_info(TileInfo *tile_info); | |||||
| }; | }; | ||||
| CCL_NAMESPACE_END | CCL_NAMESPACE_END | ||||
| #endif /* __BUFFERS_H__ */ | #endif /* __BUFFERS_H__ */ | ||||