Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/render/tile.cpp
| Show First 20 Lines • Show All 366 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 (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; | ||||
| const float *pixels = tile_buffers.buffer.data(); | const int tile_x = tile_params.full_x - buffer_params_.full_x + tile_params.window_x; | ||||
| const int tile_x = tile_params.full_x - buffer_params_.full_x; | const int tile_y = tile_params.full_y - buffer_params_.full_y + tile_params.window_y; | ||||
| const int tile_y = tile_params.full_y - buffer_params_.full_y; | |||||
| const int64_t pass_stride = tile_params.pass_stride; | |||||
| const int64_t tile_row_stride = tile_params.width * pass_stride; | |||||
| const int64_t xstride = pass_stride * sizeof(float); | |||||
| const int64_t ystride = xstride * tile_params.width; | |||||
| const int64_t zstride = ystride * tile_params.height; | |||||
| const float *pixels = tile_buffers.buffer.data() + tile_params.window_x * pass_stride + | |||||
| tile_params.window_y * tile_row_stride; | |||||
| VLOG(3) << "Write tile at " << tile_x << ", " << tile_y; | VLOG(3) << "Write tile at " << tile_x << ", " << tile_y; | ||||
| /* The image tile sizes in the OpenEXR file are different from the size of our big tiles. The | /* The image tile sizes in the OpenEXR file are different from the size of our big tiles. The | ||||
| * write_tiles() method expects a contiguous image region that will be split into tiles | * write_tiles() method expects a contiguous image region that will be split into tiles | ||||
| * internally. OpenEXR expects the size of this region to be a multiple of the tile size, | * internally. OpenEXR expects the size of this region to be a multiple of the tile size, | ||||
| * however OpenImageIO automatically adds the required padding. | * however OpenImageIO automatically adds the required padding. | ||||
| * | * | ||||
| * The only thing we have to ensure is that the tile_x and tile_y are a multiple of the | * The only thing we have to ensure is that the tile_x and tile_y are a multiple of the | ||||
| * image tile size, which happens in compute_render_tile_size. */ | * image tile size, which happens in compute_render_tile_size. */ | ||||
| if (!write_state_.tile_out->write_tiles(tile_x, | if (!write_state_.tile_out->write_tiles(tile_x, | ||||
| tile_x + tile_params.width, | tile_x + tile_params.window_width, | ||||
| tile_y, | tile_y, | ||||
| tile_y + tile_params.height, | tile_y + tile_params.window_height, | ||||
| 0, | 0, | ||||
| 1, | 1, | ||||
| TypeDesc::FLOAT, | TypeDesc::FLOAT, | ||||
| pixels)) { | pixels, | ||||
| xstride, | |||||
| ystride, | |||||
| zstride)) { | |||||
| 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_tiles(tile.x, | write_state_.tile_out->write_tiles(tile_x, | ||||
| tile.x + tile.width, | tile_x + tile.window_width, | ||||
| tile.y, | tile_y, | ||||
| tile.y + tile.height, | tile_y + tile.window_height, | ||||
| 0, | 0, | ||||
| 1, | 1, | ||||
| TypeDesc::FLOAT, | TypeDesc::FLOAT, | ||||
| pixel_storage.data()); | pixel_storage.data()); | ||||
| } | } | ||||
| } | } | ||||
| close_tile_output(); | close_tile_output(); | ||||
| ▲ Show 20 Lines • Show All 49 Lines • Show Last 20 Lines | |||||
I think this should be lower until there is really a need for it. I suggest using 4 instead.