Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/render/tile.cpp
| Show First 20 Lines • Show All 357 Lines • ▼ Show 20 Lines | void TileManager::update(const BufferParams ¶ms, const Scene *scene) | ||||
| buffer_params_ = params; | buffer_params_ = params; | ||||
| /* TODO(sergey): Proper Error handling, so that if configuration has failed we don't attempt to | /* TODO(sergey): Proper Error handling, so that if configuration has failed we don't attempt to | ||||
| * write to a partially configured file. */ | * write to a partially configured file. */ | ||||
| configure_image_spec_from_buffer(&write_state_.image_spec, buffer_params_, tile_size_); | configure_image_spec_from_buffer(&write_state_.image_spec, buffer_params_, tile_size_); | ||||
| const DenoiseParams denoise_params = scene->integrator->get_denoise_params(); | const DenoiseParams denoise_params = scene->integrator->get_denoise_params(); | ||||
| const AdaptiveSampling adaptive_sampling = scene->integrator->get_adaptive_sampling(); | |||||
| node_to_image_spec_atttributes( | node_to_image_spec_atttributes( | ||||
| &write_state_.image_spec, &denoise_params, ATTR_DENOISE_SOCKET_PREFIX); | &write_state_.image_spec, &denoise_params, ATTR_DENOISE_SOCKET_PREFIX); | ||||
| if (denoise_params.use || adaptive_sampling.use) { | |||||
| overscan_ = 4; | |||||
brecht: I think this should be lower until there is really a need for it. I suggest using 4 instead. | |||||
| } | |||||
| else { | |||||
| overscan_ = 0; | |||||
| } | |||||
| } | } | ||||
| bool TileManager::done() | bool TileManager::done() | ||||
| { | { | ||||
| return tile_state_.next_tile_index == tile_state_.num_tiles; | return tile_state_.next_tile_index == tile_state_.num_tiles; | ||||
| } | } | ||||
| bool TileManager::next() | bool TileManager::next() | ||||
| Show All 9 Lines | bool TileManager::next() | ||||
| return true; | return true; | ||||
| } | } | ||||
| Tile TileManager::get_tile_for_index(int index) const | Tile TileManager::get_tile_for_index(int index) const | ||||
| { | { | ||||
| /* TODO(sergey): Consider using hilbert spiral, or. maybe, even configurable. Not sure this | /* TODO(sergey): Consider using hilbert spiral, or. maybe, even configurable. Not sure this | ||||
| * brings a lot of value since this is only applicable to BIG tiles. */ | * brings a lot of value since this is only applicable to BIG tiles. */ | ||||
| const int tile_y = index / tile_state_.num_tiles_x; | const int tile_index_y = index / tile_state_.num_tiles_x; | ||||
| const int tile_x = index - tile_y * tile_state_.num_tiles_x; | const int tile_index_x = index - tile_index_y * tile_state_.num_tiles_x; | ||||
| const int tile_x = tile_index_x * tile_size_.x; | |||||
| const int tile_y = tile_index_y * tile_size_.y; | |||||
| Tile tile; | Tile tile; | ||||
| tile.x = tile_x * tile_size_.x; | tile.x = tile_x - overscan_; | ||||
| tile.y = tile_y * tile_size_.y; | tile.y = tile_y - overscan_; | ||||
| tile.width = tile_size_.x; | tile.width = tile_size_.x + 2 * overscan_; | ||||
| tile.height = tile_size_.y; | tile.height = tile_size_.y + 2 * overscan_; | ||||
| tile.x = max(tile.x, 0); | |||||
| tile.y = max(tile.y, 0); | |||||
| tile.width = min(tile.width, buffer_params_.width - tile.x); | tile.width = min(tile.width, buffer_params_.width - tile.x); | ||||
| tile.height = min(tile.height, buffer_params_.height - tile.y); | tile.height = min(tile.height, buffer_params_.height - tile.y); | ||||
| tile.window_x = tile_x - tile.x; | |||||
| tile.window_y = tile_y - tile.y; | |||||
| tile.window_width = min(tile_size_.x, buffer_params_.width - (tile.x + tile.window_x)); | |||||
| tile.window_height = min(tile_size_.y, buffer_params_.height - (tile.y + tile.window_y)); | |||||
| return tile; | return tile; | ||||
| } | } | ||||
| const Tile &TileManager::get_current_tile() const | const Tile &TileManager::get_current_tile() const | ||||
| { | { | ||||
| return tile_state_.current_tile; | return tile_state_.current_tile; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | bool TileManager::write_tile(const RenderBuffers &tile_buffers) | ||||
| if (!write_state_.tile_out) { | if (!write_state_.tile_out) { | ||||
| if (!open_tile_output()) { | if (!open_tile_output()) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| DCHECK_EQ(tile_buffers.params.pass_stride, buffer_params_.pass_stride); | DCHECK_EQ(tile_buffers.params.pass_stride, buffer_params_.pass_stride); | ||||
| vector<float> pixel_storage; | |||||
| const BufferParams &tile_params = tile_buffers.params; | const BufferParams &tile_params = tile_buffers.params; | ||||
| vector<float> pixel_storage; | const int tile_x = tile_params.full_x - buffer_params_.full_x + tile_params.window_x; | ||||
| const float *pixels = tile_buffers.buffer.data(); | const int tile_y = tile_params.full_y - buffer_params_.full_y + tile_params.window_y; | ||||
| /* Tiled writing expects pixels to contain data for an entire tile. Pad the render buffers with | |||||
| * empty pixels for tiles which are on the image boundary. */ | |||||
| if (tile_params.width != tile_size_.x || tile_params.height != tile_size_.y) { | |||||
| const int64_t pass_stride = tile_params.pass_stride; | const int64_t pass_stride = tile_params.pass_stride; | ||||
| const int64_t src_row_stride = tile_params.width * pass_stride; | const int64_t tile_row_stride = tile_params.width * pass_stride; | ||||
| const float *pixels = tile_buffers.buffer.data() + tile_params.window_x * pass_stride + | |||||
| tile_params.window_y * tile_row_stride; | |||||
| int3 pixels_stride_in_bytes; | |||||
| pixels_stride_in_bytes.x = pass_stride * sizeof(float); | |||||
| pixels_stride_in_bytes.y = pixels_stride_in_bytes.x * tile_params.width; | |||||
| pixels_stride_in_bytes.z = pixels_stride_in_bytes.y * tile_params.height; | |||||
| /* Tiled writing expects pixels to contain data for an entire tile. Pad the render buffers with | |||||
| * empty pixels for tiles which are on the image boundary. */ | |||||
| if (tile_params.window_width != tile_size_.x || tile_params.window_height != tile_size_.y) { | |||||
| const int64_t dst_row_stride = tile_size_.x * pass_stride; | const int64_t dst_row_stride = tile_size_.x * pass_stride; | ||||
| pixel_storage.resize(dst_row_stride * tile_size_.y); | pixel_storage.resize(dst_row_stride * tile_size_.y); | ||||
| const float *src = tile_buffers.buffer.data(); | const float *src = pixels; | ||||
| float *dst = pixel_storage.data(); | float *dst = pixel_storage.data(); | ||||
| pixels = dst; | pixels = dst; | ||||
| for (int y = 0; y < tile_params.height; ++y, src += src_row_stride, dst += dst_row_stride) { | for (int y = 0; y < tile_params.window_height; | ||||
| memcpy(dst, src, src_row_stride * sizeof(float)); | ++y, src += tile_row_stride, dst += dst_row_stride) { | ||||
| } | memcpy(dst, src, dst_row_stride * sizeof(float)); | ||||
| } | } | ||||
| const int tile_x = tile_params.full_x - buffer_params_.full_x; | pixels_stride_in_bytes.y = pixels_stride_in_bytes.x * tile_size_.x; | ||||
| const int tile_y = tile_params.full_y - buffer_params_.full_y; | pixels_stride_in_bytes.z = pixels_stride_in_bytes.y * tile_size_.y; | ||||
| } | |||||
| VLOG(3) << "Write tile at " << tile_x << ", " << tile_y; | VLOG(3) << "Write tile at " << tile_x << ", " << tile_y; | ||||
| if (!write_state_.tile_out->write_tile(tile_x, tile_y, 0, TypeDesc::FLOAT, pixels)) { | if (!write_state_.tile_out->write_tile(tile_x, | ||||
| tile_y, | |||||
| 0, | |||||
| TypeDesc::FLOAT, | |||||
| pixels, | |||||
| pixels_stride_in_bytes.x, | |||||
| pixels_stride_in_bytes.y, | |||||
| pixels_stride_in_bytes.z)) { | |||||
| LOG(ERROR) << "Error writing tile " << write_state_.tile_out->geterror(); | LOG(ERROR) << "Error writing tile " << write_state_.tile_out->geterror(); | ||||
| } | } | ||||
| ++write_state_.num_tiles_written; | ++write_state_.num_tiles_written; | ||||
| return true; | return true; | ||||
| } | } | ||||
| void TileManager::finish_write_tiles() | void TileManager::finish_write_tiles() | ||||
| { | { | ||||
| if (!write_state_.tile_out) { | if (!write_state_.tile_out) { | ||||
| /* None of the tiles were written hence the file was not created. | /* None of the tiles were written hence the file was not created. | ||||
| * Avoid creation of fully empty file since it is redundant. */ | * Avoid creation of fully empty file since it is redundant. */ | ||||
| return; | return; | ||||
| } | } | ||||
| /* EXR expects all tiles to present in file. So explicitly write missing tiles as all-zero. */ | /* EXR expects all tiles to present in file. So explicitly write missing tiles as all-zero. */ | ||||
| if (write_state_.num_tiles_written < tile_state_.num_tiles) { | if (write_state_.num_tiles_written < tile_state_.num_tiles) { | ||||
| vector<float> pixel_storage(tile_size_.x * tile_size_.y * buffer_params_.pass_stride); | vector<float> pixel_storage(tile_size_.x * tile_size_.y * buffer_params_.pass_stride); | ||||
| for (int tile_index = write_state_.num_tiles_written; tile_index < tile_state_.num_tiles; | for (int tile_index = write_state_.num_tiles_written; tile_index < tile_state_.num_tiles; | ||||
| ++tile_index) { | ++tile_index) { | ||||
| const Tile tile = get_tile_for_index(tile_index); | const Tile tile = get_tile_for_index(tile_index); | ||||
| VLOG(3) << "Write dummy tile at " << tile.x << ", " << tile.y; | const int tile_x = tile.x + tile.window_x; | ||||
| const int tile_y = tile.y + tile.window_y; | |||||
| VLOG(3) << "Write dummy tile at " << tile_x << ", " << tile_y; | |||||
| write_state_.tile_out->write_tile(tile.x, tile.y, 0, TypeDesc::FLOAT, pixel_storage.data()); | write_state_.tile_out->write_tile(tile_x, tile_y, 0, TypeDesc::FLOAT, pixel_storage.data()); | ||||
| } | } | ||||
| } | } | ||||
| close_tile_output(); | close_tile_output(); | ||||
| if (full_buffer_written_cb) { | if (full_buffer_written_cb) { | ||||
| full_buffer_written_cb(write_state_.filename); | full_buffer_written_cb(write_state_.filename); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 45 Lines • Show Last 20 Lines | |||||
I think this should be lower until there is really a need for it. I suggest using 4 instead.