Blender  V2.93
session.cpp
Go to the documentation of this file.
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 
17 #include <limits.h>
18 #include <string.h>
19 
20 #include "device/device.h"
21 #include "render/bake.h"
22 #include "render/buffers.h"
23 #include "render/camera.h"
24 #include "render/graph.h"
25 #include "render/integrator.h"
26 #include "render/light.h"
27 #include "render/mesh.h"
28 #include "render/object.h"
29 #include "render/scene.h"
30 #include "render/session.h"
31 
32 #include "util/util_foreach.h"
33 #include "util/util_function.h"
34 #include "util/util_logging.h"
35 #include "util/util_math.h"
36 #include "util/util_opengl.h"
37 #include "util/util_task.h"
38 #include "util/util_time.h"
39 
41 
42 /* Note about preserve_tile_device option for tile manager:
43  * progressive refine and viewport rendering does requires tiles to
44  * always be allocated for the same device
45  */
47  : params(params_),
48  tile_manager(params.progressive,
49  params.samples,
50  params.tile_size,
51  params.start_resolution,
52  params.background == false || params.progressive_refine,
53  params.background,
54  params.tile_order,
55  max(params.device.multi_devices.size(), 1),
56  params.pixel_size),
57  stats(),
58  profiler()
59 {
61 
63 
65  scene = NULL;
66 
67  reset_time = 0.0;
68  last_update_time = 0.0;
69 
70  delayed_reset.do_reset = false;
72 
73  display_outdated = false;
74  gpu_draw_ready = false;
76  pause = false;
77 
78  buffers = NULL;
79  display = NULL;
80 
81  /* Validate denoising parameters. */
83 
84  /* Create CPU/GPU devices. */
86 
87  if (!device->error_message().empty()) {
89  return;
90  }
91 
92  /* Create buffers for interactive rendering. */
96  }
97 }
98 
100 {
101  cancel();
102 
103  if (buffers && params.write_render_cb) {
104  /* Copy to display buffer and write out image if requested */
105  delete display;
106 
107  display = new DisplayBuffer(device, false);
110 
111  int w = display->draw_width;
112  int h = display->draw_height;
113  uchar4 *pixels = display->rgba_byte.copy_from_device(0, w, h);
114  params.write_render_cb((uchar *)pixels, w, h, 4);
115  }
116 
117  /* clean up */
119 
120  delete buffers;
121  delete display;
122  delete scene;
123  delete device;
124 
126 }
127 
129 {
130  if (!session_thread) {
132  }
133 }
134 
136 {
137  if (session_thread) {
138  /* wait for session thread to end */
139  progress.set_cancel("Exiting");
140 
143 
144  {
145  thread_scoped_lock pause_lock(pause_mutex);
146  pause = false;
147  }
148  pause_cond.notify_all();
149 
150  wait();
151  }
152 }
153 
155 {
156  double dt = time_dt() - reset_time;
157 
158  if (!display_outdated)
159  return (dt > params.reset_timeout);
160  else
161  return (dt > params.cancel_timeout);
162 }
163 
164 /* GPU Session */
165 
166 void Session::reset_gpu(BufferParams &buffer_params, int samples)
167 {
168  thread_scoped_lock pause_lock(pause_mutex);
169 
170  /* block for buffer access and reset immediately. we can't do this
171  * in the thread, because we need to allocate an OpenGL buffer, and
172  * that only works in the main thread */
173  thread_scoped_lock display_lock(display_mutex);
174  thread_scoped_lock buffers_lock(buffers_mutex);
175 
176  display_outdated = true;
177  reset_time = time_dt();
178 
179  reset_(buffer_params, samples);
180 
183 
184  pause_cond.notify_all();
185 }
186 
187 bool Session::draw_gpu(BufferParams &buffer_params, DeviceDrawParams &draw_params)
188 {
189  /* block for buffer access */
190  thread_scoped_lock display_lock(display_mutex);
191 
192  /* first check we already rendered something */
193  if (gpu_draw_ready) {
194  /* then verify the buffers have the expected size, so we don't
195  * draw previous results in a resized window */
196  if (buffer_params.width == display->params.width &&
197  buffer_params.height == display->params.height) {
198  /* for CUDA we need to do tone-mapping still, since we can
199  * only access GL buffers from the main thread. */
201  thread_scoped_lock buffers_lock(buffers_mutex);
205  }
206 
207  display->draw(device, draw_params);
208 
210  return false;
211 
212  return true;
213  }
214  }
215 
216  return false;
217 }
218 
220 {
221  bool tiles_written = false;
222 
223  reset_time = time_dt();
226 
228 
229  while (!progress.get_cancel()) {
230  /* advance to next tile */
231  bool no_tiles = !tile_manager.next();
232 
234  if (no_tiles) {
235  kernel_state = device->get_active_kernel_switch_state();
236  }
237 
238  if (params.background) {
239  /* if no work left and in background mode, we can stop immediately */
240  if (no_tiles) {
241  progress.set_status("Finished");
242  break;
243  }
244  }
245 
246  else if (no_tiles && kernel_state == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE) {
248  }
249 
250  else {
251  /* if in interactive mode, and we are either paused or done for now,
252  * wait for pause condition notify to wake up again */
253  thread_scoped_lock pause_lock(pause_mutex);
254 
255  if (!pause && !tile_manager.done()) {
256  /* reset could have happened after no_tiles was set, before this lock.
257  * in this case we shall not wait for pause condition
258  */
259  }
260  else if (pause || no_tiles) {
261  update_status_time(pause, no_tiles);
262 
263  while (1) {
264  scoped_timer pause_timer;
265  pause_cond.wait(pause_lock);
266  if (pause) {
267  progress.add_skip_time(pause_timer, params.background);
268  }
269 
270  update_status_time(pause, no_tiles);
272 
273  if (!pause)
274  break;
275  }
276  }
277 
278  if (progress.get_cancel())
279  break;
280  }
281 
282  if (!no_tiles) {
283  /* update scene */
284  scoped_timer update_timer;
285  if (update_scene()) {
286  profiler.reset(scene->shaders.size(), scene->objects.size());
287  }
288  progress.add_skip_time(update_timer, params.background);
289 
290  if (!device->error_message().empty())
292 
293  if (progress.get_cancel())
294  break;
295 
296  /* buffers mutex is locked entirely while rendering each
297  * sample, and released/reacquired on each iteration to allow
298  * reset and draw in between */
299  thread_scoped_lock buffers_lock(buffers_mutex);
300 
301  /* update status and timing */
303 
304  /* render */
305  bool delayed_denoise = false;
306  const bool need_denoise = render_need_denoise(delayed_denoise);
307  render(need_denoise);
308 
309  device->task_wait();
310 
311  if (!device->error_message().empty())
313 
314  /* update status and timing */
316 
317  gpu_need_display_buffer_update = !delayed_denoise;
318  gpu_draw_ready = true;
320 
321  /* wait for until display buffer is updated */
322  if (!params.background) {
324  if (progress.get_cancel())
325  break;
326 
327  gpu_need_display_buffer_update_cond.wait(buffers_lock);
328  }
329  }
330 
331  if (!device->error_message().empty())
333 
334  tiles_written = update_progressive_refine(progress.get_cancel());
335 
336  if (progress.get_cancel())
337  break;
338  }
339  }
340 
341  if (!tiles_written)
343 }
344 
345 /* CPU Session */
346 
347 void Session::reset_cpu(BufferParams &buffer_params, int samples)
348 {
350  thread_scoped_lock pause_lock(pause_mutex);
351 
352  display_outdated = true;
353  reset_time = time_dt();
354 
355  delayed_reset.params = buffer_params;
356  delayed_reset.samples = samples;
357  delayed_reset.do_reset = true;
358  device->task_cancel();
359 
360  pause_cond.notify_all();
361 }
362 
363 bool Session::draw_cpu(BufferParams &buffer_params, DeviceDrawParams &draw_params)
364 {
365  thread_scoped_lock display_lock(display_mutex);
366 
367  /* first check we already rendered something */
368  if (display->draw_ready()) {
369  /* then verify the buffers have the expected size, so we don't
370  * draw previous results in a resized window */
371  if (buffer_params.width == display->params.width &&
372  buffer_params.height == display->params.height) {
373  display->draw(device, draw_params);
374 
376  return false;
377 
378  return true;
379  }
380  }
381 
382  return false;
383 }
384 
385 bool Session::steal_tile(RenderTile &rtile, Device *tile_device, thread_scoped_lock &tile_lock)
386 {
387  /* Devices that can get their tiles stolen don't steal tiles themselves.
388  * Additionally, if there are no stealable tiles in flight, give up here. */
389  if (tile_device->info.type == DEVICE_CPU || stealable_tiles == 0) {
390  return false;
391  }
392 
393  /* Wait until no other thread is trying to steal a tile. */
395  /* Someone else is currently trying to get a tile.
396  * Wait on the condition variable and try later. */
397  tile_steal_cond.wait(tile_lock);
398  }
399  /* If another thread stole the last stealable tile in the meantime, give up. */
400  if (stealable_tiles == 0) {
401  return false;
402  }
403 
404  /* There are stealable tiles in flight, so signal that one should be released. */
406 
407  /* Wait until a device notices the signal and releases its tile. */
408  while (tile_stealing_state != GOT_TILE && stealable_tiles > 0) {
409  tile_steal_cond.wait(tile_lock);
410  }
411  /* If the last stealable tile finished on its own, give up. */
412  if (tile_stealing_state != GOT_TILE) {
414  return false;
415  }
416 
417  /* Successfully stole a tile, now move it to the new device. */
418  rtile = stolen_tile;
419  rtile.buffers->buffer.move_device(tile_device);
420  rtile.buffer = rtile.buffers->buffer.device_pointer;
422  rtile.num_samples -= (rtile.sample - rtile.start_sample);
423  rtile.start_sample = rtile.sample;
424 
426 
427  /* Poke any threads which might be waiting for NOT_STEALING above. */
428  tile_steal_cond.notify_one();
429 
430  return true;
431 }
432 
434 {
435  /* If tile_stealing_state is WAITING_FOR_TILE, atomically set it to RELEASING_TILE
436  * and return true. */
438  return tile_stealing_state.compare_exchange_weak(expected, RELEASING_TILE);
439 }
440 
441 bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_types)
442 {
443  if (progress.get_cancel()) {
444  if (params.progressive_refine == false) {
445  /* for progressive refine current sample should be finished for all tiles */
446  return false;
447  }
448  }
449 
450  thread_scoped_lock tile_lock(tile_mutex);
451 
452  /* get next tile from manager */
453  Tile *tile;
454  int device_num = device->device_number(tile_device);
455 
456  while (!tile_manager.next_tile(tile, device_num, tile_types)) {
457  /* Can only steal tiles on devices that support rendering
458  * This is because denoising tiles cannot be stolen (see below)
459  */
460  if ((tile_types & (RenderTile::PATH_TRACE | RenderTile::BAKE)) &&
461  steal_tile(rtile, tile_device, tile_lock)) {
462  return true;
463  }
464 
465  /* Wait for denoising tiles to become available */
466  if ((tile_types & RenderTile::DENOISE) && !progress.get_cancel() && tile_manager.has_tiles()) {
467  denoising_cond.wait(tile_lock);
468  continue;
469  }
470 
471  return false;
472  }
473 
474  /* fill render tile */
475  rtile.x = tile_manager.state.buffer.full_x + tile->x;
476  rtile.y = tile_manager.state.buffer.full_y + tile->y;
477  rtile.w = tile->w;
478  rtile.h = tile->h;
482  rtile.tile_index = tile->index;
484 
485  if (tile->state == Tile::DENOISE) {
486  rtile.task = RenderTile::DENOISE;
487  }
488  else {
489  if (tile_device->info.type == DEVICE_CPU) {
490  stealable_tiles++;
492  }
493 
494  if (read_bake_tile_cb) {
495  rtile.task = RenderTile::BAKE;
496  }
497  else {
499  }
500  }
501 
502  tile_lock.unlock();
503 
504  /* in case of a permanent buffer, return it, otherwise we will allocate
505  * a new temporary buffer */
506  if (buffers) {
508 
510  rtile.buffers = buffers;
511 
512  device->map_tile(tile_device, rtile);
513 
514  /* Reset copy state, since buffer contents change after the tile was acquired */
515  buffers->map_neighbor_copied = false;
516 
517  /* This hack ensures that the copy in 'MultiDevice::map_neighbor_tiles' accounts
518  * for the buffer resolution divider. */
522 
523  return true;
524  }
525 
526  if (tile->buffers == NULL) {
527  /* fill buffer parameters */
528  BufferParams buffer_params = tile_manager.params;
529  buffer_params.full_x = rtile.x;
530  buffer_params.full_y = rtile.y;
531  buffer_params.width = rtile.w;
532  buffer_params.height = rtile.h;
533 
534  /* allocate buffers */
535  tile->buffers = new RenderBuffers(tile_device);
536  tile->buffers->reset(buffer_params);
537  }
538  else if (tile->buffers->buffer.device != tile_device) {
539  /* Move buffer to current tile device again in case it was stolen before.
540  * Not needed for denoising since that already handles mapping of tiles and
541  * neighbors to its own device. */
542  if (rtile.task != RenderTile::DENOISE) {
543  tile->buffers->buffer.move_device(tile_device);
544  }
545  }
546 
547  tile->buffers->map_neighbor_copied = false;
548 
549  tile->buffers->params.get_offset_stride(rtile.offset, rtile.stride);
550 
551  rtile.buffer = tile->buffers->buffer.device_pointer;
552  rtile.buffers = tile->buffers;
554 
555  if (read_bake_tile_cb) {
556  /* This will read any passes needed as input for baking. */
558  {
559  thread_scoped_lock tile_lock(tile_mutex);
560  read_bake_tile_cb(rtile);
561  }
562  rtile.buffers->buffer.copy_to_device();
563  }
564  }
565  else {
566  /* This will tag tile as IN PROGRESS in blender-side render pipeline,
567  * which is needed to highlight currently rendering tile before first
568  * sample was processed for it. */
569  update_tile_sample(rtile);
570  }
571 
572  return true;
573 }
574 
576 {
577  thread_scoped_lock tile_lock(tile_mutex);
578 
579  if (update_render_tile_cb) {
580  if (params.progressive_refine == false) {
581  /* todo: optimize this by making it thread safe and removing lock */
582 
583  update_render_tile_cb(rtile, true);
584  }
585  }
586 
588 }
589 
590 void Session::release_tile(RenderTile &rtile, const bool need_denoise)
591 {
592  thread_scoped_lock tile_lock(tile_mutex);
593 
595  stealable_tiles--;
596  if (rtile.stealing_state == RenderTile::WAS_STOLEN) {
597  /* If the tile is being stolen, don't release it here - the new device will pick up where
598  * the old one left off. */
599 
601  assert(rtile.sample < rtile.start_sample + rtile.num_samples);
602 
604  stolen_tile = rtile;
605  tile_steal_cond.notify_all();
606  return;
607  }
608  else if (stealable_tiles == 0) {
609  /* If this was the last stealable tile, wake up any threads still waiting for one. */
610  tile_steal_cond.notify_all();
611  }
612  }
613 
615 
616  bool delete_tile;
617 
618  if (tile_manager.finish_tile(rtile.tile_index, need_denoise, delete_tile)) {
619  /* Finished tile pixels write. */
621  write_render_tile_cb(rtile);
622  }
623 
624  if (delete_tile) {
625  delete rtile.buffers;
626  tile_manager.state.tiles[rtile.tile_index].buffers = NULL;
627  }
628  }
629  else {
630  /* In progress tile pixels update. */
632  update_render_tile_cb(rtile, false);
633  }
634  }
635 
637 
638  /* Notify denoising thread that a tile was finished. */
639  denoising_cond.notify_all();
640 }
641 
643 {
644  thread_scoped_lock tile_lock(tile_mutex);
645 
646  const int4 image_region = make_int4(
651 
652  RenderTile &center_tile = neighbors.tiles[RenderTileNeighbors::CENTER];
653 
655  /* Fix up tile slices with overlap. */
656  if (tile_manager.slice_overlap != 0) {
657  int y = max(center_tile.y - tile_manager.slice_overlap, image_region.y);
658  center_tile.h = min(center_tile.y + center_tile.h + tile_manager.slice_overlap,
659  image_region.w) -
660  y;
661  center_tile.y = y;
662  }
663 
664  /* Tiles are not being denoised individually, which means the entire image is processed. */
665  neighbors.set_bounds_from_center();
666  }
667  else {
668  int center_idx = center_tile.tile_index;
669  assert(tile_manager.state.tiles[center_idx].state == Tile::DENOISE);
670 
671  for (int dy = -1, i = 0; dy <= 1; dy++) {
672  for (int dx = -1; dx <= 1; dx++, i++) {
673  RenderTile &rtile = neighbors.tiles[i];
674  int nindex = tile_manager.get_neighbor_index(center_idx, i);
675  if (nindex >= 0) {
676  Tile *tile = &tile_manager.state.tiles[nindex];
677 
678  rtile.x = image_region.x + tile->x;
679  rtile.y = image_region.y + tile->y;
680  rtile.w = tile->w;
681  rtile.h = tile->h;
682 
683  if (buffers) {
685 
687  rtile.buffers = buffers;
688  }
689  else {
690  assert(tile->buffers);
691  tile->buffers->params.get_offset_stride(rtile.offset, rtile.stride);
692 
693  rtile.buffer = tile->buffers->buffer.device_pointer;
694  rtile.buffers = tile->buffers;
695  }
696  }
697  else {
698  int px = center_tile.x + dx * params.tile_size.x;
699  int py = center_tile.y + dy * params.tile_size.y;
700 
701  rtile.x = clamp(px, image_region.x, image_region.z);
702  rtile.y = clamp(py, image_region.y, image_region.w);
703  rtile.w = rtile.h = 0;
704 
705  rtile.buffer = (device_ptr)NULL;
706  rtile.buffers = NULL;
707  }
708  }
709  }
710  }
711 
712  assert(center_tile.buffers);
713  device->map_neighbor_tiles(tile_device, neighbors);
714 
715  /* The denoised result is written back to the original tile. */
716  neighbors.target = center_tile;
717 }
718 
720 {
721  thread_scoped_lock tile_lock(tile_mutex);
722  device->unmap_neighbor_tiles(tile_device, neighbors);
723 }
724 
726 {
727  bool tiles_written = false;
728 
731 
732  {
733  /* reset once to start */
735  thread_scoped_lock buffers_lock(buffers_mutex);
736  thread_scoped_lock display_lock(display_mutex);
737 
739  delayed_reset.do_reset = false;
740  }
741 
742  while (!progress.get_cancel()) {
743  /* advance to next tile */
744  bool no_tiles = !tile_manager.next();
745  bool need_copy_to_display_buffer = false;
746 
748  if (no_tiles) {
749  kernel_state = device->get_active_kernel_switch_state();
750  }
751 
752  if (params.background) {
753  /* if no work left and in background mode, we can stop immediately */
754  if (no_tiles) {
755  progress.set_status("Finished");
756  break;
757  }
758  }
759 
760  else if (no_tiles && kernel_state == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE) {
762  }
763 
764  else {
765  /* if in interactive mode, and we are either paused or done for now,
766  * wait for pause condition notify to wake up again */
767  thread_scoped_lock pause_lock(pause_mutex);
768 
769  if (!pause && delayed_reset.do_reset) {
770  /* reset once to start */
772  thread_scoped_lock buffers_lock(buffers_mutex);
773  thread_scoped_lock display_lock(display_mutex);
774 
776  delayed_reset.do_reset = false;
777  }
778  else if (pause || no_tiles) {
779  update_status_time(pause, no_tiles);
780 
781  while (1) {
782  scoped_timer pause_timer;
783  pause_cond.wait(pause_lock);
784  if (pause) {
785  progress.add_skip_time(pause_timer, params.background);
786  }
787 
788  update_status_time(pause, no_tiles);
790 
791  if (!pause)
792  break;
793  }
794  }
795 
796  if (progress.get_cancel())
797  break;
798  }
799 
800  if (!no_tiles) {
801  /* update scene */
802  scoped_timer update_timer;
803  if (update_scene()) {
804  profiler.reset(scene->shaders.size(), scene->objects.size());
805  }
806  progress.add_skip_time(update_timer, params.background);
807 
808  if (!device->error_message().empty())
810 
811  if (progress.get_cancel())
812  break;
813 
814  /* buffers mutex is locked entirely while rendering each
815  * sample, and released/reacquired on each iteration to allow
816  * reset and draw in between */
817  thread_scoped_lock buffers_lock(buffers_mutex);
818 
819  /* update status and timing */
821 
822  /* render */
823  bool delayed_denoise = false;
824  const bool need_denoise = render_need_denoise(delayed_denoise);
825  render(need_denoise);
826 
827  /* update status and timing */
829 
830  if (!params.background)
831  need_copy_to_display_buffer = !delayed_denoise;
832 
833  if (!device->error_message().empty())
835  }
836 
837  device->task_wait();
838 
839  {
841  thread_scoped_lock buffers_lock(buffers_mutex);
842  thread_scoped_lock display_lock(display_mutex);
843 
844  if (delayed_reset.do_reset) {
845  /* reset rendering if request from main thread */
846  delayed_reset.do_reset = false;
848  }
849  else if (need_copy_to_display_buffer) {
850  /* Only copy to display_buffer if we do not reset, we don't
851  * want to show the result of an incomplete sample */
853  }
854 
855  if (!device->error_message().empty())
857 
858  tiles_written = update_progressive_refine(progress.get_cancel());
859  }
860 
862  }
863 
864  if (!tiles_written)
866 }
867 
869 {
871  profiler.start();
872  }
873 
874  /* session thread loop */
875  progress.set_status("Waiting for render to start");
876 
877  /* run */
878  if (!progress.get_cancel()) {
879  /* reset number of rendered samples */
881 
882  if (device_use_gl)
883  run_gpu();
884  else
885  run_cpu();
886  }
887 
888  profiler.stop();
889 
890  /* progress update */
891  if (progress.get_cancel())
893  else
895 }
896 
897 bool Session::draw(BufferParams &buffer_params, DeviceDrawParams &draw_params)
898 {
899  if (device_use_gl)
900  return draw_gpu(buffer_params, draw_params);
901  else
902  return draw_cpu(buffer_params, draw_params);
903 }
904 
905 void Session::reset_(BufferParams &buffer_params, int samples)
906 {
907  if (buffers && buffer_params.modified(tile_manager.params)) {
908  gpu_draw_ready = false;
909  buffers->reset(buffer_params);
910  if (display) {
911  display->reset(buffer_params);
912  }
913  }
914 
915  tile_manager.reset(buffer_params, samples);
916  stealable_tiles = 0;
919 
920  bool show_progress = params.background || tile_manager.get_num_effective_samples() != INT_MAX;
922 
923  if (!params.background)
926 }
927 
928 void Session::reset(BufferParams &buffer_params, int samples)
929 {
930  if (device_use_gl)
931  reset_gpu(buffer_params, samples);
932  else
933  reset_cpu(buffer_params, samples);
934 }
935 
936 void Session::set_samples(int samples)
937 {
938  if (samples != params.samples) {
939  params.samples = samples;
940  tile_manager.set_samples(samples);
941 
942  pause_cond.notify_all();
943  }
944 }
945 
946 void Session::set_pause(bool pause_)
947 {
948  bool notify = false;
949 
950  {
951  thread_scoped_lock pause_lock(pause_mutex);
952 
953  if (pause != pause_) {
954  pause = pause_;
955  notify = true;
956  }
957  }
958 
959  if (session_thread) {
960  if (notify) {
961  pause_cond.notify_all();
962  }
963  }
964  else if (pause_) {
965  update_status_time(pause_);
966  }
967 }
968 
969 void Session::set_denoising(const DenoiseParams &denoising)
970 {
971  bool need_denoise = denoising.need_denoising_task();
972 
973  /* Lock buffers so no denoising operation is triggered while the settings are changed here. */
974  thread_scoped_lock buffers_lock(buffers_mutex);
975  params.denoising = denoising;
976 
977  if (!(params.device.denoisers & denoising.type)) {
978  if (need_denoise) {
979  progress.set_error("Denoiser type not supported by compute device");
980  }
981 
982  params.denoising.use = false;
983  need_denoise = false;
984  }
985 
986  // TODO(pmours): Query the required overlap value for denoising from the device?
987  tile_manager.slice_overlap = need_denoise && !params.background ? 64 : 0;
988 
989  /* Schedule per tile denoising for final renders if we are either denoising or
990  * need prefiltered passes for the native denoiser. */
991  tile_manager.schedule_denoising = need_denoise && !buffers;
992 }
993 
995 {
998 
999  pause_cond.notify_all();
1000  }
1001 }
1002 
1004 {
1005  if (session_thread) {
1006  session_thread->join();
1007  delete session_thread;
1008  }
1009 
1010  session_thread = NULL;
1011 }
1012 
1014 {
1015  thread_scoped_lock scene_lock(scene->mutex);
1016 
1017  /* update camera if dimensions changed for progressive render. the camera
1018  * knows nothing about progressive or cropped rendering, it just gets the
1019  * image dimensions passed in */
1020  Camera *cam = scene->camera;
1023  int resolution = tile_manager.state.resolution_divider;
1024 
1025  cam->set_screen_size_and_resolution(width, height, resolution);
1026 
1027  /* number of samples is needed by multi jittered
1028  * sampling pattern and by baking */
1029  Integrator *integrator = scene->integrator;
1030  BakeManager *bake_manager = scene->bake_manager;
1031 
1032  if (integrator->get_sampling_pattern() != SAMPLING_PATTERN_SOBOL || bake_manager->get_baking()) {
1033  integrator->set_aa_samples(tile_manager.num_samples);
1034  }
1035 
1036  bool kernel_switch_needed = false;
1037  if (scene->update(progress, kernel_switch_needed)) {
1038  if (kernel_switch_needed) {
1040  }
1041  return true;
1042  }
1043  return false;
1044 }
1045 
1046 void Session::update_status_time(bool show_pause, bool show_done)
1047 {
1048  int progressive_sample = tile_manager.state.sample;
1049  int num_samples = tile_manager.get_num_effective_samples();
1050 
1051  int tile = progress.get_rendered_tiles();
1052  int num_tiles = tile_manager.state.num_tiles;
1053 
1054  /* update status */
1055  string status, substatus;
1056 
1057  if (!params.progressive) {
1058  const bool is_cpu = params.device.type == DEVICE_CPU;
1059  const bool rendering_finished = (tile == num_tiles);
1060  const bool is_last_tile = (tile + 1) == num_tiles;
1061 
1062  substatus = string_printf("Rendered %d/%d Tiles", tile, num_tiles);
1063 
1064  if (!rendering_finished && (device->show_samples() || (is_cpu && is_last_tile))) {
1065  /* Some devices automatically support showing the sample number:
1066  * - CUDADevice
1067  * - OpenCLDevice when using the megakernel (the split kernel renders multiple
1068  * samples at the same time, so the current sample isn't really defined)
1069  * - CPUDevice when using one thread
1070  * For these devices, the current sample is always shown.
1071  *
1072  * The other option is when the last tile is currently being rendered by the CPU.
1073  */
1074  substatus += string_printf(", Sample %d/%d", progress.get_current_sample(), num_samples);
1075  }
1077  substatus += string_printf(", Denoised %d tiles", progress.get_denoised_tiles());
1078  }
1080  substatus += string_printf(", Prefiltered %d tiles", progress.get_denoised_tiles());
1081  }
1082  }
1084  substatus = string_printf("Path Tracing Sample %d", progressive_sample + 1);
1085  else
1086  substatus = string_printf("Path Tracing Sample %d/%d", progressive_sample + 1, num_samples);
1087 
1088  if (show_pause) {
1089  status = "Rendering Paused";
1090  }
1091  else if (show_done) {
1092  status = "Rendering Done";
1093  progress.set_end_time(); /* Save end time so that further calls to get_time are accurate. */
1094  }
1095  else {
1096  status = substatus;
1097  substatus.clear();
1098  }
1099 
1100  progress.set_status(status, substatus);
1101 }
1102 
1103 bool Session::render_need_denoise(bool &delayed)
1104 {
1105  delayed = false;
1106 
1107  /* Not supported yet for baking. */
1108  if (read_bake_tile_cb) {
1109  return false;
1110  }
1111 
1112  /* Denoising enabled? */
1114  return false;
1115  }
1116 
1117  if (params.background) {
1118  /* Background render, only denoise when rendering the last sample. */
1119  return tile_manager.done();
1120  }
1121 
1122  /* Viewport render. */
1123 
1124  /* It can happen that denoising was already enabled, but the scene still needs an update. */
1126  return false;
1127  }
1128 
1129  /* Immediately denoise when we reach the start sample or last sample. */
1130  const int num_samples_finished = tile_manager.state.sample + 1;
1131  if (num_samples_finished == params.denoising.start_sample ||
1132  num_samples_finished == params.samples) {
1133  return true;
1134  }
1135 
1136  /* Do not denoise until the sample at which denoising should start is reached. */
1137  if (num_samples_finished < params.denoising.start_sample) {
1138  return false;
1139  }
1140 
1141  /* Avoid excessive denoising in viewport after reaching a certain amount of samples. */
1142  delayed = (tile_manager.state.sample >= 20 &&
1144  return !delayed;
1145 }
1146 
1147 void Session::render(bool need_denoise)
1148 {
1150  /* Clear buffers. */
1151  buffers->zero();
1152  }
1153 
1155  return; /* Avoid empty launches. */
1156  }
1157 
1158  /* Add path trace task. */
1160 
1161  task.acquire_tile = function_bind(&Session::acquire_tile, this, _2, _1, _3);
1162  task.release_tile = function_bind(&Session::release_tile, this, _1, need_denoise);
1163  task.map_neighbor_tiles = function_bind(&Session::map_neighbor_tiles, this, _1, _2);
1164  task.unmap_neighbor_tiles = function_bind(&Session::unmap_neighbor_tiles, this, _1, _2);
1165  task.get_cancel = function_bind(&Progress::get_cancel, &this->progress);
1167  task.update_progress_sample = function_bind(&Progress::add_samples, &this->progress, _1, _2);
1168  task.get_tile_stolen = function_bind(&Session::get_tile_stolen, this);
1169  task.need_finish_queue = params.progressive_refine;
1170  task.integrator_branched = scene->integrator->get_method() == Integrator::BRANCHED_PATH;
1171 
1172  task.adaptive_sampling.use = (scene->integrator->get_sampling_pattern() ==
1175  task.adaptive_sampling.min_samples = scene->dscene.data.integrator.adaptive_min_samples;
1176  task.adaptive_sampling.adaptive_step = scene->dscene.data.integrator.adaptive_step;
1177 
1178  /* Acquire render tiles by default. */
1179  task.tile_types = RenderTile::PATH_TRACE;
1180 
1181  if (need_denoise) {
1182  task.denoising = params.denoising;
1183 
1184  task.pass_stride = scene->film->get_pass_stride();
1185  task.target_pass_stride = task.pass_stride;
1186  task.pass_denoising_data = scene->film->get_denoising_data_offset();
1187  task.pass_denoising_clean = scene->film->get_denoising_clean_offset();
1188 
1189  task.denoising_from_render = true;
1190 
1192  /* Acquire denoising tiles during rendering. */
1193  task.tile_types |= RenderTile::DENOISE;
1194  }
1195  else {
1196  assert(buffers);
1197 
1198  /* Schedule rendering and wait for it to finish. */
1199  device->task_add(task);
1200  device->task_wait();
1201 
1202  /* Then run denoising on the whole image at once. */
1208  task.buffer = buffers->buffer.device_pointer;
1209  task.sample = tile_manager.state.sample;
1210  task.num_samples = tile_manager.state.num_samples;
1212  task.buffers = buffers;
1213  }
1214  }
1215 
1216  device->task_add(task);
1217 }
1218 
1220 {
1221  /* add film conversion task */
1223 
1228  task.rgba_byte = display->rgba_byte.device_pointer;
1229  task.rgba_half = display->rgba_half.device_pointer;
1230  task.buffer = buffers->buffer.device_pointer;
1231  task.sample = sample;
1233 
1234  if (task.w > 0 && task.h > 0) {
1235  device->task_add(task);
1236  device->task_wait();
1237 
1238  /* set display to new size */
1239  display->draw_set(task.w, task.h);
1240 
1242  }
1243 
1244  display_outdated = false;
1245 }
1246 
1248 {
1249  int sample = tile_manager.state.sample + 1;
1250  bool write = sample == tile_manager.num_samples || cancel;
1251 
1252  double current_time = time_dt();
1253 
1254  if (current_time - last_update_time < params.progressive_update_timeout) {
1255  /* if last sample was processed, we need to write buffers anyway */
1256  if (!write && sample != 1)
1257  return false;
1258  }
1259 
1260  if (params.progressive_refine) {
1261  foreach (Tile &tile, tile_manager.state.tiles) {
1262  if (!tile.buffers) {
1263  continue;
1264  }
1265 
1266  RenderTile rtile;
1267  rtile.x = tile_manager.state.buffer.full_x + tile.x;
1268  rtile.y = tile_manager.state.buffer.full_y + tile.y;
1269  rtile.w = tile.w;
1270  rtile.h = tile.h;
1271  rtile.sample = sample;
1272  rtile.buffers = tile.buffers;
1273 
1274  if (write) {
1276  write_render_tile_cb(rtile);
1277  }
1278  else {
1280  update_render_tile_cb(rtile, true);
1281  }
1282  }
1283  }
1284 
1285  last_update_time = current_time;
1286 
1287  return write;
1288 }
1289 
1291 {
1292  scene->device_free();
1293 
1295 
1296  /* used from background render only, so no need to
1297  * re-create render/display buffers here
1298  */
1299 }
1300 
1302 {
1303  scene->collect_statistics(render_stats);
1305  render_stats->collect_profiling(scene, profiler);
1306  }
1307 }
1308 
unsigned char uchar
Definition: BLI_sys_types.h:86
unsigned int uint
Definition: BLI_sys_types.h:83
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
bool get_baking()
Definition: bake.cpp:88
int width
Definition: buffers.h:43
int full_x
Definition: buffers.h:47
int full_width
Definition: buffers.h:49
int height
Definition: buffers.h:44
bool modified(const BufferParams &params)
Definition: buffers.cpp:56
void get_offset_stride(int &offset, int &stride)
Definition: buffers.cpp:50
int get_passes_size()
Definition: buffers.cpp:66
int full_height
Definition: buffers.h:50
int full_y
Definition: buffers.h:48
DenoiserType type
Definition: device_task.h:63
bool store_passes
Definition: device_task.h:60
bool need_denoising_task() const
Definition: device_task.h:112
DenoiserTypeMask denoisers
Definition: device.h:88
DeviceType type
Definition: device.h:74
KernelData data
Definition: scene.h:136
function< void(RenderTile &)> update_tile_sample
Definition: device_task.h:160
Definition: device.h:293
static Device * create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background=true)
Definition: device.cpp:382
virtual DeviceKernelStatus get_active_kernel_switch_state()
Definition: device.h:397
virtual void task_wait()=0
virtual int device_number(Device *)
Definition: device.h:441
virtual void unmap_neighbor_tiles(Device *, RenderTileNeighbors &)
Definition: device.h:448
virtual void task_cancel()=0
virtual void map_tile(Device *, RenderTile &)
Definition: device.h:438
virtual const string & error_message()
Definition: device.h:338
virtual void map_neighbor_tiles(Device *, RenderTileNeighbors &)
Definition: device.h:445
DeviceInfo info
Definition: device.h:337
virtual void task_add(DeviceTask &task)=0
virtual bool show_samples() const
Definition: device.h:354
int draw_width
Definition: buffers.h:110
bool draw_ready()
Definition: buffers.cpp:568
device_pixels< uchar4 > rgba_byte
Definition: buffers.h:116
BufferParams params
Definition: buffers.h:106
void draw_set(int width, int height)
Definition: buffers.cpp:540
void reset(BufferParams &params)
Definition: buffers.cpp:524
void draw(Device *device, const DeviceDrawParams &draw_params)
Definition: buffers.cpp:548
int draw_height
Definition: buffers.h:110
device_pixels< half4 > rgba_half
Definition: buffers.h:117
int get_denoising_data_offset() const
Definition: film.cpp:736
int get_pass_stride() const
Definition: film.cpp:731
int get_denoising_clean_offset() const
Definition: film.cpp:741
@ BRANCHED_PATH
Definition: integrator.h:82
static NODE_DECLARE const int MAX_SAMPLES
Definition: integrator.h:62
void start()
void reset(int num_shaders, int num_objects)
void set_total_pixel_samples(uint64_t total_pixel_samples_)
void set_cancel(const string &cancel_message_)
Definition: util_progress.h:98
int get_rendered_tiles()
bool get_cancel()
int get_denoised_tiles()
void set_end_time()
void reset_sample()
void set_status(const string &status_, const string &substatus_="")
void set_update()
int get_current_sample()
void add_samples(uint64_t pixel_samples_, int tile_sample)
void set_error(const string &error_message_)
void set_render_start_time()
void add_finished_tile(bool denoised)
string get_cancel_message()
void add_skip_time(const scoped_timer &start_timer, bool only_render)
void set_start_time()
device_vector< float > buffer
Definition: buffers.h:80
void reset(BufferParams &params)
Definition: buffers.cpp:145
void zero()
Definition: buffers.cpp:154
BufferParams params
Definition: buffers.h:77
bool map_neighbor_copied
Definition: buffers.h:81
RenderTile target
Definition: buffers.h:177
RenderTile tiles[SIZE]
Definition: buffers.h:176
void set_bounds_from_center()
Definition: buffers.h:192
static const int CENTER
Definition: buffers.h:174
int stride
Definition: buffers.h:143
int sample
Definition: buffers.h:140
@ NO_STEALING
Definition: buffers.h:149
@ WAS_STOLEN
Definition: buffers.h:149
@ CAN_BE_STOLEN
Definition: buffers.h:149
RenderBuffers * buffers
Definition: buffers.h:152
int num_samples
Definition: buffers.h:139
@ PATH_TRACE
Definition: buffers.h:134
int tile_index
Definition: buffers.h:144
device_ptr buffer
Definition: buffers.h:146
Task task
Definition: buffers.h:136
StealingState stealing_state
Definition: buffers.h:150
int offset
Definition: buffers.h:142
int resolution
Definition: buffers.h:141
int start_sample
Definition: buffers.h:138
double text_timeout
Definition: session.h:69
bool progressive
Definition: session.h:50
int samples
Definition: session.h:52
bool progressive_refine
Definition: session.h:48
double reset_timeout
Definition: session.h:68
DenoiseParams denoising
Definition: session.h:65
bool display_buffer_linear
Definition: session.h:63
int threads
Definition: session.h:58
bool use_profiling
Definition: session.h:61
DeviceInfo device
Definition: session.h:46
double progressive_update_timeout
Definition: session.h:70
function< bool(const uchar *pixels, int width, int height, int channels)> write_render_cb
Definition: session.h:74
double cancel_timeout
Definition: session.h:67
int2 tile_size
Definition: session.h:53
bool background
Definition: session.h:47
bool acquire_tile(RenderTile &tile, Device *tile_device, uint tile_types)
Definition: session.cpp:441
void reset_cpu(BufferParams &params, int samples)
Definition: session.cpp:347
void set_denoising_start_sample(int sample)
Definition: session.cpp:994
void collect_statistics(RenderStats *stats)
Definition: session.cpp:1301
bool pause
Definition: session.h:217
bool draw_cpu(BufferParams &params, DeviceDrawParams &draw_params)
Definition: session.cpp:363
function< void(RenderTile &, bool)> update_render_tile_cb
Definition: session.h:143
void run_cpu()
Definition: session.cpp:725
thread_condition_variable pause_cond
Definition: session.h:218
thread_mutex tile_mutex
Definition: session.h:220
volatile bool display_outdated
Definition: session.h:211
std::atomic< TileStealingState > tile_stealing_state
Definition: session.h:237
RenderBuffers * buffers
Definition: session.h:134
bool steal_tile(RenderTile &tile, Device *tile_device, thread_scoped_lock &tile_lock)
Definition: session.cpp:385
thread_condition_variable denoising_cond
Definition: session.h:223
void wait()
Definition: session.cpp:1003
Device * device
Definition: session.h:132
void update_status_time(bool show_pause=false, bool show_done=false)
Definition: session.cpp:1046
bool draw(BufferParams &params, DeviceDrawParams &draw_params)
Definition: session.cpp:897
thread_condition_variable tile_steal_cond
Definition: session.h:224
void set_pause(bool pause)
Definition: session.cpp:946
bool ready_to_reset()
Definition: session.cpp:154
void run()
Definition: session.cpp:868
double last_update_time
Definition: session.h:227
thread_condition_variable gpu_need_display_buffer_update_cond
Definition: session.h:215
TileStealingState
Definition: session.h:231
@ WAITING_FOR_TILE
Definition: session.h:233
@ RELEASING_TILE
Definition: session.h:234
@ NOT_STEALING
Definition: session.h:232
@ GOT_TILE
Definition: session.h:235
double reset_time
Definition: session.h:226
bool draw_gpu(BufferParams &params, DeviceDrawParams &draw_params)
Definition: session.cpp:187
void render(bool use_denoise)
Definition: session.cpp:1147
TileManager tile_manager
Definition: session.h:138
bool update_progressive_refine(bool cancel)
Definition: session.cpp:1247
void start()
Definition: session.cpp:128
bool render_need_denoise(bool &delayed)
Definition: session.cpp:1103
Progress progress
Definition: session.h:136
void set_denoising(const DenoiseParams &denoising)
Definition: session.cpp:969
void reset_gpu(BufferParams &params, int samples)
Definition: session.cpp:166
DisplayBuffer * display
Definition: session.h:135
Profiler profiler
Definition: session.h:140
SessionParams params
Definition: session.h:137
void release_tile(RenderTile &tile, const bool need_denoise)
Definition: session.cpp:590
thread * session_thread
Definition: session.h:209
void reset_(BufferParams &params, int samples)
Definition: session.cpp:905
bool get_tile_stolen()
Definition: session.cpp:433
volatile bool gpu_draw_ready
Definition: session.h:213
~Session()
Definition: session.cpp:99
function< void(RenderTile &)> write_render_tile_cb
Definition: session.h:142
volatile bool gpu_need_display_buffer_update
Definition: session.h:214
double last_display_time
Definition: session.h:228
bool update_scene()
Definition: session.cpp:1013
void copy_to_display_buffer(int sample)
Definition: session.cpp:1219
void cancel()
Definition: session.cpp:135
Session(const SessionParams &params)
Definition: session.cpp:46
void map_neighbor_tiles(RenderTileNeighbors &neighbors, Device *tile_device)
Definition: session.cpp:642
thread_mutex display_mutex
Definition: session.h:222
void device_free()
Definition: session.cpp:1290
void reset(BufferParams &params, int samples)
Definition: session.cpp:928
Scene * scene
Definition: session.h:133
void run_gpu()
Definition: session.cpp:219
bool device_use_gl
Definition: session.h:207
thread_mutex pause_mutex
Definition: session.h:219
void unmap_neighbor_tiles(RenderTileNeighbors &neighbors, Device *tile_device)
Definition: session.cpp:719
Stats stats
Definition: session.h:139
RenderTile stolen_tile
Definition: session.h:230
thread_mutex buffers_mutex
Definition: session.h:221
void update_tile_sample(RenderTile &tile)
Definition: session.cpp:575
void set_samples(int samples)
Definition: session.cpp:936
int stealable_tiles
Definition: session.h:238
struct Session::DelayedReset delayed_reset
function< void(RenderTile &)> read_bake_tile_cb
Definition: session.h:144
static void exit()
Definition: util_task.cpp:96
static void init(int num_threads=0)
Definition: util_task.cpp:75
int range_start_sample
Definition: tile.h:125
void device_free()
Definition: tile.cpp:122
void reset(BufferParams &params, int num_samples)
Definition: tile.cpp:148
int get_neighbor_index(int index, int neighbor)
Definition: tile.cpp:394
bool next_tile(Tile *&tile, int device, uint tile_types)
Definition: tile.cpp:498
bool done()
Definition: tile.cpp:559
int slice_overlap
Definition: tile.h:92
bool next()
Definition: tile.cpp:577
bool finish_tile(const int index, const bool need_denoise, bool &delete_tile)
Definition: tile.cpp:444
bool has_tiles()
Definition: tile.cpp:567
struct TileManager::State state
int get_num_effective_samples()
Definition: tile.cpp:611
int num_samples
Definition: tile.h:91
bool schedule_denoising
Definition: tile.h:134
void set_samples(int num_samples)
Definition: tile.cpp:164
BufferParams params
Definition: tile.h:69
Definition: tile.h:29
int index
Definition: tile.h:31
RenderBuffers * buffers
Definition: tile.h:41
int y
Definition: tile.h:32
int x
Definition: tile.h:32
State state
Definition: tile.h:40
int h
Definition: tile.h:32
@ DENOISE
Definition: tile.h:39
int w
Definition: tile.h:32
size_t data_height
device_ptr device_pointer
Device * device
T * copy_from_device(int y, int w, int h)
void move_device(Device *new_device)
void copy_to_device()
int x
Definition: btConvexHull.h:149
int w
Definition: btConvexHull.h:149
int y
Definition: btConvexHull.h:149
int z
Definition: btConvexHull.h:149
bool join()
Definition: util_thread.cpp:56
#define function_bind
DeviceKernelStatus
Definition: device.h:63
@ DEVICE_KERNEL_UNKNOWN
Definition: device.h:67
@ DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE
Definition: device.h:64
@ DEVICE_CPU
Definition: device.h:45
@ DENOISER_NLM
Definition: device_task.h:36
@ DENOISER_OPENIMAGEDENOISE
Definition: device_task.h:38
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define CCL_NAMESPACE_END
#define make_int4(x, y, z, w)
@ SAMPLING_PATTERN_PMJ
Definition: kernel_types.h:257
@ SAMPLING_PATTERN_SOBOL
Definition: kernel_types.h:255
static void sample(SocketReader *reader, int x, int y, float color[4])
struct blender::compositor::@172::@174 task
#define min(a, b)
Definition: sort.c:51
void set_screen_size_and_resolution(int width_, int height_, int resolution_)
Definition: camera.cpp:792
KernelFilm film
KernelIntegrator integrator
int pass_adaptive_aux_buffer
bool is_modified()
Definition: node.cpp:781
void collect_profiling(Scene *scene, Profiler &prof)
Definition: stats.cpp:262
BakeManager * bake_manager
Definition: scene.h:249
Film * film
Definition: scene.h:229
vector< Shader * > shaders
Definition: scene.h:236
void device_free()
Definition: scene.cpp:435
vector< Object * > objects
Definition: scene.h:234
Integrator * integrator
Definition: scene.h:231
thread_mutex mutex
Definition: scene.h:267
bool update(Progress &progress, bool &kernel_switch_needed)
Definition: scene.cpp:503
struct Object * camera
void collect_statistics(RenderStats *stats)
Definition: scene.cpp:440
DeviceScene dscene
Definition: scene.h:261
BufferParams params
Definition: session.h:175
thread_mutex mutex
Definition: session.h:173
BufferParams buffer
Definition: tile.h:74
int resolution_divider
Definition: tile.h:77
uint64_t total_pixel_samples
Definition: tile.h:82
int num_samples
Definition: tile.h:76
vector< Tile > tiles
Definition: tile.h:72
float max
ccl_device_inline int clamp(int a, int mn, int mx)
Definition: util_math.h:283
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
Definition: util_string.cpp:32
std::unique_lock< std::mutex > thread_scoped_lock
Definition: util_thread.h:41
CCL_NAMESPACE_BEGIN double time_dt()
Definition: util_time.cpp:48
uint64_t device_ptr
Definition: util_types.h:62