Cycles Bake: show progress bar during bake
authorDalai Felinto <dfelinto@gmail.com>
Tue, 22 Jul 2014 21:41:01 +0000 (18:41 -0300)
committerDalai Felinto <dfelinto@gmail.com>
Fri, 25 Jul 2014 14:42:53 +0000 (11:42 -0300)
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

12 files changed:
intern/cycles/blender/blender_session.cpp
intern/cycles/blender/blender_session.h
intern/cycles/device/device.h
intern/cycles/device/device_cpu.cpp
intern/cycles/device/device_cuda.cpp
intern/cycles/device/device_multi.cpp
intern/cycles/device/device_opencl.cpp
intern/cycles/device/device_task.cpp
intern/cycles/device/device_task.h
intern/cycles/render/bake.cpp
intern/cycles/render/bake.h
intern/cycles/util/util_progress.h

index 0f31e55d60d107f054fc857c9022fab4a8c87913..e57a67212f333bba5c3e76a3f7d1209c8c4942ef 100644 (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;
index 0e44493d674fc7669f4ac9ca0c3514fadb4fb160..5146483f368506b733e55881e91cb43cc846be79 100644 (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;
index bcddd4f73e296da8c518642eb4e2c1da11259a58..20ebfd391d686ca202ff5787f7d44cea424a83c2 100644 (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;
index 7308d036fe3ae669da3f050d3e093557182613b5..4fdeef6bdcbc7f02502e1e9858cd4828b715fe2a 100644 (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 */
index 022dcd0275c939bd03316e42fdcbe6b6248b7fa4..1c7f3a05b0be6945a089bf9bffe54ec9a3483c85 100644 (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) {
index c866ebaaea2d417e03b72caf2441a5be467c00c6..564fbdbadf82f030abdb80c0215b5fd4577428d4 100644 (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;
index abfe445414aaaaeff5fb4e473a33ac68c385d1b4..3abda6a54c1e9bb1cdeba099b4259939a01d7f72 100644 (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));
index f436b54df68cf0bac095f6ab1f022995d0b03618..dc124f8cf3789f5cc45afc37f43eed070e66a6e8 100644 (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;
                }
index 913906742864cbd9ba4ccc571abc89af074cab44..50216adefe22bea6b9d11b1ba78f102a8735288a 100644 (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;
index c68f6e1f08ef07f6129191ae5917fdefe94e91aa..bc313a524917211bee286adf366cb14fe5255f7b 100644 (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();
index f91ba589b8b2b5af668c905bf84bd84d8ea2ad39..bf03a164f8eca17dd3ddb75bb2f017ff23ea7767 100644 (file)
@@ -70,6 +70,9 @@ public:
 
        bool need_update;
 
+       int num_samples;
+       int num_parts;
+
 private:
        BakeData *m_bake_data;
        bool m_is_baking;
index 5d1219bfef36095ecfa0a547e0be5cdd4502f082..e721a3f5047d98dae1831567492eb2634c4335c5 100644 (file)
@@ -149,6 +149,12 @@ public:
                sample++;
        }
 
+       void increment_sample_update()
+       {
+               increment_sample();
+               set_update();
+       }
+
        int get_sample()
        {
                return sample;