9899fa1c39c736a7131580c6d043195b30e8af17
[blender-staging.git] / intern / cycles / render / buffers.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
19 #include "render/buffers.h"
20 #include "device/device.h"
21
22 #include "util/util_debug.h"
23 #include "util/util_foreach.h"
24 #include "util/util_hash.h"
25 #include "util/util_image.h"
26 #include "util/util_math.h"
27 #include "util/util_opengl.h"
28 #include "util/util_time.h"
29 #include "util/util_types.h"
30
31 CCL_NAMESPACE_BEGIN
32
33 /* Buffer Params */
34
35 BufferParams::BufferParams()
36 {
37         width = 0;
38         height = 0;
39
40         full_x = 0;
41         full_y = 0;
42         full_width = 0;
43         full_height = 0;
44
45         denoising_data_pass = false;
46         denoising_clean_pass = false;
47
48         Pass::add(PASS_COMBINED, passes);
49 }
50
51 void BufferParams::get_offset_stride(int& offset, int& stride)
52 {
53         offset = -(full_x + full_y*width);
54         stride = width;
55 }
56
57 bool BufferParams::modified(const BufferParams& params)
58 {
59         return !(full_x == params.full_x
60                 && full_y == params.full_y
61                 && width == params.width
62                 && height == params.height
63                 && full_width == params.full_width
64                 && full_height == params.full_height
65                 && Pass::equals(passes, params.passes));
66 }
67
68 int BufferParams::get_passes_size()
69 {
70         int size = 0;
71
72         for(size_t i = 0; i < passes.size(); i++)
73                 size += passes[i].components;
74
75         if(denoising_data_pass) {
76                 size += DENOISING_PASS_SIZE_BASE;
77                 if(denoising_clean_pass) size += DENOISING_PASS_SIZE_CLEAN;
78         }
79
80         return align_up(size, 4);
81 }
82
83 int BufferParams::get_denoising_offset()
84 {
85         int offset = 0;
86
87         for(size_t i = 0; i < passes.size(); i++)
88                 offset += passes[i].components;
89
90         return offset;
91 }
92
93 /* Render Buffer Task */
94
95 RenderTile::RenderTile()
96 {
97         x = 0;
98         y = 0;
99         w = 0;
100         h = 0;
101
102         sample = 0;
103         start_sample = 0;
104         num_samples = 0;
105         resolution = 0;
106
107         offset = 0;
108         stride = 0;
109
110         buffer = 0;
111
112         buffers = NULL;
113 }
114
115 /* Render Buffers */
116
117 RenderBuffers::RenderBuffers(Device *device)
118 : buffer(device, "RenderBuffers", MEM_READ_WRITE),
119   map_neighbor_copied(false), render_time(0.0f)
120 {
121 }
122
123 RenderBuffers::~RenderBuffers()
124 {
125         buffer.free();
126 }
127
128 void RenderBuffers::reset(BufferParams& params_)
129 {
130         params = params_;
131
132         /* re-allocate buffer */
133         buffer.alloc(params.width*params.height*params.get_passes_size());
134         buffer.zero_to_device();
135 }
136
137 void RenderBuffers::zero()
138 {
139         buffer.zero_to_device();
140 }
141
142 bool RenderBuffers::copy_from_device()
143 {
144         if(!buffer.device_pointer)
145                 return false;
146
147         buffer.copy_from_device(0, params.width * params.get_passes_size(), params.height);
148
149         return true;
150 }
151
152 bool RenderBuffers::get_denoising_pass_rect(int offset, float exposure, int sample, int components, float *pixels)
153 {
154         if(buffer.data() == NULL) {
155                 return false;
156         }
157
158         float invsample = 1.0f/sample;
159         float scale = invsample;
160         bool variance = (offset == DENOISING_PASS_NORMAL_VAR) ||
161                         (offset == DENOISING_PASS_ALBEDO_VAR) ||
162                         (offset == DENOISING_PASS_DEPTH_VAR) ||
163                         (offset == DENOISING_PASS_COLOR_VAR);
164
165         if(offset == DENOISING_PASS_COLOR) {
166                 scale *= exposure;
167         }
168         else if(offset == DENOISING_PASS_COLOR_VAR) {
169                 scale *= exposure*exposure;
170         }
171
172         offset += params.get_denoising_offset();
173         int pass_stride = params.get_passes_size();
174         int size = params.width*params.height;
175
176         if(variance) {
177                 /* Approximate variance as E[x^2] - 1/N * (E[x])^2, since online variance
178                  * update does not work efficiently with atomics in the kernel. */
179                 int mean_offset = offset - components;
180                 float *mean = buffer.data() + mean_offset;
181                 float *var = buffer.data() + offset;
182                 assert(mean_offset >= 0);
183
184                 if(components == 1) {
185                         for(int i = 0; i < size; i++, mean += pass_stride, var += pass_stride, pixels++) {
186                                 pixels[0] = max(0.0f, var[0] - mean[0]*mean[0]*invsample)*scale;
187                         }
188                 }
189                 else if(components == 3) {
190                         for(int i = 0; i < size; i++, mean += pass_stride, var += pass_stride, pixels += 3) {
191                                 pixels[0] = max(0.0f, var[0] - mean[0]*mean[0]*invsample)*scale;
192                                 pixels[1] = max(0.0f, var[1] - mean[1]*mean[1]*invsample)*scale;
193                                 pixels[2] = max(0.0f, var[2] - mean[2]*mean[2]*invsample)*scale;
194                         }
195                 }
196                 else {
197                         return false;
198                 }
199         }
200         else {
201                 float *in = buffer.data() + offset;
202
203                 if(components == 1) {
204                         for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
205                                 pixels[0] = in[0]*scale;
206                         }
207                 }
208                 else if(components == 3) {
209                         for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
210                                 pixels[0] = in[0]*scale;
211                                 pixels[1] = in[1]*scale;
212                                 pixels[2] = in[2]*scale;
213                         }
214                 }
215                 else {
216                         return false;
217                 }
218         }
219
220         return true;
221 }
222
223 bool RenderBuffers::get_pass_rect(PassType type, float exposure, int sample, int components, float *pixels)
224 {
225         if(buffer.data() == NULL) {
226                 return false;
227         }
228
229         int pass_offset = 0;
230
231         for(size_t j = 0; j < params.passes.size(); j++) {
232                 Pass& pass = params.passes[j];
233
234                 if(pass.type != type) {
235                         pass_offset += pass.components;
236                         continue;
237                 }
238
239                 float *in = buffer.data() + pass_offset;
240                 int pass_stride = params.get_passes_size();
241
242                 float scale = (pass.filter)? 1.0f/(float)sample: 1.0f;
243                 float scale_exposure = (pass.exposure)? scale*exposure: scale;
244
245                 int size = params.width*params.height;
246
247                 if(components == 1 && type == PASS_RENDER_TIME) {
248                         /* Render time is not stored by kernel, but measured per tile. */
249                         float val = (float) (1000.0 * render_time/(params.width * params.height * sample));
250                         for(int i = 0; i < size; i++, pixels++) {
251                                 pixels[0] = val;
252                         }
253                 }
254                 else if(components == 1) {
255                         assert(pass.components == components);
256
257                         /* Scalar */
258                         if(type == PASS_DEPTH) {
259                                 for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
260                                         float f = *in;
261                                         pixels[0] = (f == 0.0f)? 1e10f: f*scale_exposure;
262                                 }
263                         }
264                         else if(type == PASS_MIST) {
265                                 for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
266                                         float f = *in;
267                                         pixels[0] = saturate(f*scale_exposure);
268                                 }
269                         }
270 #ifdef WITH_CYCLES_DEBUG
271                         else if(type == PASS_BVH_TRAVERSED_NODES ||
272                                 type == PASS_BVH_TRAVERSED_INSTANCES ||
273                                 type == PASS_BVH_INTERSECTIONS ||
274                                 type == PASS_RAY_BOUNCES)
275                         {
276                                 for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
277                                         float f = *in;
278                                         pixels[0] = f*scale;
279                                 }
280                         }
281 #endif
282                         else {
283                                 for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
284                                         float f = *in;
285                                         pixels[0] = f*scale_exposure;
286                                 }
287                         }
288                 }
289                 else if(components == 3) {
290                         assert(pass.components == 4);
291
292                         /* RGBA */
293                         if(type == PASS_SHADOW) {
294                                 for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
295                                         float4 f = make_float4(in[0], in[1], in[2], in[3]);
296                                         float invw = (f.w > 0.0f)? 1.0f/f.w: 1.0f;
297
298                                         pixels[0] = f.x*invw;
299                                         pixels[1] = f.y*invw;
300                                         pixels[2] = f.z*invw;
301                                 }
302                         }
303                         else if(pass.divide_type != PASS_NONE) {
304                                 /* RGB lighting passes that need to divide out color */
305                                 pass_offset = 0;
306                                 for(size_t k = 0; k < params.passes.size(); k++) {
307                                         Pass& color_pass = params.passes[k];
308                                         if(color_pass.type == pass.divide_type)
309                                                 break;
310                                         pass_offset += color_pass.components;
311                                 }
312
313                                 float *in_divide = buffer.data() + pass_offset;
314
315                                 for(int i = 0; i < size; i++, in += pass_stride, in_divide += pass_stride, pixels += 3) {
316                                         float3 f = make_float3(in[0], in[1], in[2]);
317                                         float3 f_divide = make_float3(in_divide[0], in_divide[1], in_divide[2]);
318
319                                         f = safe_divide_even_color(f*exposure, f_divide);
320
321                                         pixels[0] = f.x;
322                                         pixels[1] = f.y;
323                                         pixels[2] = f.z;
324                                 }
325                         }
326                         else {
327                                 /* RGB/vector */
328                                 for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
329                                         float3 f = make_float3(in[0], in[1], in[2]);
330
331                                         pixels[0] = f.x*scale_exposure;
332                                         pixels[1] = f.y*scale_exposure;
333                                         pixels[2] = f.z*scale_exposure;
334                                 }
335                         }
336                 }
337                 else if(components == 4) {
338                         assert(pass.components == components);
339
340                         /* RGBA */
341                         if(type == PASS_SHADOW) {
342                                 for(int i = 0; i < size; i++, in += pass_stride, pixels += 4) {
343                                         float4 f = make_float4(in[0], in[1], in[2], in[3]);
344                                         float invw = (f.w > 0.0f)? 1.0f/f.w: 1.0f;
345
346                                         pixels[0] = f.x*invw;
347                                         pixels[1] = f.y*invw;
348                                         pixels[2] = f.z*invw;
349                                         pixels[3] = 1.0f;
350                                 }
351                         }
352                         else if(type == PASS_MOTION) {
353                                 /* need to normalize by number of samples accumulated for motion */
354                                 pass_offset = 0;
355                                 for(size_t k = 0; k < params.passes.size(); k++) {
356                                         Pass& color_pass = params.passes[k];
357                                         if(color_pass.type == PASS_MOTION_WEIGHT)
358                                                 break;
359                                         pass_offset += color_pass.components;
360                                 }
361
362                                 float *in_weight = buffer.data() + pass_offset;
363
364                                 for(int i = 0; i < size; i++, in += pass_stride, in_weight += pass_stride, pixels += 4) {
365                                         float4 f = make_float4(in[0], in[1], in[2], in[3]);
366                                         float w = in_weight[0];
367                                         float invw = (w > 0.0f)? 1.0f/w: 0.0f;
368
369                                         pixels[0] = f.x*invw;
370                                         pixels[1] = f.y*invw;
371                                         pixels[2] = f.z*invw;
372                                         pixels[3] = f.w*invw;
373                                 }
374                         }
375                         else {
376                                 for(int i = 0; i < size; i++, in += pass_stride, pixels += 4) {
377                                         float4 f = make_float4(in[0], in[1], in[2], in[3]);
378
379                                         pixels[0] = f.x*scale_exposure;
380                                         pixels[1] = f.y*scale_exposure;
381                                         pixels[2] = f.z*scale_exposure;
382
383                                         /* clamp since alpha might be > 1.0 due to russian roulette */
384                                         pixels[3] = saturate(f.w*scale);
385                                 }
386                         }
387                 }
388
389                 return true;
390         }
391
392         return false;
393 }
394
395 /* Display Buffer */
396
397 DisplayBuffer::DisplayBuffer(Device *device, bool linear)
398 : draw_width(0),
399   draw_height(0),
400   transparent(true), /* todo: determine from background */
401   half_float(linear),
402   rgba_byte(device, "display buffer byte"),
403   rgba_half(device, "display buffer half")
404 {
405 }
406
407 DisplayBuffer::~DisplayBuffer()
408 {
409         rgba_byte.free();
410         rgba_half.free();
411 }
412
413 void DisplayBuffer::reset(BufferParams& params_)
414 {
415         draw_width = 0;
416         draw_height = 0;
417
418         params = params_;
419
420         /* allocate display pixels */
421         if(half_float) {
422                 rgba_half.alloc_to_device(params.width, params.height);
423         }
424         else {
425                 rgba_byte.alloc_to_device(params.width, params.height);
426         }
427 }
428
429 void DisplayBuffer::draw_set(int width, int height)
430 {
431         assert(width <= params.width && height <= params.height);
432
433         draw_width = width;
434         draw_height = height;
435 }
436
437 void DisplayBuffer::draw(Device *device, const DeviceDrawParams& draw_params)
438 {
439         if(draw_width != 0 && draw_height != 0) {
440                 device_memory& rgba = (half_float)? (device_memory&)rgba_half:
441                                                     (device_memory&)rgba_byte;
442
443                 device->draw_pixels(rgba, 0, draw_width, draw_height, params.full_x, params.full_y, params.width, params.height, transparent, draw_params);
444         }
445 }
446
447 bool DisplayBuffer::draw_ready()
448 {
449         return (draw_width != 0 && draw_height != 0);
450 }
451
452 void DisplayBuffer::write(const string& filename)
453 {
454         int w = draw_width;
455         int h = draw_height;
456
457         if(w == 0 || h == 0)
458                 return;
459         
460         if(half_float)
461                 return;
462
463         /* read buffer from device */
464         uchar4 *pixels = rgba_byte.copy_from_device(0, w, h);
465
466         /* write image */
467         ImageOutput *out = ImageOutput::create(filename);
468         ImageSpec spec(w, h, 4, TypeDesc::UINT8);
469
470         out->open(filename, spec);
471
472         /* conversion for different top/bottom convention */
473         out->write_image(TypeDesc::UINT8,
474                 (uchar*)(pixels + (h-1)*w),
475                 AutoStride,
476                 -w*sizeof(uchar4),
477                 AutoStride);
478
479         out->close();
480
481         delete out;
482 }
483
484 CCL_NAMESPACE_END
485