Commit: 5c249fac9a4c0c2a74bf68243c3d71f227bfc4c6
Author: Thomas Dinges
Date:   Fri Jul 1 23:48:31 2016 +0200
Branches: master
https://developer.blender.org/rB5c249fac9a4c0c2a74bf68243c3d71f227bfc4c6

Fix Cycles OpenCL not taking Extend and Clip extension types into account.

(See T48720).

===================================================================

M       intern/cycles/kernel/svm/svm_image.h
M       intern/cycles/render/image.cpp
M       intern/cycles/render/image.h

===================================================================

diff --git a/intern/cycles/kernel/svm/svm_image.h 
b/intern/cycles/kernel/svm/svm_image.h
index aa9c07c..6a22488 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -72,8 +72,16 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int 
id, float x, float y,
        uint width = info.x;
        uint height = info.y;
        uint offset = info.z;
-       uint periodic = (info.w & 0x1);
-       uint interpolation = info.w >> 1;
+
+       /* Image Options */
+       uint interpolation = (info.w & (1 << 0)) ? INTERPOLATION_CLOSEST : 
INTERPOLATION_LINEAR;
+       uint extension;
+       if(info.w & (1 << 1))
+               extension = EXTENSION_REPEAT;
+       else if(info.w & (1 << 2))
+               extension = EXTENSION_EXTEND;
+       else
+               extension = EXTENSION_CLIP;
 
        float4 r;
        int ix, iy, nix, niy;
@@ -81,29 +89,37 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int 
id, float x, float y,
                svm_image_texture_frac(x*width, &ix);
                svm_image_texture_frac(y*height, &iy);
 
-               if(periodic) {
+               if(extension == EXTENSION_REPEAT) {
                        ix = svm_image_texture_wrap_periodic(ix, width);
                        iy = svm_image_texture_wrap_periodic(iy, height);
                }
-               else {
+               else if(extension == EXTENSION_CLIP) {
+                       if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f)
+                               return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+               }
+               else { /* EXTENSION_EXTEND */
                        ix = svm_image_texture_wrap_clamp(ix, width);
                        iy = svm_image_texture_wrap_clamp(iy, height);
-
                }
+
                r = svm_image_texture_read(kg, id, offset + ix + iy*width);
        }
-       else { /* We default to linear interpolation if it is not closest */
+       else { /* INTERPOLATION_LINEAR */
                float tx = svm_image_texture_frac(x*width - 0.5f, &ix);
                float ty = svm_image_texture_frac(y*height - 0.5f, &iy);
 
-               if(periodic) {
+               if(extension == EXTENSION_REPEAT) {
                        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 {
+               else if(extension == EXTENSION_CLIP) {
+                       if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f)
+                               return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+               }
+               else { /* EXTENSION_EXTEND */
                        ix = svm_image_texture_wrap_clamp(ix, width);
                        iy = svm_image_texture_wrap_clamp(iy, height);
 
@@ -111,7 +127,6 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int 
id, float x, float y,
                        niy = svm_image_texture_wrap_clamp(iy+1, height);
                }
 
-
                r = (1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, id, 
offset + ix + iy*width);
                r += (1.0f - ty)*tx*svm_image_texture_read(kg, id, offset + nix 
+ iy*width);
                r += ty*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix 
+ niy*width);
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index ecde2e9..d497661 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -1076,6 +1076,25 @@ void ImageManager::device_update_slot(Device *device,
        }
 }
 
+uint8_t ImageManager::pack_image_options(ImageDataType type, size_t slot)
+{
+       uint8_t options;
+       /* Image Options are packed into one uint:
+        * bit 0 -> Interpolation
+        * bit 1 + 2  + 3-> Extension */
+       if(images[type][slot]->interpolation == INTERPOLATION_CLOSEST)
+               options |= (1 << 0);
+
+       if(images[type][slot]->extension == EXTENSION_REPEAT)
+               options |= (1 << 1);
+       else if(images[type][slot]->extension == EXTENSION_EXTEND)
+               options |= (1 << 2);
+       else /* EXTENSION_CLIP */
+               options |= (1 << 3);
+
+       return options;
+}
+
 void ImageManager::device_pack_images(Device *device,
                                       DeviceScene *dscene,
                                       Progress& /*progess*/)
@@ -1107,11 +1126,9 @@ void ImageManager::device_pack_images(Device *device,
 
                device_vector<uchar4>& tex_img = dscene->tex_byte4_image[slot];
 
-               /* The image options are packed
-                  bit 0 -> periodic
-                  bit 1 + 2 -> interpolation type */
-               uint8_t interpolation = (images[type][slot]->interpolation << 
1) + 1;
-               info[type_index_to_flattened_slot(slot, type)] = 
make_uint4(tex_img.data_width, tex_img.data_height, offset, interpolation);
+               uint8_t options = pack_image_options(type, slot);
+
+               info[type_index_to_flattened_slot(slot, type)] = 
make_uint4(tex_img.data_width, tex_img.data_height, offset, options);
 
                memcpy(pixels_byte+offset, (void*)tex_img.data_pointer, 
tex_img.memory_size());
                offset += tex_img.size();
@@ -1139,11 +1156,8 @@ void ImageManager::device_pack_images(Device *device,
 
                /* todo: support 3D textures, only CPU for now */
 
-               /* The image options are packed
-                  bit 0 -> periodic
-                  bit 1 + 2 -> interpolation type */
-               uint8_t interpolation = (images[type][slot]->interpolation << 
1) + 1;
-               info[type_index_to_flattened_slot(slot, type)] = 
make_uint4(tex_img.data_width, tex_img.data_height, offset, interpolation);
+               uint8_t options = pack_image_options(type, slot);
+               info[type_index_to_flattened_slot(slot, type)] = 
make_uint4(tex_img.data_width, tex_img.data_height, offset, options);
 
                memcpy(pixels_float+offset, (void*)tex_img.data_pointer, 
tex_img.memory_size());
                offset += tex_img.size();
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 01d02f4..0799868 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -122,6 +122,8 @@ private:
        int flattened_slot_to_type_index(int flat_slot, ImageDataType *type);
        string name_from_type(int type);
 
+       uint8_t pack_image_options(ImageDataType type, size_t slot);
+
        void device_load_image(Device *device, DeviceScene *dscene, 
ImageDataType type, int slot, Progress *progess);
        void device_free_image(Device *device, DeviceScene *dscene, 
ImageDataType type, int slot);

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to