diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-05-13 16:32:44 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-05-13 16:32:44 +0400 |
commit | dd9c1b7fbf501ef58c9952150698fb5ce3c45903 (patch) | |
tree | f52d353e3dc36a33a3a8b6609fa8a2ffe39b2d4c /intern/cycles/kernel/svm/svm_image.h | |
parent | f9642926303ec89679e61076ca9e4b9f0be3afe9 (diff) |
Cycles: OpenCL image texture support, fix an attribute node issue and refactor
feature enabling #defines a bit.
Diffstat (limited to 'intern/cycles/kernel/svm/svm_image.h')
-rw-r--r-- | intern/cycles/kernel/svm/svm_image.h | 75 |
1 files changed, 71 insertions, 4 deletions
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h index eddd0f7034a..388f006c40f 100644 --- a/intern/cycles/kernel/svm/svm_image.h +++ b/intern/cycles/kernel/svm/svm_image.h @@ -18,6 +18,75 @@ CCL_NAMESPACE_BEGIN +#ifdef __KERNEL_OPENCL__ + +/* For OpenCL all images are packed in a single array, and we do manual lookup + * and interpolation. */ + +__device_inline float4 svm_image_texture_read(KernelGlobals *kg, int offset) +{ + uchar4 r = kernel_tex_fetch(__tex_image_packed, offset); + float f = 1.0f/255.0f; + return make_float4(r.x*f, r.y*f, r.z*f, r.w*f); +} + +__device_inline int svm_image_texture_wrap_periodic(int x, int width) +{ + x %= width; + if(x < 0) + x += width; + return x; +} + +__device_inline int svm_image_texture_wrap_clamp(int x, int width) +{ + return clamp(x, 0, width-1); +} + +__device_inline float svm_image_texture_frac(float x, int *ix) +{ + int i = (int)x - ((x < 0.0f)? 1: 0); + *ix = i; + return x - (float)i; +} + +__device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y) +{ + uint4 info = kernel_tex_fetch(__tex_image_packed_info, id); + uint width = info.x; + uint height = info.y; + uint offset = info.z; + uint periodic = info.w; + + int ix, iy, nix, niy; + float tx = svm_image_texture_frac(x*width, &ix); + float ty = svm_image_texture_frac(y*height, &iy); + + if(periodic) { + ix = svm_image_texture_wrap_periodic(ix, width); + iy = svm_image_texture_wrap_periodic(iy, height); + + nix = svm_image_texture_wrap_periodic(ix+1, width); + niy = svm_image_texture_wrap_periodic(iy+1, height); + } + else { + ix = svm_image_texture_wrap_clamp(ix, width); + iy = svm_image_texture_wrap_clamp(iy, height); + + nix = svm_image_texture_wrap_clamp(ix+1, width); + niy = svm_image_texture_wrap_clamp(iy+1, height); + } + + float4 r = (1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, offset + ix + iy*width); + r += (1.0f - ty)*tx*svm_image_texture_read(kg, offset + nix + iy*width); + r += ty*(1.0f - tx)*svm_image_texture_read(kg, offset + ix + niy*width); + r += ty*tx*svm_image_texture_read(kg, offset + nix + niy*width); + + return r; +} + +#else + __device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y) { float4 r; @@ -31,9 +100,6 @@ __device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y) also note that cuda has 128 textures limit, we use 100 now, since we still need some for other storage */ -#ifdef __KERNEL_OPENCL__ - r = make_float4(0.0f, 0.0f, 0.0f, 0.0f); /* todo */ -#else switch(id) { case 0: r = kernel_tex_image_interp(__tex_image_000, x, y); break; case 1: r = kernel_tex_image_interp(__tex_image_001, x, y); break; @@ -139,11 +205,12 @@ __device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y) kernel_assert(0); return make_float4(0.0f, 0.0f, 0.0f, 0.0f); } -#endif return r; } +#endif + __device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { uint id = node.y; |