diff options
author | Thomas Dinges <blender@dingto.org> | 2016-07-02 00:48:31 +0300 |
---|---|---|
committer | Thomas Dinges <blender@dingto.org> | 2016-07-02 00:48:31 +0300 |
commit | 5c249fac9a4c0c2a74bf68243c3d71f227bfc4c6 (patch) | |
tree | c6215f7f983874a75d0fdfafeaae9a5d306df9c4 | |
parent | 85c9aefe0fef6d9f862d34ca66beb0bb4c2bcf6c (diff) |
Fix Cycles OpenCL not taking Extend and Clip extension types into account.
(See T48720).
-rw-r--r-- | intern/cycles/kernel/svm/svm_image.h | 33 | ||||
-rw-r--r-- | intern/cycles/render/image.cpp | 34 | ||||
-rw-r--r-- | intern/cycles/render/image.h | 2 |
3 files changed, 50 insertions, 19 deletions
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h index aa9c07c867e..6a2248865d7 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 ecde2e99a7b..d497661ee1d 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 01d02f4dbec..07998684b23 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); |