Cycles: add single program debug option for split kernel
[blender-staging.git] / intern / cycles / device / device_task.cpp
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 <stdlib.h>
18 #include <string.h>
19
20 #include "device_task.h"
21
22 #include "buffers.h"
23
24 #include "util_algorithm.h"
25 #include "util_time.h"
26
27 CCL_NAMESPACE_BEGIN
28
29 /* Device Task */
30
31 DeviceTask::DeviceTask(Type type_)
32 : type(type_), x(0), y(0), w(0), h(0), rgba_byte(0), rgba_half(0), buffer(0),
33   sample(0), num_samples(1),
34   shader_input(0), shader_output(0), shader_output_luma(0),
35   shader_eval_type(0), shader_filter(0), shader_x(0), shader_w(0)
36 {
37         last_update_time = time_dt();
38 }
39
40 int DeviceTask::get_subtask_count(int num, int max_size)
41 {
42         if(max_size != 0) {
43                 int max_size_num;
44
45                 if(type == SHADER) {
46                         max_size_num = (shader_w + max_size - 1)/max_size;
47                 }
48                 else {
49                         max_size = max(1, max_size/w);
50                         max_size_num = (h + max_size - 1)/max_size;
51                 }
52
53                 num = max(max_size_num, num);
54         }
55
56         if(type == SHADER) {
57                 num = min(shader_w, num);
58         }
59         else if(type == PATH_TRACE) {
60         }
61         else {
62                 num = min(h, num);
63         }
64
65         return num;
66 }
67
68 void DeviceTask::split(list<DeviceTask>& tasks, int num, int max_size)
69 {
70         num = get_subtask_count(num, max_size);
71
72         if(type == SHADER) {
73                 for(int i = 0; i < num; i++) {
74                         int tx = shader_x + (shader_w/num)*i;
75                         int tw = (i == num-1)? shader_w - i*(shader_w/num): shader_w/num;
76
77                         DeviceTask task = *this;
78
79                         task.shader_x = tx;
80                         task.shader_w = tw;
81
82                         tasks.push_back(task);
83                 }
84         }
85         else if(type == PATH_TRACE) {
86                 for(int i = 0; i < num; i++)
87                         tasks.push_back(*this);
88         }
89         else {
90                 for(int i = 0; i < num; i++) {
91                         int ty = y + (h/num)*i;
92                         int th = (i == num-1)? h - i*(h/num): h/num;
93
94                         DeviceTask task = *this;
95
96                         task.y = ty;
97                         task.h = th;
98
99                         tasks.push_back(task);
100                 }
101         }
102 }
103
104 void DeviceTask::update_progress(RenderTile *rtile, int pixel_samples)
105 {
106         if((type != PATH_TRACE) &&
107            (type != SHADER))
108                 return;
109
110         if(update_progress_sample) {
111                 if(pixel_samples == -1) {
112                         pixel_samples = shader_w;
113                 }
114                 update_progress_sample(pixel_samples, rtile? rtile->sample : 0);
115         }
116
117         if(update_tile_sample) {
118                 double current_time = time_dt();
119
120                 if(current_time - last_update_time >= 1.0) {
121                         update_tile_sample(*rtile);
122
123                         last_update_time = current_time;
124                 }
125         }
126 }
127
128 CCL_NAMESPACE_END
129