blender/intern/cycles/device/device_network.cpp
Brecht Van Lommel 4e235c184b Blender modifications for Cycles integration.
Some notes about code status:

* The Blender modifications were fairly quickly put together, much more code
  polish and work is needed to get this to a state where it can be committed
  to trunk. Files created with this version may not work in future versions.

* Only simple path tracing is supported currently, but we intend to provide
  finer control, and more options where it makes sense.

* For GPU rendering, only CUDA works currently. The intention is to have the
  same kernel code compile for C++/OpenCL/CUDA, some more work is needed to
  get OpenCL functional.

* There are two shading backends: GPU compatible and Open Shading Language.
  Unfortunately, OSL only runs on the CPU currently, getting this to run on
  the GPU would be a major undertaking, and is unlikely to be supported soon.
  Additionally, it's not possible yet to write custom OSL shaders.

* There is some code for adaptive subdivision and displacement, but it's far
  from finished. The intention is to eventually have a nice unified bump and
  displacement system.

* The code currently has a number of fairly heavy dependencies: Boost,
  OpenImageIO, GLEW, GLUT, and optionally OSL, Partio. This makes it difficult
  to compile, we'll try to eliminate some, it may take a while before it
  becomes easy to compile this.
2011-04-27 14:36:02 +00:00

387 lines
7.7 KiB
C++

