Cycles: Make all #include statements relative to cycles source directory
[blender.git] / intern / cycles / device / device_multi.cpp
index 546ffe5e4b9651aac25310428db02d85a234affe..624260a81c80346de0ddabbf908aaf37b464273d 100644 (file)
@@ -1,34 +1,33 @@
 /*
- * Copyright 2011, Blender Foundation.
+ * Copyright 2011-2013 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.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 #include <stdlib.h>
 #include <sstream>
 
-#include "device.h"
-#include "device_intern.h"
-#include "device_network.h"
+#include "device/device.h"
+#include "device/device_intern.h"
+#include "device/device_network.h"
 
-#include "buffers.h"
+#include "render/buffers.h"
 
-#include "util_foreach.h"
-#include "util_list.h"
-#include "util_map.h"
-#include "util_time.h"
+#include "util/util_foreach.h"
+#include "util/util_list.h"
+#include "util/util_logging.h"
+#include "util/util_map.h"
+#include "util/util_time.h"
 
 CCL_NAMESPACE_BEGIN
 
@@ -36,7 +35,7 @@ class MultiDevice : public Device
 {
 public:
        struct SubDevice {
-               SubDevice(Device *device_)
+               explicit SubDevice(Device *device_)
                : device(device_) {}
 
                Device *device;
@@ -46,26 +45,25 @@ public:
        list<SubDevice> devices;
        device_ptr unique_ptr;
 
-       MultiDevice(DeviceInfo& info, bool background_)
-       : unique_ptr(1)
+       MultiDevice(DeviceInfo& info, Stats &stats, bool background_)
+       : Device(info, stats, background_), unique_ptr(1)
        {
                Device *device;
-               background = background_;
 
                foreach(DeviceInfo& subinfo, info.multi_devices) {
-                       device = Device::create(subinfo, background);
+                       device = Device::create(subinfo, sub_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));
                }
@@ -91,24 +89,33 @@ public:
                return error_msg;
        }
 
-       bool load_kernels(bool experimental)
+       virtual bool show_samples() const
+       {
+               if(devices.size() > 1) {
+                       return false;
+               }
+               return devices.front().device->show_samples();
+       }
+
+       bool load_kernels(const DeviceRequestedFeatures& requested_features)
        {
                foreach(SubDevice& sub, devices)
-                       if(!sub.device->load_kernels(experimental))
+                       if(!sub.device->load_kernels(requested_features))
                                return false;
 
                return true;
        }
 
-       void mem_alloc(device_memory& mem, MemoryType type)
+       void mem_alloc(const char *name, device_memory& mem, MemoryType type)
        {
                foreach(SubDevice& sub, devices) {
                        mem.device_pointer = 0;
-                       sub.device->mem_alloc(mem, type);
+                       sub.device->mem_alloc(name, mem, type);
                        sub.ptr_map[unique_ptr] = mem.device_pointer;
                }
 
                mem.device_pointer = unique_ptr++;
+               stats.mem_alloc(mem.device_size);
        }
 
        void mem_copy_to(device_memory& mem)
@@ -155,6 +162,7 @@ public:
        void mem_free(device_memory& mem)
        {
                device_ptr tmp = mem.device_pointer;
+               stats.mem_free(mem.device_size);
 
                foreach(SubDevice& sub, devices) {
                        mem.device_pointer = sub.ptr_map[tmp];
@@ -171,20 +179,30 @@ public:
                        sub.device->const_copy_to(name, host, size);
        }
 
-       void tex_alloc(const char *name, device_memory& mem, bool interpolation, bool periodic)
+       void tex_alloc(const char *name,
+                      device_memory& mem,
+                      InterpolationType
+                      interpolation,
+                      ExtensionType extension)
        {
+               VLOG(1) << "Texture allocate: " << name << ", "
+                       << string_human_readable_number(mem.memory_size()) << " bytes. ("
+                       << string_human_readable_size(mem.memory_size()) << ")";
+
                foreach(SubDevice& sub, devices) {
                        mem.device_pointer = 0;
-                       sub.device->tex_alloc(name, mem, interpolation, periodic);
+                       sub.device->tex_alloc(name, mem, interpolation, extension);
                        sub.ptr_map[unique_ptr] = mem.device_pointer;
                }
 
                mem.device_pointer = unique_ptr++;
+               stats.mem_alloc(mem.device_size);
        }
 
        void tex_free(device_memory& mem)
        {
                device_ptr tmp = mem.device_pointer;
+               stats.mem_free(mem.device_size);
 
                foreach(SubDevice& sub, devices) {
                        mem.device_pointer = sub.ptr_map[tmp];
@@ -236,7 +254,8 @@ public:
                mem.device_pointer = tmp;
        }
 
-       void draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent)
+       void draw_pixels(device_memory& rgba, int y, int w, int h, int dx, int dy, int width, int height, bool transparent,
+               const DeviceDrawParams &draw_params)
        {
                device_ptr tmp = rgba.device_pointer;
                int i = 0, sub_h = h/devices.size();
@@ -250,7 +269,7 @@ public:
                        /* adjust math for w/width */
 
                        rgba.device_pointer = sub.ptr_map[tmp];
-                       sub.device->draw_pixels(rgba, sy, w, sh, sdy, width, sheight, transparent);
+                       sub.device->draw_pixels(rgba, sy, w, sh, dx, sdy, width, sheight, transparent, draw_params);
                        i++;
                }
 
