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

View File

@ -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->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);
/* 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;
}
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()
{
string timestatus, status, substatus;

View File

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

View File

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

View File

@ -185,7 +185,7 @@ public:
tile.sample = sample + 1;
task.update_progress(tile);
task.update_progress(&tile);
}
}
else
@ -207,7 +207,7 @@ public:
tile.sample = sample + 1;
task.update_progress(tile);
task.update_progress(&tile);
}
}
else
@ -229,7 +229,7 @@ public:
tile.sample = sample + 1;
task.update_progress(tile);
task.update_progress(&tile);
}
}
else
@ -251,7 +251,7 @@ public:
tile.sample = sample + 1;
task.update_progress(tile);
task.update_progress(&tile);
}
}
else
@ -273,7 +273,7 @@ public:
tile.sample = sample + 1;
task.update_progress(tile);
task.update_progress(&tile);
}
}
else
@ -294,7 +294,7 @@ public:
tile.sample = sample + 1;
task.update_progress(tile);
task.update_progress(&tile);
}
}
@ -433,71 +433,83 @@ public:
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_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);
if(task.get_cancel() || task_pool.canceled())
break;
task.update_progress(NULL);
}
}
else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_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);
if(task.get_cancel() || task_pool.canceled())
break;
task.update_progress(NULL);
}
}
else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_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);
if(task.get_cancel() || task_pool.canceled())
break;
task.update_progress(NULL);
}
}
else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_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);
if(task.get_cancel() || task_pool.canceled())
break;
task.update_progress(NULL);
}
}
else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_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);
if(task.get_cancel() || task_pool.canceled())
break;
task.update_progress(NULL);
}
}
else
#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);
if(task.get_cancel() || task_pool.canceled())
break;
task.update_progress(NULL);
}
}
@ -506,6 +518,14 @@ public:
#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)
{
/* split task into smaller ones */

View File

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

View File

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

View File

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

View File

@ -35,7 +35,7 @@ DeviceTask::DeviceTask(Type type_)
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) {
int max_size_num;
@ -53,7 +53,21 @@ void DeviceTask::split(list<DeviceTask>& tasks, int num, int max_size)
if(type == SHADER) {
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++) {
int tx = shader_x + (shader_w/num)*i;
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);
}
else {
num = min(h, num);
for(int i = 0; i < num; i++) {
int ty = y + (h/num)*i;
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;
if(update_progress_sample)
@ -99,7 +112,7 @@ void DeviceTask::update_progress(RenderTile &rtile)
double current_time = time_dt();
if (current_time - last_update_time >= 1.0) {
update_tile_sample(rtile);
update_tile_sample(*rtile);
last_update_time = current_time;
}

View File

@ -52,9 +52,10 @@ public:
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 update_progress(RenderTile &rtile);
void update_progress(RenderTile *rtile);
boost::function<bool(Device *device, RenderTile&)> acquire_tile;
boost::function<void(void)> update_progress_sample;

View File

@ -155,6 +155,10 @@ bool BakeManager::bake(Device *device, DeviceScene *dscene, Scene *scene, Progre
task.shader_w = d_output.size();
task.num_samples = is_aa_pass(shader_type)? scene->integrator->aa_samples: 1;
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_wait();

View File

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

View File

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