Cycles Bake: show progress bar during bake

Baking progress preview is not possible, in parts due to the way the API
was designed. But at least you get to see the progress bar while baking.

Reviewers: sergey

Differential Revision: https://developer.blender.org/D656
This commit is contained in:
Dalai Felinto 2014-07-22 18:41:01 -03:00
parent 2e50b4dc51
commit fc55c41bba
12 changed files with 131 additions and 35 deletions

@ -554,6 +554,8 @@ void BlenderSession::bake(BL::Object b_object, const string& pass_type, BL::Bake
session->reset(buffer_params, session_params.samples); session->reset(buffer_params, session_params.samples);
session->update_scene(); session->update_scene();
session->progress.set_update_callback(function_bind(&BlenderSession::update_bake_progress, this));
scene->bake_manager->bake(scene->device, &scene->dscene, scene, session->progress, shader_type, bake_data, result); scene->bake_manager->bake(scene->device, &scene->dscene, scene, session->progress, shader_type, bake_data, result);
/* free all memory used (host and device), so we wouldn't leave render /* free all memory used (host and device), so we wouldn't leave render
@ -765,6 +767,26 @@ void BlenderSession::get_progress(float& progress, double& total_time)
progress = 0.0; progress = 0.0;
} }
void BlenderSession::update_bake_progress()
{
float progress;
int sample, samples_per_task, parts_total;
sample = session->progress.get_sample();
samples_per_task = scene->bake_manager->num_samples;
parts_total = scene->bake_manager->num_parts;
if(samples_per_task)
progress = ((float)sample / (float)(parts_total * samples_per_task));
else
progress = 0.0;
if(progress != last_progress) {
b_engine.update_progress(progress);
last_progress = progress;
}
}
void BlenderSession::update_status_progress() void BlenderSession::update_status_progress()
{ {
string timestatus, status, substatus; string timestatus, status, substatus;

@ -73,6 +73,7 @@ public:
void get_progress(float& progress, double& total_time); void get_progress(float& progress, double& total_time);
void test_cancel(); void test_cancel();
void update_status_progress(); void update_status_progress();
void update_bake_progress();
bool background; bool background;
Session *session; Session *session;

@ -122,6 +122,7 @@ public:
virtual bool load_kernels(bool experimental) { return true; } virtual bool load_kernels(bool experimental) { return true; }
/* tasks */ /* tasks */
virtual int get_split_task_count(DeviceTask& task) = 0;
virtual void task_add(DeviceTask& task) = 0; virtual void task_add(DeviceTask& task) = 0;
virtual void task_wait() = 0; virtual void task_wait() = 0;
virtual void task_cancel() = 0; virtual void task_cancel() = 0;

@ -185,7 +185,7 @@ public:
tile.sample = sample + 1; tile.sample = sample + 1;
task.update_progress(tile); task.update_progress(&tile);
} }
} }
else else
@ -207,7 +207,7 @@ public:
tile.sample = sample + 1; tile.sample = sample + 1;
task.update_progress(tile); task.update_progress(&tile);
} }
} }
else else
@ -229,7 +229,7 @@ public:
tile.sample = sample + 1; tile.sample = sample + 1;
task.update_progress(tile); task.update_progress(&tile);
} }
} }
else else
@ -251,7 +251,7 @@ public:
tile.sample = sample + 1; tile.sample = sample + 1;
task.update_progress(tile); task.update_progress(&tile);
} }
} }
else else
@ -273,7 +273,7 @@ public:
tile.sample = sample + 1; tile.sample = sample + 1;
task.update_progress(tile); task.update_progress(&tile);
} }
} }
else else
@ -294,7 +294,7 @@ public:
tile.sample = sample + 1; tile.sample = sample + 1;
task.update_progress(tile); task.update_progress(&tile);
} }
} }
@ -433,71 +433,83 @@ public:
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2 #ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
if(system_cpu_support_avx2()) { if(system_cpu_support_avx2()) {
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { for(int sample = 0; sample < task.num_samples; sample++) {
for(int sample = 0; sample < task.num_samples; sample++) for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++)
kernel_cpu_avx2_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x, sample); kernel_cpu_avx2_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x, sample);
if(task.get_cancel() || task_pool.canceled()) if(task.get_cancel() || task_pool.canceled())
break; break;
task.update_progress(NULL);
} }
} }
else else
#endif #endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX #ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX
if(system_cpu_support_avx()) { if(system_cpu_support_avx()) {
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { for(int sample = 0; sample < task.num_samples; sample++) {
for(int sample = 0; sample < task.num_samples; sample++) for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++)
kernel_cpu_avx_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x, sample); kernel_cpu_avx_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x, sample);
if(task.get_cancel() || task_pool.canceled()) if(task.get_cancel() || task_pool.canceled())
break; break;
task.update_progress(NULL);
} }
} }
else else
#endif #endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41 #ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
if(system_cpu_support_sse41()) { if(system_cpu_support_sse41()) {
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { for(int sample = 0; sample < task.num_samples; sample++) {
for(int sample = 0; sample < task.num_samples; sample++) for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++)
kernel_cpu_sse41_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x, sample); kernel_cpu_sse41_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x, sample);
if(task.get_cancel() || task_pool.canceled()) if(task.get_cancel() || task_pool.canceled())
break; break;
task.update_progress(NULL);
} }
} }
else else
#endif #endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE3 #ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE3
if(system_cpu_support_sse3()) { if(system_cpu_support_sse3()) {
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { for(int sample = 0; sample < task.num_samples; sample++) {
for(int sample = 0; sample < task.num_samples; sample++) for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++)
kernel_cpu_sse3_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x, sample); kernel_cpu_sse3_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x, sample);
if(task.get_cancel() || task_pool.canceled()) if(task.get_cancel() || task_pool.canceled())
break; break;
task.update_progress(NULL);
} }
} }
else else
#endif #endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2 #ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
if(system_cpu_support_sse2()) { if(system_cpu_support_sse2()) {
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { for(int sample = 0; sample < task.num_samples; sample++) {
for(int sample = 0; sample < task.num_samples; sample++) for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++)
kernel_cpu_sse2_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x, sample); kernel_cpu_sse2_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x, sample);
if(task.get_cancel() || task_pool.canceled()) if(task.get_cancel() || task_pool.canceled())
break; break;
task.update_progress(NULL);
} }
} }
else else
#endif #endif
{ {
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { for(int sample = 0; sample < task.num_samples; sample++) {
for(int sample = 0; sample < task.num_samples; sample++) for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++)
kernel_cpu_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x, sample); kernel_cpu_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x, sample);
if(task.get_cancel() || task_pool.canceled()) if(task.get_cancel() || task_pool.canceled())
break; break;
task.update_progress(NULL);
} }
} }
@ -506,6 +518,14 @@ public:
#endif #endif
} }
int get_split_task_count(DeviceTask& task)
{
if (task.type == DeviceTask::SHADER)
return task.get_subtask_count(TaskScheduler::num_threads(), 256);
else
return task.get_subtask_count(TaskScheduler::num_threads());
}
void task_add(DeviceTask& task) void task_add(DeviceTask& task)
{ {
/* split task into smaller ones */ /* split task into smaller ones */

@ -732,14 +732,11 @@ public:
const int start = task.shader_x; const int start = task.shader_x;
const int end = task.shader_x + task.shader_w; const int end = task.shader_x + task.shader_w;
bool cancelled = false;
for(int sample = 0; sample < task.num_samples && !cancelled; sample++) {
for(int shader_x = start; shader_x < end; shader_x += shader_chunk_size) { for(int shader_x = start; shader_x < end; shader_x += shader_chunk_size) {
if(task.get_cancel())
break;
int shader_w = min(shader_chunk_size, end - shader_x); int shader_w = min(shader_chunk_size, end - shader_x);
for(int sample = 0; sample < task.num_samples; sample++) {
/* pass in parameters */ /* pass in parameters */
void *args[] = {&d_input, void *args[] = {&d_input,
&d_output, &d_output,
@ -761,9 +758,16 @@ public:
0, 0, args, 0)); 0, 0, args, 0));
cuda_assert(cuCtxSynchronize()); cuda_assert(cuCtxSynchronize());
if(task.get_cancel()) {
cancelled = false;
break;
} }
} }
task.update_progress(NULL);
}
cuda_pop_context(); cuda_pop_context();
} }
@ -991,7 +995,7 @@ public:
tile.sample = sample + 1; tile.sample = sample + 1;
task->update_progress(tile); task->update_progress(&tile);
} }
task->release_tile(tile); task->release_tile(tile);
@ -1015,6 +1019,11 @@ public:
} }
}; };
int get_split_task_count(DeviceTask& task)
{
return 1;
}
void task_add(DeviceTask& task) void task_add(DeviceTask& task)
{ {
if(task.type == DeviceTask::FILM_CONVERT) { if(task.type == DeviceTask::FILM_CONVERT) {

@ -278,6 +278,11 @@ public:
return -1; return -1;
} }
int get_split_task_count(DeviceTask& task)
{
return 1;
}
void task_add(DeviceTask& task) void task_add(DeviceTask& task)
{ {
list<DeviceTask> tasks; list<DeviceTask> tasks;

@ -1068,7 +1068,11 @@ public:
kernel = ckShaderKernel; kernel = ckShaderKernel;
for(int sample = 0; sample < task.num_samples; sample++) { for(int sample = 0; sample < task.num_samples; sample++) {
cl_int d_sample = task.sample;
if(task.get_cancel())
break;
cl_int d_sample = sample;
opencl_assert(clSetKernelArg(kernel, narg++, sizeof(d_data), (void*)&d_data)); opencl_assert(clSetKernelArg(kernel, narg++, sizeof(d_data), (void*)&d_data));
opencl_assert(clSetKernelArg(kernel, narg++, sizeof(d_input), (void*)&d_input)); opencl_assert(clSetKernelArg(kernel, narg++, sizeof(d_input), (void*)&d_input));
@ -1084,6 +1088,8 @@ public:
opencl_assert(clSetKernelArg(kernel, narg++, sizeof(d_sample), (void*)&d_sample)); opencl_assert(clSetKernelArg(kernel, narg++, sizeof(d_sample), (void*)&d_sample));
enqueue_kernel(kernel, task.shader_w, 1); enqueue_kernel(kernel, task.shader_w, 1);
task.update_progress(NULL);
} }
} }
@ -1113,7 +1119,7 @@ public:
tile.sample = sample + 1; tile.sample = sample + 1;
task->update_progress(tile); task->update_progress(&tile);
} }
task->release_tile(tile); task->release_tile(tile);
@ -1130,6 +1136,11 @@ public:
} }
}; };
int get_split_task_count(DeviceTask& task)
{
return 1;
}
void task_add(DeviceTask& task) void task_add(DeviceTask& task)
{ {
task_pool.push(new OpenCLDeviceTask(this, task)); task_pool.push(new OpenCLDeviceTask(this, task));

@ -35,7 +35,7 @@ DeviceTask::DeviceTask(Type type_)
last_update_time = time_dt(); last_update_time = time_dt();
} }
void DeviceTask::split(list<DeviceTask>& tasks, int num, int max_size) int DeviceTask::get_subtask_count(int num, int max_size)
{ {
if(max_size != 0) { if(max_size != 0) {
int max_size_num; int max_size_num;
@ -53,7 +53,21 @@ void DeviceTask::split(list<DeviceTask>& tasks, int num, int max_size)
if(type == SHADER) { if(type == SHADER) {
num = min(shader_w, num); num = min(shader_w, num);
}
else if(type == PATH_TRACE) {
}
else {
num = min(h, num);
}
return num;
}
void DeviceTask::split(list<DeviceTask>& tasks, int num, int max_size)
{
num = get_subtask_count(num, max_size);
if(type == SHADER) {
for(int i = 0; i < num; i++) { for(int i = 0; i < num; i++) {
int tx = shader_x + (shader_w/num)*i; int tx = shader_x + (shader_w/num)*i;
int tw = (i == num-1)? shader_w - i*(shader_w/num): shader_w/num; int tw = (i == num-1)? shader_w - i*(shader_w/num): shader_w/num;
@ -71,8 +85,6 @@ void DeviceTask::split(list<DeviceTask>& tasks, int num, int max_size)
tasks.push_back(*this); tasks.push_back(*this);
} }
else { else {
num = min(h, num);
for(int i = 0; i < num; i++) { for(int i = 0; i < num; i++) {
int ty = y + (h/num)*i; int ty = y + (h/num)*i;
int th = (i == num-1)? h - i*(h/num): h/num; int th = (i == num-1)? h - i*(h/num): h/num;
@ -87,9 +99,10 @@ void DeviceTask::split(list<DeviceTask>& tasks, int num, int max_size)
} }
} }
void DeviceTask::update_progress(RenderTile &rtile) void DeviceTask::update_progress(RenderTile *rtile)
{ {
if (type != PATH_TRACE) if((type != PATH_TRACE) &&
(type != SHADER))
return; return;
if(update_progress_sample) if(update_progress_sample)
@ -99,7 +112,7 @@ void DeviceTask::update_progress(RenderTile &rtile)
double current_time = time_dt(); double current_time = time_dt();
if (current_time - last_update_time >= 1.0) { if (current_time - last_update_time >= 1.0) {
update_tile_sample(rtile); update_tile_sample(*rtile);
last_update_time = current_time; last_update_time = current_time;
} }

@ -52,9 +52,10 @@ public:
DeviceTask(Type type = PATH_TRACE); DeviceTask(Type type = PATH_TRACE);
int get_subtask_count(int num, int max_size = 0);
void split(list<DeviceTask>& tasks, int num, int max_size = 0); void split(list<DeviceTask>& tasks, int num, int max_size = 0);
void update_progress(RenderTile &rtile); void update_progress(RenderTile *rtile);
boost::function<bool(Device *device, RenderTile&)> acquire_tile; boost::function<bool(Device *device, RenderTile&)> acquire_tile;
boost::function<void(void)> update_progress_sample; boost::function<void(void)> update_progress_sample;

@ -155,6 +155,10 @@ bool BakeManager::bake(Device *device, DeviceScene *dscene, Scene *scene, Progre
task.shader_w = d_output.size(); task.shader_w = d_output.size();
task.num_samples = is_aa_pass(shader_type)? scene->integrator->aa_samples: 1; task.num_samples = is_aa_pass(shader_type)? scene->integrator->aa_samples: 1;
task.get_cancel = function_bind(&Progress::get_cancel, &progress); task.get_cancel = function_bind(&Progress::get_cancel, &progress);
task.update_progress_sample = function_bind(&Progress::increment_sample_update, &progress);
this->num_parts = device->get_split_task_count(task);
this->num_samples = task.num_samples;
device->task_add(task); device->task_add(task);
device->task_wait(); device->task_wait();

@ -70,6 +70,9 @@ public:
bool need_update; bool need_update;
int num_samples;
int num_parts;
private: private:
BakeData *m_bake_data; BakeData *m_bake_data;
bool m_is_baking; bool m_is_baking;

@ -149,6 +149,12 @@ public:
sample++; sample++;
} }
void increment_sample_update()
{
increment_sample();
set_update();
}
int get_sample() int get_sample()
{ {
return sample; return sample;