Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/session/tile.cpp
| Show First 20 Lines • Show All 499 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 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 + tile_params.window_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 + tile_params.window_y; | ||||
| const int tile_x_end = tile_x + tile_params.window_width; | |||||
| const int tile_y_end = tile_y + tile_params.window_height; | |||||
| const int64_t pass_stride = tile_params.pass_stride; | const int64_t pass_stride = tile_params.pass_stride; | ||||
| const int64_t tile_row_stride = tile_params.width * pass_stride; | const int64_t tile_row_stride = tile_params.width * pass_stride; | ||||
| const int64_t xstride = pass_stride * sizeof(float); | const int64_t stride_x = pass_stride; | ||||
| const int64_t ystride = xstride * tile_params.width; | const int64_t stride_y = stride_x * tile_params.width; | ||||
| const int64_t zstride = ystride * tile_params.height; | const int64_t stride_z = stride_y * tile_params.height; | ||||
| const int64_t stride_x_in_bytes = stride_x * sizeof(float); | |||||
| const int64_t stride_y_in_bytes = stride_y * sizeof(float); | |||||
| const int64_t stride_z_in_bytes = stride_z * sizeof(float); | |||||
| const float *pixels = tile_buffers.buffer.data() + tile_params.window_x * pass_stride + | const float *pixels = tile_buffers.buffer.data() + tile_params.window_x * pass_stride + | ||||
| tile_params.window_y * tile_row_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. | ||||
| * write_tiles() method expects a contiguous image region that will be split into tiles | * Don't rely on automatic tile mapping happening in the OIIO/OpenEXR since under certain | ||||
| * internally. OpenEXR expects the size of this region to be a multiple of the tile size, | * conditions this could lead to an unwanted memory peaks. Forcing small tiles passed to | ||||
| * however OpenImageIO automatically adds the required padding. | * `write_tiles` solves those peaks. | ||||
| * | * See T93008 for the .blend file demonstrating the issue. */ | ||||
| * 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. */ | const int num_x_tiles = divide_up(tile_params.window_width, IMAGE_TILE_SIZE); | ||||
| if (!write_state_.tile_out->write_tiles(tile_x, | const int num_y_tiles = divide_up(tile_params.window_height, IMAGE_TILE_SIZE); | ||||
| tile_x + tile_params.window_width, | |||||
| tile_y, | for (int y = 0; y < num_y_tiles; ++y) { | ||||
| tile_y + tile_params.window_height, | const float *small_tile_pixels = pixels + y * stride_y * IMAGE_TILE_SIZE; | ||||
| const int small_tile_y = tile_y + y * IMAGE_TILE_SIZE; | |||||
| const int small_tile_height = min(IMAGE_TILE_SIZE, tile_y_end - small_tile_y); | |||||
| for (int x = 0; x < num_x_tiles; ++x, small_tile_pixels += IMAGE_TILE_SIZE * pass_stride) { | |||||
| const int small_tile_x = tile_x + x * IMAGE_TILE_SIZE; | |||||
| const int small_tile_width = min(IMAGE_TILE_SIZE, tile_x_end - small_tile_x); | |||||
| if (!write_state_.tile_out->write_tiles(small_tile_x, | |||||
| small_tile_x + small_tile_width, | |||||
| small_tile_y, | |||||
| small_tile_y + small_tile_height, | |||||
| 0, | 0, | ||||
| 1, | 1, | ||||
| TypeDesc::FLOAT, | TypeDesc::FLOAT, | ||||
| pixels, | small_tile_pixels, | ||||
| xstride, | stride_x_in_bytes, | ||||
| ystride, | stride_y_in_bytes, | ||||
| zstride)) { | stride_z_in_bytes)) { | ||||
| LOG(ERROR) << "Error writing tile " << write_state_.tile_out->geterror(); | LOG(ERROR) << "Error writing tile " << write_state_.tile_out->geterror(); | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | |||||
| } | |||||
| ++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(IMAGE_TILE_SIZE * IMAGE_TILE_SIZE * 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); | ||||
| const int tile_x = tile.x + tile.window_x; | const int tile_x = tile.x + tile.window_x; | ||||
| const int tile_y = tile.y + tile.window_y; | const int tile_y = tile.y + tile.window_y; | ||||
| const int tile_x_end = tile_x + tile.window_width; | |||||
| const int tile_y_end = tile_y + tile.window_height; | |||||
| VLOG(3) << "Write dummy tile at " << tile_x << ", " << tile_y; | VLOG(3) << "Write dummy tile at " << tile_x << ", " << tile_y; | ||||
| write_state_.tile_out->write_tiles(tile_x, | const int num_x_tiles = divide_up(tile.window_width, IMAGE_TILE_SIZE); | ||||
| tile_x + tile.window_width, | const int num_y_tiles = divide_up(tile.window_height, IMAGE_TILE_SIZE); | ||||
| tile_y, | |||||
| tile_y + tile.window_height, | for (int y = 0; y < num_y_tiles; ++y) { | ||||
| const int small_tile_y = tile_y + y * IMAGE_TILE_SIZE; | |||||
| const int small_tile_height = min(IMAGE_TILE_SIZE, tile_y_end - small_tile_y); | |||||
| for (int x = 0; x < num_x_tiles; ++x) { | |||||
| const int small_tile_x = tile_x + x * IMAGE_TILE_SIZE; | |||||
| const int small_tile_width = min(IMAGE_TILE_SIZE, tile_x_end - small_tile_x); | |||||
| if (!write_state_.tile_out->write_tiles(small_tile_x, | |||||
| small_tile_x + small_tile_width, | |||||
| small_tile_y, | |||||
| small_tile_y + small_tile_height, | |||||
| 0, | 0, | ||||
| 1, | 1, | ||||
| TypeDesc::FLOAT, | TypeDesc::FLOAT, | ||||
| pixel_storage.data()); | pixel_storage.data())) { | ||||
| LOG(ERROR) << "Error writing tile " << write_state_.tile_out->geterror(); | |||||
| return; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| 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 | |||||