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

(See T48720).
This commit is contained in:
Thomas Dinges 2016-07-01 23:48:31 +02:00
parent 85c9aefe0f
commit 5c249fac9a
3 changed files with 50 additions and 19 deletions

View File

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

View File

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

View File

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