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:
-rw-r--r--intern/cycles/blender/blender_sync.cpp12
-rw-r--r--intern/cycles/device/device_memory.h8
-rw-r--r--intern/cycles/kernel/kernel_camera.h5
-rw-r--r--intern/cycles/kernel/kernel_compat_cpu.h6
-rw-r--r--intern/cycles/kernel/kernel_compat_cuda.h2
-rw-r--r--intern/cycles/kernel/kernel_compat_opencl.h6
-rw-r--r--intern/cycles/kernel/kernel_textures.h4
-rw-r--r--intern/cycles/kernel/kernel_types.h5
-rw-r--r--intern/cycles/render/CMakeLists.txt4
-rw-r--r--intern/cycles/render/film.cpp92
-rw-r--r--intern/cycles/render/film.h14
-rw-r--r--intern/cycles/render/filter.cpp142
-rw-r--r--intern/cycles/render/scene.cpp31
-rw-r--r--intern/cycles/render/scene.h8
-rw-r--r--intern/cycles/render/tables.cpp106
-rw-r--r--intern/cycles/render/tables.h (renamed from intern/cycles/render/filter.h)32
16 files changed, 271 insertions, 206 deletions
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index f6ff78ab2ac..66401d80a2e 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -19,7 +19,6 @@
#include "background.h"
#include "camera.h"
#include "film.h"
-#include "../render/filter.h"
#include "graph.h"
#include "integrator.h"
#include "light.h"
@@ -213,18 +212,11 @@ void BlenderSync::sync_film()
Film prevfilm = *film;
film->exposure = get_float(cscene, "film_exposure");
+ film->filter_type = (FilterType)RNA_enum_get(&cscene, "filter_type");
+ film->filter_width = (film->filter_type == FILTER_BOX)? 1.0f: get_float(cscene, "filter_width");
if(film->modified(prevfilm))
film->tag_update(scene);
-
- Filter *filter = scene->filter;
- Filter prevfilter = *filter;
-
- filter->filter_type = (FilterType)RNA_enum_get(&cscene, "filter_type");
- filter->filter_width = (filter->filter_type == FILTER_BOX)? 1.0f: get_float(cscene, "filter_width");
-
- if(filter->modified(prevfilter))
- filter->tag_update(scene);
}
/* Render Layer */
diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h
index 3223ca91b9e..fd0bed33396 100644
--- a/intern/cycles/device/device_memory.h
+++ b/intern/cycles/device/device_memory.h
@@ -216,6 +216,14 @@ public:
return mem;
}
+ void copy_at(T *ptr, size_t offset, size_t size)
+ {
+ if(size > 0) {
+ size_t mem_size = size*data_elements*datatype_size(data_type);
+ memcpy(&data[0] + offset, ptr, mem_size);
+ }
+ }
+
void reference(T *ptr, size_t width, size_t height = 0)
{
data.clear();
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index 02f64cd649a..1d081b54681 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -224,8 +224,9 @@ __device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, flo
float lens_u, float lens_v, float time, Ray *ray)
{
/* pixel filter */
- float raster_x = x + kernel_tex_interp(__filter_table, filter_u, FILTER_TABLE_SIZE);
- float raster_y = y + kernel_tex_interp(__filter_table, filter_v, FILTER_TABLE_SIZE);
+ int filter_table_offset = kernel_data.film.filter_table_offset;
+ float raster_x = x + kernel_tex_lookup(__lookup_table, filter_u, filter_table_offset, FILTER_TABLE_SIZE);
+ float raster_y = y + kernel_tex_lookup(__lookup_table, filter_v, filter_table_offset, FILTER_TABLE_SIZE);
#ifdef __CAMERA_MOTION__
/* motion blur */
diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h
index 01bb78e8e1c..b7df7f86bf6 100644
--- a/intern/cycles/kernel/kernel_compat_cpu.h
+++ b/intern/cycles/kernel/kernel_compat_cpu.h
@@ -57,7 +57,7 @@ template<typename T> struct texture {
}
#endif
- float interp(float x, int size)
+ float lookup(float x, int offset, int size)
{
kernel_assert(size == width);
@@ -67,7 +67,7 @@ template<typename T> struct texture {
int nindex = min(index+1, width-1);
float t = x - index;
- return (1.0f - t)*data[index] + t*data[nindex];
+ return (1.0f - t)*data[index + offset] + t*data[nindex + offset];
}
T *data;
@@ -157,7 +157,7 @@ typedef texture_image<uchar4> texture_image_uchar4;
#define kernel_tex_fetch(tex, index) (kg->tex.fetch(index))
#define kernel_tex_fetch_m128(tex, index) (kg->tex.fetch_m128(index))
#define kernel_tex_fetch_m128i(tex, index) (kg->tex.fetch_m128i(index))
-#define kernel_tex_interp(tex, t, size) (kg->tex.interp(t, size))
+#define kernel_tex_lookup(tex, t, offset, size) (kg->tex.lookup(t, offset, size))
#define kernel_tex_image_interp(tex, x, y) ((tex < MAX_FLOAT_IMAGES) ? kg->texture_float_images[tex].interp(x, y) : kg->texture_byte_images[tex - MAX_FLOAT_IMAGES].interp(x, y))
#define kernel_data (kg->__data)
diff --git a/intern/cycles/kernel/kernel_compat_cuda.h b/intern/cycles/kernel/kernel_compat_cuda.h
index 9fd065c3cda..fdee59e225e 100644
--- a/intern/cycles/kernel/kernel_compat_cuda.h
+++ b/intern/cycles/kernel/kernel_compat_cuda.h
@@ -58,7 +58,7 @@ typedef texture<uchar4, 2, cudaReadModeNormalizedFloat> texture_image_uchar4;
/* Macros to handle different memory storage on different devices */
#define kernel_tex_fetch(t, index) tex1Dfetch(t, index)
-#define kernel_tex_interp(t, x, size) tex1D(t, x)
+#define kernel_tex_lookup(t, x, offset, size) tex1D(t, x) // XXX broken!
#define kernel_tex_image_interp(t, x, y) tex2D(t, x, y)
#define kernel_data __data
diff --git a/intern/cycles/kernel/kernel_compat_opencl.h b/intern/cycles/kernel/kernel_compat_opencl.h
index abb2f094f5c..dcbaf8fdbd2 100644
--- a/intern/cycles/kernel/kernel_compat_opencl.h
+++ b/intern/cycles/kernel/kernel_compat_opencl.h
@@ -46,7 +46,7 @@
#define kernel_assert(cond)
/* manual implementation of interpolated 1D lookup */
-__device float kernel_tex_interp_(__global float *data, int width, float x)
+__device float kernel_tex_lookup_(__global float *data, int offset, int width, float x)
{
x = clamp(x, 0.0f, 1.0f)*width;
@@ -54,7 +54,7 @@ __device float kernel_tex_interp_(__global float *data, int width, float x)
int nindex = min(index+1, width-1);
float t = x - index;
- return (1.0f - t)*data[index] + t*data[nindex];
+ return (1.0f - t)*data[index + offset] + t*data[nindex + offset];
}
/* make_type definitions with opencl style element initializers */
@@ -114,7 +114,7 @@ __device float kernel_tex_interp_(__global float *data, int width, float x)
/* data lookup defines */
#define kernel_data (*kg->data)
-#define kernel_tex_interp(t, x, size) kernel_tex_interp_(kg->t, size, x)
+#define kernel_tex_lookup(t, x, offset, size) kernel_tex_lookup_(kg->t, offset, size, x)
#define kernel_tex_fetch(t, index) kg->t[index]
/* define NULL */
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index e27de95e7ab..55c6e15ad04 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -66,8 +66,8 @@ KERNEL_TEX(uint4, texture_uint4, __svm_nodes)
KERNEL_TEX(uint, texture_uint, __shader_flag)
KERNEL_TEX(uint, texture_uint, __object_flag)
-/* camera/film */
-KERNEL_TEX(float, texture_float, __filter_table)
+/* lookup tables */
+KERNEL_TEX(float, texture_float, __lookup_table)
/* sobol */
KERNEL_TEX(uint, texture_uint, __sobol_directions)
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index ddbda9240fb..f6b8a1b8b82 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -611,8 +611,9 @@ typedef struct KernelFilm {
int pass_shadow;
float pass_shadow_scale;
- int pass_pad1;
- int pass_pad2;
+
+ int filter_table_offset;
+ int filter_pad;
} KernelFilm;
typedef struct KernelBackground {
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__ */