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
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-01-09 20:58:01 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-01-09 20:58:01 +0400
commitd7932ceea82a3c2277a179c00ca72ecb3cfb97cb (patch)
tree933570102e52c7562b87534e87c0c38bb5eb47ec
parent47d9c6689be0448b898d18a1e810d2150867938b (diff)
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.
-rw-r--r--intern/cycles/blender/CCL_api.h46
-rw-r--r--intern/cycles/blender/CMakeLists.txt1
-rw-r--r--intern/cycles/blender/addon/engine.py3
-rw-r--r--intern/cycles/blender/addon/enums.py24
-rw-r--r--intern/cycles/blender/addon/properties.py3
-rw-r--r--intern/cycles/blender/addon/ui.py16
-rw-r--r--intern/cycles/blender/blender_python.cpp73
-rw-r--r--intern/cycles/blender/blender_session.cpp19
-rw-r--r--intern/cycles/blender/blender_session.h7
-rw-r--r--intern/cycles/blender/blender_sync.cpp50
-rw-r--r--intern/cycles/blender/blender_sync.h2
-rw-r--r--intern/cycles/device/device.cpp2
-rw-r--r--intern/cycles/device/device.h2
-rw-r--r--intern/cycles/device/device_cpu.cpp2
-rw-r--r--intern/cycles/device/device_cuda.cpp19
-rw-r--r--intern/cycles/device/device_multi.cpp55
-rw-r--r--intern/cycles/device/device_network.cpp2
-rw-r--r--intern/cycles/device/device_opencl.cpp7
-rw-r--r--intern/cycles/render/buffers.cpp2
-rw-r--r--intern/cycles/render/mesh_displace.cpp2
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py30
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h7
-rw-r--r--source/blender/makesrna/SConscript5
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt4
-rw-r--r--source/blender/makesrna/intern/SConscript5
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c100
-rw-r--r--source/blender/python/SConscript2
-rw-r--r--source/blender/python/intern/CMakeLists.txt1
-rw-r--r--source/blender/python/intern/bpy_interface.c15
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c3
30 files changed, 361 insertions, 148 deletions
diff --git a/intern/cycles/blender/CCL_api.h b/intern/cycles/blender/CCL_api.h
new file mode 100644
index 00000000000..469d63d1530
--- /dev/null
+++ b/intern/cycles/blender/CCL_api.h
@@ -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 */
+
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index 3b685346791..003c6c84f8f 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -27,6 +27,7 @@ set(SRC
blender_shader.cpp
blender_sync.cpp
+ CCL_api.h
blender_sync.h
blender_session.h
blender_util.h
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index 3d71c25d7ad..05b1f883594 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -35,6 +35,7 @@ def create(engine, data, scene, region=0, v3d=0, rv3d=0):
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 @@ def create(engine, data, scene, region=0, v3d=0, rv3d=0):
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):
diff --git a/intern/cycles/blender/addon/enums.py b/intern/cycles/blender/addon/enums.py
index a11f5ca0f87..da4c73a5d3b 100644
--- a/intern/cycles/blender/addon/enums.py
+++ b/intern/cycles/blender/addon/enums.py
@@ -20,29 +20,9 @@
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"),
- )
-
-gpu_type = (
- ("CUDA", "CUDA", "NVidia only"),
- ("OPENCL", "OpenCL", ""),
- )
+ ("CPU", "CPU", "Use CPU for rendering"),
+ ("GPU", "GPU Compute", "Use GPU compute device for rendering, configured in user preferences"))
feature_set = (
("SUPPORTED", "Supported", "Only use finished and supported features"),
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 0ea7396f9c2..0b096c529b8 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -38,9 +38,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
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")
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 6e73795666e..ea23e2b56a5 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -148,7 +148,6 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
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,19 +711,12 @@ def draw_device(self, context):
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")
+ elif device_type == 'OPENCL' and cscene.feature_set == 'EXPERIMENTAL':
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")
-
def draw_pause(self, context):
layout = self.layout
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index 90dab298dc3..6e892095387 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -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 *init_func(PyObject *self, PyObject *args)
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 @@ static PyObject *create_func(PyObject *self, PyObject *args)
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 @@ static PyObject *create_func(PyObject *self, PyObject *args)
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 *sync_func(PyObject *self, PyObject *value)
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 @@ static struct PyModuleDef module = {
NULL, NULL, NULL, NULL
};
-CCL_NAMESPACE_END
+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);
+ }
+ }
-extern "C" PyObject *CYCLES_initPython();
+ return (device_list.empty())? NULL: &device_list[0];
+}
-PyObject *CYCLES_initPython()
+
+CCL_NAMESPACE_END
+
+void *CCL_python_module_init()
{
PyObject *mod= PyModule_Create(&ccl::module);
@@ -185,6 +224,12 @@ PyObject *CYCLES_initPython()
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);
}
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index c7c35b537bd..b052fb3e195 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -39,8 +39,10 @@
CCL_NAMESPACE_BEGIN
-BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::BlendData b_data_, BL::Scene b_scene_)
-: b_engine(b_engine_), b_data(b_data_), b_scene(b_scene_), b_v3d(PointerRNA_NULL), b_rv3d(PointerRNA_NULL),
+BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::UserPreferences b_userpref_,
+ BL::BlendData b_data_, BL::Scene b_scene_)
+: b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_scene(b_scene_),
+ b_v3d(PointerRNA_NULL), b_rv3d(PointerRNA_NULL),
b_rr(PointerRNA_NULL), b_rlay(PointerRNA_NULL)
{
/* offline render */
@@ -54,10 +56,11 @@ BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::BlendData b_data_
create_session();
}
-BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::BlendData b_data_, BL::Scene b_scene_,
+BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::UserPreferences b_userpref_,
+ BL::BlendData b_data_, BL::Scene b_scene_,
BL::SpaceView3D b_v3d_, BL::RegionView3D b_rv3d_, int width_, int height_)
-: b_engine(b_engine_), b_data(b_data_), b_scene(b_scene_), b_v3d(b_v3d_), b_rv3d(b_rv3d_),
- b_rr(PointerRNA_NULL), b_rlay(PointerRNA_NULL)
+: b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_scene(b_scene_),
+ b_v3d(b_v3d_), b_rv3d(b_rv3d_), b_rr(PointerRNA_NULL), b_rlay(PointerRNA_NULL)
{
/* 3d view render */
width = width_;
@@ -77,7 +80,7 @@ BlenderSession::~BlenderSession()
void BlenderSession::create_session()
{
SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
- SessionParams session_params = BlenderSync::get_session_params(b_scene, background);
+ SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background);
/* reset status/progress */
last_status= "";
@@ -184,7 +187,7 @@ void BlenderSession::synchronize()
{
/* on session/scene parameter changes, we recreate session entirely */
SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
- SessionParams session_params = BlenderSync::get_session_params(b_scene, background);
+ SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background);
if(session->params.modified(session_params) ||
scene->params.modified(scene_params)) {
@@ -258,7 +261,7 @@ bool BlenderSession::draw(int w, int h)
/* reset if requested */
if(reset) {
- SessionParams session_params = BlenderSync::get_session_params(b_scene, background);
+ SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height);
session->reset(buffer_params, session_params.samples);
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 26fffcf3aff..b98e3ffed54 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -32,8 +32,10 @@ class Session;
class BlenderSession {
public:
- BlenderSession(BL::RenderEngine b_engine, BL::BlendData b_data, BL::Scene b_scene);
- BlenderSession(BL::RenderEngine b_engine, BL::BlendData b_data, BL::Scene b_scene,
+ BlenderSession(BL::RenderEngine b_engine, BL::UserPreferences b_userpref,
+ BL::BlendData b_data, BL::Scene b_scene);
+ BlenderSession(BL::RenderEngine b_engine, BL::UserPreferences b_userpref,
+ BL::BlendData b_data, BL::Scene b_scene,
BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height);
~BlenderSession();
@@ -65,6 +67,7 @@ public:
double last_redraw_time;
BL::RenderEngine b_engine;
+ BL::UserPreferences b_userpref;
BL::BlendData b_data;
BL::Scene b_scene;
BL::SpaceView3D b_v3d;
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 8f54f291cfb..c00320f0094 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -248,16 +248,7 @@ 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<DeviceInfo>& devices, DeviceType dtype)
-{
- foreach(DeviceInfo& info, devices)
- if(info.type == dtype)
- return true;
-
- return false;
-}
-
-SessionParams BlenderSync::get_session_params(BL::Scene b_scene, bool background)
+SessionParams BlenderSync::get_session_params(BL::UserPreferences b_userpref, BL::Scene b_scene, bool background)
{
SessionParams params;
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
@@ -266,29 +257,26 @@ SessionParams BlenderSync::get_session_params(BL::Scene b_scene, bool background
params.experimental = (RNA_enum_get(&cscene, "feature_set") != 0);
/* device type */
- vector<DeviceInfo> devices = Device::available_devices();
- DeviceType device_type = DEVICE_CPU;
+ vector<DeviceInfo>& devices = Device::available_devices();
+
+ /* device default CPU */
+ params.device = devices[0];
if(RNA_enum_get(&cscene, "device") != 0) {
-
- if(!params.experimental || RNA_enum_get(&cscene, "gpu_type") == 0)
- device_type = DEVICE_CUDA;
- else
- 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;
+ /* find GPU device with given id */
+ PointerRNA systemptr = b_userpref.system().ptr;
+ PropertyRNA *deviceprop = RNA_struct_find_property(&systemptr, "compute_device");
+ int device_id = b_userpref.system().compute_device();
+
+ const char *id;
+
+ if(RNA_property_enum_identifier(NULL, &systemptr, deviceprop, device_id, &id)) {
+ foreach(DeviceInfo& info, devices)
+ if(info.id == id)
+ params.device = info;
+ }
}
- params.device = devices[0];
- foreach(DeviceInfo& info, devices)
- if(info.type == device_type)
- params.device = info;
-
/* Background */
params.background = background;
@@ -316,6 +304,10 @@ SessionParams BlenderSync::get_session_params(BL::Scene b_scene, bool background
}
else
params.progressive = true;
+
+ /* todo: multi device only works with single tiles now */
+ if(params.device.type == DEVICE_MULTI)
+ params.tile_size = INT_MAX;
return params;
}
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 60fdd7c386b..7b65376bd84 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -60,7 +60,7 @@ public:
/* get parameters */
static SceneParams get_scene_params(BL::Scene b_scene, bool background);
- static SessionParams get_session_params(BL::Scene b_scene, bool background);
+ static SessionParams get_session_params(BL::UserPreferences b_userpref, BL::Scene b_scene, bool background);
static bool get_session_pause(BL::Scene b_scene, bool background);
static BufferParams get_buffer_params(BL::Scene b_scene, BL::RegionView3D b_rv3d, int width, int height);
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index 83600120fdd..1f0be1599bf 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -110,7 +110,7 @@ void Device::pixels_alloc(device_memory& mem)
void Device::pixels_copy_from(device_memory& mem, int y, int w, int h)
{
- mem_copy_from(mem, sizeof(uint8_t)*4*y*w, sizeof(uint8_t)*4*w*h);
+ mem_copy_from(mem, y, w, h, sizeof(uint8_t)*4);
}
void Device::pixels_free(device_memory& mem)
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 51505aa9cb9..b8fea4c4c69 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -111,7 +111,7 @@ public:
virtual void mem_alloc(device_memory& mem, MemoryType type) = 0;
virtual void mem_copy_to(device_memory& mem) = 0;
virtual void mem_copy_from(device_memory& mem,
- size_t offset, size_t size) = 0;
+ int y, int w, int h, int elem) = 0;
virtual void mem_zero(device_memory& mem) = 0;
virtual void mem_free(device_memory& mem) = 0;
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index c93c6ff17da..e29266b0a7d 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -92,7 +92,7 @@ public:
/* no-op */
}
- void mem_copy_from(device_memory& mem, size_t offset, size_t size)
+ void mem_copy_from(device_memory& mem, int y, int w, int h, int elem)
{
/* no-op */
}
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 73d87ae4a2e..55b467fc856 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -341,9 +341,11 @@ public:
cuda_pop_context();
}
- void mem_copy_from(device_memory& mem, size_t offset, size_t size)
+ void mem_copy_from(device_memory& mem, int y, int w, int h, int elem)
{
- /* todo: offset is ignored */
+ size_t offset = elem*y*w;
+ size_t size = elem*w*h;
+
cuda_push_context();
cuda_assert(cuMemcpyDtoH((uchar*)mem.data_pointer + offset,
(CUdeviceptr)((uchar*)mem.device_pointer + offset), size))
@@ -863,6 +865,8 @@ void device_cuda_info(vector<DeviceInfo>& devices)
if(cuDeviceGetCount(&count) != CUDA_SUCCESS)
return;
+ vector<DeviceInfo> display_devices;
+
for(int num = 0; num < count; num++) {
char name[256];
int attr;
@@ -878,11 +882,16 @@ void device_cuda_info(vector<DeviceInfo>& devices)
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)
+ if(cuDeviceGetAttribute(&attr, CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT, num) == CUDA_SUCCESS && attr == 1) {
info.display_device = true;
-
- devices.push_back(info);
+ display_devices.push_back(info);
+ }
+ else
+ devices.push_back(info);
}
+
+ if(!display_devices.empty())
+ devices.insert(devices.end(), display_devices.begin(), display_devices.end());
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp
index f8b512f209c..41d0e268526 100644
--- a/intern/cycles/device/device_multi.cpp
+++ b/intern/cycles/device/device_multi.cpp
@@ -163,15 +163,18 @@ public:
mem.device_pointer = tmp;
}
- void mem_copy_from(device_memory& mem, size_t offset, size_t size)
+ void mem_copy_from(device_memory& mem, int y, int w, int h, int elem)
{
device_ptr tmp = mem.device_pointer;
+ int i = 0, sub_h = h/devices.size();
- /* todo: how does this work? */
foreach(SubDevice& sub, devices) {
+ int sy = y + i*sub_h;
+ int sh = (i == (int)devices.size() - 1)? h - sub_h*i: sub_h;
+
mem.device_pointer = sub.ptr_map[tmp];
- sub.device->mem_copy_from(mem, offset, size);
- break;
+ sub.device->mem_copy_from(mem, sy, w, sh, elem);
+ i++;
}
mem.device_pointer = tmp;
@@ -332,37 +335,39 @@ 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)
+static void device_multi_add(vector<DeviceInfo>& devices, DeviceType type, bool with_display, const char *id_fmt, int num)
{
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;
+ int num_added = 0, num_display = 0;
foreach(DeviceInfo& subinfo, devices) {
if(subinfo.type == type) {
- if(skip_display && subinfo.display_device) {
- num_skipped++;
+ if(subinfo.display_device) {
+ if(with_display)
+ num_display++;
+ else
+ continue;
}
- else {
- string key = subinfo.description;
- if(dupli_map.find(key) == dupli_map.end())
- dupli_map[key] = 1;
- else
- dupli_map[key]++;
+ string key = subinfo.description;
- info.multi_devices.push_back(subinfo);
- if(subinfo.display_device)
- info.display_device = true;
- num_added++;
- }
+ 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))
+ if(num_added <= 1 || (with_display && num_display == 0))
return;
/* generate string */
@@ -410,20 +415,24 @@ static void device_multi_add(vector<DeviceInfo>& devices, DeviceType type, bool
info.type = DEVICE_MULTI;
info.description = desc.str();
info.id = string_printf(id_fmt, num);
+ info.display_device = with_display;
info.num = 0;
- devices.push_back(info);
+ if(with_display)
+ devices.push_back(info);
+ else
+ devices.insert(devices.begin(), 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++);
+ device_multi_add(devices, DEVICE_CUDA, true, "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++);
+ device_multi_add(devices, DEVICE_OPENCL, true, "OPENCL_MULTI_%d", num++);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_network.cpp b/intern/cycles/device/device_network.cpp
index 4347d7eecd8..14518b1507e 100644
--- a/intern/cycles/device/device_network.cpp
+++ b/intern/cycles/device/device_network.cpp
@@ -103,7 +103,7 @@ public:
#endif
}
- void mem_copy_from(device_memory& mem, size_t offset, size_t size)
+ void mem_copy_from(device_memory& mem, int y, int w, int h, int elem)
{
#if 0
RPCSend snd(socket, "mem_copy_from");
diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index 41844d37f50..ccfd8544362 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -489,8 +489,11 @@ public:
opencl_assert(ciErr);
}
- void mem_copy_from(device_memory& mem, size_t offset, size_t size)
+ void mem_copy_from(device_memory& mem, int y, int w, int h, int elem)
{
+ size_t offset = elem*y*w;
+ size_t size = elem*w*h;
+
ciErr = clEnqueueReadBuffer(cqCommandQueue, CL_MEM_PTR(mem.device_pointer), CL_TRUE, offset, size, (uchar*)mem.data_pointer + offset, 0, NULL, NULL);
opencl_assert(ciErr);
}
@@ -745,6 +748,8 @@ void device_opencl_info(vector<DeviceInfo>& devices)
info.description = string(name);
info.id = string_printf("OPENCL_%d", num);
info.num = num;
+ /* we don't know if it's used for display, but assume it is */
+ info.display_device = true;
devices.push_back(info);
}
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index dd78ccd8f32..a6bbbc91901 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -87,7 +87,7 @@ float4 *RenderBuffers::copy_from_device(float exposure, int sample)
if(!buffer.device_pointer)
return NULL;
- device->mem_copy_from(buffer, 0, buffer.memory_size());
+ device->mem_copy_from(buffer, 0, params.width, params.height, sizeof(float4));
float4 *out = new float4[params.width*params.height];
float4 *in = (float4*)buffer.data_pointer;
diff --git a/intern/cycles/render/mesh_displace.cpp b/intern/cycles/render/mesh_displace.cpp
index f0ddf4e8d7b..c4f3e43bfba 100644
--- a/intern/cycles/render/mesh_displace.cpp
+++ b/intern/cycles/render/mesh_displace.cpp
@@ -106,7 +106,7 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
device->task_add(task);
device->task_wait();
- device->mem_copy_from(d_output, 0, sizeof(float3)*d_output.size());
+ device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float3));
device->mem_free(d_input);
device->mem_free(d_output);
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 046026a3b6e..544fc92e8a4 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -388,13 +388,9 @@ class USERPREF_PT_system(Panel):
col.prop(system, "dpi")
col.prop(system, "frame_server_port")
col.prop(system, "scrollback", text="Console Scrollback")
- col.prop(system, "author", text="Author")
- col.prop(system, "use_scripts_auto_execute")
- col.prop(system, "use_tabs_as_spaces")
col.separator()
col.separator()
- col.separator()
col.label(text="Sound:")
col.row().prop(system, "audio_device", expand=True)
@@ -408,14 +404,20 @@ class USERPREF_PT_system(Panel):
col.separator()
col.separator()
- col.separator()
col.label(text="Screencast:")
col.prop(system, "screencast_fps")
col.prop(system, "screencast_wait_time")
+
col.separator()
col.separator()
- col.separator()
+
+ if hasattr(system, 'compute_device'):
+ col.label(text="Compute Device:")
+ col.row().prop(system, "compute_device_type", expand=True)
+ sub = col.row()
+ sub.active = system.compute_device_type != 'CPU'
+ sub.prop(system, "compute_device", text="")
# 2. Column
column = split.column()
@@ -727,6 +729,7 @@ class USERPREF_PT_file(Panel):
userpref = context.user_preferences
paths = userpref.filepaths
+ system = userpref.system
split = layout.split(percentage=0.7)
@@ -762,6 +765,14 @@ class USERPREF_PT_file(Panel):
subsplit.prop(paths, "animation_player_preset", text="")
subsplit.prop(paths, "animation_player", text="")
+ col.separator()
+ col.separator()
+
+ colsplit = col.split(percentage=0.95)
+ sub = colsplit.column()
+ sub.label(text="Author:")
+ sub.prop(system, "author", text="")
+
col = split.column()
col.label(text="Save & Load:")
col.prop(paths, "use_relative_paths")
@@ -784,6 +795,13 @@ class USERPREF_PT_file(Panel):
sub.active = paths.use_auto_save_temporary_files
sub.prop(paths, "auto_save_time", text="Timer (mins)")
+ col.separator()
+
+ col.label(text="Scripts:")
+ col.prop(system, "use_scripts_auto_execute")
+ col.prop(system, "use_tabs_as_spaces")
+
+
from .space_userpref_keymap import InputKeyMapPanel
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index b3398460500..fc418069c5c 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -413,6 +413,9 @@ typedef struct UserDef {
short pad3;
char author[80]; /* author name for file formats supporting it */
+
+ int compute_device_type;
+ int compute_device_id;
} UserDef;
extern UserDef U; /* from blenkernel blender.c */
@@ -627,6 +630,10 @@ extern UserDef U; /* from blenkernel blender.c */
#define NDOF_PANY_INVERT_AXIS (1 << 13)
#define NDOF_PANZ_INVERT_AXIS (1 << 14)
+/* compute_device_type */
+#define USER_COMPUTE_DEVICE_NONE 0
+#define USER_COMPUTE_DEVICE_OPENCL 1
+#define USER_COMPUTE_DEVICE_CUDA 2
#ifdef __cplusplus
}
diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript
index 9eea6d83cb9..7eb5d042dd7 100644
--- a/source/blender/makesrna/SConscript
+++ b/source/blender/makesrna/SConscript
@@ -8,7 +8,7 @@ objs += o
incs = '#/intern/guardedalloc #/intern/memutil #/intern/audaspace/intern ../blenkernel ../blenlib ../makesdna intern .'
incs += ' ../windowmanager ../editors/include ../gpu ../imbuf ../ikplugin ../blenfont ../blenloader'
-incs += ' ../render/extern/include'
+incs += ' ../render/extern/include #/intern/cycles/blender'
incs += ' ../nodes'
incs += ' #/extern/glew/include'
@@ -58,6 +58,9 @@ if env['WITH_BF_COLLADA']:
if env['WITH_BF_OCEANSIM']:
defs.append('WITH_OCEANSIM')
+if env['WITH_BF_CYCLES']:
+ defs.append('WITH_CYCLES')
+
if env['OURPLATFORM'] == 'linux':
cflags='-pthread'
incs += ' ../../../extern/binreloc/include'
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index fd9cd26cbfa..5bbdac646a7 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -143,6 +143,9 @@ set(INC_SYS
)
+if(WITH_CYCLES)
+ add_definitions(-DWITH_CYCLES)
+endif()
if(WITH_PYTHON)
add_definitions(-DWITH_PYTHON)
@@ -246,6 +249,7 @@ blender_include_dirs(
../../editors/include
../../render/extern/include
../../../../intern/audaspace/intern
+ ../../../../intern/cycles/blender
../../../../intern/guardedalloc
../../../../intern/memutil
)
diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript
index d710dd06a17..1fc6ed0f130 100644
--- a/source/blender/makesrna/intern/SConscript
+++ b/source/blender/makesrna/intern/SConscript
@@ -33,7 +33,7 @@ incs = '#/intern/guardedalloc ../../blenlib ../../blenkernel ../../blenloader'
incs += ' ../../imbuf ../../makesdna ../../makesrna ../../ikplugin'
incs += ' ../../windowmanager ../../editors/include ../../blenfont'
incs += ' ../../render/extern/include'
-incs += ' #/intern/audaspace/intern '
+incs += ' #/intern/audaspace/intern #/intern/cycles/blender'
incs += ' #/extern/glew/include '
if env['WITH_BF_OPENEXR']:
@@ -91,6 +91,9 @@ if env['WITH_BF_PYTHON']:
if env['WITH_BF_COLLADA']:
defs.append('WITH_COLLADA')
+if env['WITH_BF_CYCLES']:
+ defs.append('WITH_CYCLES')
+
if env['OURPLATFORM'] == 'linux':
cflags='-pthread'
incs += ' ../../../extern/binreloc/include'
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 164f8e4f0d0..4564b9f2946 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -46,6 +46,14 @@
#include "BKE_sound.h"
+#ifdef WITH_CYCLES
+static EnumPropertyItem compute_device_type_items[] = {
+ {USER_COMPUTE_DEVICE_NONE, "NONE", 0, "None", "Don't use compute device"},
+ {USER_COMPUTE_DEVICE_CUDA, "CUDA", 0, "CUDA", "Use CUDA for GPU acceleration"},
+ {USER_COMPUTE_DEVICE_OPENCL, "OPENCL", 0, "OpenCL", "Use OpenCL for GPU acceleration"},
+ { 0, NULL, 0, NULL, NULL}};
+#endif
+
#ifdef RNA_RUNTIME
#include "DNA_object_types.h"
@@ -65,6 +73,8 @@
#include "UI_interface.h"
+#include "CCL_api.h"
+
static void rna_userdef_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
WM_main_add_notifier(NC_WINDOW, NULL);
@@ -302,6 +312,68 @@ static void rna_userdef_text_update(Main *UNUSED(bmain), Scene *UNUSED(scene), P
WM_main_add_notifier(NC_WINDOW, NULL);
}
+#ifdef WITH_CYCLES
+static EnumPropertyItem *rna_userdef_compute_device_type_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
+{
+ EnumPropertyItem *item= NULL;
+ int totitem= 0;
+
+ /* add supported device types */
+ RNA_enum_items_add_value(&item, &totitem, compute_device_type_items, USER_COMPUTE_DEVICE_NONE);
+ if(CCL_compute_device_list(0))
+ RNA_enum_items_add_value(&item, &totitem, compute_device_type_items, USER_COMPUTE_DEVICE_CUDA);
+ if(CCL_compute_device_list(1))
+ RNA_enum_items_add_value(&item, &totitem, compute_device_type_items, USER_COMPUTE_DEVICE_OPENCL);
+
+ RNA_enum_item_end(&item, &totitem);
+ *free = 1;
+
+ return item;
+}
+
+static int rna_userdef_compute_device_get(PointerRNA *UNUSED(ptr))
+{
+ if(U.compute_device_type == USER_COMPUTE_DEVICE_NONE)
+ return 0;
+
+ return U.compute_device_id;
+}
+
+static EnumPropertyItem *rna_userdef_compute_device_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
+{
+ EnumPropertyItem tmp= {0, "", 0, "", ""};
+ EnumPropertyItem *item= NULL;
+ int totitem= 0;
+
+ if(U.compute_device_type == USER_COMPUTE_DEVICE_NONE) {
+ /* only add a single CPU device */
+ tmp.value = 0;
+ tmp.name = "CPU";
+ tmp.identifier = "CPU";
+ RNA_enum_item_add(&item, &totitem, &tmp);
+ }
+ else {
+ /* get device list from cycles. it would be good to make this generic
+ once we have more subsystems using opencl, for now this is easiest */
+ int opencl = (U.compute_device_type == USER_COMPUTE_DEVICE_OPENCL);
+ CCLDeviceInfo *devices = CCL_compute_device_list(opencl);
+ int a;
+
+ for(a = 0; devices[a].name; a++) {
+ tmp.value = devices[a].value;
+ tmp.identifier = devices[a].identifier;
+ tmp.name = devices[a].name;
+ RNA_enum_item_add(&item, &totitem, &tmp);
+ }
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *free = 1;
+
+ return item;
+}
+#endif
+
#else
static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna)
@@ -2645,6 +2717,12 @@ static void rna_def_userdef_system(BlenderRNA *brna)
{18, "UKRAINIAN", 0, "Ukrainian (Український)", "uk_UA"},
{ 0, NULL, 0, NULL, NULL}};
+#ifdef WITH_CYCLES
+ static EnumPropertyItem compute_device_items[] = {
+ {0, "CPU", 0, "CPU", ""},
+ { 0, NULL, 0, NULL, NULL}};
+#endif
+
srna= RNA_def_struct(brna, "UserPreferencesSystem", NULL);
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_nested(brna, srna, "UserPreferences");
@@ -2853,14 +2931,20 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Text Anti-aliasing", "Draw user interface text anti-aliased");
RNA_def_property_update(prop, 0, "rna_userdef_text_update");
-#if 0
- prop= RNA_def_property(srna, "verse_master", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "versemaster");
- RNA_def_property_ui_text(prop, "Verse Master", "Verse Master-server IP");
-
- prop= RNA_def_property(srna, "verse_username", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "verseuser");
- RNA_def_property_ui_text(prop, "Verse Username", "Verse user name");
+#ifdef WITH_CYCLES
+ prop= RNA_def_property(srna, "compute_device_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
+ RNA_def_property_enum_sdna(prop, NULL, "compute_device_type");
+ RNA_def_property_enum_items(prop, compute_device_type_items);
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_userdef_compute_device_type_itemf");
+ RNA_def_property_ui_text(prop, "Compute Device Type", "Device to use for computation (rendering with Cycles)");
+
+ prop= RNA_def_property(srna, "compute_device", PROP_ENUM, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
+ RNA_def_property_enum_sdna(prop, NULL, "compute_device_id");
+ RNA_def_property_enum_items(prop, compute_device_items);
+ RNA_def_property_enum_funcs(prop, "rna_userdef_compute_device_get", NULL, "rna_userdef_compute_device_itemf");
+ RNA_def_property_ui_text(prop, "Compute Device", "Device to use for computation");
#endif
}
diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript
index cd1666d0eed..2a47c2dcb96 100644
--- a/source/blender/python/SConscript
+++ b/source/blender/python/SConscript
@@ -6,7 +6,7 @@ Import ('env')
incs = '. ../editors/include ../makesdna ../makesrna ../blenfont ../blenlib ../blenkernel ../nodes'
incs += ' ../imbuf ../blenloader ../gpu ../render/extern/include ../windowmanager'
-incs += ' #intern/guardedalloc #intern/memutil #extern/glew/include'
+incs += ' #intern/guardedalloc #intern/memutil #extern/glew/include #intern/cycles/blender'
incs += ' #intern/audaspace/intern ' + env['BF_PYTHON_INC']
is_debug = (env['OURPLATFORM'] in ('win32-mingw', 'win32-vc','win64-vc') and env['BF_DEBUG'])
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index f110576a297..05583e133dc 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -35,6 +35,7 @@ set(INC
../../windowmanager
../../gpu
../../../../intern/guardedalloc
+ ../../../../intern/cycles/blender
)
set(INC_SYS
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 7d91438e4f7..6c961d8e6a8 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -57,12 +57,13 @@
#include "BLI_string_utf8.h"
#include "BLI_utildefines.h"
-
#include "BKE_context.h"
#include "BKE_text.h"
#include "BKE_main.h"
#include "BKE_global.h" /* only for script checking */
+#include "CCL_api.h"
+
#include "BPY_extern.h"
#include "../generic/bpy_internal_import.h" // our own imports
@@ -176,8 +177,14 @@ void BPY_context_set(bContext *C)
/* defined in AUD_C-API.cpp */
extern PyObject *AUD_initPython(void);
-/* defined in cycles/blender */
-extern PyObject *CYCLES_initPython(void);
+
+#ifdef WITH_CYCLES
+/* defined in cycles module */
+static PyObject *CCL_initPython(void)
+{
+ return (PyObject*)CCL_python_module_init();
+}
+#endif
static struct _inittab bpy_internal_modules[] = {
{(char *)"mathutils", PyInit_mathutils},
@@ -189,7 +196,7 @@ static struct _inittab bpy_internal_modules[] = {
{(char *)"aud", AUD_initPython},
#endif
#ifdef WITH_CYCLES
- {(char *)"_cycles", CYCLES_initPython},
+ {(char *)"_cycles", CCL_initPython},
#endif
{(char *)"gpu", GPU_initPython},
{NULL, NULL}
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 75d1f182189..9efb8114cbd 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -475,6 +475,9 @@ struct DualConMesh *dualcon(const struct DualConMesh *input_mesh,
float scale,
int depth) {return 0;}
+/* intern/cycles */
+struct CCLDeviceInfo;
+struct CCLDeviceInfo *CCL_compute_device_list(int opencl) { return NULL; }
char blender_path[] = "";