[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [43238] trunk/blender: Cycles: multi GPU rendering support.

Brecht Van Lommel brechtvanlommel at pandora.be
Mon Jan 9 17:58:03 CET 2012


Revision: 43238
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=43238
Author:   blendix
Date:     2012-01-09 16:58:01 +0000 (Mon, 09 Jan 2012)
Log Message:
-----------
Cycles: multi GPU rendering support.

The rendering device is now set in User Preferences > System, where you can
choose between OpenCL/CUDA and devices. Per scene you can then still choose
to use CPU or GPU rendering.

Load balancing still needs to be improved, now it just splits the entire
render in two, that will be done in a separate commit.

Modified Paths:
--------------
    trunk/blender/intern/cycles/blender/CMakeLists.txt
    trunk/blender/intern/cycles/blender/addon/engine.py
    trunk/blender/intern/cycles/blender/addon/enums.py
    trunk/blender/intern/cycles/blender/addon/properties.py
    trunk/blender/intern/cycles/blender/addon/ui.py
    trunk/blender/intern/cycles/blender/blender_python.cpp
    trunk/blender/intern/cycles/blender/blender_session.cpp
    trunk/blender/intern/cycles/blender/blender_session.h
    trunk/blender/intern/cycles/blender/blender_sync.cpp
    trunk/blender/intern/cycles/blender/blender_sync.h
    trunk/blender/intern/cycles/device/device.cpp
    trunk/blender/intern/cycles/device/device.h
    trunk/blender/intern/cycles/device/device_cpu.cpp
    trunk/blender/intern/cycles/device/device_cuda.cpp
    trunk/blender/intern/cycles/device/device_multi.cpp
    trunk/blender/intern/cycles/device/device_network.cpp
    trunk/blender/intern/cycles/device/device_opencl.cpp
    trunk/blender/intern/cycles/render/buffers.cpp
    trunk/blender/intern/cycles/render/mesh_displace.cpp
    trunk/blender/release/scripts/startup/bl_ui/space_userpref.py
    trunk/blender/source/blender/makesdna/DNA_userdef_types.h
    trunk/blender/source/blender/makesrna/intern/CMakeLists.txt
    trunk/blender/source/blender/makesrna/intern/SConscript
    trunk/blender/source/blender/makesrna/intern/rna_userdef.c
    trunk/blender/source/blender/python/SConscript
    trunk/blender/source/blender/python/intern/CMakeLists.txt
    trunk/blender/source/blender/python/intern/bpy_interface.c
    trunk/blender/source/blenderplayer/bad_level_call_stubs/stubs.c

Added Paths:
-----------
    trunk/blender/intern/cycles/blender/CCL_api.h

Added: trunk/blender/intern/cycles/blender/CCL_api.h
===================================================================
--- trunk/blender/intern/cycles/blender/CCL_api.h	                        (rev 0)
+++ trunk/blender/intern/cycles/blender/CCL_api.h	2012-01-09 16:58:01 UTC (rev 43238)
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef CCL_API_H
+#define CCL_API_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* returns a list of devices for selection, array is name NULL pointer
+ * terminated and must not be freed */
+
+typedef struct CCLDeviceInfo {
+	const char *identifier;
+	const char *name;
+	int value;
+} CCLDeviceInfo;
+
+CCLDeviceInfo *CCL_compute_device_list(int opencl);
+
+/* create python module _cycles used by addon */
+
+void *CCL_python_module_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CCL_API_H */
+

Modified: trunk/blender/intern/cycles/blender/CMakeLists.txt
===================================================================
--- trunk/blender/intern/cycles/blender/CMakeLists.txt	2012-01-09 16:57:46 UTC (rev 43237)
+++ trunk/blender/intern/cycles/blender/CMakeLists.txt	2012-01-09 16:58:01 UTC (rev 43238)
@@ -27,6 +27,7 @@
 	blender_shader.cpp
 	blender_sync.cpp
 
+	CCL_api.h
 	blender_sync.h
 	blender_session.h
 	blender_util.h

Modified: trunk/blender/intern/cycles/blender/addon/engine.py
===================================================================
--- trunk/blender/intern/cycles/blender/addon/engine.py	2012-01-09 16:57:46 UTC (rev 43237)
+++ trunk/blender/intern/cycles/blender/addon/engine.py	2012-01-09 16:58:01 UTC (rev 43238)
@@ -35,6 +35,7 @@
     import _cycles
 
     data = data.as_pointer()
+    userpref = bpy.context.user_preferences.as_pointer()
     scene = scene.as_pointer()
     if region:
         region = region.as_pointer()
@@ -43,7 +44,7 @@
     if rv3d:
         rv3d = rv3d.as_pointer()
 
-    engine.session = _cycles.create(engine.as_pointer(), data, scene, region, v3d, rv3d)
+    engine.session = _cycles.create(engine.as_pointer(), userpref, data, scene, region, v3d, rv3d)
 
 
 def free(engine):

Modified: trunk/blender/intern/cycles/blender/addon/enums.py
===================================================================
--- trunk/blender/intern/cycles/blender/addon/enums.py	2012-01-09 16:57:46 UTC (rev 43237)
+++ trunk/blender/intern/cycles/blender/addon/enums.py	2012-01-09 16:58:01 UTC (rev 43238)
@@ -20,30 +20,10 @@
 
 from . import engine
 
-
-def get_gpu_device():
-    available_devices = engine.available_devices()
-    cuda = 'cuda' in available_devices
-    opencl = 'opencl' in available_devices
-    if cuda and opencl:
-        gpu_string = "GPU"
-    elif cuda and not opencl:
-        gpu_string = "CUDA GPU"
-    else:
-        gpu_string = "OpenCL GPU"
-
-    return gpu_string
-
 devices = (
-    ("CPU", "CPU", "Processor"),
-    ("GPU", get_gpu_device(), "Graphics card"),
-    )
+	("CPU", "CPU", "Use CPU for rendering"),
+	("GPU", "GPU Compute", "Use GPU compute device for rendering, configured in user preferences"))
 
