Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorThomas Dinges <blender@dingto.org>2016-07-02 00:48:31 +0300
committerThomas Dinges <blender@dingto.org>2016-07-02 00:48:31 +0300
commit5c249fac9a4c0c2a74bf68243c3d71f227bfc4c6 (patch)
treec6215f7f983874a75d0fdfafeaae9a5d306df9c4 /intern
parent85c9aefe0fef6d9f862d34ca66beb0bb4c2bcf6c (diff)
Fix Cycles OpenCL not taking Extend and Clip extension types into account.
(See T48720).
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/kernel/svm/svm_image.h33
-rw-r--r--intern/cycles/render/image.cpp34
-rw-r--r--intern/cycles/render/image.h2
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);