Cycles: svn merge -r39669:39870 https://svn.blender.org/svnroot/bf-blender/trunk...
[blender.git] / intern / cycles / device / device.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include "device.h"
23 #include "device_intern.h"
24
25 #include "util_cuda.h"
26 #include "util_debug.h"
27 #include "util_opencl.h"
28 #include "util_opengl.h"
29 #include "util_types.h"
30 #include "util_vector.h"
31
32 CCL_NAMESPACE_BEGIN
33
34 /* Device Task */
35
36 DeviceTask::DeviceTask(Type type_)
37 : type(type_), x(0), y(0), w(0), h(0), rng_state(0), rgba(0), buffer(0),
38   pass(0), resolution(0),
39   displace_input(0), displace_offset(0), displace_x(0), displace_w(0)
40 {
41 }
42
43 void DeviceTask::split(ThreadQueue<DeviceTask>& tasks, int num)
44 {
45         if(type == DISPLACE) {
46                 for(int i = 0; i < num; i++) {
47                         int tx = displace_x + (displace_w/num)*i;
48                         int tw = (i == num-1)? displace_w - i*(displace_w/num): displace_w/num;
49
50                         DeviceTask task = *this;
51
52                         task.displace_x = tx;
53                         task.displace_w = tw;
54
55                         tasks.push(task);
56                 }
57         }
58         else {
59                 for(int i = 0; i < num; i++) {
60                         int ty = y + (h/num)*i;
61                         int th = (i == num-1)? h - i*(h/num): h/num;
62
63                         DeviceTask task = *this;
64
65                         task.y = ty;
66                         task.h = th;
67
68                         tasks.push(task);
69                 }
70         }
71 }
72
73 /* Device */
74
75 void Device::pixels_alloc(device_memory& mem)
76 {
77         mem_alloc(mem, MEM_READ_WRITE);
78 }
79
80 void Device::pixels_copy_from(device_memory& mem, int y, int w, int h)
81 {
82         mem_copy_from(mem, sizeof(uchar)*4*y*w, sizeof(uchar)*4*w*h);
83 }
84
85 void Device::pixels_free(device_memory& mem)
86 {
87         mem_free(mem);
88 }
89
90 void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int width, int height, bool transparent)
91 {
92         pixels_copy_from(rgba, y, w, h);
93
94         if(transparent) {
95                 glEnable(GL_BLEND);
96                 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
97         }
98
99         glPixelZoom((float)width/(float)w, (float)height/(float)h);
100         glRasterPos2f(0, y);
101
102         glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)rgba.data_pointer);
103
104         glRasterPos2f(0.0f, 0.0f);
105         glPixelZoom(1.0f, 1.0f);
106
107         if(transparent)
108                 glDisable(GL_BLEND);
109 }
110
111 Device *Device::create(DeviceType type, bool background, int threads)
112 {
113         Device *device;
114
115         switch(type) {
116                 case DEVICE_CPU:
117                         device = device_cpu_create(threads);
118                         break;
119 #ifdef WITH_CUDA
120                 case DEVICE_CUDA:
121                         if(cuLibraryInit())
122                                 device = device_cuda_create(background);
123                         else
124                                 device = NULL;
125                         break;
126 #endif
127 #ifdef WITH_MULTI
128                 case DEVICE_MULTI:
129                         device = device_multi_create(background);
130                         break;
131 #endif
132 #ifdef WITH_NETWORK
133                 case DEVICE_NETWORK:
134                         device = device_network_create("127.0.0.1");
135                         break;
136 #endif
137 #ifdef WITH_OPENCL
138                 case DEVICE_OPENCL:
139                         if(clLibraryInit())
140                                 device = device_opencl_create(background);
141                         else
142                                 device = NULL;
143                         break;
144 #endif
145                 default:
146                         return NULL;
147         }
148
149         return device;
150 }
151
152 DeviceType Device::type_from_string(const char *name)
153 {
154         if(strcmp(name, "cpu") == 0)
155                 return DEVICE_CPU;
156         else if(strcmp(name, "cuda") == 0)
157                 return DEVICE_CUDA;
158         else if(strcmp(name, "opencl") == 0)
159                 return DEVICE_OPENCL;
160         else if(strcmp(name, "network") == 0)
161                 return DEVICE_NETWORK;
162         else if(strcmp(name, "multi") == 0)
163                 return DEVICE_MULTI;
164         
165         return DEVICE_NONE;
166 }
167
168 string Device::string_from_type(DeviceType type)
169 {
170         if(type == DEVICE_CPU)
171                 return "cpu";
172         else if(type == DEVICE_CUDA)
173                 return "cuda";
174         else if(type == DEVICE_OPENCL)
175                 return "opencl";
176         else if(type == DEVICE_NETWORK)
177                 return "network";
178         else if(type == DEVICE_MULTI)
179                 return "multi";
180         
181         return "";
182 }
183
184 vector<DeviceType> Device::available_types()
185 {
186         vector<DeviceType> types;
187
188         types.push_back(DEVICE_CPU);
189
190 #ifdef WITH_CUDA
191         if(cuLibraryInit())
192                 types.push_back(DEVICE_CUDA);
193 #endif
194
195 #ifdef WITH_OPENCL
196         if(clLibraryInit())
197                 types.push_back(DEVICE_OPENCL);
198 #endif
199
200 #ifdef WITH_NETWORK
201         types.push_back(DEVICE_NETWORK);
202 #endif
203 #ifdef WITH_MULTI
204         types.push_back(DEVICE_MULTI);
205 #endif
206
207         return types;
208 }
209
210 CCL_NAMESPACE_END
211