-gpu_type = (
-    ("CUDA", "CUDA", "NVidia only"),
-    ("OPENCL", "OpenCL", ""),
-    )
-
 feature_set = (
     ("SUPPORTED", "Supported", "Only use finished and supported features"),
     ("EXPERIMENTAL", "Experimental", "Use experimental and incomplete features that might be broken or change in the future"),

Modified: trunk/blender/intern/cycles/blender/addon/properties.py
===================================================================
--- trunk/blender/intern/cycles/blender/addon/properties.py	2012-01-09 16:57:46 UTC (rev 43237)
+++ trunk/blender/intern/cycles/blender/addon/properties.py	2012-01-09 16:58:01 UTC (rev 43238)
@@ -38,9 +38,6 @@
         cls.device = EnumProperty(name="Device", description="Device to use for rendering",
             items=enums.devices, default="CPU")
 
-        cls.gpu_type = EnumProperty(name="GPU Type", description="Processing system to use on the GPU",
-            items=enums.gpu_type, default="CUDA")
-
         cls.feature_set = EnumProperty(name="Feature Set", description="Feature set to use for rendering",
             items=enums.feature_set, default="SUPPORTED")
 

Modified: trunk/blender/intern/cycles/blender/addon/ui.py
===================================================================
--- trunk/blender/intern/cycles/blender/addon/ui.py	2012-01-09 16:57:46 UTC (rev 43237)
+++ trunk/blender/intern/cycles/blender/addon/ui.py	2012-01-09 16:58:01 UTC (rev 43238)
@@ -148,7 +148,6 @@
         sub.prop(cscene, "debug_bvh_type", text="")
         sub.prop(cscene, "debug_use_spatial_splits")
 
-
 class CyclesRender_PT_layers(CyclesButtonsPanel, Panel):
     bl_label = "Layers"
     bl_options = {'DEFAULT_CLOSED'}
@@ -712,20 +711,13 @@
         cscene = scene.cycles
 
         layout.prop(cscene, "feature_set")
-        experimental = cscene.feature_set == 'EXPERIMENTAL'
 
-        available_devices = engine.available_devices()
-        available_cuda = 'cuda' in available_devices
-        available_opencl = experimental and 'opencl' in available_devices
-
-        if available_cuda or available_opencl:
+        device_type = context.user_preferences.system.compute_device_type
+        if device_type == 'CUDA':
             layout.prop(cscene, "device")
-            if cscene.device == 'GPU' and available_cuda and available_opencl:
-                layout.prop(cscene, "gpu_type")
-        if experimental and cscene.device == 'CPU' and engine.with_osl():
-            layout.prop(cscene, "shading_system")
+        elif device_type == 'OPENCL' and cscene.feature_set == 'EXPERIMENTAL':
+            layout.prop(cscene, "device")
 
-
 def draw_pause(self, context):
     layout = self.layout
     scene = context.scene

Modified: trunk/blender/intern/cycles/blender/blender_python.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_python.cpp	2012-01-09 16:57:46 UTC (rev 43237)
+++ trunk/blender/intern/cycles/blender/blender_python.cpp	2012-01-09 16:58:01 UTC (rev 43238)
@@ -18,9 +18,12 @@
 
 #include <Python.h>
 
+#include "CCL_api.h"
+
 #include "blender_sync.h"
 #include "blender_session.h"
 
+#include "util_foreach.h"
 #include "util_opengl.h"
 #include "util_path.h"
 
@@ -40,9 +43,9 @@
 
 static PyObject *create_func(PyObject *self, PyObject *args)
 {
-	PyObject *pyengine, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d;
+	PyObject *pyengine, *pyuserpref, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d;
 
-	if(!PyArg_ParseTuple(args, "OOOOOO", &pyengine, &pydata, &pyscene, &pyregion, &pyv3d, &pyrv3d))
+	if(!PyArg_ParseTuple(args, "OOOOOOO", &pyengine, &pyuserpref, &pydata, &pyscene, &pyregion, &pyv3d, &pyrv3d))
 		return NULL;
 
 	/* RNA */
@@ -50,6 +53,10 @@
 	RNA_pointer_create(NULL, &RNA_RenderEngine, (void*)PyLong_AsVoidPtr(pyengine), &engineptr);
 	BL::RenderEngine engine(engineptr);
 
+	PointerRNA userprefptr;
+	RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyuserpref), &userprefptr);
+	BL::UserPreferences userpref(userprefptr);
+
 	PointerRNA dataptr;
 	RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pydata), &dataptr);
 	BL::BlendData data(dataptr);