/*
* 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.
*/
#include "device.h"
#include "device_intern.h"
#include "device_network.h"
#include "util_foreach.h"
CCL_NAMESPACE_BEGIN
#ifdef WITH_NETWORK
class NetworkDevice : public Device
{
public:
boost::asio::io_service io_service;
tcp::socket socket;
NetworkDevice(const char *address)
: socket(io_service)
{
stringstream portstr;
portstr << SERVER_PORT;
tcp::resolver resolver(io_service);
tcp::resolver::query query(address, portstr.str());
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
boost::system::error_code error = boost::asio::error::host_not_found;
while(error && endpoint_iterator != end)
{
socket.close();
socket.connect(*endpoint_iterator++, error);
}
if(error)
throw boost::system::system_error(error);
}
~NetworkDevice()
{
}
string description()
{
RPCSend snd(socket, "description");
snd.write();
RPCReceive rcv(socket);
string desc_string;
*rcv.archive & desc_string;
return desc_string + " (remote)";
}
void mem_alloc(device_memory& mem, MemoryType type)
{
#if 0
RPCSend snd(socket, "mem_alloc");
snd.archive & size & type;
snd.write();
RPCReceive rcv(socket);
device_ptr mem;
*rcv.archive & mem;
return mem;
#endif
}
void mem_copy_to(device_memory& mem)
{
#if 0
RPCSend snd(socket, "mem_copy_to");
snd.archive & mem & size;
snd.write();
snd.write_buffer(host, size);
#endif
}
void mem_copy_from(device_memory& mem, size_t offset, size_t size)
{
#if 0
RPCSend snd(socket, "mem_copy_from");
snd.archive & mem & offset & size;
snd.write();
RPCReceive rcv(socket);
rcv.read_buffer(host, size);
#endif
}
void mem_zero(device_memory& mem)
{
#if 0
RPCSend snd(socket, "mem_zero");
snd.archive & mem & size;
snd.write();
#endif
}
void mem_free(device_memory& mem)
{
#if 0
if(mem) {
RPCSend snd(socket, "mem_free");
snd.archive & mem;
snd.write();
}
#endif
}
void const_copy_to(const char *name, void *host, size_t size)
{
RPCSend snd(socket, "const_copy_to");
string name_string(name);
snd.archive & name_string & size;
snd.write();
snd.write_buffer(host, size);
}
void tex_alloc(const char *name, device_memory& mem, bool interpolation, bool periodic)
{
#if 0
RPCSend snd(socket, "tex_alloc");
string name_string(name);
snd.archive & name_string & width & height & datatype & components & interpolation;
snd.write();
size_t size = width*height*components*datatype_size(datatype);
snd.write_buffer(host, size);
RPCReceive rcv(socket);
device_ptr mem;
*rcv.archive & mem;
return mem;
#endif
}
void tex_free(device_memory& mem)
{
#if 0
if(mem) {
RPCSend snd(socket, "tex_free");
snd.archive & mem;
snd.write();
}
#endif
}
void path_trace(int x, int y, int w, int h, device_ptr buffer, device_ptr rng_state, int pass)
{
#if 0
RPCSend snd(socket, "path_trace");
snd.archive & x & y & w & h & buffer & rng_state & pass;
snd.write();
#endif
}
void tonemap(int x, int y, int w, int h, device_ptr rgba, device_ptr buffer, int pass, int resolution)
{
#if 0
RPCSend snd(socket, "tonemap");
snd.archive & x & y & w & h & rgba & buffer & pass & resolution;
snd.write();
#endif
}
void task_add(DeviceTask& task)
{
if(task.type == DeviceTask::TONEMAP)
tonemap(task.x, task.y, task.w, task.h, task.rgba, task.buffer, task.pass, task.resolution);
else if(task.type == DeviceTask::PATH_TRACE)
path_trace(task.x, task.y, task.w, task.h, task.buffer, task.rng_state, task.pass);
}
void task_wait()
{
}
void task_cancel()
{
}
};
Device *device_network_create(const char *address)
{
return new NetworkDevice(address);
}
void Device::server_run()
{
try
{
/* starts thread that responds to discovery requests */
ServerDiscovery discovery;
for(;;)
{
/* accept connection */
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), SERVER_PORT));
tcp::socket socket(io_service);
acceptor.accept(socket);
/* receive remote function calls */
for(;;) {
RPCReceive rcv(socket);
if(rcv.name == "description") {
string desc = description();
RPCSend snd(socket);
snd.archive & desc;
snd.write();
}
else if(rcv.name == "mem_alloc") {
#if 0
MemoryType type;
size_t size;
device_ptr mem;
*rcv.archive & size & type;
mem = mem_alloc(size, type);
RPCSend snd(socket);
snd.archive & mem;
snd.write();
#endif
}
else if(rcv.name == "mem_copy_to") {
#if 0
device_ptr mem;
size_t size;
*rcv.archive & mem & size;
vector<char> host_vector(size);
rcv.read_buffer(&host_vector[0], size);
mem_copy_to(mem, &host_vector[0], size);
#endif
}
else if(rcv.name == "mem_copy_from") {
#if 0
device_ptr mem;
size_t offset, size;
*rcv.archive & mem & offset & size;
vector<char> host_vector(size);
mem_copy_from(&host_vector[0], mem, offset, size);
RPCSend snd(socket);
snd.write();
snd.write_buffer(&host_vector[0], size);
#endif
}
else if(rcv.name == "mem_zero") {
#if 0
device_ptr mem;
size_t size;
*rcv.archive & mem & size;
mem_zero(mem, size);
#endif
}
else if(rcv.name == "mem_free") {
#if 0
device_ptr mem;
*rcv.archive & mem;
mem_free(mem);
#endif
}
else if(rcv.name == "const_copy_to") {
string name_string;
size_t size;
*rcv.archive & name_string & size;
vector<char> host_vector(size);
rcv.read_buffer(&host_vector[0], size);
const_copy_to(name_string.c_str(), &host_vector[0], size);
}
else if(rcv.name == "tex_alloc") {
#if 0
string name_string;
DataType datatype;
device_ptr mem;
size_t width, height;
int components;
bool interpolation;
*rcv.archive & name_string & width & height & datatype & components & interpolation;
size_t size = width*height*components*datatype_size(datatype);
vector<char> host_vector(size);
rcv.read_buffer(&host_vector[0], size);
mem = tex_alloc(name_string.c_str(), &host_vector[0], width, height, datatype, components, interpolation);
RPCSend snd(socket);
snd.archive & mem;
snd.write();
#endif
}
else if(rcv.name == "tex_free") {
#if 0
device_ptr mem;
*rcv.archive & mem;
tex_free(mem);
#endif
}
else if(rcv.name == "path_trace") {
#if 0
device_ptr buffer, rng_state;
int x, y, w, h;
int pass;
*rcv.archive & x & y & w & h & buffer & rng_state & pass;
path_trace(x, y, w, h, buffer, rng_state, pass);
#endif
}
else if(rcv.name == "tonemap") {
#if 0
device_ptr rgba, buffer;
int x, y, w, h;
int pass, resolution;
*rcv.archive & x & y & w & h & rgba & buffer & pass & resolution;
tonemap(x, y, w, h, rgba, buffer, pass, resolution);
#endif
}
}
}
}
catch(exception& e)
{
cerr << "Network server exception: " << e.what() << endl;
}
}
#endif
CCL_NAMESPACE_END