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:
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/app/CMakeLists.txt4
-rw-r--r--intern/cycles/app/cycles_server.cpp6
-rw-r--r--intern/cycles/blender/CCL_api.h2
-rw-r--r--intern/cycles/blender/addon/engine.py4
-rw-r--r--intern/cycles/blender/addon/properties.py10
-rw-r--r--intern/cycles/blender/addon/ui.py2
-rw-r--r--intern/cycles/blender/blender_python.cpp26
-rw-r--r--intern/cycles/device/CMakeLists.txt2
-rw-r--r--intern/cycles/device/device.cpp5
-rw-r--r--intern/cycles/device/device.h2
-rw-r--r--intern/cycles/device/device_cpu.cpp8
-rw-r--r--intern/cycles/device/device_cuda.cpp3
-rw-r--r--intern/cycles/device/device_intern.h2
-rw-r--r--intern/cycles/device/device_multi.cpp9
-rw-r--r--intern/cycles/device/device_network.cpp457
-rw-r--r--intern/cycles/device/device_network.h53
-rw-r--r--intern/cycles/device/device_opencl.cpp3
-rw-r--r--intern/cycles/render/session.cpp18
-rw-r--r--intern/cycles/util/util_string.cpp9
-rw-r--r--intern/cycles/util/util_string.h1
-rw-r--r--intern/cycles/util/util_system.cpp4
21 files changed, 481 insertions, 149 deletions
diff --git a/intern/cycles/app/CMakeLists.txt b/intern/cycles/app/CMakeLists.txt
index ada5ea55fb2..8a81ddde1e1 100644
--- a/intern/cycles/app/CMakeLists.txt
+++ b/intern/cycles/app/CMakeLists.txt
@@ -30,6 +30,10 @@ set(LIBRARIES
${TIFF_LIBRARY}
)
+if(UNIX)
+ list(APPEND LIBRARIES dl)
+endif()
+
if(WIN32)
list(APPEND LIBRARIES ${PTHREADS_LIBRARIES})
endif()
diff --git a/intern/cycles/app/cycles_server.cpp b/intern/cycles/app/cycles_server.cpp
index e80fc0cb95f..f4cacb2d001 100644
--- a/intern/cycles/app/cycles_server.cpp
+++ b/intern/cycles/app/cycles_server.cpp
@@ -35,6 +35,7 @@ int main(int argc, const char **argv)
string devicelist = "";
string devicename = "cpu";
bool list = false;
+ int threads = 0;
vector<DeviceType>& types = Device::available_types();
@@ -51,6 +52,7 @@ int main(int argc, const char **argv)
ap.options ("Usage: cycles_server [options]",
"--device %s", &devicename, ("Devices to use: " + devicelist).c_str(),
"--list-devices", &list, "List information about all available devices",
+ "--threads %d", &threads, "Number of threads to use for CPU device",
NULL);
if(ap.parse(argc, argv) < 0) {
@@ -84,11 +86,11 @@ int main(int argc, const char **argv)
}
}
- TaskScheduler::init();
+ TaskScheduler::init(threads);
while(1) {
Stats stats;
- Device *device = Device::create(device_info, stats);
+ Device *device = Device::create(device_info, stats, true);
printf("Cycles Server with device: %s\n", device->info.description.c_str());
device->server_run();
delete device;
diff --git a/intern/cycles/blender/CCL_api.h b/intern/cycles/blender/CCL_api.h
index 29d8ed0d98e..6532315cf39 100644
--- a/intern/cycles/blender/CCL_api.h
+++ b/intern/cycles/blender/CCL_api.h
@@ -30,7 +30,7 @@ typedef struct CCLDeviceInfo {
int value;
} CCLDeviceInfo;
-CCLDeviceInfo *CCL_compute_device_list(int opencl);
+CCLDeviceInfo *CCL_compute_device_list(int device_type);
/* create python module _cycles used by addon */
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index 3f15e232de7..66dc5e78e5a 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -88,3 +88,7 @@ def available_devices():
def with_osl():
import _cycles
return _cycles.with_osl
+
+def with_network():
+ import _cycles
+ return _cycles.with_network
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 791f1ed51fb..f5c052e7f0c 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -25,9 +25,15 @@ from bpy.props import (BoolProperty,
# enums
+import _cycles
+
enum_devices = (
- ('CPU', "CPU", "Use CPU for rendering"),
- ('GPU', "GPU Compute", "Use GPU compute device for rendering, configured in user preferences"))
+ ('CPU', "CPU", "Use CPU for rendering"),
+ ('GPU', "GPU Compute", "Use GPU compute device for rendering, configured in user preferences"),
+ )
+
+if _cycles.with_network:
+ enum_devices += (('NETWORK', "Networked Device", "Use networked device for rendering"),)
enum_feature_set = (
('SUPPORTED', "Supported", "Only use finished and supported features"),
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 14e78c4bf1f..42d5e011b83 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -1254,6 +1254,8 @@ def draw_device(self, context):
layout.prop(cscene, "device")
elif device_type == 'OPENCL':
layout.prop(cscene, "device")
+ elif device_type == 'NETWORK':
+ layout.prop(cscene, "device")
if engine.with_osl() and (cscene.device == 'CPU' or device_type == 'NONE'):
layout.prop(cscene, "shading_system")
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index 71c84869ff6..8e6bcaee350 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -482,12 +482,34 @@ void *CCL_python_module_init()
Py_INCREF(Py_False);
#endif
+#ifdef WITH_NETWORK
+ PyModule_AddObject(mod, "with_network", Py_True);
+ Py_INCREF(Py_True);
+#else /* WITH_NETWORK */
+ PyModule_AddObject(mod, "with_network", Py_False);
+ Py_INCREF(Py_False);
+#endif /* WITH_NETWORK */
+
return (void*)mod;
}
-CCLDeviceInfo *CCL_compute_device_list(int opencl)
+CCLDeviceInfo *CCL_compute_device_list(int device_type)
{
- ccl::DeviceType type = (opencl)? ccl::DEVICE_OPENCL: ccl::DEVICE_CUDA;
+ ccl::DeviceType type;
+ switch(device_type) {
+ case 0:
+ type = ccl::DEVICE_CUDA;
+ break;
+ case 1:
+ type = ccl::DEVICE_OPENCL;
+ break;
+ case 2:
+ type = ccl::DEVICE_NETWORK;
+ break;
+ default:
+ type = ccl::DEVICE_NONE;
+ break;
+ }
return ccl::compute_device_list(type);
}
diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt
index 920223dd8a4..825e82209aa 100644
--- a/intern/cycles/device/CMakeLists.txt
+++ b/intern/cycles/device/CMakeLists.txt
@@ -26,7 +26,7 @@ set(SRC
device_task.cpp
)
-if(WITH_NETWORK)
+if(WITH_CYCLES_NETWORK)
list(APPEND SRC
device_network.cpp
)
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index 5c771aa1c8b..6283e34f563 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -127,7 +127,7 @@ Device *Device::create(DeviceInfo& info, Stats &stats, bool background)
switch(info.type) {
case DEVICE_CPU:
- device = device_cpu_create(info, stats);
+ device = device_cpu_create(info, stats, background);
break;
#ifdef WITH_CUDA
case DEVICE_CUDA:
@@ -159,9 +159,6 @@ Device *Device::create(DeviceInfo& info, Stats &stats, bool background)
return NULL;
}
- if(device)
- device->info = info;
-
return device;
}
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 18868d19a85..bd309e35788 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -71,7 +71,7 @@ public:
class Device {
protected:
- Device(Stats &stats_) : stats(stats_) {}
+ Device(DeviceInfo& info_, Stats &stats_, bool background) : background(background), info(info_), stats(stats_) {}
bool background;
string error_msg;
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 85a7b9c186d..e084116c72d 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -45,11 +45,13 @@ class CPUDevice : public Device
public:
TaskPool task_pool;
KernelGlobals kernel_globals;
+
#ifdef WITH_OSL
OSLGlobals osl_globals;
#endif
- CPUDevice(Stats &stats) : Device(stats)
+ CPUDevice(DeviceInfo& info, Stats &stats, bool background)
+ : Device(info, stats, background)
{
#ifdef WITH_OSL
kernel_globals.osl = &osl_globals;
@@ -401,9 +403,9 @@ public:
}
};
-Device *device_cpu_create(DeviceInfo& info, Stats &stats)
+Device *device_cpu_create(DeviceInfo& info, Stats &stats, bool background)
{
- return new CPUDevice(stats);
+ return new CPUDevice(info, stats, background);
}
void device_cpu_info(vector<DeviceInfo>& devices)
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 4ce7f6fd729..8db915f769c 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -171,7 +171,8 @@ public:
cuda_assert(cuCtxSetCurrent(NULL));
}
- CUDADevice(DeviceInfo& info, Stats &stats, bool background_) : Device(stats)
+ CUDADevice(DeviceInfo& info, Stats &stats, bool background_)
+ : Device(info, stats, background_)
{
first_error = true;
background = background_;
diff --git a/intern/cycles/device/device_intern.h b/intern/cycles/device/device_intern.h
index d667478beed..7eb66c25a81 100644
--- a/intern/cycles/device/device_intern.h
+++ b/intern/cycles/device/device_intern.h
@@ -21,7 +21,7 @@ CCL_NAMESPACE_BEGIN
class Device;
-Device *device_cpu_create(DeviceInfo& info, Stats &stats);
+Device *device_cpu_create(DeviceInfo& info, Stats &stats, bool background);
Device *device_opencl_create(DeviceInfo& info, Stats &stats, bool background);
Device *device_cuda_create(DeviceInfo& info, Stats &stats, bool background);
Device *device_network_create(DeviceInfo& info, Stats &stats, const char *address);
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp
index 4df0fdbd4c7..27b9de0769e 100644
--- a/intern/cycles/device/device_multi.cpp
+++ b/intern/cycles/device/device_multi.cpp
@@ -45,25 +45,24 @@ public:
device_ptr unique_ptr;
MultiDevice(DeviceInfo& info, Stats &stats, bool background_)
- : Device(stats), unique_ptr(1)
+ : Device(info, stats, background_), unique_ptr(1)
{
Device *device;
- background = background_;
foreach(DeviceInfo& subinfo, info.multi_devices) {
device = Device::create(subinfo, stats, background);
devices.push_back(SubDevice(device));
}
-#if 0 //def WITH_NETWORK
+#ifdef WITH_NETWORK
/* try to add network devices */
ServerDiscovery discovery(true);
time_sleep(1.0);
- list<string> servers = discovery.get_server_list();
+ vector<string> servers = discovery.get_server_list();
foreach(string& server, servers) {
- device = device_network_create(info, server.c_str());
+ device = device_network_create(info, stats, server.c_str());
if(device)
devices.push_back(SubDevice(device));
}
diff --git a/intern/cycles/device/device_network.cpp b/intern/cycles/device/device_network.cpp
index 23c1a10fa0a..90339b89cce 100644
--- a/intern/cycles/device/device_network.cpp
+++ b/intern/cycles/device/device_network.cpp
@@ -20,9 +20,25 @@
#include "util_foreach.h"
+#if defined(WITH_NETWORK)
+
CCL_NAMESPACE_BEGIN
-#ifdef WITH_NETWORK
+typedef map<device_ptr, device_ptr> PtrMap;
+typedef vector<uint8_t> DataVector;
+typedef map<device_ptr, DataVector> DataMap;
+
+/* tile list */
+typedef vector<RenderTile> TileList;
+
+/* search a list of tiles and find the one that matches the passed render tile */
+static TileList::iterator tile_list_find(TileList& tile_list, RenderTile& tile)
+{
+ for(TileList::iterator it = tile_list.begin(); it != tile_list.end(); ++it)
+ if(tile.x == it->x && tile.y == it->y && tile.start_sample == it->start_sample)
+ return it;
+ return tile_list.end();
+}
class NetworkDevice : public Device
{
@@ -32,8 +48,10 @@ public:
device_ptr mem_counter;
DeviceTask the_task; /* todo: handle multiple tasks */
- NetworkDevice(Stats &stats, const char *address)
- : Device(stats), socket(io_service)
+ thread_mutex rpc_lock;
+
+ NetworkDevice(DeviceInfo& info, Stats &stats, const char *address)
+ : Device(info, stats, true), socket(io_service)
{
stringstream portstr;
portstr << SERVER_PORT;
@@ -64,6 +82,8 @@ public:
void mem_alloc(device_memory& mem, MemoryType type)
{
+ thread_scoped_lock lock(rpc_lock);
+
mem.device_pointer = ++mem_counter;
RPCSend snd(socket, "mem_alloc");
@@ -75,6 +95,8 @@ public:
void mem_copy_to(device_memory& mem)
{
+ thread_scoped_lock lock(rpc_lock);
+
RPCSend snd(socket, "mem_copy_to");
snd.add(mem);
@@ -84,6 +106,10 @@ public:
void mem_copy_from(device_memory& mem, int y, int w, int h, int elem)
{
+ thread_scoped_lock lock(rpc_lock);
+
+ size_t data_size = mem.memory_size();
+
RPCSend snd(socket, "mem_copy_from");
snd.add(mem);
@@ -94,11 +120,13 @@ public:
snd.write();
RPCReceive rcv(socket);
- rcv.read_buffer((void*)mem.data_pointer, mem.memory_size());
+ rcv.read_buffer((void*)mem.data_pointer, data_size);
}
void mem_zero(device_memory& mem)
{
+ thread_scoped_lock lock(rpc_lock);
+
RPCSend snd(socket, "mem_zero");
snd.add(mem);
@@ -108,6 +136,8 @@ public:
void mem_free(device_memory& mem)
{
if(mem.device_pointer) {
+ thread_scoped_lock lock(rpc_lock);
+
RPCSend snd(socket, "mem_free");
snd.add(mem);
@@ -119,6 +149,8 @@ public:
void const_copy_to(const char *name, void *host, size_t size)
{
+ thread_scoped_lock lock(rpc_lock);
+
RPCSend snd(socket, "const_copy_to");
string name_string(name);
@@ -131,6 +163,8 @@ public:
void tex_alloc(const char *name, device_memory& mem, bool interpolation, bool periodic)
{
+ thread_scoped_lock lock(rpc_lock);
+
mem.device_pointer = ++mem_counter;
RPCSend snd(socket, "tex_alloc");
@@ -148,6 +182,8 @@ public:
void tex_free(device_memory& mem)
{
if(mem.device_pointer) {
+ thread_scoped_lock lock(rpc_lock);
+
RPCSend snd(socket, "tex_free");
snd.add(mem);
@@ -157,8 +193,25 @@ public:
}
}
+ bool load_kernels(bool experimental)
+ {
+ thread_scoped_lock lock(rpc_lock);
+
+ RPCSend snd(socket, "load_kernels");
+ snd.add(experimental);
+ snd.write();
+
+ bool result;
+ RPCReceive rcv(socket);
+ rcv.read(result);
+
+ return result;
+ }
+
void task_add(DeviceTask& task)
{
+ thread_scoped_lock lock(rpc_lock);
+
the_task = task;
RPCSend snd(socket, "task_add");
@@ -168,55 +221,73 @@ public:
void task_wait()
{
+ thread_scoped_lock lock(rpc_lock);
+
RPCSend snd(socket, "task_wait");
snd.write();
- list<RenderTile> the_tiles;
+ lock.unlock();
+
+ TileList the_tiles;
/* todo: run this threaded for connecting to multiple clients */
for(;;) {
- RPCReceive rcv(socket);
RenderTile tile;
+ lock.lock();
+ RPCReceive rcv(socket);
+
if(rcv.name == "acquire_tile") {
+ lock.unlock();
+
/* todo: watch out for recursive calls! */
if(the_task.acquire_tile(this, tile)) { /* write return as bool */
the_tiles.push_back(tile);
+ lock.lock();
RPCSend snd(socket, "acquire_tile");
snd.add(tile);
snd.write();
+ lock.unlock();
}
else {
+ lock.lock();
RPCSend snd(socket, "acquire_tile_none");
snd.write();
+ lock.unlock();
}
}
else if(rcv.name == "release_tile") {
rcv.read(tile);
+ lock.unlock();
- for(list<RenderTile>::iterator it = the_tiles.begin(); it != the_tiles.end(); it++) {
- if(tile.x == it->x && tile.y == it->y && tile.start_sample == it->start_sample) {
- tile.buffers = it->buffers;
- the_tiles.erase(it);
- break;
- }
+ TileList::iterator it = tile_list_find(the_tiles, tile);
+ if (it != the_tiles.end()) {
+ tile.buffers = it->buffers;
+ the_tiles.erase(it);
}
assert(tile.buffers != NULL);
the_task.release_tile(tile);
+ lock.lock();
RPCSend snd(socket, "release_tile");
snd.write();
+ lock.unlock();
}
- else if(rcv.name == "task_wait_done")
+ else if(rcv.name == "task_wait_done") {
+ lock.unlock();
break;
+ }
+ else
+ lock.unlock();
}
}
void task_cancel()
{
+ thread_scoped_lock lock(rpc_lock);
RPCSend snd(socket, "task_cancel");
snd.write();
}
@@ -224,7 +295,7 @@ public:
Device *device_network_create(DeviceInfo& info, Stats &stats, const char *address)
{
- return new NetworkDevice(stats, address);
+ return new NetworkDevice(info, stats, address);
}
void device_network_info(vector<DeviceInfo>& devices)
@@ -243,8 +314,10 @@ void device_network_info(vector<DeviceInfo>& devices)
class DeviceServer {
public:
+ thread_mutex rpc_lock;
+
DeviceServer(Device *device_, tcp::socket& socket_)
- : device(device_), socket(socket_)
+ : device(device_), socket(socket_), stop(false), blocked_waiting(false)
{
}
@@ -252,56 +325,151 @@ public:
{
/* receive remote function calls */
for(;;) {
- RPCReceive rcv(socket);
+ listen_step();
- if(rcv.name == "stop")
+ if(stop)
break;
-
- process(rcv);
}
}
protected:
- void process(RPCReceive& rcv)
+ void listen_step()
+ {
+ thread_scoped_lock lock(rpc_lock);
+ RPCReceive rcv(socket);
+
+ if(rcv.name == "stop")
+ stop = true;
+ else
+ process(rcv, lock);
+ }
+
+ /* create a memory buffer for a device buffer and insert it into mem_data */
+ DataVector &data_vector_insert(device_ptr client_pointer, size_t data_size)
+ {
+ /* create a new DataVector and insert it into mem_data */
+ pair<DataMap::iterator,bool> data_ins = mem_data.insert(
+ DataMap::value_type(client_pointer, DataVector()));
+
+ /* make sure it was a unique insertion */
+ assert(data_ins.second);
+
+ /* get a reference to the inserted vector */
+ DataVector &data_v = data_ins.first->second;
+
+ /* size the vector */
+ data_v.resize(data_size);
+
+ return data_v;
+ }
+
+ DataVector &data_vector_find(device_ptr client_pointer)
{
- // fprintf(stderr, "receive process %s\n", rcv.name.c_str());
+ DataMap::iterator i = mem_data.find(client_pointer);
+ assert(i != mem_data.end());
+ return i->second;
+ }
+
+ /* setup mapping and reverse mapping of client_pointer<->real_pointer */
+ void pointer_mapping_insert(device_ptr client_pointer, device_ptr real_pointer)
+ {
+ pair<PtrMap::iterator,bool> mapins;
+
+ /* insert mapping from client pointer to our real device pointer */
+ mapins = ptr_map.insert(PtrMap::value_type(client_pointer, real_pointer));
+ assert(mapins.second);
+
+ /* insert reverse mapping from real our device pointer to client pointer */
+ mapins = ptr_imap.insert(PtrMap::value_type(real_pointer, client_pointer));
+ assert(mapins.second);
+ }
+
+ device_ptr device_ptr_from_client_pointer(device_ptr client_pointer)
+ {
+ PtrMap::iterator i = ptr_map.find(client_pointer);
+ assert(i != ptr_map.end());
+ return i->second;
+ }
+
+ device_ptr device_ptr_from_client_pointer_erase(device_ptr client_pointer)
+ {
+ PtrMap::iterator i = ptr_map.find(client_pointer);
+ assert(i != ptr_map.end());
+
+ device_ptr result = i->second;
+ /* erase the mapping */
+ ptr_map.erase(i);
+
+ /* erase the reverse mapping */
+ PtrMap::iterator irev = ptr_imap.find(result);
+ assert(irev != ptr_imap.end());
+ ptr_imap.erase(irev);
+
+ /* erase the data vector */
+ DataMap::iterator idata = mem_data.find(client_pointer);
+ assert(idata != mem_data.end());
+ mem_data.erase(idata);
+
+ return result;
+ }
+
+ /* note that the lock must be already acquired upon entry.
+ * This is necessary because the caller often peeks at
+ * the header and delegates control to here when it doesn't
+ * specifically handle the current RPC.
+ * The lock must be unlocked before returning */
+ void process(RPCReceive& rcv, thread_scoped_lock &lock)
+ {
if(rcv.name == "mem_alloc") {
MemoryType type;
network_device_memory mem;
- device_ptr remote_pointer;
+ device_ptr client_pointer;
rcv.read(mem);
rcv.read(type);
- /* todo: CPU needs mem.data_pointer */
+ lock.unlock();
+
+ client_pointer = mem.device_pointer;
- remote_pointer = mem.device_pointer;
+ /* create a memory buffer for the device buffer */
+ size_t data_size = mem.memory_size();
+ DataVector &data_v = data_vector_insert(client_pointer, data_size);
- mem_data[remote_pointer] = vector<uint8_t>();
- mem_data[remote_pointer].resize(mem.memory_size());
- if(mem.memory_size())
- mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
+ if(data_size)
+ mem.data_pointer = (device_ptr)&(data_v[0]);
else
mem.data_pointer = 0;
+ /* perform the allocation on the actual device */
device->mem_alloc(mem, type);
- ptr_map[remote_pointer] = mem.device_pointer;
- ptr_imap[mem.device_pointer] = remote_pointer;
+ /* store a mapping to/from client_pointer and real device pointer */
+ pointer_mapping_insert(client_pointer, mem.device_pointer);
}
else if(rcv.name == "mem_copy_to") {
network_device_memory mem;
rcv.read(mem);
+ lock.unlock();
- device_ptr remote_pointer = mem.device_pointer;
- mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
+ device_ptr client_pointer = mem.device_pointer;
- rcv.read_buffer((uint8_t*)mem.data_pointer, mem.memory_size());
+ DataVector &data_v = data_vector_find(client_pointer);
- mem.device_pointer = ptr_map[remote_pointer];
+ size_t data_size = mem.memory_size();
+ /* get pointer to memory buffer for device buffer */
+ mem.data_pointer = (device_ptr)&data_v[0];
+
+ /* copy data from network into memory buffer */
+ rcv.read_buffer((uint8_t*)mem.data_pointer, data_size);
+
+ /* translate the client pointer to a real device pointer */
+ mem.device_pointer = device_ptr_from_client_pointer(client_pointer);
+
+ /* copy the data from the memory buffer to the device buffer */
device->mem_copy_to(mem);
}
else if(rcv.name == "mem_copy_from") {
@@ -314,37 +482,47 @@ protected:
rcv.read(h);
rcv.read(elem);
- device_ptr remote_pointer = mem.device_pointer;
- mem.device_pointer = ptr_map[remote_pointer];
- mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
+ device_ptr client_pointer = mem.device_pointer;
+ mem.device_pointer = device_ptr_from_client_pointer(client_pointer);
+
+ DataVector &data_v = data_vector_find(client_pointer);
+
+ mem.data_pointer = (device_ptr)&(data_v[0]);
device->mem_copy_from(mem, y, w, h, elem);
+ size_t data_size = mem.memory_size();
+
RPCSend snd(socket);
snd.write();
- snd.write_buffer((uint8_t*)mem.data_pointer, mem.memory_size());
+ snd.write_buffer((uint8_t*)mem.data_pointer, data_size);
+ lock.unlock();
}
else if(rcv.name == "mem_zero") {
network_device_memory mem;
rcv.read(mem);
- device_ptr remote_pointer = mem.device_pointer;
- mem.device_pointer = ptr_map[mem.device_pointer];
- mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
+ lock.unlock();
+
+ device_ptr client_pointer = mem.device_pointer;
+ mem.device_pointer = device_ptr_from_client_pointer(client_pointer);
+
+ DataVector &data_v = data_vector_find(client_pointer);
+
+ mem.data_pointer = (device_ptr)&(data_v[0]);
device->mem_zero(mem);
}
else if(rcv.name == "mem_free") {
network_device_memory mem;
- device_ptr remote_pointer;
+ device_ptr client_pointer;
rcv.read(mem);
+ lock.unlock();
+
+ client_pointer = mem.device_pointer;
- remote_pointer = mem.device_pointer;
- mem.device_pointer = ptr_map[mem.device_pointer];
- ptr_map.erase(remote_pointer);
- ptr_imap.erase(mem.device_pointer);
- mem_data.erase(remote_pointer);
+ mem.device_pointer = device_ptr_from_client_pointer_erase(client_pointer);
device->mem_free(mem);
}
@@ -357,6 +535,7 @@ protected:
vector<char> host_vector(size);
rcv.read_buffer(&host_vector[0], size);
+ lock.unlock();
device->const_copy_to(name_string.c_str(), &host_vector[0], size);
}
@@ -365,53 +544,76 @@ protected:
string name;
bool interpolation;
bool periodic;
- device_ptr remote_pointer;
+ device_ptr client_pointer;
rcv.read(name);
rcv.read(mem);
rcv.read(interpolation);
rcv.read(periodic);
+ lock.unlock();
+
+ client_pointer = mem.device_pointer;
+
+ size_t data_size = mem.memory_size();
- remote_pointer = mem.device_pointer;
+ DataVector &data_v = data_vector_insert(client_pointer, data_size);
- mem_data[remote_pointer] = vector<uint8_t>();
- mem_data[remote_pointer].resize(mem.memory_size());
- if(mem.memory_size())
- mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
+ if(data_size)
+ mem.data_pointer = (device_ptr)&(data_v[0]);
else
mem.data_pointer = 0;
- rcv.read_buffer((uint8_t*)mem.data_pointer, mem.memory_size());
+ rcv.read_buffer((uint8_t*)mem.data_pointer, data_size);
device->tex_alloc(name.c_str(), mem, interpolation, periodic);
- ptr_map[remote_pointer] = mem.device_pointer;
- ptr_imap[mem.device_pointer] = remote_pointer;
+ pointer_mapping_insert(client_pointer, mem.device_pointer);
}
else if(rcv.name == "tex_free") {
network_device_memory mem;
- device_ptr remote_pointer;
+ device_ptr client_pointer;
rcv.read(mem);
+ lock.unlock();
- remote_pointer = mem.device_pointer;
- mem.device_pointer = ptr_map[mem.device_pointer];
- ptr_map.erase(remote_pointer);
- ptr_map.erase(mem.device_pointer);
- mem_data.erase(remote_pointer);
+ client_pointer = mem.device_pointer;
+
+ mem.device_pointer = device_ptr_from_client_pointer_erase(client_pointer);
device->tex_free(mem);
}
+ else if(rcv.name == "load_kernels") {
+ bool experimental;
+ rcv.read(experimental);
+
+ bool result;
+ result = device->load_kernels(experimental);
+ RPCSend snd(socket);
+ snd.add(result);
+ snd.write();
+ lock.unlock();
+ }
else if(rcv.name == "task_add") {
DeviceTask task;
rcv.read(task);
+ lock.unlock();
+
+ if(task.buffer)
+ task.buffer = device_ptr_from_client_pointer(task.buffer);
+
+ if(task.rgba_half)
+ task.rgba_half = device_ptr_from_client_pointer(task.rgba_half);
+
+ if(task.rgba_byte)
+ task.rgba_byte = device_ptr_from_client_pointer(task.rgba_byte);
+
+ if(task.shader_input)
+ task.shader_input = device_ptr_from_client_pointer(task.shader_input);
+
+ if(task.shader_output)
+ task.shader_output = device_ptr_from_client_pointer(task.shader_output);
- if(task.buffer) task.buffer = ptr_map[task.buffer];
- if(task.rgba_byte) task.rgba_byte = ptr_map[task.rgba_byte];
- if(task.rgba_half) task.rgba_half = ptr_map[task.rgba_half];
- if(task.shader_input) task.shader_input = ptr_map[task.shader_input];
- if(task.shader_output) task.shader_output = ptr_map[task.shader_output];
task.acquire_tile = function_bind(&DeviceServer::task_acquire_tile, this, _1, _2);
task.release_tile = function_bind(&DeviceServer::task_release_tile, this, _1);
@@ -422,14 +624,44 @@ protected:
device->task_add(task);
}
else if(rcv.name == "task_wait") {
+ lock.unlock();
+
+ blocked_waiting = true;
device->task_wait();
+ blocked_waiting = false;
+ lock.lock();
RPCSend snd(socket, "task_wait_done");
snd.write();
+ lock.unlock();
}
else if(rcv.name == "task_cancel") {
+ lock.unlock();
device->task_cancel();
}
+ else if(rcv.name == "acquire_tile") {
+ AcquireEntry entry;
+ entry.name = rcv.name;
+ rcv.read(entry.tile);
+ acquire_queue.push_back(entry);
+ lock.unlock();
+ }
+ else if(rcv.name == "acquire_tile_none") {
+ AcquireEntry entry;
+ entry.name = rcv.name;
+ acquire_queue.push_back(entry);
+ lock.unlock();
+ }
+ else if(rcv.name == "release_tile") {
+ AcquireEntry entry;
+ entry.name = rcv.name;
+ acquire_queue.push_back(entry);
+ lock.unlock();
+ }
+ else {
+ cout << "Error: unexpected RPC receive call \"" + rcv.name + "\"\n";
+ lock.unlock();
+ }
}
bool task_acquire_tile(Device *device, RenderTile& tile)
@@ -441,23 +673,34 @@ protected:
RPCSend snd(socket, "acquire_tile");
snd.write();
- while(1) {
- RPCReceive rcv(socket);
+ do {
+ if(blocked_waiting)
+ listen_step();
- if(rcv.name == "acquire_tile") {
- rcv.read(tile);
+ /* todo: avoid busy wait loop */
+ thread_scoped_lock lock(rpc_lock);
- if(tile.buffer) tile.buffer = ptr_map[tile.buffer];
- if(tile.rng_state) tile.rng_state = ptr_map[tile.rng_state];
+ if(!acquire_queue.empty()) {
+ AcquireEntry entry = acquire_queue.front();
+ acquire_queue.pop_front();
- result = true;
- break;
+ if(entry.name == "acquire_tile") {
+ tile = entry.tile;
+
+ if(tile.buffer) tile.buffer = ptr_map[tile.buffer];
+ if(tile.rng_state) tile.rng_state = ptr_map[tile.rng_state];
+
+ result = true;
+ break;
+ }
+ else if(entry.name == "acquire_tile_none") {
+ break;
+ }
+ else {
+ cout << "Error: unexpected acquire RPC receive call \"" + entry.name + "\"\n";
+ }
}
- else if(rcv.name == "acquire_tile_none")
- break;
- else
- process(rcv);
- }
+ } while(acquire_queue.empty() && !stop);
return result;
}
@@ -479,18 +722,34 @@ protected:
if(tile.buffer) tile.buffer = ptr_imap[tile.buffer];
if(tile.rng_state) tile.rng_state = ptr_imap[tile.rng_state];
- RPCSend snd(socket, "release_tile");
- snd.add(tile);
- snd.write();
+ {
+ thread_scoped_lock lock(rpc_lock);
+ RPCSend snd(socket, "release_tile");
+ snd.add(tile);
+ snd.write();
+ lock.unlock();
+ }
- while(1) {
- RPCReceive rcv(socket);
+ do {
+ if(blocked_waiting)
+ listen_step();
- if(rcv.name == "release_tile")
- break;
- else
- process(rcv);
- }
+ /* todo: avoid busy wait loop */
+ thread_scoped_lock lock(rpc_lock);
+
+ if(!acquire_queue.empty()) {
+ AcquireEntry entry = acquire_queue.front();
+ acquire_queue.pop_front();
+
+ if(entry.name == "release_tile") {
+ lock.unlock();
+ break;
+ }
+ else {
+ cout << "Error: unexpected release RPC receive call \"" + entry.name + "\"\n";
+ }
+ }
+ } while(acquire_queue.empty() && !stop);
}
bool task_get_cancel()
@@ -503,11 +762,20 @@ protected:
tcp::socket& socket;
/* mapping of remote to local pointer */
- map<device_ptr, device_ptr> ptr_map;
- map<device_ptr, device_ptr> ptr_imap;
- map<device_ptr, vector<uint8_t> > mem_data;
+ PtrMap ptr_map;
+ PtrMap ptr_imap;
+ DataMap mem_data;
+
+ struct AcquireEntry {
+ string name;
+ RenderTile tile;
+ };
thread_mutex acquire_mutex;
+ list<AcquireEntry> acquire_queue;
+
+ bool stop;
+ bool blocked_waiting;
/* todo: free memory and device (osl) on network error */
};
@@ -540,7 +808,8 @@ void Device::server_run()
}
}
+CCL_NAMESPACE_END
+
#endif
-CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_network.h b/intern/cycles/device/device_network.h
index db399cf4240..d639450b9ea 100644
--- a/intern/cycles/device/device_network.h
+++ b/intern/cycles/device/device_network.h
@@ -28,6 +28,8 @@
#include <boost/thread.hpp>
#include <iostream>
+#include <sstream>
+#include <deque>
#include "buffers.h"
@@ -70,12 +72,12 @@ public:
: name(name_), socket(socket_), archive(archive_stream), sent(false)
{
archive & name_;
+
+ fprintf(stderr, "rpc send %s\n", name.c_str());
}
~RPCSend()
{
- if(!sent)
- fprintf(stderr, "Error: RPC %s not sent\n", name.c_str());
}
void add(const device_memory& mem)
@@ -98,13 +100,14 @@ public:
archive & task.offset & task.stride;
archive & task.shader_input & task.shader_output & task.shader_eval_type;
archive & task.shader_x & task.shader_w;
+ archive & task.need_finish_queue;
}
void add(const RenderTile& tile)
{
archive & tile.x & tile.y & tile.w & tile.h;
archive & tile.start_sample & tile.num_samples & tile.sample;
- archive & tile.offset & tile.stride;
+ archive & tile.resolution & tile.offset & tile.stride;
archive & tile.buffer & tile.rng_state;
}
@@ -178,6 +181,7 @@ public:
size_t data_size;
if((header_stream >> hex >> data_size)) {
+
vector<char> data(data_size);
size_t len = boost::asio::read(socket, boost::asio::buffer(data));
@@ -191,15 +195,19 @@ public:
archive = new boost::archive::text_iarchive(*archive_stream);
*archive & name;
+ fprintf(stderr, "rpc receive %s\n", name.c_str());
+ }
+ else {
+ cout << "Network receive error: data size doesn't match header\n";
}
- else
- cout << "Network receive error: data size doens't match header\n";
}
- else
+ else {
cout << "Network receive error: can't decode data size from header\n";
+ }
}
- else
+ else {
cout << "Network receive error: invalid header size\n";
+ }
}
~RPCReceive()
@@ -235,9 +243,10 @@ public:
*archive & type & task.x & task.y & task.w & task.h;
*archive & task.rgba_byte & task.rgba_half & task.buffer & task.sample & task.num_samples;
- *archive & task.resolution & task.offset & task.stride;
+ *archive & task.offset & task.stride;
*archive & task.shader_input & task.shader_output & task.shader_eval_type;
*archive & task.shader_x & task.shader_w;
+ *archive & task.need_finish_queue;
task.type = (DeviceTask::Type)type;
}
@@ -247,7 +256,7 @@ public:
*archive & tile.x & tile.y & tile.w & tile.h;
*archive & tile.start_sample & tile.num_samples & tile.sample;
*archive & tile.resolution & tile.offset & tile.stride;
- *archive & tile.buffer & tile.rng_state & tile.rgba_byte & tile.rgba_half;
+ *archive & tile.buffer & tile.rng_state;
tile.buffers = NULL;
}
@@ -303,12 +312,12 @@ public:
delete work;
}
- list<string> get_server_list()
+ vector<string> get_server_list()
{
- list<string> result;
+ vector<string> result;
mutex.lock();
- result = servers;
+ result = vector<string>(servers.begin(), servers.end());
mutex.unlock();
return result;
@@ -333,11 +342,8 @@ private:
mutex.lock();
/* add address if it's not already in the list */
- bool found = false;
-
- foreach(string& server, servers)
- if(server == address)
- found = true;
+ bool found = std::find(servers.begin(), servers.end(),
+ address) != servers.end();
if(!found)
servers.push_back(address);
@@ -393,10 +399,21 @@ private:
/* buffer and endpoint for receiving messages */
char receive_buffer[256];
boost::asio::ip::udp::endpoint receive_endpoint;
+
+ // os, version, devices, status, host name, group name, ip as far as fields go
+ struct ServerInfo {
+ string cycles_version;
+ string os;
+ int device_count;
+ string status;
+ string host_name;
+ string group_name;
+ string host_addr;
+ };
/* collection of server addresses in list */
bool collect_servers;
- list<string> servers;
+ vector<string> servers;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index 11c7bc6f099..98d3b07b7ee 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -423,9 +423,8 @@ public:
}
OpenCLDevice(DeviceInfo& info, Stats &stats, bool background_)
- : Device(stats)
+ : Device(info, stats, background_)
{
- background = background_;
cpPlatform = NULL;
cdDevice = NULL;
cxContext = NULL;
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 6c15849d815..0805a685467 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -95,7 +95,7 @@ Session::~Session()
wait();
}
- if(display && params.output_path != "") {
+ if(display && !params.output_path.empty()) {
tonemap();
progress.set_status("Writing Image", params.output_path);
@@ -242,7 +242,7 @@ void Session::run_gpu()
/* update scene */
update_scene();
- if(device->error_message() != "")
+ if(!device->error_message().empty())
progress.set_cancel(device->error_message());
if(progress.get_cancel())
@@ -263,7 +263,7 @@ void Session::run_gpu()
device->task_wait();
- if(device->error_message() != "")
+ if(!device->error_message().empty())
progress.set_cancel(device->error_message());
/* update status and timing */
@@ -283,7 +283,7 @@ void Session::run_gpu()
}
}
- if(device->error_message() != "")
+ if(!device->error_message().empty())
progress.set_cancel(device->error_message());
tiles_written = update_progressive_refine(progress.get_cancel());
@@ -531,7 +531,7 @@ void Session::run_cpu()
/* update scene */
update_scene();
- if(device->error_message() != "")
+ if(!device->error_message().empty())
progress.set_cancel(device->error_message());
if(progress.get_cancel())
@@ -549,7 +549,7 @@ void Session::run_cpu()
if(!params.background)
need_tonemap = true;
- if(device->error_message() != "")
+ if(!device->error_message().empty())
progress.set_cancel(device->error_message());
}
@@ -571,7 +571,7 @@ void Session::run_cpu()
tonemap();
}
- if(device->error_message() != "")
+ if(!device->error_message().empty())
progress.set_cancel(device->error_message());
tiles_written = update_progressive_refine(progress.get_cancel());
@@ -592,7 +592,7 @@ void Session::run()
if(!device->load_kernels(params.experimental)) {
string message = device->error_message();
- if(message == "")
+ if(message.empty())
message = "Failed loading render kernel, see console for errors";
progress.set_status("Error", message);
@@ -796,7 +796,7 @@ void Session::update_status_time(bool show_pause, bool show_done)
}
else {
status = substatus;
- substatus = "";
+ substatus.clear();
}
progress.set_status(status, substatus);
diff --git a/intern/cycles/util/util_string.cpp b/intern/cycles/util/util_string.cpp
index c4a81fc7190..61a16b63351 100644
--- a/intern/cycles/util/util_string.cpp
+++ b/intern/cycles/util/util_string.cpp
@@ -96,5 +96,14 @@ bool string_endswith(const string& s, const char *end)
return strncmp(s.c_str() + s.size() - len, end, len) == 0;
}
+string string_strip(const string& s)
+{
+ string result = s;
+ result.erase(0, result.find_first_not_of(' '));
+ result.erase(result.find_last_not_of(' ') + 1);
+ return result;
+
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_string.h b/intern/cycles/util/util_string.h
index 2d63a075e71..6808f085834 100644
--- a/intern/cycles/util/util_string.h
+++ b/intern/cycles/util/util_string.h
@@ -41,6 +41,7 @@ string string_printf(const char *format, ...) PRINTF_ATTRIBUTE;
bool string_iequals(const string& a, const string& b);
void string_split(vector<string>& tokens, const string& str, const string& separators = "\t ");
bool string_endswith(const string& s, const char *end);
+string string_strip(const string& s);
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_system.cpp b/intern/cycles/util/util_system.cpp
index 8b249106913..79bf5fd26b7 100644
--- a/intern/cycles/util/util_system.cpp
+++ b/intern/cycles/util/util_system.cpp
@@ -101,9 +101,7 @@ string system_cpu_brand_string()
replace_string(brand, "(TM)", "");
replace_string(brand, "(R)", "");
- size_t i;
- if((i = brand.find(" ")) != string::npos)
- brand = brand.substr(0, i);
+ brand = string_strip(brand);
return brand;
}