2 * Copyright 2011, Blender Foundation.
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.
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.
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.
23 #include "device_intern.h"
25 #include "util_cuda.h"
26 #include "util_debug.h"
27 #include "util_math.h"
28 #include "util_opencl.h"
29 #include "util_opengl.h"
30 #include "util_types.h"
31 #include "util_vector.h"
37 DeviceTask::DeviceTask(Type type_)
38 : type(type_), x(0), y(0), w(0), h(0), rng_state(0), rgba(0), buffer(0),
39 sample(0), resolution(0),
40 displace_input(0), displace_offset(0), displace_x(0), displace_w(0)
44 void DeviceTask::split(ThreadQueue<DeviceTask>& tasks, int num)
46 if(type == DISPLACE) {
47 num = min(displace_w, num);
49 for(int i = 0; i < num; i++) {
50 int tx = displace_x + (displace_w/num)*i;
51 int tw = (i == num-1)? displace_w - i*(displace_w/num): displace_w/num;
53 DeviceTask task = *this;
64 for(int i = 0; i < num; i++) {
65 int ty = y + (h/num)*i;
66 int th = (i == num-1)? h - i*(h/num): h/num;
68 DeviceTask task = *this;
80 void Device::pixels_alloc(device_memory& mem)
82 mem_alloc(mem, MEM_READ_WRITE);
85 void Device::pixels_copy_from(device_memory& mem, int y, int w, int h)
87 mem_copy_from(mem, sizeof(uint8_t)*4*y*w, sizeof(uint8_t)*4*w*h);
90 void Device::pixels_free(device_memory& mem)
95 void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int width, int height, bool transparent)
97 pixels_copy_from(rgba, y, w, h);
101 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
104 glPixelZoom((float)width/(float)w, (float)height/(float)h);
107 uint8_t *pixels = (uint8_t*)rgba.data_pointer;
109 /* for multi devices, this assumes the ineffecient method that we allocate
110 all pixels on the device even though we only render to a subset */
113 glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
115 glRasterPos2f(0.0f, 0.0f);
116 glPixelZoom(1.0f, 1.0f);
122 Device *Device::create(DeviceType type, bool background, int threads)
128 device = device_cpu_create(threads);
133 device = device_cuda_create(background);
140 device = device_multi_create(background);
145 device = device_network_create("127.0.0.1");
151 device = device_opencl_create(background);
160 device->device_type = type;
165 DeviceType Device::type_from_string(const char *name)
167 if(strcmp(name, "cpu") == 0)
169 else if(strcmp(name, "cuda") == 0)
171 else if(strcmp(name, "opencl") == 0)
172 return DEVICE_OPENCL;
173 else if(strcmp(name, "network") == 0)
174 return DEVICE_NETWORK;
175 else if(strcmp(name, "multi") == 0)
181 string Device::string_from_type(DeviceType type)
183 if(type == DEVICE_CPU)
185 else if(type == DEVICE_CUDA)
187 else if(type == DEVICE_OPENCL)
189 else if(type == DEVICE_NETWORK)
191 else if(type == DEVICE_MULTI)
197 vector<DeviceType> Device::available_types()
199 vector<DeviceType> types;
201 types.push_back(DEVICE_CPU);
205 types.push_back(DEVICE_CUDA);
210 types.push_back(DEVICE_OPENCL);
214 types.push_back(DEVICE_NETWORK);
217 types.push_back(DEVICE_MULTI);