@@ -78,11 +85,11 @@
 		int width = region.width();
 		int height = region.height();
 
-		session = new BlenderSession(engine, data, scene, v3d, rv3d, width, height);
+		session = new BlenderSession(engine, userpref, data, scene, v3d, rv3d, width, height);
 	}
 	else {
 		/* offline session */
-		session = new BlenderSession(engine, data, scene);
+		session = new BlenderSession(engine, userpref, data, scene);
 	}
 	
 	return PyLong_FromVoidPtr(session);
@@ -137,13 +144,12 @@
 
 static PyObject *available_devices_func(PyObject *self, PyObject *args)
 {
-	vector<DeviceType> types = Device::available_types();
+	vector<DeviceInfo>& devices = Device::available_devices();
+	PyObject *ret = PyTuple_New(devices.size());
 
-	PyObject *ret = PyTuple_New(types.size());
-
-	for(size_t i = 0; i < types.size(); i++) {
-		string name = Device::string_from_type(types[i]);
-		PyTuple_SET_ITEM(ret, i, PyUnicode_FromString(name.c_str()));
+	for(size_t i = 0; i < devices.size(); i++) {
+		DeviceInfo& device = devices[i];
+		PyTuple_SET_ITEM(ret, i, PyUnicode_FromString(device.description.c_str()));
 	}
 
 	return ret;
@@ -169,11 +175,44 @@
 	NULL, NULL, NULL, NULL
 };
 
+CCLDeviceInfo *compute_device_list(DeviceType type)
+{
+	/* device list stored static */
+	static ccl::vector<CCLDeviceInfo> device_list;
+	static ccl::DeviceType device_type = DEVICE_NONE;
+
+	/* create device list if it's not already done */
+	if(type != device_type) {
+		ccl::vector<DeviceInfo>& devices = ccl::Device::available_devices();
+
+		device_type = type;
+		device_list.clear();
+
+		/* add devices */
+		int i = 0;
+
+		foreach(DeviceInfo& info, devices) {
+			if(info.type == type ||
+			   (info.type == DEVICE_MULTI && info.multi_devices[0].type == type)) {
+				CCLDeviceInfo cinfo = {info.id.c_str(), info.description.c_str(), i++};
+				device_list.push_back(cinfo);
+			}
+		}
+
+		/* null terminate */
+		if(!device_list.empty()) {
+			CCLDeviceInfo cinfo = {NULL, NULL, 0};
+			device_list.push_back(cinfo);
+		}
+	}
+
+	return (device_list.empty())? NULL: &device_list[0];
+}
+
+
 CCL_NAMESPACE_END
 
-extern "C" PyObject *CYCLES_initPython();
-
-PyObject *CYCLES_initPython()
+void *CCL_python_module_init()
 {
 	PyObject *mod= PyModule_Create(&ccl::module);
 
@@ -185,6 +224,12 @@
 	Py_INCREF(Py_False);
 #endif
 
-	return mod;
+	return (void*)mod;
 }
 
+CCLDeviceInfo *CCL_compute_device_list(int opencl)
+{
+	ccl::DeviceType type = (opencl)? ccl::DEVICE_OPENCL: ccl::DEVICE_CUDA;
+	return ccl::compute_device_list(type);
+}
+

Modified: trunk/blender/intern/cycles/blender/blender_session.cpp

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-blender-cvs mailing list