Cycles: Remove unneeded include statements
[blender-staging.git] / intern / cycles / device / device.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/device.h"
21 #include "device/device_intern.h"
22
23 #include "util/util_foreach.h"
24 #include "util/util_half.h"
25 #include "util/util_logging.h"
26 #include "util/util_math.h"
27 #include "util/util_opengl.h"
28 #include "util/util_time.h"
29 #include "util/util_system.h"
30 #include "util/util_types.h"
31 #include "util/util_vector.h"
32 #include "util/util_string.h"
33
34 CCL_NAMESPACE_BEGIN
35
36 bool Device::need_types_update = true;
37 bool Device::need_devices_update = true;
38 thread_mutex Device::device_mutex;
39 vector<DeviceType> Device::types;
40 vector<DeviceInfo> Device::devices;
41
42 /* Device Requested Features */
43
44 std::ostream& operator <<(std::ostream &os,
45                           const DeviceRequestedFeatures& requested_features)
46 {
47         os << "Experimental features: "
48            << (requested_features.experimental ? "On" : "Off") << std::endl;
49         os << "Max nodes group: " << requested_features.max_nodes_group << std::endl;
50         /* TODO(sergey): Decode bitflag into list of names. */
51         os << "Nodes features: " << requested_features.nodes_features << std::endl;
52         os << "Use Hair: "
53            << string_from_bool(requested_features.use_hair) << std::endl;
54         os << "Use Object Motion: "
55            << string_from_bool(requested_features.use_object_motion) << std::endl;
56         os << "Use Camera Motion: "
57            << string_from_bool(requested_features.use_camera_motion) << std::endl;
58         os << "Use Baking: "
59            << string_from_bool(requested_features.use_baking) << std::endl;
60         os << "Use Subsurface: "
61            << string_from_bool(requested_features.use_subsurface) << std::endl;
62         os << "Use Volume: "
63            << string_from_bool(requested_features.use_volume) << std::endl;
64         os << "Use Branched Integrator: "
65            << string_from_bool(requested_features.use_integrator_branched) << std::endl;
66         os << "Use Patch Evaluation: "
67            << string_from_bool(requested_features.use_patch_evaluation) << std::endl;
68         os << "Use Transparent Shadows: "
69            << string_from_bool(requested_features.use_transparent) << std::endl;
70         os << "Use Principled BSDF: "
71            << string_from_bool(requested_features.use_principled) << std::endl;
72         os << "Use Denoising: "
73            << string_from_bool(requested_features.use_denoising) << std::endl;
74         return os;
75 }
76
77 /* Device */
78
79 Device::~Device()
80 {
81         if(!background && vertex_buffer != 0) {
82                 glDeleteBuffers(1, &vertex_buffer);
83         }
84 }
85
86 void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dx, int dy, int width, int height, bool transparent,
87         const DeviceDrawParams &draw_params)
88 {
89         assert(rgba.type == MEM_PIXELS);
90
91         mem_copy_from(rgba, y, w, h, rgba.memory_elements_size(1));
92
93         if(transparent) {
94                 glEnable(GL_BLEND);
95                 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
96         }
97
98         glColor3f(1.0f, 1.0f, 1.0f);
99
100         if(rgba.data_type == TYPE_HALF) {
101                 /* for multi devices, this assumes the inefficient method that we allocate
102                  * all pixels on the device even though we only render to a subset */
103                 GLhalf *host_pointer = (GLhalf*)rgba.host_pointer;
104                 float vbuffer[16], *basep;
105                 float *vp = NULL;
106
107                 host_pointer += 4*y*w;
108
109                 /* draw half float texture, GLSL shader for display transform assumed to be bound */
110                 GLuint texid;
111                 glGenTextures(1, &texid);
112                 glBindTexture(GL_TEXTURE_2D, texid);
113                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGBA, GL_HALF_FLOAT, host_pointer);
114                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
115                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
116
117                 glEnable(GL_TEXTURE_2D);
118
119                 if(draw_params.bind_display_space_shader_cb) {
120                         draw_params.bind_display_space_shader_cb();
121                 }
122
123                 if(GLEW_VERSION_1_5) {
124                         if(!vertex_buffer)
125                                 glGenBuffers(1, &vertex_buffer);
126
127                         glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
128                         /* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */
129                         glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
130
131                         vp = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
132
133                         basep = NULL;
134                 }
135                 else {
136                         basep = vbuffer;
137                         vp = vbuffer;
138                 }
139
140                 if(vp) {
141                         /* texture coordinate - vertex pair */
142                         vp[0] = 0.0f;
143                         vp[1] = 0.0f;
144                         vp[2] = dx;
145                         vp[3] = dy;
146
147                         vp[4] = 1.0f;
148                         vp[5] = 0.0f;
149                         vp[6] = (float)width + dx;
150                         vp[7] = dy;
151
152                         vp[8] = 1.0f;
153                         vp[9] = 1.0f;
154                         vp[10] = (float)width + dx;
155                         vp[11] = (float)height + dy;
156
157                         vp[12] = 0.0f;
158                         vp[13] = 1.0f;
159                         vp[14] = dx;
160                         vp[15] = (float)height + dy;
161
162                         if(vertex_buffer)
163                                 glUnmapBuffer(GL_ARRAY_BUFFER);
164                 }
165
166                 glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), basep);
167                 glVertexPointer(2, GL_FLOAT, 4 * sizeof(float), ((char *)basep) + 2 * sizeof(float));
168
169                 glEnableClientState(GL_VERTEX_ARRAY);
170                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
171
172                 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
173
174                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
175                 glDisableClientState(GL_VERTEX_ARRAY);
176
177                 if(vertex_buffer) {
178                         glBindBuffer(GL_ARRAY_BUFFER, 0);
179                 }
180
181                 if(draw_params.unbind_display_space_shader_cb) {
182                         draw_params.unbind_display_space_shader_cb();
183                 }
184
185                 glBindTexture(GL_TEXTURE_2D, 0);
186                 glDisable(GL_TEXTURE_2D);
187                 glDeleteTextures(1, &texid);
188         }
189         else {
190                 /* fallback for old graphics cards that don't support GLSL, half float,
191                  * and non-power-of-two textures */
192                 glPixelZoom((float)width/(float)w, (float)height/(float)h);
193                 glRasterPos2f(dx, dy);
194
195                 uint8_t *pixels = (uint8_t*)rgba.host_pointer;
196
197                 pixels += 4*y*w;
198
199                 glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
200
201                 glRasterPos2f(0.0f, 0.0f);
202                 glPixelZoom(1.0f, 1.0f);
203         }
204
205         if(transparent)
206                 glDisable(GL_BLEND);
207 }
208
209 Device *Device::create(DeviceInfo& info, Stats &stats, bool background)
210 {
211         Device *device;
212
213         switch(info.type) {
214                 case DEVICE_CPU:
215                         device = device_cpu_create(info, stats, background);
216                         break;
217 #ifdef WITH_CUDA
218                 case DEVICE_CUDA:
219                         if(device_cuda_init())
220                                 device = device_cuda_create(info, stats, background);
221                         else
222                                 device = NULL;
223                         break;
224 #endif
225 #ifdef WITH_MULTI
226                 case DEVICE_MULTI:
227                         device = device_multi_create(info, stats, background);
228                         break;
229 #endif
230 #ifdef WITH_NETWORK
231                 case DEVICE_NETWORK:
232                         device = device_network_create(info, stats, "127.0.0.1");
233                         break;
234 #endif
235 #ifdef WITH_OPENCL
236                 case DEVICE_OPENCL:
237                         if(device_opencl_init())
238                                 device = device_opencl_create(info, stats, background);
239                         else
240                                 device = NULL;
241                         break;
242 #endif
243                 default:
244                         return NULL;
245         }
246
247         return device;
248 }
249
250 DeviceType Device::type_from_string(const char *name)
251 {
252         if(strcmp(name, "CPU") == 0)
253                 return DEVICE_CPU;
254         else if(strcmp(name, "CUDA") == 0)
255                 return DEVICE_CUDA;
256         else if(strcmp(name, "OPENCL") == 0)
257                 return DEVICE_OPENCL;
258         else if(strcmp(name, "NETWORK") == 0)
259                 return DEVICE_NETWORK;
260         else if(strcmp(name, "MULTI") == 0)
261                 return DEVICE_MULTI;
262
263         return DEVICE_NONE;
264 }
265
266 string Device::string_from_type(DeviceType type)
267 {
268         if(type == DEVICE_CPU)
269                 return "CPU";
270         else if(type == DEVICE_CUDA)
271                 return "CUDA";
272         else if(type == DEVICE_OPENCL)
273                 return "OPENCL";
274         else if(type == DEVICE_NETWORK)
275                 return "NETWORK";
276         else if(type == DEVICE_MULTI)
277                 return "MULTI";
278
279         return "";
280 }
281
282 vector<DeviceType>& Device::available_types()
283 {
284         thread_scoped_lock lock(device_mutex);
285         if(need_types_update) {
286                 types.clear();
287                 types.push_back(DEVICE_CPU);
288 #ifdef WITH_CUDA
289                 if(device_cuda_init()) {
290                         types.push_back(DEVICE_CUDA);
291                 }
292 #endif
293 #ifdef WITH_OPENCL
294                 if(device_opencl_init()) {
295                         types.push_back(DEVICE_OPENCL);
296                 }
297 #endif
298 #ifdef WITH_NETWORK
299                 types.push_back(DEVICE_NETWORK);
300 #endif
301                 need_types_update = false;
302         }
303         return types;
304 }
305
306 vector<DeviceInfo>& Device::available_devices()
307 {
308         thread_scoped_lock lock(device_mutex);
309         if(need_devices_update) {
310                 devices.clear();
311 #ifdef WITH_OPENCL
312                 if(device_opencl_init()) {
313                         device_opencl_info(devices);
314                 }
315 #endif
316 #ifdef WITH_CUDA
317                 if(device_cuda_init()) {
318                         device_cuda_info(devices);
319                 }
320 #endif
321                 device_cpu_info(devices);
322 #ifdef WITH_NETWORK
323                 device_network_info(devices);
324 #endif
325                 need_devices_update = false;
326         }
327         return devices;
328 }
329
330 string Device::device_capabilities()
331 {
332         string capabilities = "CPU device capabilities: ";
333         capabilities += device_cpu_capabilities() + "\n";
334
335 #ifdef WITH_OPENCL
336         if(device_opencl_init()) {
337                 capabilities += "\nOpenCL device capabilities:\n";
338                 capabilities += device_opencl_capabilities();
339         }
340 #endif
341
342 #ifdef WITH_CUDA
343         if(device_cuda_init()) {
344                 capabilities += "\nCUDA device capabilities:\n";
345                 capabilities += device_cuda_capabilities();
346         }
347 #endif
348
349         return capabilities;
350 }
351
352 DeviceInfo Device::get_multi_device(const vector<DeviceInfo>& subdevices, int threads, bool background)
353 {
354         assert(subdevices.size() > 1);
355
356         DeviceInfo info;
357         info.type = DEVICE_MULTI;
358         info.id = "MULTI";
359         info.description = "Multi Device";
360         info.num = 0;
361
362         info.has_fermi_limits = false;
363         info.has_half_images = true;
364         info.has_volume_decoupled = true;
365         info.has_qbvh = true;
366         info.has_osl = true;
367
368         foreach(const DeviceInfo &device, subdevices) {
369                 /* Ensure CPU device does not slow down GPU. */
370                 if(device.type == DEVICE_CPU && subdevices.size() > 1) {
371                         if(background) {
372                                 int orig_cpu_threads = (threads)? threads: system_cpu_thread_count();
373                                 int cpu_threads = max(orig_cpu_threads - (subdevices.size() - 1), 0);
374
375                                 VLOG(1) << "CPU render threads reduced from "
376                                                 << orig_cpu_threads << " to " << cpu_threads
377                                                 << ", to dedicate to GPU.";
378
379                                 if(cpu_threads >= 1) {
380                                         DeviceInfo cpu_device = device;
381                                         cpu_device.cpu_threads = cpu_threads;
382                                         info.multi_devices.push_back(cpu_device);
383                                 }
384                                 else {
385                                         continue;
386                                 }
387                         }
388                         else {
389                                 VLOG(1) << "CPU render threads disabled for interactive render.";
390                                 continue;
391                         }
392                 }
393                 else {
394                         info.multi_devices.push_back(device);
395                 }
396
397                 /* Accumulate device info. */
398                 info.has_fermi_limits = info.has_fermi_limits ||
399                                         device.has_fermi_limits;
400                 info.has_half_images &= device.has_half_images;
401                 info.has_volume_decoupled &= device.has_volume_decoupled;
402                 info.has_qbvh &= device.has_qbvh;
403                 info.has_osl &= device.has_osl;
404         }
405
406         return info;
407 }
408
409 void Device::tag_update()
410 {
411         need_types_update = true;
412         need_devices_update = true;
413 }
414
415 void Device::free_memory()
416 {
417         need_types_update = true;
418         need_devices_update = true;
419         types.free_memory();
420         devices.free_memory();
421 }
422
423 CCL_NAMESPACE_END