diff options
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/CMakeLists.txt | 4 | ||||
-rw-r--r-- | intern/cycles/render/film.cpp | 92 | ||||
-rw-r--r-- | intern/cycles/render/film.h | 14 | ||||
-rw-r--r-- | intern/cycles/render/filter.cpp | 142 | ||||
-rw-r--r-- | intern/cycles/render/scene.cpp | 31 | ||||
-rw-r--r-- | intern/cycles/render/scene.h | 8 | ||||
-rw-r--r-- | intern/cycles/render/tables.cpp | 106 | ||||
-rw-r--r-- | intern/cycles/render/tables.h (renamed from intern/cycles/render/filter.h) | 32 |
8 files changed, 246 insertions, 183 deletions
diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt index d67a686d1e8..0f45f63d78a 100644 --- a/intern/cycles/render/CMakeLists.txt +++ b/intern/cycles/render/CMakeLists.txt @@ -20,7 +20,6 @@ set(SRC camera.cpp film.cpp # film_response.cpp (code unused) - filter.cpp graph.cpp image.cpp integrator.cpp @@ -37,6 +36,7 @@ set(SRC shader.cpp sobol.cpp svm.cpp + tables.cpp tile.cpp ) @@ -47,7 +47,6 @@ set(SRC_HEADERS camera.h film.h # film_response.h (code unused) - filter.h graph.h image.h integrator.h @@ -63,6 +62,7 @@ set(SRC_HEADERS shader.h sobol.h svm.h + tables.h tile.h ) diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp index fdf25ca7908..7dcbfa2278c 100644 --- a/intern/cycles/render/film.cpp +++ b/intern/cycles/render/film.cpp @@ -22,9 +22,12 @@ #include "integrator.h" #include "mesh.h" #include "scene.h" +#include "tables.h" #include "util_algorithm.h" +#include "util_debug.h" #include "util_foreach.h" +#include "util_math.h" CCL_NAMESPACE_BEGIN @@ -171,12 +174,84 @@ bool Pass::contains(const vector<Pass>& passes, PassType type) return false; } +/* Pixel Filter */ + +static float filter_func_box(float v, float width) +{ + return (float)1; +} + +static float filter_func_gaussian(float v, float width) +{ + v *= (float)2/width; + return (float)expf((float)-2*v*v); +} + +static vector<float> filter_table(FilterType type, float width) +{ + const int filter_table_size = FILTER_TABLE_SIZE-1; + vector<float> filter_table_cdf(filter_table_size+1); + vector<float> filter_table(filter_table_size+1); + float (*filter_func)(float, float) = NULL; + int i, half_size = filter_table_size/2; + + switch(type) { + case FILTER_BOX: + filter_func = filter_func_box; + break; + case FILTER_GAUSSIAN: + filter_func = filter_func_gaussian; + break; + default: + assert(0); + } + + /* compute cumulative distribution function */ + filter_table_cdf[0] = 0.0f; + + for(i = 0; i < filter_table_size; i++) { + float x = i*width*0.5f/(filter_table_size-1); + float y = filter_func(x, width); + filter_table_cdf[i+1] += filter_table_cdf[i] + fabsf(y); + } + + for(i = 0; i <= filter_table_size; i++) + filter_table_cdf[i] /= filter_table_cdf[filter_table_size]; + + /* create importance sampling table */ + for(i = 0; i <= half_size; i++) { + float x = i/(float)half_size; + int index = upper_bound(filter_table_cdf.begin(), filter_table_cdf.end(), x) - filter_table_cdf.begin(); + float t; + + if(index < filter_table_size+1) { + t = (x - filter_table_cdf[index])/(filter_table_cdf[index+1] - filter_table_cdf[index]); + } + else { + t = 0.0f; + index = filter_table_size; + } + + float y = ((index + t)/(filter_table_size))*width; + + filter_table[half_size+i] = 0.5f*(1.0f + y); + filter_table[half_size-i] = 0.5f*(1.0f - y); + } + + return filter_table; +} + /* Film */ Film::Film() { exposure = 0.8f; Pass::add(PASS_COMBINED, passes); + + filter_type = FILTER_BOX; + filter_width = 1.0f; + filter_table_offset = -1; + need_update = true; } @@ -184,10 +259,12 @@ Film::~Film() { } -void Film::device_update(Device *device, DeviceScene *dscene) +void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene) { if(!need_update) return; + + device_free(device, dscene, scene); KernelFilm *kfilm = &dscene->data.film; @@ -284,17 +361,26 @@ void Film::device_update(Device *device, DeviceScene *dscene) kfilm->pass_stride = align_up(kfilm->pass_stride, 4); + /* update filter table */ + vector<float> table = filter_table(filter_type, filter_width); + filter_table_offset = scene->lookup_tables->add_table(dscene, table); + kfilm->filter_table_offset = (int)filter_table_offset; + need_update = false; } -void Film::device_free(Device *device, DeviceScene *dscene) +void Film::device_free(Device *device, DeviceScene *dscene, Scene *scene) { + if(filter_table_offset != -1) + scene->lookup_tables->remove_table(filter_table_offset); } bool Film::modified(const Film& film) { return !(exposure == film.exposure - && Pass::equals(passes, film.passes)); + && Pass::equals(passes, film.passes) + && filter_type == film.filter_type + && filter_width == film.filter_width); } void Film::tag_passes_update(Scene *scene, const vector<Pass>& passes_) diff --git a/intern/cycles/render/film.h b/intern/cycles/render/film.h index 52d1a8428f8..bc1619c3f2d 100644 --- a/intern/cycles/render/film.h +++ b/intern/cycles/render/film.h @@ -30,6 +30,11 @@ class Device; class DeviceScene; class Scene; +typedef enum FilterType { + FILTER_BOX, + FILTER_GAUSSIAN +} FilterType; + class Pass { public: PassType type; @@ -47,13 +52,18 @@ class Film { public: float exposure; vector<Pass> passes; + + FilterType filter_type; + float filter_width; + size_t filter_table_offset; + bool need_update; Film(); ~Film(); - void device_update(Device *device, DeviceScene *dscene); - void device_free(Device *device, DeviceScene *dscene); + void device_update(Device *device, DeviceScene *dscene, Scene *scene); + void device_free(Device *device, DeviceScene *dscene, Scene *scene); bool modified(const Film& film); void tag_passes_update(Scene *scene, const vector<Pass>& passes_); diff --git a/intern/cycles/render/filter.cpp b/intern/cycles/render/filter.cpp deleted file mode 100644 index 0bd4fb4d579..00000000000 --- a/intern/cycles/render/filter.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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 "camera.h" -#include "device.h" -#include "filter.h" -#include "scene.h" - -#include "kernel_types.h" - -#include "util_algorithm.h" -#include "util_debug.h" -#include "util_math.h" - -CCL_NAMESPACE_BEGIN - -Filter::Filter() -{ - filter_type = FILTER_BOX; - filter_width = 1.0f; - need_update = true; -} - -Filter::~Filter() -{ -} - -static float filter_func_box(float v, float width) -{ - return (float)1; -} - -static float filter_func_gaussian(float v, float width) -{ - v *= (float)2/width; - return (float)expf((float)-2*v*v); -} - -static vector<float> filter_table(FilterType type, float width) -{ - const int filter_table_size = FILTER_TABLE_SIZE-1; - vector<float> filter_table_cdf(filter_table_size+1); - vector<float> filter_table(filter_table_size+1); - float (*filter_func)(float, float) = NULL; - int i, half_size = filter_table_size/2; - - switch(type) { - case FILTER_BOX: - filter_func = filter_func_box; - break; - case FILTER_GAUSSIAN: - filter_func = filter_func_gaussian; - break; - default: - assert(0); - } - - /* compute cumulative distribution function */ - filter_table_cdf[0] = 0.0f; - - for(i = 0; i < filter_table_size; i++) { - float x = i*width*0.5f/(filter_table_size-1); - float y = filter_func(x, width); - filter_table_cdf[i+1] += filter_table_cdf[i] + fabsf(y); - } - - for(i = 0; i <= filter_table_size; i++) - filter_table_cdf[i] /= filter_table_cdf[filter_table_size]; - - /* create importance sampling table */ - for(i = 0; i <= half_size; i++) { - float x = i/(float)half_size; - int index = upper_bound(filter_table_cdf.begin(), filter_table_cdf.end(), x) - filter_table_cdf.begin(); - float t; - - if(index < filter_table_size+1) { - t = (x - filter_table_cdf[index])/(filter_table_cdf[index+1] - filter_table_cdf[index]); - } - else { - t = 0.0f; - index = filter_table_size; - } - - float y = ((index + t)/(filter_table_size))*width; - - filter_table[half_size+i] = 0.5f*(1.0f + y); - filter_table[half_size-i] = 0.5f*(1.0f - y); - } - - return filter_table; -} - -void Filter::device_update(Device *device, DeviceScene *dscene) -{ - if(!need_update) - return; - - device_free(device, dscene); - - /* update __filter_table */ - vector<float> table = filter_table(filter_type, filter_width); - - dscene->filter_table.copy(&table[0], table.size()); - device->tex_alloc("__filter_table", dscene->filter_table, true); - - need_update = false; -} - -void Filter::device_free(Device *device, DeviceScene *dscene) -{ - device->tex_free(dscene->filter_table); - dscene->filter_table.clear(); -} - -bool Filter::modified(const Filter& filter) -{ - return !(filter_type == filter.filter_type && - filter_width == filter.filter_width); -} - -void Filter::tag_update(Scene *scene) -{ - need_update = true; -} - -CCL_NAMESPACE_END - diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index 7b82a91cae8..2b0609fdf1f 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -20,19 +20,19 @@ #include "background.h" #include "camera.h" +#include "curves.h" #include "device.h" #include "film.h" -#include "filter.h" #include "integrator.h" #include "light.h" -#include "shader.h" #include "mesh.h" #include "object.h" +#include "osl.h" #include "particles.h" -#include "curves.h" #include "scene.h" +#include "shader.h" #include "svm.h" -#include "osl.h" +#include "tables.h" #include "util_foreach.h" #include "util_progress.h" @@ -46,7 +46,7 @@ Scene::Scene(const SceneParams& params_, const DeviceInfo& device_info_) memset(&dscene.data, 0, sizeof(dscene.data)); camera = new Camera(); - filter = new Filter(); + lookup_tables = new LookupTables(); film = new Film(); background = new Background(); light_manager = new LightManager(); @@ -93,8 +93,7 @@ void Scene::free_memory(bool final) if(device) { camera->device_free(device, &dscene); - filter->device_free(device, &dscene); - film->device_free(device, &dscene); + film->device_free(device, &dscene, this); background->device_free(device, &dscene); integrator->device_free(device, &dscene); @@ -108,10 +107,12 @@ void Scene::free_memory(bool final) if(!params.persistent_data || final) image_manager->device_free(device, &dscene); + + lookup_tables->device_free(device, &dscene); } if(final) { - delete filter; + delete lookup_tables; delete camera; delete film; delete background; @@ -186,15 +187,11 @@ void Scene::device_update(Device *device_, Progress& progress) progress.set_status("Updating Particle Systems"); particle_system_manager->device_update(device, &dscene, this, progress); - if(progress.get_cancel()) return; - - progress.set_status("Updating Filter"); - filter->device_update(device, &dscene); if(progress.get_cancel()) return; progress.set_status("Updating Film"); - film->device_update(device, &dscene); + film->device_update(device, &dscene, this); if(progress.get_cancel()) return; @@ -203,6 +200,11 @@ void Scene::device_update(Device *device_, Progress& progress) if(progress.get_cancel()) return; + progress.set_status("Updating Lookup Tables"); + lookup_tables->device_update(device, &dscene); + + if(progress.get_cancel()) return; + progress.set_status("Updating Device", "Writing constant memory"); device->const_copy_to("__data", &dscene.data, sizeof(dscene.data)); } @@ -247,7 +249,7 @@ bool Scene::need_reset() || object_manager->need_update || mesh_manager->need_update || light_manager->need_update - || filter->need_update + || lookup_tables->need_update || integrator->need_update || shader_manager->need_update || particle_system_manager->need_update @@ -261,7 +263,6 @@ void Scene::reset() /* ensure all objects are updated */ camera->tag_update(); - filter->tag_update(this); film->tag_update(this); background->tag_update(this); integrator->tag_update(this); diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index fc6b538af03..545a765cc22 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -39,10 +39,10 @@ class Camera; class Device; class DeviceInfo; class Film; -class Filter; class Integrator; class Light; class LightManager; +class LookupTables; class Mesh; class MeshManager; class Object; @@ -99,8 +99,8 @@ public: device_vector<uint> shader_flag; device_vector<uint> object_flag; - /* filter */ - device_vector<float> filter_table; + /* lookup tables */ + device_vector<float> lookup_table; /* integrator */ device_vector<uint> sobol_directions; @@ -155,7 +155,7 @@ class Scene { public: /* data */ Camera *camera; - Filter *filter; + LookupTables *lookup_tables; Film *film; Background *background; Integrator *integrator; diff --git a/intern/cycles/render/tables.cpp b/intern/cycles/render/tables.cpp new file mode 100644 index 00000000000..fecdd52c60c --- /dev/null +++ b/intern/cycles/render/tables.cpp @@ -0,0 +1,106 @@ +/* + * 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 "scene.h" +#include "tables.h" + +#include "util_debug.h" + +CCL_NAMESPACE_BEGIN + +LookupTables::LookupTables() +{ + need_update = true; +} + +LookupTables::~LookupTables() +{ + assert(lookup_tables.size() == 0); +} + +void LookupTables::device_update(Device *device, DeviceScene *dscene) +{ + if(!need_update) + return; + + device->tex_alloc("__lookup_table", dscene->lookup_table, true); // XXX interpolation + + need_update = false; +} + +void LookupTables::device_free(Device *device, DeviceScene *dscene) +{ + device->tex_free(dscene->lookup_table); + dscene->lookup_table.clear(); +} + +static size_t round_up_to_multiple(size_t size, size_t chunk) +{ + return ((size + chunk - 1)/chunk) * chunk; +} + +size_t LookupTables::add_table(DeviceScene *dscene, vector<float>& data) +{ + assert(data.size() > 0); + + need_update = true; + + Table new_table; + new_table.offset = 0; + new_table.size = round_up_to_multiple(data.size(), TABLE_CHUNK_SIZE); + + /* find space to put lookup table */ + list<Table>::iterator table; + + for(table = lookup_tables.begin(); table != lookup_tables.end(); table++) { + if(new_table.offset + new_table.size <= table->offset) { + lookup_tables.insert(table, new_table); + break; + } + } + + if(table == lookup_tables.end()) { + /* add at the end */ + lookup_tables.push_back(new_table); + dscene->lookup_table.resize(new_table.offset + new_table.size); + } + + /* copy table data and return offset */ + dscene->lookup_table.copy_at(&data[0], new_table.offset, data.size()); + return new_table.offset; +} + +void LookupTables::remove_table(size_t offset) +{ + need_update = true; + + list<Table>::iterator table; + + for(table = lookup_tables.begin(); table != lookup_tables.end(); table++) { + if(table->offset == offset) { + lookup_tables.erase(table); + break; + } + } + + assert(table != lookup_tables.end()); +} + +CCL_NAMESPACE_END + diff --git a/intern/cycles/render/filter.h b/intern/cycles/render/tables.h index 5df7bb8fd14..5fa5136ae79 100644 --- a/intern/cycles/render/filter.h +++ b/intern/cycles/render/tables.h @@ -16,8 +16,10 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef __FILTER_H__ -#define __FILTER_H__ +#ifndef __TABLES_H__ +#define __TABLES_H__ + +#include <util_list.h> CCL_NAMESPACE_BEGIN @@ -25,29 +27,29 @@ class Device; class DeviceScene; class Scene; -typedef enum FilterType { - FILTER_BOX, - FILTER_GAUSSIAN -} FilterType; +enum { TABLE_CHUNK_SIZE = 256 }; -class Filter { +class LookupTables { public: - /* pixel filter */ - FilterType filter_type; - float filter_width; + struct Table { + size_t offset; + size_t size; + }; + bool need_update; + list<Table> lookup_tables; - Filter(); - ~Filter(); + LookupTables(); + ~LookupTables(); void device_update(Device *device, DeviceScene *dscene); void device_free(Device *device, DeviceScene *dscene); - bool modified(const Filter& filter); - void tag_update(Scene *scene); + size_t add_table(DeviceScene *dscene, vector<float>& data); + void remove_table(size_t offset); }; CCL_NAMESPACE_END -#endif /* __FILTER_H__ */ +#endif /* __TABLES_H__ */ |