ClangFormat: apply to source, most of intern
[blender.git] / intern / cycles / render / bake.cpp
1 /*
2  * Copyright 2011-2014 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 "render/bake.h"
18 #include "render/mesh.h"
19 #include "render/object.h"
20 #include "render/shader.h"
21 #include "render/integrator.h"
22
23 #include "util/util_foreach.h"
24
25 CCL_NAMESPACE_BEGIN
26
27 BakeData::BakeData(const int object, const size_t tri_offset, const size_t num_pixels)
28     : m_object(object), m_tri_offset(tri_offset), m_num_pixels(num_pixels)
29 {
30   m_primitive.resize(num_pixels);
31   m_u.resize(num_pixels);
32   m_v.resize(num_pixels);
33   m_dudx.resize(num_pixels);
34   m_dudy.resize(num_pixels);
35   m_dvdx.resize(num_pixels);
36   m_dvdy.resize(num_pixels);
37 }
38
39 BakeData::~BakeData()
40 {
41   m_primitive.clear();
42   m_u.clear();
43   m_v.clear();
44   m_dudx.clear();
45   m_dudy.clear();
46   m_dvdx.clear();
47   m_dvdy.clear();
48 }
49
50 void BakeData::set(int i, int prim, float uv[2], float dudx, float dudy, float dvdx, float dvdy)
51 {
52   m_primitive[i] = (prim == -1 ? -1 : m_tri_offset + prim);
53   m_u[i] = uv[0];
54   m_v[i] = uv[1];
55   m_dudx[i] = dudx;
56   m_dudy[i] = dudy;
57   m_dvdx[i] = dvdx;
58   m_dvdy[i] = dvdy;
59 }
60
61 void BakeData::set_null(int i)
62 {
63   m_primitive[i] = -1;
64 }
65
66 int BakeData::object()
67 {
68   return m_object;
69 }
70
71 size_t BakeData::size()
72 {
73   return m_num_pixels;
74 }
75
76 bool BakeData::is_valid(int i)
77 {
78   return m_primitive[i] != -1;
79 }
80
81 uint4 BakeData::data(int i)
82 {
83   return make_uint4(m_object, m_primitive[i], __float_as_int(m_u[i]), __float_as_int(m_v[i]));
84 }
85
86 uint4 BakeData::differentials(int i)
87 {
88   return make_uint4(__float_as_int(m_dudx[i]),
89                     __float_as_int(m_dudy[i]),
90                     __float_as_int(m_dvdx[i]),
91                     __float_as_int(m_dvdy[i]));
92 }
93
94 BakeManager::BakeManager()
95 {
96   m_bake_data = NULL;
97   m_is_baking = false;
98   need_update = true;
99   m_shader_limit = 512 * 512;
100 }
101
102 BakeManager::~BakeManager()
103 {
104   if (m_bake_data)
105     delete m_bake_data;
106 }
107
108 bool BakeManager::get_baking()
109 {
110   return m_is_baking;
111 }
112
113 void BakeManager::set_baking(const bool value)
114 {
115   m_is_baking = value;
116 }
117
118 BakeData *BakeManager::init(const int object, const size_t tri_offset, const size_t num_pixels)
119 {
120   m_bake_data = new BakeData(object, tri_offset, num_pixels);
121   return m_bake_data;
122 }
123
124 void BakeManager::set_shader_limit(const size_t x, const size_t y)
125 {
126   m_shader_limit = x * y;
127   m_shader_limit = (size_t)pow(2, ceil(log(m_shader_limit) / log(2)));
128 }
129
130 bool BakeManager::bake(Device *device,
131                        DeviceScene *dscene,
132                        Scene *scene,
133                        Progress &progress,
134                        ShaderEvalType shader_type,
135                        const int pass_filter,
136                        BakeData *bake_data,
137                        float result[])
138 {
139   size_t num_pixels = bake_data->size();
140
141   int num_samples = aa_samples(scene, bake_data, shader_type);
142
143   /* calculate the total pixel samples for the progress bar */
144   total_pixel_samples = 0;
145   for (size_t shader_offset = 0; shader_offset < num_pixels; shader_offset += m_shader_limit) {
146     size_t shader_size = (size_t)fminf(num_pixels - shader_offset, m_shader_limit);
147     total_pixel_samples += shader_size * num_samples;
148   }
149   progress.reset_sample();
150   progress.set_total_pixel_samples(total_pixel_samples);
151
152   /* needs to be up to date for baking specific AA samples */
153   dscene->data.integrator.aa_samples = num_samples;
154   device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
155
156   for (size_t shader_offset = 0; shader_offset < num_pixels; shader_offset += m_shader_limit) {
157     size_t shader_size = (size_t)fminf(num_pixels - shader_offset, m_shader_limit);
158
159     /* setup input for device task */
160     device_vector<uint4> d_input(device, "bake_input", MEM_READ_ONLY);
161     uint4 *d_input_data = d_input.alloc(shader_size * 2);
162     size_t d_input_size = 0;
163
164     for (size_t i = shader_offset; i < (shader_offset + shader_size); i++) {
165       d_input_data[d_input_size++] = bake_data->data(i);
166       d_input_data[d_input_size++] = bake_data->differentials(i);
167     }
168
169     if (d_input_size == 0) {
170       m_is_baking = false;
171       return false;
172     }
173
174     /* run device task */
175     device_vector<float4> d_output(device, "bake_output", MEM_READ_WRITE);
176     d_output.alloc(shader_size);
177     d_output.zero_to_device();
178     d_input.copy_to_device();
179
180     DeviceTask task(DeviceTask::SHADER);
181     task.shader_input = d_input.device_pointer;
182     task.shader_output = d_output.device_pointer;
183     task.shader_eval_type = shader_type;
184     task.shader_filter = pass_filter;
185     task.shader_x = 0;
186     task.offset = shader_offset;
187     task.shader_w = d_output.size();
188     task.num_samples = num_samples;
189     task.get_cancel = function_bind(&Progress::get_cancel, &progress);
190     task.update_progress_sample = function_bind(&Progress::add_samples_update, &progress, _1, _2);
191
192     device->task_add(task);
193     device->task_wait();
194
195     if (progress.get_cancel()) {
196       d_input.free();
197       d_output.free();
198       m_is_baking = false;
199       return false;
200     }
201
202     d_output.copy_from_device(0, 1, d_output.size());
203     d_input.free();
204
205     /* read result */
206     int k = 0;
207
208     float4 *offset = d_output.data();
209
210     size_t depth = 4;
211     for (size_t i = shader_offset; i < (shader_offset + shader_size); i++) {
212       size_t index = i * depth;
213       float4 out = offset[k++];
214
215       if (bake_data->is_valid(i)) {
216         for (size_t j = 0; j < 4; j++) {
217           result[index + j] = out[j];
218         }
219       }
220     }
221
222     d_output.free();
223   }
224
225   m_is_baking = false;
226   return true;
227 }
228
229 void BakeManager::device_update(Device * /*device*/,
230                                 DeviceScene * /*dscene*/,
231                                 Scene * /*scene*/,
232                                 Progress &progress)
233 {
234   if (!need_update)
235     return;
236
237   if (progress.get_cancel())
238     return;
239
240   need_update = false;
241 }
242
243 void BakeManager::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
244 {
245 }
246
247 int BakeManager::aa_samples(Scene *scene, BakeData *bake_data, ShaderEvalType type)
248 {
249   if (type == SHADER_EVAL_UV || type == SHADER_EVAL_ROUGHNESS) {
250     return 1;
251   }
252   else if (type == SHADER_EVAL_NORMAL) {
253     /* Only antialias normal if mesh has bump mapping. */
254     Object *object = scene->objects[bake_data->object()];
255
256     if (object->mesh) {
257       foreach (Shader *shader, object->mesh->used_shaders) {
258         if (shader->has_bump) {
259           return scene->integrator->aa_samples;
260         }
261       }
262     }
263
264     return 1;
265   }
266   else {
267     return scene->integrator->aa_samples;
268   }
269 }
270
271 /* Keep it synced with kernel_bake.h logic */
272 int BakeManager::shader_type_to_pass_filter(ShaderEvalType type, const int pass_filter)
273 {
274   const int component_flags = pass_filter &
275                               (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT | BAKE_FILTER_COLOR);
276
277   switch (type) {
278     case SHADER_EVAL_AO:
279       return BAKE_FILTER_AO;
280     case SHADER_EVAL_SHADOW:
281       return BAKE_FILTER_DIRECT;
282     case SHADER_EVAL_DIFFUSE:
283       return BAKE_FILTER_DIFFUSE | component_flags;
284     case SHADER_EVAL_GLOSSY:
285       return BAKE_FILTER_GLOSSY | component_flags;
286     case SHADER_EVAL_TRANSMISSION:
287       return BAKE_FILTER_TRANSMISSION | component_flags;
288     case SHADER_EVAL_SUBSURFACE:
289       return BAKE_FILTER_SUBSURFACE | component_flags;
290     case SHADER_EVAL_COMBINED:
291       return pass_filter;
292     default:
293       return 0;
294   }
295 }
296
297 CCL_NAMESPACE_END