Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-01-04 22:06:32 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-01-04 22:06:32 +0400
commit049ab984697aa277c476833670275624c4385257 (patch)
tree28f01921f0372247a669b36fd4877d3011a1f73e /intern
parentcd84a43334f59d9ff613a240467bbec5c882b7da (diff)
Cycles: device code refactoring, no functional changes.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/app/cycles_server.cpp31
-rw-r--r--intern/cycles/app/cycles_test.cpp54
-rw-r--r--intern/cycles/blender/blender_sync.cpp34
-rw-r--r--intern/cycles/device/device.cpp73
-rw-r--r--intern/cycles/device/device.h31
-rw-r--r--intern/cycles/device/device_cpu.cpp14
-rw-r--r--intern/cycles/device/device_cuda.cpp47
-rw-r--r--intern/cycles/device/device_intern.h16
-rw-r--r--intern/cycles/device/device_memory.h6
-rw-r--r--intern/cycles/device/device_multi.cpp142
-rw-r--r--intern/cycles/device/device_network.cpp13
-rw-r--r--intern/cycles/device/device_opencl.cpp82
-rw-r--r--intern/cycles/render/buffers.cpp2
-rw-r--r--intern/cycles/render/session.cpp4
-rw-r--r--intern/cycles/render/session.h6
-rw-r--r--intern/cycles/render/tile.cpp4
16 files changed, 438 insertions, 121 deletions
diff --git a/intern/cycles/app/cycles_server.cpp b/intern/cycles/app/cycles_server.cpp
index bcf4d3ea769..e6a13e04b48 100644
--- a/intern/cycles/app/cycles_server.cpp
+++ b/intern/cycles/app/cycles_server.cpp
@@ -34,8 +34,9 @@ int main(int argc, const char **argv)
/* device types */
string devices = "";
string devicename = "cpu";
+ bool list = false;
- vector<DeviceType> types = Device::available_types();
+ vector<DeviceType>& types = Device::available_types();
foreach(DeviceType type, types) {
if(devices != "")
@@ -49,6 +50,7 @@ int main(int argc, const char **argv)
ap.options ("Usage: cycles_server [options]",
"--device %s", &devicename, ("Devices to use: " + devices).c_str(),
+ "--list-devices", &list, "List information about all available devices",
NULL);
if(ap.parse(argc, argv) < 0) {
@@ -56,11 +58,34 @@ int main(int argc, const char **argv)
ap.usage();
exit(EXIT_FAILURE);
}
+ else if(list) {
+ vector<DeviceInfo>& devices = Device::available_devices();
- DeviceType dtype = Device::type_from_string(devicename.c_str());
+ printf("Devices:\n");
+
+ foreach(DeviceInfo& info, devices) {
+ printf(" %s%s\n",
+ info.description.c_str(),
+ (info.display_device)? " (display)": "");
+ }
+
+ exit(EXIT_SUCCESS);
+ }
+
+ /* find matching device */
+ DeviceType device_type = Device::type_from_string(devicename.c_str());
+ vector<DeviceInfo>& devices = Device::available_devices();
+ DeviceInfo device_info;
+
+ foreach(DeviceInfo& device, devices) {
+ if(device_type == device.type) {
+ device_info = device;
+ break;
+ }
+ }
while(1) {
- Device *device = Device::create(dtype);
+ Device *device = Device::create(device_info);
printf("Cycles Server with device: %s\n", device->description().c_str());
device->server_run();
delete device;
diff --git a/intern/cycles/app/cycles_test.cpp b/intern/cycles/app/cycles_test.cpp
index d9386f75141..0b8853d7036 100644
--- a/intern/cycles/app/cycles_test.cpp
+++ b/intern/cycles/app/cycles_test.cpp
@@ -203,17 +203,18 @@ static void options_parse(int argc, const char **argv)
options.session = NULL;
options.quiet = false;
- /* devices */
- string devices = "";
+ /* device names */
+ string device_names = "";
string devicename = "cpu";
+ bool list = false;
- vector<DeviceType> types = Device::available_types();
+ vector<DeviceType>& types = Device::available_types();
foreach(DeviceType type, types) {
- if(devices != "")
- devices += ", ";
+ if(device_names != "")
+ device_names += ", ";
- devices += Device::string_from_type(type);
+ device_names += Device::string_from_type(type);
}
/* shading system */
@@ -230,7 +231,7 @@ static void options_parse(int argc, const char **argv)
ap.options ("Usage: cycles_test [options] file.xml",
"%*", files_parse, "",
- "--device %s", &devicename, ("Devices to use: " + devices).c_str(),
+ "--device %s", &devicename, ("Devices to use: " + device_names).c_str(),
"--shadingsys %s", &ssname, "Shading system to use: svm, osl",
"--background", &options.session_params.background, "Render in background, without user interface",
"--quiet", &options.quiet, "In background mode, don't print progress messages",
@@ -239,6 +240,7 @@ static void options_parse(int argc, const char **argv)
"--threads %d", &options.session_params.threads, "CPU Rendering Threads",
"--width %d", &options.width, "Window width in pixel",
"--height %d", &options.height, "Window height in pixel",
+ "--list-devices", &list, "List information about all available devices",
"--help", &help, "Print help message",
NULL);
@@ -247,26 +249,44 @@ static void options_parse(int argc, const char **argv)
ap.usage();
exit(EXIT_FAILURE);
}
+ else if(list) {
+ vector<DeviceInfo>& devices = Device::available_devices();
+ printf("Devices:\n");
+
+ foreach(DeviceInfo& info, devices) {
+ printf(" %s%s\n",
+ info.description.c_str(),
+ (info.display_device)? " (display)": "");
+ }
+
+ exit(EXIT_SUCCESS);
+ }
else if(help || options.filepath == "") {
ap.usage();
exit(EXIT_SUCCESS);
}
- options.session_params.device_type = Device::type_from_string(devicename.c_str());
-
if(ssname == "osl")
options.scene_params.shadingsystem = SceneParams::OSL;
else if(ssname == "svm")
options.scene_params.shadingsystem = SceneParams::SVM;
- /* handle invalid configurations */
- bool type_available = false;
-
- foreach(DeviceType dtype, types)
- if(options.session_params.device_type == dtype)
- type_available = true;
+ /* find matching device */
+ DeviceType device_type = Device::type_from_string(devicename.c_str());
+ vector<DeviceInfo>& devices = Device::available_devices();
+ DeviceInfo device_info;
+ bool device_available = false;
+
+ foreach(DeviceInfo& device, devices) {
+ if(device_type == device.type) {
+ options.session_params.device = device;
+ device_available = true;
+ break;
+ }
+ }
- if(options.session_params.device_type == DEVICE_NONE || !type_available) {
+ /* handle invalid configurations */
+ if(options.session_params.device.type == DEVICE_NONE || !device_available) {
fprintf(stderr, "Unknown device: %s\n", devicename.c_str());
exit(EXIT_FAILURE);
}
@@ -278,7 +298,7 @@ static void options_parse(int argc, const char **argv)
fprintf(stderr, "Unknown shading system: %s\n", ssname.c_str());
exit(EXIT_FAILURE);
}
- else if(options.scene_params.shadingsystem == SceneParams::OSL && options.session_params.device_type != DEVICE_CPU) {
+ else if(options.scene_params.shadingsystem == SceneParams::OSL && options.session_params.device.type != DEVICE_CPU) {
fprintf(stderr, "OSL shading system only works with CPU device\n");
exit(EXIT_FAILURE);
}
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 286a9b5b24f..8f54f291cfb 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -248,10 +248,10 @@ bool BlenderSync::get_session_pause(BL::Scene b_scene, bool background)
return (background)? false: get_boolean(cscene, "preview_pause");
}
-static bool device_type_available(vector<DeviceType>& types, DeviceType dtype)
+static bool device_type_available(vector<DeviceInfo>& devices, DeviceType dtype)
{
- foreach(DeviceType dt, types)
- if(dt == dtype)
+ foreach(DeviceInfo& info, devices)
+ if(info.type == dtype)
return true;
return false;
@@ -266,24 +266,28 @@ SessionParams BlenderSync::get_session_params(BL::Scene b_scene, bool background
params.experimental = (RNA_enum_get(&cscene, "feature_set") != 0);
/* device type */
- params.device_type = DEVICE_CPU;
+ vector<DeviceInfo> devices = Device::available_devices();
+ DeviceType device_type = DEVICE_CPU;
if(RNA_enum_get(&cscene, "device") != 0) {
- vector<DeviceType> types = Device::available_types();
- DeviceType dtype;
if(!params.experimental || RNA_enum_get(&cscene, "gpu_type") == 0)
- dtype = DEVICE_CUDA;
+ device_type = DEVICE_CUDA;
else
- dtype = DEVICE_OPENCL;
-
- if(device_type_available(types, dtype))
- params.device_type = dtype;
- else if(params.experimental && device_type_available(types, DEVICE_OPENCL))
- params.device_type = DEVICE_OPENCL;
- else if(device_type_available(types, DEVICE_CUDA))
- params.device_type = DEVICE_CUDA;
+ device_type = DEVICE_OPENCL;
+
+ if(device_type_available(devices, device_type))
+ ;
+ else if(params.experimental && device_type_available(devices, DEVICE_OPENCL))
+ device_type = DEVICE_OPENCL;
+ else if(device_type_available(devices, DEVICE_CUDA))
+ device_type = DEVICE_CUDA;
}
+
+ params.device = devices[0];
+ foreach(DeviceInfo& info, devices)
+ if(info.type == device_type)
+ params.device = info;
/* Background */
params.background = background;
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index 55fc3bacbba..83600120fdd 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -118,7 +118,7 @@ void Device::pixels_free(device_memory& mem)
mem_free(mem);
}
-void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int width, int height, bool transparent)
+void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent)
{
pixels_copy_from(rgba, y, w, h);
@@ -128,7 +128,7 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int width, in
}
glPixelZoom((float)width/(float)w, (float)height/(float)h);
- glRasterPos2f(0, y);
+ glRasterPos2f(0, dy);
uint8_t *pixels = (uint8_t*)rgba.data_pointer;
@@ -145,36 +145,36 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int width, in
glDisable(GL_BLEND);
}
-Device *Device::create(DeviceType type, bool background, int threads)
+Device *Device::create(DeviceInfo& info, bool background, int threads)
{
Device *device;
- switch(type) {
+ switch(info.type) {
case DEVICE_CPU:
- device = device_cpu_create(threads);
+ device = device_cpu_create(info, threads);
break;
#ifdef WITH_CUDA
case DEVICE_CUDA:
if(cuLibraryInit())
- device = device_cuda_create(background);
+ device = device_cuda_create(info, background);
else
device = NULL;
break;
#endif
#ifdef WITH_MULTI
case DEVICE_MULTI:
- device = device_multi_create(background);
+ device = device_multi_create(info, background);
break;
#endif
#ifdef WITH_NETWORK
case DEVICE_NETWORK:
- device = device_network_create("127.0.0.1");
+ device = device_network_create(info, "127.0.0.1");
break;
#endif
#ifdef WITH_OPENCL
case DEVICE_OPENCL:
if(clLibraryInit())
- device = device_opencl_create(background);
+ device = device_opencl_create(info, background);
else
device = NULL;
break;
@@ -218,31 +218,68 @@ string Device::string_from_type(DeviceType type)
return "";
}
-vector<DeviceType> Device::available_types()
+vector<DeviceType>& Device::available_types()
{
- vector<DeviceType> types;
+ static vector<DeviceType> types;
+ static bool types_init = false;
- types.push_back(DEVICE_CPU);
+ if(!types_init) {
+ types.push_back(DEVICE_CPU);
#ifdef WITH_CUDA
- if(cuLibraryInit())
- types.push_back(DEVICE_CUDA);
+ if(cuLibraryInit())
+ types.push_back(DEVICE_CUDA);
#endif
#ifdef WITH_OPENCL
- if(clLibraryInit())
- types.push_back(DEVICE_OPENCL);
+ if(clLibraryInit())
+ types.push_back(DEVICE_OPENCL);
#endif
#ifdef WITH_NETWORK
- types.push_back(DEVICE_NETWORK);
+ types.push_back(DEVICE_NETWORK);
#endif
#ifdef WITH_MULTI
- types.push_back(DEVICE_MULTI);
+ types.push_back(DEVICE_MULTI);
#endif
+ types_init = true;
+ }
+
return types;
}
+vector<DeviceInfo>& Device::available_devices()
+{
+ static vector<DeviceInfo> devices;
+ static bool devices_init = false;
+
+ if(!devices_init) {
+ device_cpu_info(devices);
+
+#ifdef WITH_CUDA
+ if(cuLibraryInit())
+ device_cuda_info(devices);
+#endif
+
+#ifdef WITH_OPENCL
+ if(clLibraryInit())
+ device_opencl_info(devices);
+#endif
+
+#ifdef WITH_MULTI
+ device_multi_info(devices);
+#endif
+
+#ifdef WITH_NETWORK
+ device_network_info(devices);
+#endif
+
+ devices_init = true;
+ }
+
+ return devices;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index af9bb694c1b..51505aa9cb9 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -33,6 +33,8 @@ CCL_NAMESPACE_BEGIN
class Progress;
+/* Device Types */
+
enum DeviceType {
DEVICE_NONE,
DEVICE_CPU,
@@ -42,10 +44,22 @@ enum DeviceType {
DEVICE_MULTI
};
-enum MemoryType {
- MEM_READ_ONLY,
- MEM_WRITE_ONLY,
- MEM_READ_WRITE
+class DeviceInfo {
+public:
+ DeviceType type;
+ string description;
+ string id;
+ int num;
+ bool display_device;
+ vector<DeviceInfo> multi_devices;
+
+ DeviceInfo()
+ {
+ type = DEVICE_CPU;
+ id = "CPU";
+ num = 0;
+ display_device = false;
+ }
};
/* Device Task */
@@ -91,7 +105,7 @@ public:
/* info */
virtual string description() = 0;
- const string& error_message() { return error_msg; }
+ virtual const string& error_message() { return error_msg; }
/* regular memory */
virtual void mem_alloc(device_memory& mem, MemoryType type) = 0;
@@ -127,7 +141,7 @@ public:
/* opengl drawing */
virtual void draw_pixels(device_memory& mem, int y, int w, int h,
- int width, int height, bool transparent);
+ int dy, int width, int height, bool transparent);
#ifdef WITH_NETWORK
/* networking */
@@ -135,11 +149,12 @@ public:
#endif
/* static */
- static Device *create(DeviceType type, bool background = true, int threads = 0);
+ static Device *create(DeviceInfo& info, bool background = true, int threads = 0);
static DeviceType type_from_string(const char *name);
static string string_from_type(DeviceType type);
- static vector<DeviceType> available_types();
+ static vector<DeviceType>& available_types();
+ static vector<DeviceInfo>& available_devices();
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 145eab9ff59..c93c6ff17da 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -258,10 +258,22 @@ public:
}
};
-Device *device_cpu_create(int threads)
+Device *device_cpu_create(DeviceInfo& info, int threads)
{
return new CPUDevice(threads);
}
+void device_cpu_info(vector<DeviceInfo>& devices)
+{
+ DeviceInfo info;
+
+ info.type = DEVICE_CPU;
+ info.description = system_cpu_brand_string();
+ info.id = "CPU";
+ info.num = 0;
+
+ devices.push_back(info);
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 3c5aafd3f60..73d87ae4a2e 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -159,11 +159,11 @@ public:
cuda_assert(cuCtxSetCurrent(NULL));
}
- CUDADevice(bool background_)
+ CUDADevice(DeviceInfo& info, bool background_)
{
background = background_;
- cuDevId = 0;
+ cuDevId = info.num;
cuDevice = 0;
cuContext = 0;
@@ -205,7 +205,7 @@ public:
string description()
{
/* print device information */
- char deviceName[100];
+ char deviceName[256];
cuda_push_context();
cuDeviceGetName(deviceName, 256, cuDevId);
@@ -768,7 +768,7 @@ public:
}
}
- void draw_pixels(device_memory& mem, int y, int w, int h, int width, int height, bool transparent)
+ void draw_pixels(device_memory& mem, int y, int w, int h, int dy, int width, int height, bool transparent)
{
if(!background) {
PixelMem pmem = pixel_mem_map[mem.device_pointer];
@@ -794,7 +794,7 @@ public:
glColor3f(1.0f, 1.0f, 1.0f);
glPushMatrix();
- glTranslatef(0.0f, (float)y, 0.0f);
+ glTranslatef(0.0f, (float)dy, 0.0f);
glBegin(GL_QUADS);
@@ -822,7 +822,7 @@ public:
return;
}
- Device::draw_pixels(mem, y, w, h, width, height, transparent);
+ Device::draw_pixels(mem, y, w, h, dy, width, height, transparent);
}
void task_add(DeviceTask& task)
@@ -849,9 +849,40 @@ public:
}
};
-Device *device_cuda_create(bool background)
+Device *device_cuda_create(DeviceInfo& info, bool background)
{
- return new CUDADevice(background);
+ return new CUDADevice(info, background);
+}
+
+void device_cuda_info(vector<DeviceInfo>& devices)
+{
+ int count = 0;
+
+ if(cuInit(0) != CUDA_SUCCESS)
+ return;
+ if(cuDeviceGetCount(&count) != CUDA_SUCCESS)
+ return;
+
+ for(int num = 0; num < count; num++) {
+ char name[256];
+ int attr;
+
+ if(cuDeviceGetName(name, 256, num) != CUDA_SUCCESS)
+ continue;
+
+ DeviceInfo info;
+
+ info.type = DEVICE_CUDA;
+ info.description = string(name);
+ info.id = string_printf("CUDA_%d", num);
+ info.num = num;
+
+ /* if device has a kernel timeout, assume it is used for display */
+ if(cuDeviceGetAttribute(&attr, CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT, num) == CUDA_SUCCESS && attr == 1)
+ info.display_device = true;
+
+ devices.push_back(info);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_intern.h b/intern/cycles/device/device_intern.h
index e098ac1f0e3..e3601aa8ad4 100644
--- a/intern/cycles/device/device_intern.h
+++ b/intern/cycles/device/device_intern.h
@@ -23,11 +23,17 @@ CCL_NAMESPACE_BEGIN
class Device;
-Device *device_cpu_create(int threads);
-Device *device_opencl_create(bool background);
-Device *device_cuda_create(bool background);
-Device *device_network_create(const char *address);
-Device *device_multi_create(bool background);
+Device *device_cpu_create(DeviceInfo& info, int threads);
+Device *device_opencl_create(DeviceInfo& info, bool background);
+Device *device_cuda_create(DeviceInfo& info, bool background);
+Device *device_network_create(DeviceInfo& info, const char *address);
+Device *device_multi_create(DeviceInfo& info, bool background);
+
+void device_cpu_info(vector<DeviceInfo>& devices);
+void device_opencl_info(vector<DeviceInfo>& devices);
+void device_cuda_info(vector<DeviceInfo>& devices);
+void device_network_info(vector<DeviceInfo>& devices);
+void device_multi_info(vector<DeviceInfo>& devices);
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h
index 516a6bd0739..3223ca91b9e 100644
--- a/intern/cycles/device/device_memory.h
+++ b/intern/cycles/device/device_memory.h
@@ -36,6 +36,12 @@
CCL_NAMESPACE_BEGIN
+enum MemoryType {
+ MEM_READ_ONLY,
+ MEM_WRITE_ONLY,
+ MEM_READ_WRITE
+};
+
/* Supported Data Types */
enum DataType {
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp
index 7f24e5789cc..f8b512f209c 100644
--- a/intern/cycles/device/device_multi.cpp
+++ b/intern/cycles/device/device_multi.cpp
@@ -44,32 +44,18 @@ public:
list<SubDevice> devices;
device_ptr unique_ptr;
- MultiDevice(bool background_)
+ MultiDevice(DeviceInfo& info, bool background_)
: unique_ptr(1)
{
Device *device;
+ background = background_;
- /* add CPU device */
- device = Device::create(DEVICE_CPU, background);
- devices.push_back(SubDevice(device));
-
-#ifdef WITH_CUDA
- /* try to add GPU device */
- device = Device::create(DEVICE_CUDA, background);
- if(device) {
+ foreach(DeviceInfo& subinfo, info.multi_devices) {
+ device = Device::create(subinfo, background);
devices.push_back(SubDevice(device));
}
- else
-#endif
- {
-#ifdef WITH_OPENCL
- device = Device::create(DEVICE_OPENCL, background);
- if(device)
- devices.push_back(SubDevice(device));
-#endif
- }
-#ifdef WITH_NETWORK
+#if 0 //def WITH_NETWORK
/* try to add network devices */
ServerDiscovery discovery(true);
time_sleep(1.0);
@@ -77,7 +63,7 @@ public:
list<string> servers = discovery.get_server_list();
foreach(string& server, servers) {
- device = device_network_create(server.c_str());
+ device = device_network_create(info, server.c_str());
if(device)
devices.push_back(SubDevice(device));
}
@@ -100,6 +86,19 @@ public:
return true;
}
+ const string& error_message()
+ {
+ foreach(SubDevice& sub, devices) {
+ if(sub.device->error_message() != "") {
+ if(error_msg == "")
+ error_msg = sub.device->error_message();
+ break;
+ }
+ }
+
+ return error_msg;
+ }
+
string description()
{
/* create map to find duplicate descriptions */
@@ -274,7 +273,7 @@ public:
mem.device_pointer = tmp;
}
- void draw_pixels(device_memory& rgba, int y, int w, int h, int width, int height, bool transparent)
+ void draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent)
{
device_ptr tmp = rgba.device_pointer;
int i = 0, sub_h = h/devices.size();
@@ -284,10 +283,11 @@ public:
int sy = y + i*sub_h;
int sh = (i == (int)devices.size() - 1)? h - sub_h*i: sub_h;
int sheight = (i == (int)devices.size() - 1)? height - sub_height*i: sub_height;
+ int sdy = dy + i*sub_height;
/* adjust math for w/width */
rgba.device_pointer = sub.ptr_map[tmp];
- sub.device->draw_pixels(rgba, sy, w, sh, width, sheight, transparent);
+ sub.device->draw_pixels(rgba, sy, w, sh, sdy, width, sheight, transparent);
i++;
}
@@ -327,9 +327,103 @@ public:
}
};
-Device *device_multi_create(bool background)
+Device *device_multi_create(DeviceInfo& info, bool background)
+{
+ return new MultiDevice(info, background);
+}
+
+static void device_multi_add(vector<DeviceInfo>& devices, DeviceType type, bool skip_display, const char *id_fmt, int num)
{
- return new MultiDevice(background);
+ DeviceInfo info;
+
+ /* create map to find duplicate descriptions */
+ map<string, int> dupli_map;
+ map<string, int>::iterator dt;
+ int num_added = 0, num_skipped = 0;
+
+ foreach(DeviceInfo& subinfo, devices) {
+ if(subinfo.type == type) {
+ if(skip_display && subinfo.display_device) {
+ num_skipped++;
+ }
+ else {
+ string key = subinfo.description;
+
+ if(dupli_map.find(key) == dupli_map.end())
+ dupli_map[key] = 1;
+ else
+ dupli_map[key]++;
+
+ info.multi_devices.push_back(subinfo);
+ if(subinfo.display_device)
+ info.display_device = true;
+ num_added++;
+ }
+ }
+ }
+
+ if(num_added <= 1 || (skip_display && num_skipped == 0))
+ return;
+
+ /* generate string */
+ stringstream desc;
+ vector<string> last_tokens;
+ bool first = true;
+
+ for(dt = dupli_map.begin(); dt != dupli_map.end(); dt++) {
+ if(!first) desc << " + ";
+ first = false;
+
+ /* get name and count */
+ string name = dt->first;
+ int count = dt->second;
+
+ /* strip common prefixes */
+ vector<string> tokens;
+ string_split(tokens, dt->first);
+
+ if(tokens.size() > 1) {
+ int i;
+
+ for(i = 0; i < tokens.size() && i < last_tokens.size(); i++)
+ if(tokens[i] != last_tokens[i])
+ break;
+
+ name = "";
+ for(; i < tokens.size(); i++) {
+ name += tokens[i];
+ if(i != tokens.size() - 1)
+ name += " ";
+ }
+ }
+
+ last_tokens = tokens;
+
+ /* add */
+ if(count > 1)
+ desc << name << " (" << count << "x)";
+ else
+ desc << name;
+ }
+
+ /* add info */
+ info.type = DEVICE_MULTI;
+ info.description = desc.str();
+ info.id = string_printf(id_fmt, num);
+ info.num = 0;
+
+ devices.push_back(info);
+}
+
+void device_multi_info(vector<DeviceInfo>& devices)
+{
+ int num = 0;
+ device_multi_add(devices, DEVICE_CUDA, true, "CUDA_MULTI_%d", num++);
+ device_multi_add(devices, DEVICE_CUDA, false, "CUDA_MULTI_%d", num++);
+
+ num = 0;
+ device_multi_add(devices, DEVICE_OPENCL, true, "OPENCL_MULTI_%d", num++);
+ device_multi_add(devices, DEVICE_OPENCL, false, "OPENCL_MULTI_%d", num++);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_network.cpp b/intern/cycles/device/device_network.cpp
index a5ad84831fc..4347d7eecd8 100644
--- a/intern/cycles/device/device_network.cpp
+++ b/intern/cycles/device/device_network.cpp
@@ -220,11 +220,22 @@ public:
}
};
-Device *device_network_create(const char *address)
+Device *device_network_create(DeviceInfo& info, const char *address)
{
return new NetworkDevice(address);
}
+void device_network_info(vector<DeviceInfo>& devices)
+{
+ DeviceInfo info;
+
+ info.type = DEVICE_NETWORK;
+ info.description = "Network Device";
+ info.id = "NETWORK";
+ info.num = 0;
+
+ devices.push_back(info);
+}
void Device::server_run()
{
diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index 6014dd0fdb7..41844d37f50 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -141,7 +141,7 @@ public:
}
}
- OpenCLDevice(bool background_)
+ OpenCLDevice(DeviceInfo& info, bool background_)
{
background = background_;
cpPlatform = NULL;
@@ -153,10 +153,9 @@ public:
null_mem = 0;
device_initialized = false;
- vector<cl_platform_id> platform_ids;
+ /* setup platform */
cl_uint num_platforms;
- /* setup device */
ciErr = clGetPlatformIDs(0, NULL, &num_platforms);
if(opencl_error(ciErr))
return;
@@ -166,14 +165,7 @@ public:
return;
}
- platform_ids.resize(num_platforms);
- ciErr = clGetPlatformIDs(num_platforms, &platform_ids[0], NULL);
- if(opencl_error(ciErr))
- return;
-
- cpPlatform = platform_ids[0]; /* todo: pick specified platform && device */
-
- ciErr = clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, 1, &cdDevice, NULL);
+ ciErr = clGetPlatformIDs(num_platforms, &cpPlatform, NULL);
if(opencl_error(ciErr))
return;
@@ -181,6 +173,29 @@ public:
clGetPlatformInfo(cpPlatform, CL_PLATFORM_NAME, sizeof(name), &name, NULL);
platform_name = name;
+ /* get devices */
+ vector<cl_device_id> device_ids;
+ cl_uint num_devices;
+
+ if(opencl_error(clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, 0, NULL, &num_devices)))
+ return;
+
+ if(info.num > num_devices) {
+ if(num_devices == 0)
+ opencl_error("OpenCL: no devices found.");
+ else
+ opencl_error("OpenCL: specified device not found.");
+ return;
+ }
+
+ device_ids.resize(num_devices);
+
+ if(opencl_error(clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, num_devices, &device_ids[0], NULL)))
+ return;
+
+ cdDevice = device_ids[info.num];
+
+ /* create context */
cxContext = clCreateContext(0, 1, &cdDevice, NULL, NULL, &ciErr);
if(opencl_error(ciErr))
return;
@@ -689,9 +704,50 @@ public:
}
};
-Device *device_opencl_create(bool background)
+Device *device_opencl_create(DeviceInfo& info, bool background)
{
- return new OpenCLDevice(background);
+ return new OpenCLDevice(info, background);
+}
+
+void device_opencl_info(vector<DeviceInfo>& devices)
+{
+ vector<cl_device_id> device_ids;
+ cl_uint num_devices;
+ cl_platform_id platform_id;
+ cl_uint num_platforms;
+
+ /* get devices */
+ if(clGetPlatformIDs(0, NULL, &num_platforms) != CL_SUCCESS || num_platforms == 0)
+ return;
+
+ if(clGetPlatformIDs(num_platforms, &platform_id, NULL) != CL_SUCCESS)
+ return;
+
+ if(clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, 0, NULL, &num_devices) != CL_SUCCESS)
+ return;
+
+ device_ids.resize(num_devices);
+
+ if(clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, num_devices, &device_ids[0], NULL) != CL_SUCCESS)
+ return;
+
+ /* add devices */
+ for(int num = 0; num < num_devices; num++) {
+ cl_device_id device_id = device_ids[num];
+ char name[1024];
+
+ if(clGetDeviceInfo(device_id, CL_DEVICE_NAME, sizeof(name), &name, NULL) != CL_SUCCESS)
+ continue;
+
+ DeviceInfo info;
+
+ info.type = DEVICE_OPENCL;
+ info.description = string(name);
+ info.id = string_printf("OPENCL_%d", num);
+ info.num = num;
+
+ devices.push_back(info);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index 29141b25b59..dd78ccd8f32 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -183,7 +183,7 @@ void DisplayBuffer::draw(Device *device)
if(transparent)
draw_transparency_grid();
- device->draw_pixels(rgba, 0, draw_width, draw_height, params.width, params.height, transparent);
+ device->draw_pixels(rgba, 0, draw_width, draw_height, 0, params.width, params.height, transparent);
}
}
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index be2e493dc7f..4634e4de0d8 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -35,9 +35,9 @@ Session::Session(const SessionParams& params_)
: params(params_),
tile_manager(params.progressive, params.samples, params.tile_size, params.min_size)
{
- device_use_gl = ((params.device_type != DEVICE_CPU) && !params.background);
+ device_use_gl = ((params.device.type != DEVICE_CPU) && !params.background);
- device = Device::create(params.device_type, params.background, params.threads);
+ device = Device::create(params.device, params.background, params.threads);
buffers = new RenderBuffers(device);
display = new DisplayBuffer(device);
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 89979b8c451..a662948c15b 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -40,7 +40,7 @@ class Scene;
class SessionParams {
public:
- DeviceType device_type;
+ DeviceInfo device;
bool background;
string output_path;
@@ -57,7 +57,6 @@ public:
SessionParams()
{
- device_type = DEVICE_CPU;
background = false;
output_path = "";
@@ -74,7 +73,8 @@ public:
}
bool modified(const SessionParams& params)
- { return !(device_type == params.device_type
+ { return !(device.type == params.device.type
+ && device.id == params.device.id
&& background == params.background
&& output_path == params.output_path
/* && samples == params.samples */
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index 40833e5b08b..04e48d44029 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -71,8 +71,8 @@ void TileManager::set_tiles()
int resolution = state.resolution;
int image_w = max(1, params.width/resolution);
int image_h = max(1, params.height/resolution);
- int tile_w = (image_w + tile_size - 1)/tile_size;
- int tile_h = (image_h + tile_size - 1)/tile_size;
+ int tile_w = (tile_size >= image_w)? 1: (image_w + tile_size - 1)/tile_size;
+ int tile_h = (tile_size >= image_h)? 1: (image_h + tile_size - 1)/tile_size;
int sub_w = image_w/tile_w;
int sub_h = image_h/tile_h;