@@ -263,7 +282,6 @@ public:
                        if(sub.device == sub_device) {
                                if(tile.buffer) tile.buffer = sub.ptr_map[tile.buffer];
                                if(tile.rng_state) tile.rng_state = sub.ptr_map[tile.rng_state];
-                               if(tile.rgba) tile.rgba = sub.ptr_map[tile.rgba];
                        }
                }
        }
@@ -281,6 +299,22 @@ public:
                return -1;
        }
 
+       int get_split_task_count(DeviceTask& task)
+       {
+               int total_tasks = 0;
+               list<DeviceTask> tasks;
+               task.split(tasks, devices.size());
+               foreach(SubDevice& sub, devices) {
+                       if(!tasks.empty()) {
+                               DeviceTask subtask = tasks.front();
+                               tasks.pop_front();
+
+                               total_tasks += sub.device->get_split_task_count(subtask);
+                       }
+               }
+               return total_tasks;
+       }
+
        void task_add(DeviceTask& task)
        {
                list<DeviceTask> tasks;
@@ -292,9 +326,11 @@ public:
                                tasks.pop_front();
 
                                if(task.buffer) subtask.buffer = sub.ptr_map[task.buffer];
-                               if(task.rgba) subtask.rgba = sub.ptr_map[task.rgba];
+                               if(task.rgba_byte) subtask.rgba_byte = sub.ptr_map[task.rgba_byte];
+                               if(task.rgba_half) subtask.rgba_half = sub.ptr_map[task.rgba_half];
                                if(task.shader_input) subtask.shader_input = sub.ptr_map[task.shader_input];
                                if(task.shader_output) subtask.shader_output = sub.ptr_map[task.shader_output];
+                               if(task.shader_output_luma) subtask.shader_output_luma = sub.ptr_map[task.shader_output_luma];
 
                                sub.device->task_add(subtask);
                        }
@@ -312,124 +348,14 @@ public:
                foreach(SubDevice& sub, devices)
                        sub.device->task_cancel();
        }
-};
-
-Device *device_multi_create(DeviceInfo& info, bool background)
-{
-       return new MultiDevice(info, background);
-}
-
-static bool device_multi_add(vector<DeviceInfo>& devices, DeviceType type, bool with_display, bool with_advanced_shading, 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_display = 0;
-
-       info.advanced_shading = with_advanced_shading;
-       info.pack_images = false;
-
-       foreach(DeviceInfo& subinfo, devices) {
-               if(subinfo.type == type) {
-                       if(subinfo.advanced_shading != info.advanced_shading)
-                               continue;
-                       if(subinfo.display_device) {
-                               if(with_display)
-                                       num_display++;
-                               else
-                                       continue;
-                       }
-
-                       string key = subinfo.description;
-
-                       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;
-                       info.pack_images = info.pack_images || subinfo.pack_images;
-                       num_added++;
-               }
-       }
-
-       if(num_added <= 1 || (with_display && num_display == 0))
-               return false;
-
-       /* generate string */
-       stringstream desc;
-       vector<string> last_tokens;
-       bool first = true;
-
-       for(dt = dupli_map.begin(); dt != dupli_map.end(); dt++) {
-               if(!first) desc << " + ";
-               first = false;
-
-               /* get name and count */
-               string name = dt->first;
-               int count = dt->second;
-
-               /* strip common prefixes */
-               vector<string> tokens;
-               string_split(tokens, dt->first);
-
-               if(tokens.size() > 1) {
-                       int i;
-
-                       for(i = 0; i < tokens.size() && i < last_tokens.size(); i++)
-                               if(tokens[i] != last_tokens[i])
-                                       break;
-
-                       name = "";
-                       for(; i < tokens.size(); i++) {
-                               name += tokens[i];
-                               if(i != tokens.size() - 1)
-                                       name += " ";
-                       }
-               }
-
-               last_tokens = tokens;
-
-               /* add */
-               if(count > 1)
-                       desc << name << " (" << count << "x)";
-               else
-                       desc << name;
-       }
 
-       /* add info */
-       info.type = DEVICE_MULTI;
-       info.description = desc.str();
-       info.id = string_printf(id_fmt, num);
-       info.display_device = with_display;
-       info.num = 0;
-
-       if(with_display)
-               devices.push_back(info);
-       else
-               devices.insert(devices.begin(), info);
-       
-       return true;
-}
+protected:
+       Stats sub_stats_;
+};
 
-void device_multi_info(vector<DeviceInfo>& devices)
+Device *device_multi_create(DeviceInfo& info, Stats &stats, bool background)
 {
-       int num = 0;
-
-       if(!device_multi_add(devices, DEVICE_CUDA, false, true, "CUDA_MULTI_%d", num++))
-               device_multi_add(devices, DEVICE_CUDA, false, false, "CUDA_MULTI_%d", num++);
-       if(!device_multi_add(devices, DEVICE_CUDA, true, true, "CUDA_MULTI_%d", num++))
-               device_multi_add(devices, DEVICE_CUDA, true, false, "CUDA_MULTI_%d", num++);
-
-       num = 0;
-       if(!device_multi_add(devices, DEVICE_OPENCL, false, true, "OPENCL_MULTI_%d", num++))
-               device_multi_add(devices, DEVICE_OPENCL, false, false, "OPENCL_MULTI_%d", num++);
-       if(!device_multi_add(devices, DEVICE_OPENCL, true, true, "OPENCL_MULTI_%d", num++))
-               device_multi_add(devices, DEVICE_OPENCL, true, false, "OPENCL_MULTI_%d", num++);
+       return new MultiDevice(info, stats, background);
 }
 
 CCL_NAMESPACE_END