45 static const char *component_suffixes[] = {
"R",
"G",
"B",
"A"};
48 std::vector<std::string> channel_names;
54 const PassInfo pass_info = pass.get_info();
62 const string channel_name_prefix = prefix + string(pass.name) +
".";
65 channel_names.push_back(channel_name_prefix + component_suffixes[i]);
76 return attr_name_prefix + string(socket.
name);
79template<
typename Val
idateValueFunc,
typename GetValueFunc>
81 ImageSpec *image_spec,
84 const string &attr_name_prefix,
85 const ValidateValueFunc &validate_value_func,
86 const GetValueFunc &get_value_func)
88 if (!validate_value_func(node, socket)) {
93 get_value_func(node, socket));
101 const string &attr_name_prefix)
105 switch (socket.
type) {
107 const ustring value = node->get_string(socket);
111 if (!enum_values.
exists(value)) {
112 LOG(DFATAL) <<
"Node enum contains invalid value " << value;
116 image_spec->attribute(attr_name, value);
122 image_spec->attribute(attr_name, node->get_string(socket));
126 image_spec->attribute(attr_name, node->get_int(socket));
130 image_spec->attribute(attr_name, node->get_float(socket));
134 image_spec->attribute(attr_name, node->get_bool(socket));
138 LOG(DFATAL) <<
"Unhandled socket type " << socket.
type <<
", should never happen.";
145 const ImageSpec &image_spec,
146 const string &attr_name_prefix)
150 switch (socket.
type) {
153 const ustring value(image_spec.get_string_attribute(attr_name,
""));
157 if (!enum_values.
exists(value)) {
158 LOG(ERROR) <<
"Invalid enumerator value " << value;
162 node->set(socket, enum_values[value]);
169 node->set(socket, ustring(image_spec.get_string_attribute(attr_name,
"")));
173 node->set(socket, image_spec.get_int_attribute(attr_name, 0));
177 node->set(socket, image_spec.get_float_attribute(attr_name, 0));
181 node->set(socket,
static_cast<bool>(image_spec.get_int_attribute(attr_name, 0)));
185 LOG(DFATAL) <<
"Unhandled socket type " << socket.
type <<
", should never happen.";
192 const string &attr_name_prefix)
194 for (
const SocketType &socket : node->type->inputs) {
204 const ImageSpec &image_spec,
205 const string &attr_name_prefix)
207 for (
const SocketType &socket : node->type->inputs) {
225 const int num_passes = buffer_params.
passes.size();
228 for (
int pass_index = 0; pass_index < num_passes; ++pass_index) {
241 const ImageSpec &image_spec)
250 if (num_passes == 0) {
251 LOG(ERROR) <<
"Missing passes count attribute.";
255 for (
int pass_index = 0; pass_index < num_passes; ++pass_index) {
264 buffer_params->
passes.emplace_back(std::move(pass));
284 const int num_channels = channel_names.size();
286 *image_spec = ImageSpec(
287 buffer_params.
width, buffer_params.
height, num_channels, TypeDesc::FLOAT);
289 image_spec->channelnames = std::move(channel_names);
295 if (tile_size.x != 0 || tile_size.y != 0) {
317 const int tile_manager_id =
g_instance_index.fetch_add(1, std::memory_order_relaxed);
330 const int computed_tile_size = (suggested_tile_size <=
IMAGE_TILE_SIZE) ?
331 suggested_tile_size :
338 VLOG_WORK <<
"Using tile size of " << tile_size;
364 const DenoiseParams denoise_params = scene->integrator->get_denoise_params();
365 const AdaptiveSampling adaptive_sampling = scene->integrator->get_adaptive_sampling();
372 if (adaptive_sampling.
use && !scene->bake_manager->get_baking()) {
413 const int tile_index_y = index /
tile_state_.num_tiles_x;
414 const int tile_index_x = index - tile_index_y *
tile_state_.num_tiles_x;
416 const int tile_window_x = tile_index_x *
tile_size_.
x;
417 const int tile_window_y = tile_index_y *
tile_size_.
y;
454 LOG(ERROR) <<
"Error creating image output for " <<
write_state_.filename;
459 LOG(ERROR) <<
"Progress tile file format does not support tiling.";
464 LOG(ERROR) <<
"Error opening tile file: " <<
write_state_.tile_out->geterror();
486 LOG(ERROR) <<
"Error closing tile file.";
503 const double time_start =
time_dt();
513 const int64_t tile_row_stride = tile_params.
width * pass_stride;
516 const float *pixels = tile_buffers.
buffer.
data() + tile_params.
window_x * pass_stride +
517 tile_params.
window_y * tile_row_stride;
528 float *pixels_continuous = pixel_storage.data();
530 const int64_t pixels_row_stride = pass_stride * tile_params.
width;
534 memcpy(pixels_continuous, pixels,
sizeof(
float) * pixels_continuous_row_stride);
535 pixels += pixels_row_stride;
536 pixels_continuous += pixels_continuous_row_stride;
539 pixels = pixel_storage.data();
542 VLOG_WORK <<
"Write tile at " << tile_x <<
", " << tile_y;
568 LOG(ERROR) <<
"Error writing tile " <<
write_state_.tile_out->geterror();
596 const int tile_x =
tile.
x +
tile.window_x;
597 const int tile_y =
tile.
y +
tile.window_y;
599 VLOG_WORK <<
"Write dummy tile at " << tile_x <<
", " << tile_y;
602 tile_x +
tile.window_width,
604 tile_y +
tile.window_height,
608 pixel_storage.data());
633 unique_ptr<ImageInput> in(ImageInput::open(
filename));
635 LOG(ERROR) <<
"Error opening tile file " <<
filename;
651 const int num_channels = in->spec().nchannels;
652 if (!in->read_image(0, 0, 0, num_channels, TypeDesc::FLOAT,
buffers->buffer.data())) {
653 LOG(ERROR) <<
"Error reading pixels from the tile file " << in->geterror();
658 LOG(ERROR) <<
"Error closing tile file " << in->geterror();
vector< BufferPass > passes
device_vector< float > buffer
BufferParams buffer_params_
void set_temp_dir(const string &temp_dir)
function< void(string_view)> full_buffer_written_cb
struct TileManager::@1465 tile_state_
void reset_scheduling(const BufferParams ¶ms, int2 tile_size)
int compute_render_tile_size(const int suggested_tile_size) const
bool has_multiple_tiles() const
Tile get_tile_for_index(int index) const
void update(const BufferParams ¶ms, const Scene *scene)
const int2 get_size() const
const Tile & get_current_tile() const
bool write_tile(const RenderBuffers &tile_buffers)
struct TileManager::@1466 write_state_
bool read_full_buffer_from_disk(string_view filename, RenderBuffers *buffers, DenoiseParams *denoise_params)
static const int MAX_TILE_SIZE
string tile_file_unique_part_
void finish_write_tiles()
static const int IMAGE_TILE_SIZE
#define CCL_NAMESPACE_END
draw_view in_light_buf[] float
static const char * to_string(const Interpolation &interp)
ccl_global const KernelWorkTile * tile
size_t path_file_size(const string &path)
string path_join(const string &dir, const string &file)
static const char * ATTR_PASS_SOCKET_PREFIX_FORMAT
static bool node_socket_generic_to_image_spec_atttributes(ImageSpec *image_spec, const Node *node, const SocketType &socket, const string &attr_name_prefix, const ValidateValueFunc &validate_value_func, const GetValueFunc &get_value_func)
static const char * ATTR_BUFFER_SOCKET_PREFIX
static std::vector< std::string > exr_channel_names_for_passes(const BufferParams &buffer_params)
static bool buffer_params_to_image_spec_atttributes(ImageSpec *image_spec, const BufferParams &buffer_params)
static const char * ATTR_DENOISE_SOCKET_PREFIX
static CCL_NAMESPACE_BEGIN const char * ATTR_PASSES_COUNT
static std::atomic< uint64_t > g_instance_index
static bool node_socket_from_image_spec_atttributes(Node *node, const SocketType &socket, const ImageSpec &image_spec, const string &attr_name_prefix)
static bool node_from_image_spec_atttributes(Node *node, const ImageSpec &image_spec, const string &attr_name_prefix)
static bool node_to_image_spec_atttributes(ImageSpec *image_spec, const Node *node, const string &attr_name_prefix)
string node_socket_attribute_name(const SocketType &socket, const string &attr_name_prefix)
static bool buffer_params_from_image_spec_atttributes(BufferParams *buffer_params, const ImageSpec &image_spec)
static bool configure_image_spec_from_buffer(ImageSpec *image_spec, const BufferParams &buffer_params, const int2 tile_size=make_int2(0, 0))
static bool node_socket_to_image_spec_atttributes(ImageSpec *image_spec, const Node *node, const SocketType &socket, const string &attr_name_prefix)
_W64 unsigned int uintptr_t
string string_human_readable_number(size_t num)
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
bool exists(ustring x) const
const NodeEnum * enum_values
uint64_t system_self_process_id()
CCL_NAMESPACE_BEGIN double time_dt()
ccl_device_inline size_t align_up(size_t offset, size_t alignment)
ccl_device_inline size_t divide_up(size_t x, size_t y)