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_foreach.h"
28 #include "util_math.h"
29 #include "util_opencl.h"
30 #include "util_opengl.h"
31 #include "util_time.h"
32 #include "util_types.h"
33 #include "util_vector.h"
39 void Device::pixels_alloc(device_memory& mem)
41 mem_alloc(mem, MEM_READ_WRITE);
44 void Device::pixels_copy_from(device_memory& mem, int y, int w, int h)
46 mem_copy_from(mem, y, w, h, sizeof(uint8_t)*4);
49 void Device::pixels_free(device_memory& mem)
54 void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent)
56 pixels_copy_from(rgba, y, w, h);
60 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
63 glPixelZoom((float)width/(float)w, (float)height/(float)h);
66 uint8_t *pixels = (uint8_t*)rgba.data_pointer;
68 /* for multi devices, this assumes the ineffecient method that we allocate
69 * all pixels on the device even though we only render to a subset */
72 glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
74 glRasterPos2f(0.0f, 0.0f);
75 glPixelZoom(1.0f, 1.0f);
81 Device *Device::create(DeviceInfo& info, Stats &stats, bool background, int threads)
87 device = device_cpu_create(info, stats, threads);
92 device = device_cuda_create(info, stats, background);
99 device = device_multi_create(info, stats, background);
104 device = device_network_create(info, stats, "127.0.0.1");
110 device = device_opencl_create(info, stats, background);
125 DeviceType Device::type_from_string(const char *name)
127 if(strcmp(name, "cpu") == 0)
129 else if(strcmp(name, "cuda") == 0)
131 else if(strcmp(name, "opencl") == 0)
132 return DEVICE_OPENCL;
133 else if(strcmp(name, "network") == 0)
134 return DEVICE_NETWORK;
135 else if(strcmp(name, "multi") == 0)
141 string Device::string_from_type(DeviceType type)
143 if(type == DEVICE_CPU)
145 else if(type == DEVICE_CUDA)
147 else if(type == DEVICE_OPENCL)
149 else if(type == DEVICE_NETWORK)
151 else if(type == DEVICE_MULTI)
157 vector<DeviceType>& Device::available_types()
159 static vector<DeviceType> types;
160 static bool types_init = false;
163 types.push_back(DEVICE_CPU);
167 types.push_back(DEVICE_CUDA);
172 types.push_back(DEVICE_OPENCL);
176 types.push_back(DEVICE_NETWORK);
179 types.push_back(DEVICE_MULTI);
188 vector<DeviceInfo>& Device::available_devices()
190 static vector<DeviceInfo> devices;
191 static bool devices_init = false;
192 static double device_update_time = 0.0;
194 /* only update device list if we're not actively rendering already, things
195 * could go very wrong if a device suddenly becomes (un)available. also do
196 * it only every 5 seconds. it not super cpu intensive but don't want to do
197 * it on every redraw. */
199 if(!TaskScheduler::active() && (time_dt() > device_update_time + 5.0)) {
201 devices_init = false;
208 device_cuda_info(devices);
213 device_opencl_info(devices);
217 device_multi_info(devices);
220 device_cpu_info(devices);
223 device_network_info(devices);
227 device_update_time = time_dt();