Cycles-Bake: displacement support (fix T40068)
[blender-staging.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 "bake.h"
18
19 CCL_NAMESPACE_BEGIN
20
21 BakeData::BakeData(const int object, const int tri_offset, const int num_pixels):
22 m_object(object),
23 m_tri_offset(tri_offset),
24 m_num_pixels(num_pixels)
25 {
26         m_primitive.resize(num_pixels);
27         m_u.resize(num_pixels);
28         m_v.resize(num_pixels);
29         m_dudx.resize(num_pixels);
30         m_dudy.resize(num_pixels);
31         m_dvdx.resize(num_pixels);
32         m_dvdy.resize(num_pixels);
33 }
34
35 BakeData::~BakeData()
36 {
37         m_primitive.clear();
38         m_u.clear();
39         m_v.clear();
40         m_dudx.clear();
41         m_dudy.clear();
42         m_dvdx.clear();
43         m_dvdy.clear();
44 }
45
46 void BakeData::set(int i, int prim, float uv[2], float dudx, float dudy, float dvdx, float dvdy)
47 {
48         m_primitive[i] = (prim == -1 ? -1 : m_tri_offset + prim);
49         m_u[i] = uv[0];
50         m_v[i] = uv[1];
51         m_dudx[i] = dudx;
52         m_dudy[i] = dudy;
53         m_dvdx[i] = dvdx;
54         m_dvdy[i] = dvdy;
55 }
56
57 int BakeData::object()
58 {
59         return m_object;
60 }
61
62 int BakeData::size()
63 {
64         return m_num_pixels;
65 }
66
67 bool BakeData::is_valid(int i)
68 {
69         return m_primitive[i] != -1;
70 }
71
72 uint4 BakeData::data(int i)
73 {
74         return make_uint4(
75                 m_object,
76                 m_primitive[i],
77                 __float_as_int(m_u[i]),
78                 __float_as_int(m_v[i])
79                 );
80 }
81
82 uint4 BakeData::differentials(int i)
83 {
84         return make_uint4(
85                   __float_as_int(m_dudx[i]),
86                   __float_as_int(m_dudy[i]),
87                   __float_as_int(m_dvdx[i]),
88                   __float_as_int(m_dvdy[i])
89                   );
90 }
91
92 BakeManager::BakeManager()
93 {
94         m_bake_data = NULL;
95         m_is_baking = false;
96         need_update = true;
97 }
98
99 BakeManager::~BakeManager()
100 {
101         if(m_bake_data)
102                 delete m_bake_data;
103 }
104
105 bool BakeManager::get_baking()
106 {
107         return m_is_baking;
108 }
109
110 void BakeManager::set_baking(const bool value)
111 {
112         m_is_baking = value;
113 }
114
115 BakeData *BakeManager::init(const int object, const int tri_offset, const int num_pixels)
116 {
117         m_bake_data = new BakeData(object, tri_offset, num_pixels);
118         return m_bake_data;
119 }
120
121 bool BakeManager::bake(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress, ShaderEvalType shader_type, BakeData *bake_data, float result[])
122 {
123         size_t limit = bake_data->size();
124
125         /* setup input for device task */
126         device_vector<uint4> d_input;
127         uint4 *d_input_data = d_input.resize(limit * 2);
128         size_t d_input_size = 0;
129
130         for(size_t i = 0; i < limit; i++) {
131                 d_input_data[d_input_size++] = bake_data->data(i);
132                 d_input_data[d_input_size++] = bake_data->differentials(i);
133         }
134
135         if(d_input_size == 0)
136                 return false;
137
138         /* run device task */
139         device_vector<float4> d_output;
140         d_output.resize(limit);
141
142         /* needs to be up to data for attribute access */
143         device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
144
145         device->mem_alloc(d_input, MEM_READ_ONLY);
146         device->mem_copy_to(d_input);
147         device->mem_alloc(d_output, MEM_WRITE_ONLY);
148
149         DeviceTask task(DeviceTask::SHADER);
150         task.shader_input = d_input.device_pointer;
151         task.shader_output = d_output.device_pointer;
152         task.shader_eval_type = shader_type;
153         task.shader_x = 0;
154         task.shader_w = d_output.size();
155         task.get_cancel = function_bind(&Progress::get_cancel, &progress);
156
157         device->task_add(task);
158         device->task_wait();
159
160         if(progress.get_cancel()) {
161                 device->mem_free(d_input);
162                 device->mem_free(d_output);
163                 m_is_baking = false;
164                 return false;
165         }
166
167         device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4));
168         device->mem_free(d_input);
169         device->mem_free(d_output);
170
171         /* read result */
172         int k = 0;
173
174         float4 *offset = (float4*)d_output.data_pointer;
175
176         size_t depth = 4;
177         for(size_t i = 0; i < limit; i++) {
178                 size_t index = i * depth;
179                 float4 out = offset[k++];
180
181                 if(bake_data->is_valid(i)) {
182                         for(size_t j=0; j < 4; j++) {
183                                 result[index + j] = out[j];
184                         }
185                 }
186         }
187
188         m_is_baking = false;
189         return true;
190 }
191
192 void BakeManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
193 {
194         if(!need_update)
195                 return;
196
197         if(progress.get_cancel()) return;
198
199         need_update = false;
200 }
201
202 void BakeManager::device_free(Device *device, DeviceScene *dscene)
203 {
204 }
205
206 CCL_NAMESPACE_END