Cycles: OpenCL image texture support, fix an attribute node issue and refactor

feature enabling #defines a bit.
This commit is contained in:
Brecht Van Lommel
2012-05-13 12:32:44 +00:00
parent f964292630
commit dd9c1b7fbf
19 changed files with 222 additions and 23 deletions

View File

@@ -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;