2011-04-27 11:58:34 +00:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
|
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
|
|
|
#ifdef WITH_NETWORK
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
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()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2012-01-09 16:58:01 +00:00
|
|
|
void mem_copy_from(device_memory& mem, int y, int w, int h, int elem)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
#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
|
|
|
|
}
|
|
|
|
|
2011-09-16 13:14:02 +00:00
|
|
|
void path_trace(int x, int y, int w, int h, device_ptr buffer, device_ptr rng_state, int sample)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
#if 0
|
|
|
|
RPCSend snd(socket, "path_trace");
|
|
|
|
|
2011-09-16 13:14:02 +00:00
|
|
|
snd.archive & x & y & w & h & buffer & rng_state & sample;
|
2011-04-27 11:58:34 +00:00
|
|
|
snd.write();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-09-16 13:14:02 +00:00
|
|
|
void tonemap(int x, int y, int w, int h, device_ptr rgba, device_ptr buffer, int sample, int resolution)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
#if 0
|
|
|
|
RPCSend snd(socket, "tonemap");
|
|
|
|
|
2011-09-16 13:14:02 +00:00
|
|
|
snd.archive & x & y & w & h & rgba & buffer & sample & resolution;
|
2011-04-27 11:58:34 +00:00
|
|
|
snd.write();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void task_add(DeviceTask& task)
|
|
|
|
{
|
|
|
|
if(task.type == DeviceTask::TONEMAP)
|
2011-09-16 13:14:02 +00:00
|
|
|
tonemap(task.x, task.y, task.w, task.h, task.rgba, task.buffer, task.sample, task.resolution);
|
2011-04-27 11:58:34 +00:00
|
|
|
else if(task.type == DeviceTask::PATH_TRACE)
|
2011-09-16 13:14:02 +00:00
|
|
|
path_trace(task.x, task.y, task.w, task.h, task.buffer, task.rng_state, task.sample);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void task_wait()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void task_cancel()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-01-04 18:06:32 +00:00
|
|
|
Device *device_network_create(DeviceInfo& info, const char *address)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
return new NetworkDevice(address);
|
|
|
|
}
|
|
|
|
|
2012-01-04 18:06:32 +00:00
|
|
|
void device_network_info(vector<DeviceInfo>& devices)
|
|
|
|
{
|
|
|
|
DeviceInfo info;
|
|
|
|
|
|
|
|
info.type = DEVICE_NETWORK;
|
|
|
|
info.description = "Network Device";
|
|
|
|
info.id = "NETWORK";
|
|
|
|
info.num = 0;
|
|
|
|
|
|
|
|
devices.push_back(info);
|
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
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;
|
2011-09-16 13:14:02 +00:00
|
|
|
int sample;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2011-09-16 13:14:02 +00:00
|
|
|
*rcv.archive & x & y & w & h & buffer & rng_state & sample;
|
|
|
|
path_trace(x, y, w, h, buffer, rng_state, sample);
|
2011-04-27 11:58:34 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if(rcv.name == "tonemap") {
|
|
|
|
#if 0
|
|
|
|
device_ptr rgba, buffer;
|
|
|
|
int x, y, w, h;
|
2011-09-16 13:14:02 +00:00
|
|
|
int sample, resolution;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2011-09-16 13:14:02 +00:00
|
|
|
*rcv.archive & x & y & w & h & rgba & buffer & sample & resolution;
|
|
|
|
tonemap(x, y, w, h, rgba, buffer, sample, resolution);
|
2011-04-27 11:58:34 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(exception& e)
|
|
|
|
{
|
|
|
|
cerr << "Network server exception: " << e.what() << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
#endif
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
CCL_NAMESPACE_END
|
|
|
|
|