Blender V2.61 - r43446

kernel_compat_cpu.h

Go to the documentation of this file.
00001 /*
00002  * Copyright 2011, Blender Foundation.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019 #ifndef __KERNEL_COMPAT_CPU_H__
00020 #define __KERNEL_COMPAT_CPU_H__
00021 
00022 #define __KERNEL_CPU__
00023 
00024 #include "util_debug.h"
00025 #include "util_math.h"
00026 #include "util_types.h"
00027 
00028 CCL_NAMESPACE_BEGIN
00029 
00030 /* Assertions inside the kernel only work for the CPU device, so we wrap it in
00031    a macro which is empty for other devices */
00032 
00033 #define kernel_assert(cond) assert(cond)
00034 
00035 /* Texture types to be compatible with CUDA textures. These are really just
00036    simple arrays and after inlining fetch hopefully revert to being a simple
00037    pointer lookup. */
00038 
00039 template<typename T> struct texture  {
00040     T fetch(int index)
00041     {
00042         kernel_assert(index >= 0 && index < width);
00043         return data[index];
00044     }
00045 
00046     /*__m128 fetch_m128(int index)
00047     {
00048         kernel_assert(index >= 0 && index < width);
00049         return ((__m128*)data)[index];
00050     }
00051 
00052     __m128i fetch_m128i(int index)
00053     {
00054         kernel_assert(index >= 0 && index < width);
00055         return ((__m128i*)data)[index];
00056     }*/
00057 
00058     float interp(float x, int size)
00059     {
00060         kernel_assert(size == width);
00061 
00062         x = clamp(x, 0.0f, 1.0f)*width;
00063 
00064         int index = min((int)x, width-1);
00065         int nindex = min(index+1, width-1);
00066         float t = x - index;
00067 
00068         return (1.0f - t)*data[index] + t*data[nindex];
00069     }
00070 
00071     T *data;
00072     int width;
00073 };
00074 
00075 template<typename T> struct texture_image  {
00076     float4 read(float4 r)
00077     {
00078         return r;
00079     }
00080 
00081     float4 read(uchar4 r)
00082     {
00083         float f = 1.0f/255.0f;
00084         return make_float4(r.x*f, r.y*f, r.z*f, r.w*f);
00085     }
00086 
00087     int wrap_periodic(int x, int width)
00088     {
00089         x %= width;
00090         if(x < 0)
00091             x += width;
00092         return x;
00093     }
00094 
00095     int wrap_clamp(int x, int width)
00096     {
00097         return clamp(x, 0, width-1);
00098     }
00099 
00100     float frac(float x, int *ix)
00101     {
00102         int i = (int)x - ((x < 0.0f)? 1: 0);
00103         *ix = i;
00104         return x - (float)i;
00105     }
00106 
00107     float4 interp(float x, float y, bool periodic = true)
00108     {
00109         if(!data)
00110             return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
00111 
00112         int ix, iy, nix, niy;
00113         float tx = frac(x*width, &ix);
00114         float ty = frac(y*height, &iy);
00115 
00116         if(periodic) {
00117             ix = wrap_periodic(ix, width);
00118             iy = wrap_periodic(iy, height);
00119 
00120             nix = wrap_periodic(ix+1, width);
00121             niy = wrap_periodic(iy+1, height);
00122         }
00123         else {
00124             ix = wrap_clamp(ix, width);
00125             iy = wrap_clamp(iy, height);
00126 
00127             nix = wrap_clamp(ix+1, width);
00128             niy = wrap_clamp(iy+1, height);
00129         }
00130 
00131         float4 r = (1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width]);
00132         r += (1.0f - ty)*tx*read(data[nix + iy*width]);
00133         r += ty*(1.0f - tx)*read(data[ix + niy*width]);
00134         r += ty*tx*read(data[nix + niy*width]);
00135 
00136         return r;
00137     }
00138 
00139     T *data;
00140     int width, height;
00141 };
00142 
00143 typedef texture<float4> texture_float4;
00144 typedef texture<float> texture_float;
00145 typedef texture<uint> texture_uint;
00146 typedef texture<int> texture_int;
00147 typedef texture<uint4> texture_uint4;
00148 typedef texture_image<float4> texture_image_float4;
00149 typedef texture_image<uchar4> texture_image_uchar4;
00150 
00151 /* Macros to handle different memory storage on different devices */
00152 
00153 #define kernel_tex_fetch(tex, index) (kg->tex.fetch(index))
00154 #define kernel_tex_fetch_m128(tex, index) (kg->tex.fetch_m128(index))
00155 #define kernel_tex_fetch_m128i(tex, index) (kg->tex.fetch_m128i(index))
00156 #define kernel_tex_interp(tex, t, size) (kg->tex.interp(t, size))
00157 #define kernel_tex_image_interp(tex, x, y) (kg->tex.interp(x, y))
00158 
00159 #define kernel_data (kg->__data)
00160 
00161 CCL_NAMESPACE_END
00162 
00163 #endif /* __KERNEL_COMPAT_CPU_H__ */
00164