2342dd52d866099efb43bdb9998f8fae20440610
[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   device(device)
120 {
121 }
122
123 RenderBuffers::~RenderBuffers()
124 {
125         device_free();
126 }
127
128 void RenderBuffers::device_free()
129 {
130         if(buffer.device_pointer) {
131                 device->mem_free(buffer);
132                 buffer.clear();
133         }
134 }
135
136 void RenderBuffers::reset(Device *device, BufferParams& params_)
137 {
138         params = params_;
139
140         /* free existing buffers */
141         device_free();
142
143         /* allocate buffer */
144         buffer.resize(params.width*params.height*params.get_passes_size());
145         device->mem_alloc(buffer);
146         device->mem_zero(buffer);
147 }
148
149 void RenderBuffers::zero(Device *device)
150 {
151         if(buffer.device_pointer) {
152                 device->mem_zero(buffer);
153         }
154 }
155
156 bool RenderBuffers::copy_from_device(Device *from_device)
157 {
158         if(!buffer.device_pointer)
159                 return false;
160
161         if(!from_device) {
162                 from_device = device;
163         }
164
165         from_device->mem_copy_from(buffer, 0, params.width, params.height, params.get_passes_size()*sizeof(float));
166
167         return true;
168 }
169
170 bool RenderBuffers::get_denoising_pass_rect(int offset, float exposure, int sample, int components, float *pixels)
171 {
172         float invsample = 1.0f/sample;
173         float scale = invsample;
174         bool variance = (offset == DENOISING_PASS_NORMAL_VAR) ||
175                         (offset == DENOISING_PASS_ALBEDO_VAR) ||
176                         (offset == DENOISING_PASS_DEPTH_VAR) ||
177                         (offset == DENOISING_PASS_COLOR_VAR);
178
179         if(offset == DENOISING_PASS_COLOR) {
180                 scale *= exposure;
181         }
182         else if(offset == DENOISING_PASS_COLOR_VAR) {
183                 scale *= exposure*exposure;
184         }
185
186         offset += params.get_denoising_offset();
187         int pass_stride = params.get_passes_size();
188         int size = params.width*params.height;
189
190         if(variance) {
191                 /* Approximate variance as E[x^2] - 1/N * (E[x])^2, since online variance
192                  * update does not work efficiently with atomics in the kernel. */
193                 int mean_offset = offset - components;
194                 float *mean = (float*)buffer.data_pointer + mean_offset;
195                 float *var = (float*)buffer.data_pointer + offset;
196                 assert(mean_offset >= 0);
197
198                 if(components == 1) {
199                         for(int i = 0; i < size; i++, mean += pass_stride, var += pass_stride, pixels++) {
200                                 pixels[0] = max(0.0f, var[0] - mean[0]*mean[0]*invsample)*scale;
201                         }
202                 }
203                 else if(components == 3) {
204                         for(int i = 0; i < size; i++, mean += pass_stride, var += pass_stride, pixels += 3) {
205                                 pixels[0] = max(0.0f, var[0] - mean[0]*mean[0]*invsample)*scale;
206                                 pixels[1] = max(0.0f, var[1] - mean[1]*mean[1]*invsample)*scale;
207                                 pixels[2] = max(0.0f, var[2] - mean[2]*mean[2]*invsample)*scale;
208                         }
209                 }
210                 else {
211                         return false;
212                 }
213         }
214         else {
215                 float *in = (float*)buffer.data_pointer + offset;
216
217                 if(components == 1) {
218                         for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
219                                 pixels[0] = in[0]*scale;
220                         }
221                 }
222                 else if(components == 3) {
223                         for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
224                                 pixels[0] = in[0]*scale;
225                                 pixels[1] = in[1]*scale;
226                                 pixels[2] = in[2]*scale;
227                         }
228                 }
229                 else {
230                         return false;
231                 }
232         }
233
234         return true;
235 }
236
237 bool RenderBuffers::get_pass_rect(PassType type, float exposure, int sample, int components, float *pixels)
238 {
239         int pass_offset = 0;
240
241         for(size_t j = 0; j < params.passes.size(); j++) {
242                 Pass& pass = params.passes[j];
243
244                 if(pass.type != type) {
245                         pass_offset += pass.components;
246                         continue;
247                 }
248
249                 float *in = (float*)buffer.data_pointer + pass_offset;
250                 int pass_stride = params.get_passes_size();
251
252                 float scale = (pass.filter)? 1.0f/(float)sample: 1.0f;
253                 float scale_exposure = (pass.exposure)? scale*exposure: scale;
254
255                 int size = params.width*params.height;
256
257                 if(components == 1) {
258                         assert(pass.components == components);
259
260                         /* scalar */
261                         if(type == PASS_DEPTH) {
262                                 for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
263                                         float f = *in;
264                                         pixels[0] = (f == 0.0f)? 1e10f: f*scale_exposure;
265                                 }
266                         }
267                         else if(type == PASS_MIST) {
268                                 for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
269                                         float f = *in;
270                                         pixels[0] = saturate(f*scale_exposure);
271                                 }
272                         }
273 #ifdef WITH_CYCLES_DEBUG
274                         else if(type == PASS_BVH_TRAVERSED_NODES ||
275                                 type == PASS_BVH_TRAVERSED_INSTANCES ||
276                                 type == PASS_BVH_INTERSECTIONS ||
277                                 type == PASS_RAY_BOUNCES)
278                         {
279                                 for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
280                                         float f = *in;
281                                         pixels[0] = f*scale;
282                                 }
283                         }
284 #endif
285                         else {
286                                 for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
287                                         float f = *in;
288                                         pixels[0] = f*scale_exposure;
289                                 }
290                         }
291                 }
292                 else if(components == 3) {
293                         assert(pass.components == 4);
294
295                         /* RGBA */
296                         if(type == PASS_SHADOW) {
297                                 for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
298                                         float4 f = make_float4(in[0], in[1], in[2], in[3]);
299                                         float invw = (f.w > 0.0f)? 1.0f/f.w: 1.0f;
300
301                                         pixels[0] = f.x*invw;
302                                         pixels[1] = f.y*invw;
303                                         pixels[2] = f.z*invw;
304                                 }
305                         }
306                         else if(pass.divide_type != PASS_NONE) {
307                                 /* RGB lighting passes that need to divide out color */
308                                 pass_offset = 0;
309                                 for(size_t k = 0; k < params.passes.size(); k++) {
310                                         Pass& color_pass = params.passes[k];
311                                         if(color_pass.type == pass.divide_type)
312                                                 break;
313                                         pass_offset += color_pass.components;
314                                 }
315
316                                 float *in_divide = (float*)buffer.data_pointer + pass_offset;
317
318                                 for(int i = 0; i < size; i++, in += pass_stride, in_divide += pass_stride, pixels += 3) {
319                                         float3 f = make_float3(in[0], in[1], in[2]);
320                                         float3 f_divide = make_float3(in_divide[0], in_divide[1], in_divide[2]);
321
322                                         f = safe_divide_even_color(f*exposure, f_divide);
323
324                                         pixels[0] = f.x;
325                                         pixels[1] = f.y;
326                                         pixels[2] = f.z;
327                                 }
328                         }
329                         else {
330                                 /* RGB/vector */
331                                 for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
332                                         float3 f = make_float3(in[0], in[1], in[2]);
333
334                                         pixels[0] = f.x*scale_exposure;
335                                         pixels[1] = f.y*scale_exposure;
336                                         pixels[2] = f.z*scale_exposure;
337                                 }
338                         }
339                 }
340                 else if(components == 4) {
341                         assert(pass.components == components);
342
343                         /* RGBA */
344                         if(type == PASS_SHADOW) {
345                                 for(int i = 0; i < size; i++, in += pass_stride, pixels += 4) {
346                                         float4 f = make_float4(in[0], in[1], in[2], in[3]);
347                                         float invw = (f.w > 0.0f)? 1.0f/f.w: 1.0f;
348
349                                         pixels[0] = f.x*invw;
350                                         pixels[1] = f.y*invw;
351                                         pixels[2] = f.z*invw;
352                                         pixels[3] = 1.0f;
353                                 }
354                         }
355                         else if(type == PASS_MOTION) {
356                                 /* need to normalize by number of samples accumulated for motion */
357                                 pass_offset = 0;
358                                 for(size_t k = 0; k < params.passes.size(); k++) {
359                                         Pass& color_pass = params.passes[k];
360                                         if(color_pass.type == PASS_MOTION_WEIGHT)
361                                                 break;
362                                         pass_offset += color_pass.components;
363                                 }
364
365                                 float *in_weight = (float*)buffer.data_pointer + pass_offset;
366
367                                 for(int i = 0; i < size; i++, in += pass_stride, in_weight += pass_stride, pixels += 4) {
368                                         float4 f = make_float4(in[0], in[1], in[2], in[3]);
369                                         float w = in_weight[0];
370                                         float invw = (w > 0.0f)? 1.0f/w: 0.0f;
371
372                                         pixels[0] = f.x*invw;
373                                         pixels[1] = f.y*invw;
374                                         pixels[2] = f.z*invw;
375                                         pixels[3] = f.w*invw;
376                                 }
377                         }
378                         else {
379                                 for(int i = 0; i < size; i++, in += pass_stride, pixels += 4) {
380                                         float4 f = make_float4(in[0], in[1], in[2], in[3]);
381
382                                         pixels[0] = f.x*scale_exposure;
383                                         pixels[1] = f.y*scale_exposure;
384                                         pixels[2] = f.z*scale_exposure;
385
386                                         /* clamp since alpha might be > 1.0 due to russian roulette */
387                                         pixels[3] = saturate(f.w*scale);
388                                 }
389                         }
390                 }
391
392                 return true;
393         }
394
395         return false;
396 }
397
398 /* Display Buffer */
399
400 DisplayBuffer::DisplayBuffer(Device *device, bool linear)
401 : draw_width(0),
402   draw_height(0),
403   transparent(true), /* todo: determine from background */
404   half_float(linear),
405   rgba_byte(device, "display buffer byte", MEM_WRITE_ONLY),
406   rgba_half(device, "display buffer half", MEM_WRITE_ONLY),
407   device(device)
408 {
409 }
410
411 DisplayBuffer::~DisplayBuffer()
412 {
413         device_free();
414 }
415
416 void DisplayBuffer::device_free()
417 {
418         if(rgba_byte.device_pointer) {
419                 device->pixels_free(rgba_byte);
420                 rgba_byte.clear();
421         }
422         if(rgba_half.device_pointer) {
423                 device->pixels_free(rgba_half);
424                 rgba_half.clear();
425         }
426 }
427
428 void DisplayBuffer::reset(Device *device, BufferParams& params_)
429 {
430         draw_width = 0;
431         draw_height = 0;
432
433         params = params_;
434
435         /* free existing buffers */
436         device_free();
437
438         /* allocate display pixels */
439         if(half_float) {
440                 rgba_half.resize(params.width, params.height);
441                 device->pixels_alloc(rgba_half);
442         }
443         else {
444                 rgba_byte.resize(params.width, params.height);
445                 device->pixels_alloc(rgba_byte);
446         }
447 }
448
449 void DisplayBuffer::draw_set(int width, int height)
450 {
451         assert(width <= params.width && height <= params.height);
452
453         draw_width = width;
454         draw_height = height;
455 }
456
457 void DisplayBuffer::draw(Device *device, const DeviceDrawParams& draw_params)
458 {
459         if(draw_width != 0 && draw_height != 0) {
460                 device_memory& rgba = rgba_data();
461
462                 device->draw_pixels(rgba, 0, draw_width, draw_height, params.full_x, params.full_y, params.width, params.height, transparent, draw_params);
463         }
464 }
465
466 bool DisplayBuffer::draw_ready()
467 {
468         return (draw_width != 0 && draw_height != 0);
469 }
470
471 void DisplayBuffer::write(Device *device, const string& filename)
472 {
473         int w = draw_width;
474         int h = draw_height;
475
476         if(w == 0 || h == 0)
477                 return;
478         
479         if(half_float)
480                 return;
481
482         /* read buffer from device */
483         device_memory& rgba = rgba_data();
484         device->pixels_copy_from(rgba, 0, w, h);
485
486         /* write image */
487         ImageOutput *out = ImageOutput::create(filename);
488         ImageSpec spec(w, h, 4, TypeDesc::UINT8);
489         int scanlinesize = w*4*sizeof(uchar);
490
491         out->open(filename, spec);
492
493         /* conversion for different top/bottom convention */
494         out->write_image(TypeDesc::UINT8,
495                 (uchar*)rgba.data_pointer + (h-1)*scanlinesize,
496                 AutoStride,
497                 -scanlinesize,
498                 AutoStride);
499
500         out->close();
501
502         delete out;
503 }
504
505 device_memory& DisplayBuffer::rgba_data()
506 {
507         if(half_float)
508                 return rgba_half;
509         else
510                 return rgba_byte;
511 }
512
513 CCL_NAMESPACE_END
514