Fix cycles texture interpolation mode closest constant offset on some devices
authorMartijn Berger <martijn.berger@gmail.com>
Thu, 13 Mar 2014 19:08:10 +0000 (20:08 +0100)
committerMartijn Berger <martijn.berger@gmail.com>
Thu, 13 Mar 2014 19:08:33 +0000 (20:08 +0100)
intern/cycles/kernel/kernel_compat_cpu.h
intern/cycles/kernel/svm/svm_image.h

index 55f4484ba1f94d815af260b3a6c5e75a61dab9c0..850ef0abed1321747ac2bc8cfe1c76a81a37f577 100644 (file)
@@ -99,28 +99,38 @@ template<typename T> struct texture_image  {
                        return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
 
                int ix, iy, nix, niy;
-               float tx = frac(x*width - 0.5f, &ix);
-               float ty = frac(y*height - 0.5f, &iy);
-
-               if(periodic) {
-                       ix = wrap_periodic(ix, width);
-                       iy = wrap_periodic(iy, height);
-
-                       nix = wrap_periodic(ix+1, width);
-                       niy = wrap_periodic(iy+1, height);
-               }
-               else {
-                       ix = wrap_clamp(ix, width);
-                       iy = wrap_clamp(iy, height);
-
-                       nix = wrap_clamp(ix+1, width);
-                       niy = wrap_clamp(iy+1, height);
-               }
-
                if(interpolation == INTERPOLATION_CLOSEST) {
+                       frac(x*width, &ix);
+                       frac(y*height, &iy);
+                       if(periodic) {
+                               ix = wrap_periodic(ix, width);
+                               iy = wrap_periodic(iy, height);
+
+                       }
+                       else {
+                               ix = wrap_clamp(ix, width);
+                               iy = wrap_clamp(iy, height);
+                       }
                        return read(data[ix + iy*width]);
                }
                else {
+                       float tx = frac(x*width - 0.5f, &ix);
+                       float ty = frac(y*height - 0.5f, &iy);
+
+                       if(periodic) {
+                               ix = wrap_periodic(ix, width);
+                               iy = wrap_periodic(iy, height);
+
+                               nix = wrap_periodic(ix+1, width);
+                               niy = wrap_periodic(iy+1, height);
+                       }
+                       else {
+                               ix = wrap_clamp(ix, width);
+                               iy = wrap_clamp(iy, height);
+
+                               nix = wrap_clamp(ix+1, width);
+                               niy = wrap_clamp(iy+1, height);
+                       }
                        float4 r = (1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width]);
                        r += (1.0f - ty)*tx*read(data[nix + iy*width]);
                        r += ty*(1.0f - tx)*read(data[ix + niy*width]);
index 750af97150ec56d3856bbfed3693ab03cb27d6a9..73c0ab1ae0b9731eb746a54f4a6ede17c802b638 100644 (file)
@@ -63,30 +63,43 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y,
        uint periodic = (info.w & 0x1);
        uint interpolation = info.w >> 1;
 
+       float4 r;
        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);
+       if (interpolation == INTERPOLATION_CLOSEST){
+               svm_image_texture_frac(x*width, &ix);
+               svm_image_texture_frac(y*height, &iy);
 
-               nix = svm_image_texture_wrap_clamp(ix+1, width);
-               niy = svm_image_texture_wrap_clamp(iy+1, height);
-       }
+               if(periodic) {
+                       ix = svm_image_texture_wrap_periodic(ix, width);
+                       iy = svm_image_texture_wrap_periodic(iy, height);
+               }
+               else {
+                       ix = svm_image_texture_wrap_clamp(ix, width);
+                       iy = svm_image_texture_wrap_clamp(iy, height);
 
-       float4 r;
-       if (interpolation == INTERPOLATION_CLOSEST){
+               }
                r = svm_image_texture_read(kg, offset + ix + iy*width);
        }
        else { /* We default to linear interpolation if it is not closest */
+               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);
+               }
+
+
                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);