diff options
Diffstat (limited to 'intern/cycles')
-rw-r--r-- | intern/cycles/blender/CCL_api.h | 46 | ||||
-rw-r--r-- | intern/cycles/blender/CMakeLists.txt | 1 | ||||
-rw-r--r-- | intern/cycles/blender/addon/engine.py | 3 | ||||
-rw-r--r-- | intern/cycles/blender/addon/enums.py | 24 | ||||
-rw-r--r-- | intern/cycles/blender/addon/properties.py | 3 | ||||
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 16 | ||||
-rw-r--r-- | intern/cycles/blender/blender_python.cpp | 73 | ||||
-rw-r--r-- | intern/cycles/blender/blender_session.cpp | 19 | ||||
-rw-r--r-- | intern/cycles/blender/blender_session.h | 7 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.cpp | 50 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.h | 2 | ||||
-rw-r--r-- | intern/cycles/device/device.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/device/device.h | 2 | ||||
-rw-r--r-- | intern/cycles/device/device_cpu.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/device/device_cuda.cpp | 19 | ||||
-rw-r--r-- | intern/cycles/device/device_multi.cpp | 55 | ||||
-rw-r--r-- | intern/cycles/device/device_network.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/device/device_opencl.cpp | 7 | ||||
-rw-r--r-- | intern/cycles/render/buffers.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/render/mesh_displace.cpp | 2 |
20 files changed, 210 insertions, 127 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); |