tile.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  1. /*
  2. * Copyright 2011-2013 Blender Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "render/tile.h"
  17. #include "util/util_algorithm.h"
  18. #include "util/util_foreach.h"
  19. #include "util/util_types.h"
  20. CCL_NAMESPACE_BEGIN
  21. namespace {
  22. class TileComparator {
  23. public:
  24. TileComparator(TileOrder order_, int2 center_, Tile *tiles_)
  25. : order(order_), center(center_), tiles(tiles_)
  26. {
  27. }
  28. bool operator()(int a, int b)
  29. {
  30. switch (order) {
  31. case TILE_CENTER: {
  32. float2 dist_a = make_float2(center.x - (tiles[a].x + tiles[a].w / 2),
  33. center.y - (tiles[a].y + tiles[a].h / 2));
  34. float2 dist_b = make_float2(center.x - (tiles[b].x + tiles[b].w / 2),
  35. center.y - (tiles[b].y + tiles[b].h / 2));
  36. return dot(dist_a, dist_a) < dot(dist_b, dist_b);
  37. }
  38. case TILE_LEFT_TO_RIGHT:
  39. return (tiles[a].x == tiles[b].x) ? (tiles[a].y < tiles[b].y) : (tiles[a].x < tiles[b].x);
  40. case TILE_RIGHT_TO_LEFT:
  41. return (tiles[a].x == tiles[b].x) ? (tiles[a].y < tiles[b].y) : (tiles[a].x > tiles[b].x);
  42. case TILE_TOP_TO_BOTTOM:
  43. return (tiles[a].y == tiles[b].y) ? (tiles[a].x < tiles[b].x) : (tiles[a].y > tiles[b].y);
  44. case TILE_BOTTOM_TO_TOP:
  45. default:
  46. return (tiles[a].y == tiles[b].y) ? (tiles[a].x < tiles[b].x) : (tiles[a].y < tiles[b].y);
  47. }
  48. }
  49. protected:
  50. TileOrder order;
  51. int2 center;
  52. Tile *tiles;
  53. };
  54. inline int2 hilbert_index_to_pos(int n, int d)
  55. {
  56. int2 r, xy = make_int2(0, 0);
  57. for (int s = 1; s < n; s *= 2) {
  58. r.x = (d >> 1) & 1;
  59. r.y = (d ^ r.x) & 1;
  60. if (!r.y) {
  61. if (r.x) {
  62. xy = make_int2(s - 1, s - 1) - xy;
  63. }
  64. swap(xy.x, xy.y);
  65. }
  66. xy += r * make_int2(s, s);
  67. d >>= 2;
  68. }
  69. return xy;
  70. }
  71. enum SpiralDirection {
  72. DIRECTION_UP,
  73. DIRECTION_LEFT,
  74. DIRECTION_DOWN,
  75. DIRECTION_RIGHT,
  76. };
  77. } /* namespace */
  78. TileManager::TileManager(bool progressive_,
  79. int num_samples_,
  80. int2 tile_size_,
  81. int start_resolution_,
  82. bool preserve_tile_device_,
  83. bool background_,
  84. TileOrder tile_order_,
  85. int num_devices_,
  86. int pixel_size_)
  87. {
  88. progressive = progressive_;
  89. tile_size = tile_size_;
  90. tile_order = tile_order_;
  91. start_resolution = start_resolution_;
  92. pixel_size = pixel_size_;
  93. num_samples = num_samples_;
  94. num_devices = num_devices_;
  95. preserve_tile_device = preserve_tile_device_;
  96. background = background_;
  97. schedule_denoising = false;
  98. range_start_sample = 0;
  99. range_num_samples = -1;
  100. BufferParams buffer_params;
  101. reset(buffer_params, 0);
  102. }
  103. TileManager::~TileManager()
  104. {
  105. }
  106. void TileManager::device_free()
  107. {
  108. if (schedule_denoising || progressive) {
  109. for (int i = 0; i < state.tiles.size(); i++) {
  110. delete state.tiles[i].buffers;
  111. state.tiles[i].buffers = NULL;
  112. }
  113. }
  114. state.tiles.clear();
  115. }
  116. static int get_divider(int w, int h, int start_resolution)
  117. {
  118. int divider = 1;
  119. if (start_resolution != INT_MAX) {
  120. while (w * h > start_resolution * start_resolution) {
  121. w = max(1, w / 2);
  122. h = max(1, h / 2);
  123. divider <<= 1;
  124. }
  125. }
  126. return divider;
  127. }
  128. void TileManager::reset(BufferParams &params_, int num_samples_)
  129. {
  130. params = params_;
  131. set_samples(num_samples_);
  132. state.buffer = BufferParams();
  133. state.sample = range_start_sample - 1;
  134. state.num_tiles = 0;
  135. state.num_samples = 0;
  136. state.resolution_divider = get_divider(params.width, params.height, start_resolution);
  137. state.render_tiles.clear();
  138. state.denoising_tiles.clear();
  139. device_free();
  140. }
  141. void TileManager::set_samples(int num_samples_)
  142. {
  143. num_samples = num_samples_;
  144. /* No real progress indication is possible when using unlimited samples. */
  145. if (num_samples == INT_MAX) {
  146. state.total_pixel_samples = 0;
  147. }
  148. else {
  149. uint64_t pixel_samples = 0;
  150. /* While rendering in the viewport, the initial preview resolution is increased to the native
  151. * resolution before the actual rendering begins. Therefore, additional pixel samples will be
  152. * rendered. */
  153. int divider = max(get_divider(params.width, params.height, start_resolution) / 2, pixel_size);
  154. while (divider > pixel_size) {
  155. int image_w = max(1, params.width / divider);
  156. int image_h = max(1, params.height / divider);
  157. pixel_samples += image_w * image_h;
  158. divider >>= 1;
  159. }
  160. int image_w = max(1, params.width / divider);
  161. int image_h = max(1, params.height / divider);
  162. state.total_pixel_samples = pixel_samples +
  163. (uint64_t)get_num_effective_samples() * image_w * image_h;
  164. if (schedule_denoising) {
  165. state.total_pixel_samples += params.width * params.height;
  166. }
  167. }
  168. }
  169. /* If sliced is false, splits image into tiles and assigns equal amount of tiles to every render
  170. * device. If sliced is true, slice image into as much pieces as how many devices are rendering
  171. * this image. */
  172. int TileManager::gen_tiles(bool sliced)
  173. {
  174. int resolution = state.resolution_divider;
  175. int image_w = max(1, params.width / resolution);
  176. int image_h = max(1, params.height / resolution);
  177. int2 center = make_int2(image_w / 2, image_h / 2);
  178. int num_logical_devices = preserve_tile_device ? num_devices : 1;
  179. int num = min(image_h, num_logical_devices);
  180. int slice_num = sliced ? num : 1;
  181. int tile_w = (tile_size.x >= image_w) ? 1 : divide_up(image_w, tile_size.x);
  182. device_free();
  183. state.render_tiles.clear();
  184. state.denoising_tiles.clear();
  185. state.render_tiles.resize(num);
  186. state.denoising_tiles.resize(num);
  187. state.tile_stride = tile_w;
  188. vector<list<int>>::iterator tile_list;
  189. tile_list = state.render_tiles.begin();
  190. if (tile_order == TILE_HILBERT_SPIRAL) {
  191. assert(!sliced);
  192. int tile_h = (tile_size.y >= image_h) ? 1 : divide_up(image_h, tile_size.y);
  193. state.tiles.resize(tile_w * tile_h);
  194. /* Size of blocks in tiles, must be a power of 2 */
  195. const int hilbert_size = (max(tile_size.x, tile_size.y) <= 12) ? 8 : 4;
  196. int tiles_per_device = divide_up(tile_w * tile_h, num);
  197. int cur_device = 0, cur_tiles = 0;
  198. int2 block_size = tile_size * make_int2(hilbert_size, hilbert_size);
  199. /* Number of blocks to fill the image */
  200. int blocks_x = (block_size.x >= image_w) ? 1 : divide_up(image_w, block_size.x);
  201. int blocks_y = (block_size.y >= image_h) ? 1 : divide_up(image_h, block_size.y);
  202. int n = max(blocks_x, blocks_y) | 0x1; /* Side length of the spiral (must be odd) */
  203. /* Offset of spiral (to keep it centered) */
  204. int2 offset = make_int2((image_w - n * block_size.x) / 2, (image_h - n * block_size.y) / 2);
  205. offset = (offset / tile_size) * tile_size; /* Round to tile border. */
  206. int2 block = make_int2(0, 0); /* Current block */
  207. SpiralDirection prev_dir = DIRECTION_UP, dir = DIRECTION_UP;
  208. for (int i = 0;;) {
  209. /* Generate the tiles in the current block. */
  210. for (int hilbert_index = 0; hilbert_index < hilbert_size * hilbert_size; hilbert_index++) {
  211. int2 tile, hilbert_pos = hilbert_index_to_pos(hilbert_size, hilbert_index);
  212. /* Rotate block according to spiral direction. */
  213. if (prev_dir == DIRECTION_UP && dir == DIRECTION_UP) {
  214. tile = make_int2(hilbert_pos.y, hilbert_pos.x);
  215. }
  216. else if (dir == DIRECTION_LEFT || prev_dir == DIRECTION_LEFT) {
  217. tile = hilbert_pos;
  218. }
  219. else if (dir == DIRECTION_DOWN) {
  220. tile = make_int2(hilbert_size - 1 - hilbert_pos.y, hilbert_size - 1 - hilbert_pos.x);
  221. }
  222. else {
  223. tile = make_int2(hilbert_size - 1 - hilbert_pos.x, hilbert_size - 1 - hilbert_pos.y);
  224. }
  225. int2 pos = block * block_size + tile * tile_size + offset;
  226. /* Only add tiles which are in the image (tiles outside of the image can be generated since
  227. * the spiral is always square). */
  228. if (pos.x >= 0 && pos.y >= 0 && pos.x < image_w && pos.y < image_h) {
  229. int w = min(tile_size.x, image_w - pos.x);
  230. int h = min(tile_size.y, image_h - pos.y);
  231. int2 ipos = pos / tile_size;
  232. int idx = ipos.y * tile_w + ipos.x;
  233. state.tiles[idx] = Tile(idx, pos.x, pos.y, w, h, cur_device, Tile::RENDER);
  234. tile_list->push_front(idx);
  235. cur_tiles++;
  236. if (cur_tiles == tiles_per_device) {
  237. tile_list++;
  238. cur_tiles = 0;
  239. cur_device++;
  240. }
  241. }
  242. }
  243. /* Stop as soon as the spiral has reached the center block. */
  244. if (block.x == (n - 1) / 2 && block.y == (n - 1) / 2)
  245. break;
  246. /* Advance to next block. */
  247. prev_dir = dir;
  248. switch (dir) {
  249. case DIRECTION_UP:
  250. block.y++;
  251. if (block.y == (n - i - 1)) {
  252. dir = DIRECTION_LEFT;
  253. }
  254. break;
  255. case DIRECTION_LEFT:
  256. block.x++;
  257. if (block.x == (n - i - 1)) {
  258. dir = DIRECTION_DOWN;
  259. }
  260. break;
  261. case DIRECTION_DOWN:
  262. block.y--;
  263. if (block.y == i) {
  264. dir = DIRECTION_RIGHT;
  265. }
  266. break;
  267. case DIRECTION_RIGHT:
  268. block.x--;
  269. if (block.x == i + 1) {
  270. dir = DIRECTION_UP;
  271. i++;
  272. }
  273. break;
  274. }
  275. }
  276. return tile_w * tile_h;
  277. }
  278. int idx = 0;
  279. for (int slice = 0; slice < slice_num; slice++) {
  280. int slice_y = (image_h / slice_num) * slice;
  281. int slice_h = (slice == slice_num - 1) ? image_h - slice * (image_h / slice_num) :
  282. image_h / slice_num;
  283. int tile_h = (tile_size.y >= slice_h) ? 1 : divide_up(slice_h, tile_size.y);
  284. int tiles_per_device = divide_up(tile_w * tile_h, num);
  285. int cur_device = 0, cur_tiles = 0;
  286. for (int tile_y = 0; tile_y < tile_h; tile_y++) {
  287. for (int tile_x = 0; tile_x < tile_w; tile_x++, idx++) {
  288. int x = tile_x * tile_size.x;
  289. int y = tile_y * tile_size.y;
  290. int w = (tile_x == tile_w - 1) ? image_w - x : tile_size.x;
  291. int h = (tile_y == tile_h - 1) ? slice_h - y : tile_size.y;
  292. state.tiles.push_back(
  293. Tile(idx, x, y + slice_y, w, h, sliced ? slice : cur_device, Tile::RENDER));
  294. tile_list->push_back(idx);
  295. if (!sliced) {
  296. cur_tiles++;
  297. if (cur_tiles == tiles_per_device) {
  298. /* Tiles are already generated in Bottom-to-Top order, so no sort is necessary in that
  299. * case. */
  300. if (tile_order != TILE_BOTTOM_TO_TOP) {
  301. tile_list->sort(TileComparator(tile_order, center, &state.tiles[0]));
  302. }
  303. tile_list++;
  304. cur_tiles = 0;
  305. cur_device++;
  306. }
  307. }
  308. }
  309. }
  310. if (sliced) {
  311. tile_list++;
  312. }
  313. }
  314. return idx;
  315. }
  316. void TileManager::gen_render_tiles()
  317. {
  318. /* Regenerate just the render tiles for progressive render. */
  319. foreach (Tile &tile, state.tiles) {
  320. state.render_tiles[tile.device].push_back(tile.index);
  321. }
  322. }
  323. void TileManager::set_tiles()
  324. {
  325. int resolution = state.resolution_divider;
  326. int image_w = max(1, params.width / resolution);
  327. int image_h = max(1, params.height / resolution);
  328. state.num_tiles = gen_tiles(!background);
  329. state.buffer.width = image_w;
  330. state.buffer.height = image_h;
  331. state.buffer.full_x = params.full_x / resolution;
  332. state.buffer.full_y = params.full_y / resolution;
  333. state.buffer.full_width = max(1, params.full_width / resolution);
  334. state.buffer.full_height = max(1, params.full_height / resolution);
  335. }
  336. int TileManager::get_neighbor_index(int index, int neighbor)
  337. {
  338. static const int dx[] = {-1, 0, 1, -1, 1, -1, 0, 1, 0}, dy[] = {-1, -1, -1, 0, 0, 1, 1, 1, 0};
  339. int resolution = state.resolution_divider;
  340. int image_w = max(1, params.width / resolution);
  341. int image_h = max(1, params.height / resolution);
  342. int tile_w = (tile_size.x >= image_w) ? 1 : divide_up(image_w, tile_size.x);
  343. int tile_h = (tile_size.y >= image_h) ? 1 : divide_up(image_h, tile_size.y);
  344. int nx = state.tiles[index].x / tile_size.x + dx[neighbor],
  345. ny = state.tiles[index].y / tile_size.y + dy[neighbor];
  346. if (nx < 0 || ny < 0 || nx >= tile_w || ny >= tile_h)
  347. return -1;
  348. return ny * state.tile_stride + nx;
  349. }
  350. /* Checks whether all neighbors of a tile (as well as the tile itself) are at least at state
  351. * min_state. */
  352. bool TileManager::check_neighbor_state(int index, Tile::State min_state)
  353. {
  354. if (index < 0 || state.tiles[index].state < min_state) {
  355. return false;
  356. }
  357. for (int neighbor = 0; neighbor < 9; neighbor++) {
  358. int nindex = get_neighbor_index(index, neighbor);
  359. /* Out-of-bounds tiles don't matter. */
  360. if (nindex >= 0 && state.tiles[nindex].state < min_state) {
  361. return false;
  362. }
  363. }
  364. return true;
  365. }
  366. /* Returns whether the tile should be written (and freed if no denoising is used) instead of
  367. * updating. */
  368. bool TileManager::finish_tile(int index, bool &delete_tile)
  369. {
  370. delete_tile = false;
  371. if (progressive) {
  372. return true;
  373. }
  374. switch (state.tiles[index].state) {
  375. case Tile::RENDER: {
  376. if (!schedule_denoising) {
  377. state.tiles[index].state = Tile::DONE;
  378. delete_tile = true;
  379. return true;
  380. }
  381. state.tiles[index].state = Tile::RENDERED;
  382. /* For each neighbor and the tile itself, check whether all of its neighbors have been
  383. * rendered. If yes, it can be denoised. */
  384. for (int neighbor = 0; neighbor < 9; neighbor++) {
  385. int nindex = get_neighbor_index(index, neighbor);
  386. if (check_neighbor_state(nindex, Tile::RENDERED)) {
  387. state.tiles[nindex].state = Tile::DENOISE;
  388. state.denoising_tiles[state.tiles[nindex].device].push_back(nindex);
  389. }
  390. }
  391. return false;
  392. }
  393. case Tile::DENOISE: {
  394. state.tiles[index].state = Tile::DENOISED;
  395. /* For each neighbor and the tile itself, check whether all of its neighbors have been
  396. * denoised. If yes, it can be freed. */
  397. for (int neighbor = 0; neighbor < 9; neighbor++) {
  398. int nindex = get_neighbor_index(index, neighbor);
  399. if (check_neighbor_state(nindex, Tile::DENOISED)) {
  400. state.tiles[nindex].state = Tile::DONE;
  401. /* It can happen that the tile just finished denoising and already can be freed here.
  402. * However, in that case it still has to be written before deleting, so we can't delete
  403. * it yet. */
  404. if (neighbor == 8) {
  405. delete_tile = true;
  406. }
  407. else {
  408. delete state.tiles[nindex].buffers;
  409. state.tiles[nindex].buffers = NULL;
  410. }
  411. }
  412. }
  413. return true;
  414. }
  415. default:
  416. assert(false);
  417. return true;
  418. }
  419. }
  420. bool TileManager::next_tile(Tile *&tile, int device)
  421. {
  422. int logical_device = preserve_tile_device ? device : 0;
  423. if (logical_device >= state.render_tiles.size())
  424. return false;
  425. if (!state.denoising_tiles[logical_device].empty()) {
  426. int idx = state.denoising_tiles[logical_device].front();
  427. state.denoising_tiles[logical_device].pop_front();
  428. tile = &state.tiles[idx];
  429. return true;
  430. }
  431. if (state.render_tiles[logical_device].empty())
  432. return false;
  433. int idx = state.render_tiles[logical_device].front();
  434. state.render_tiles[logical_device].pop_front();
  435. tile = &state.tiles[idx];
  436. return true;
  437. }
  438. bool TileManager::done()
  439. {
  440. int end_sample = (range_num_samples == -1) ? num_samples :
  441. range_start_sample + range_num_samples;
  442. return (state.resolution_divider == pixel_size) &&
  443. (state.sample + state.num_samples >= end_sample);
  444. }
  445. bool TileManager::next()
  446. {
  447. if (done())
  448. return false;
  449. if (progressive && state.resolution_divider > pixel_size) {
  450. state.sample = 0;
  451. state.resolution_divider = max(state.resolution_divider / 2, pixel_size);
  452. state.num_samples = 1;
  453. set_tiles();
  454. }
  455. else {
  456. state.sample++;
  457. if (progressive)
  458. state.num_samples = 1;
  459. else if (range_num_samples == -1)
  460. state.num_samples = num_samples;
  461. else
  462. state.num_samples = range_num_samples;
  463. state.resolution_divider = pixel_size;
  464. if (state.sample == range_start_sample) {
  465. set_tiles();
  466. }
  467. else {
  468. gen_render_tiles();
  469. }
  470. }
  471. return true;
  472. }
  473. int TileManager::get_num_effective_samples()
  474. {
  475. return (range_num_samples == -1) ? num_samples : range_num_samples;
  476. }
  477. CCL_NAMESPACE_END