diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 09e7472caf2..82434712ca7 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -93,6 +93,11 @@ void BlenderSession::create_session() /* create scene */ scene = new Scene(scene_params, session_params.device); + /* setup callbacks for builtin image support */ + scene->image_manager->builtin_image_info_cb = function_bind(&BlenderSession::builtin_image_info, this, _1, _2, _3, _4, _5, _6, _7); + scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3); + scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3); + /* create session */ session = new Session(session_params); session->scene = scene; @@ -121,11 +126,6 @@ void BlenderSession::create_session() session->reset(buffer_params, session_params.samples); b_engine.use_highlight_tiles(session_params.progressive_refine == false); - - /* setup callbacks for builtin image support */ - scene->image_manager->builtin_image_info_cb = function_bind(&BlenderSession::builtin_image_info, this, _1, _2, _3, _4, _5, _6); - scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3); - scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3); } void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_) @@ -724,7 +724,7 @@ int BlenderSession::builtin_image_frame(const string &builtin_name) return atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str()); } -void BlenderSession::builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &channels) +void BlenderSession::builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels) { PointerRNA ptr; RNA_id_pointer_create((ID*)builtin_data, &ptr); @@ -734,12 +734,14 @@ void BlenderSession::builtin_image_info(const string &builtin_name, void *builti is_float = b_image.is_float(); width = b_image.size()[0]; height = b_image.size()[1]; + depth = 1; channels = b_image.channels(); } else { is_float = false; width = 0; height = 0; + depth = 0; channels = 0; } } diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h index 0568fb291d0..d30e3eda870 100644 --- a/intern/cycles/blender/blender_session.h +++ b/intern/cycles/blender/blender_session.h @@ -99,7 +99,7 @@ protected: void do_write_update_render_tile(RenderTile& rtile, bool do_update_only); int builtin_image_frame(const string &builtin_name); - void builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &channels); + void builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels); bool builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels); bool builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels); }; diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp index de44feb2deb..e14e403d82b 100644 --- a/intern/cycles/device/device_cpu.cpp +++ b/intern/cycles/device/device_cpu.cpp @@ -105,7 +105,7 @@ public: void tex_alloc(const char *name, device_memory& mem, InterpolationType interpolation, bool periodic) { - kernel_tex_copy(&kernel_globals, name, mem.data_pointer, mem.data_width, mem.data_height, interpolation); + kernel_tex_copy(&kernel_globals, name, mem.data_pointer, mem.data_width, mem.data_height, mem.data_depth, interpolation); mem.device_pointer = mem.data_pointer; stats.mem_alloc(mem.memory_size()); diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index a8a3134328f..26d356af458 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -461,6 +461,8 @@ public: void tex_alloc(const char *name, device_memory& mem, InterpolationType interpolation, bool periodic) { + /* todo: support 3D textures, only CPU for now */ + /* determine format */ CUarray_format_enum format; size_t dsize = datatype_size(mem.data_type); diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h index 1427d12cba2..8d6f4a49a9c 100644 --- a/intern/cycles/device/device_memory.h +++ b/intern/cycles/device/device_memory.h @@ -169,6 +169,7 @@ public: size_t data_size; size_t data_width; size_t data_height; + size_t data_depth; /* device pointer */ device_ptr device_pointer; @@ -195,6 +196,7 @@ public: data_size = 0; data_width = 0; data_height = 0; + data_depth = 0; assert(data_elements > 0); @@ -204,20 +206,21 @@ public: virtual ~device_vector() {} /* vector functions */ - T *resize(size_t width, size_t height = 0) + T *resize(size_t width, size_t height = 0, size_t depth = 0) { - data_size = (height == 0)? width: width*height; + data_size = width * ((height == 0)? 1: height) * ((depth == 0)? 1: depth); data.resize(data_size); data_pointer = (device_ptr)&data[0]; data_width = width; data_height = height; + data_depth = depth; return &data[0]; } - T *copy(T *ptr, size_t width, size_t height = 0) + T *copy(T *ptr, size_t width, size_t height = 0, size_t depth = 0) { - T *mem = resize(width, height); + T *mem = resize(width, height, depth); memcpy(mem, ptr, memory_size()); return mem; } @@ -230,13 +233,14 @@ public: } } - void reference(T *ptr, size_t width, size_t height = 0) + void reference(T *ptr, size_t width, size_t height = 0, size_t depth = 0) { data.clear(); - data_size = (height == 0)? width: width*height; + data_size = width * ((height == 0)? 1: height) * ((depth == 0)? 1: depth); data_pointer = (device_ptr)ptr; data_width = width; data_height = height; + data_depth = depth; } void clear() @@ -245,6 +249,7 @@ public: data_pointer = 0; data_width = 0; data_height = 0; + data_depth = 0; data_size = 0; } diff --git a/intern/cycles/device/device_network.h b/intern/cycles/device/device_network.h index bf8f3c70c49..8596b61b179 100644 --- a/intern/cycles/device/device_network.h +++ b/intern/cycles/device/device_network.h @@ -118,7 +118,7 @@ public: void add(const device_memory& mem) { archive & mem.data_type & mem.data_elements & mem.data_size; - archive & mem.data_width & mem.data_height & mem.device_pointer; + archive & mem.data_width & mem.data_height & mem.data_depth & mem.device_pointer; } template void add(const T& data) @@ -261,7 +261,7 @@ public: void read(network_device_memory& mem) { *archive & mem.data_type & mem.data_elements & mem.data_size; - *archive & mem.data_width & mem.data_height & mem.device_pointer; + *archive & mem.data_width & mem.data_height & mem.data_depth & mem.device_pointer; mem.data_pointer = 0; } diff --git a/intern/cycles/kernel/kernel.cpp b/intern/cycles/kernel/kernel.cpp index 5d74feed9f4..41cf7a6b66c 100644 --- a/intern/cycles/kernel/kernel.cpp +++ b/intern/cycles/kernel/kernel.cpp @@ -37,7 +37,7 @@ void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t s assert(0); } -void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t width, size_t height, InterpolationType interpolation) +void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t width, size_t height, size_t depth, InterpolationType interpolation) { if(0) { } @@ -63,6 +63,7 @@ void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t tex->data = (float4*)mem; tex->width = width; tex->height = height; + tex->depth = depth; tex->interpolation = interpolation; } } @@ -79,6 +80,7 @@ void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t tex->data = (uchar4*)mem; tex->width = width; tex->height = height; + tex->depth = depth; tex->interpolation = interpolation; } } diff --git a/intern/cycles/kernel/kernel.h b/intern/cycles/kernel/kernel.h index a4f13e78006..c4a08646bab 100644 --- a/intern/cycles/kernel/kernel.h +++ b/intern/cycles/kernel/kernel.h @@ -32,7 +32,7 @@ void *kernel_osl_memory(KernelGlobals *kg); bool kernel_osl_use(KernelGlobals *kg); void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t size); -void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t width, size_t height, InterpolationType interpolation=INTERPOLATION_LINEAR); +void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t width, size_t height, size_t depth, InterpolationType interpolation=INTERPOLATION_LINEAR); void kernel_cpu_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state, int sample, int x, int y, int offset, int stride); diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h index 850ef0abed1..feaff503212 100644 --- a/intern/cycles/kernel/kernel_compat_cpu.h +++ b/intern/cycles/kernel/kernel_compat_cpu.h @@ -99,6 +99,7 @@ template struct texture_image { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); int ix, iy, nix, niy; + if(interpolation == INTERPOLATION_CLOSEST) { frac(x*width, &ix); frac(y*height, &iy); @@ -131,17 +132,84 @@ template struct texture_image { 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]); r += ty*tx*read(data[nix + niy*width]); + + return r; + } + } + + ccl_always_inline float4 interp_3d(float x, float y, float z, bool periodic = false) + { + if(!data) + return make_float4(0.0f, 0.0f, 0.0f, 0.0f); + + int ix, iy, iz, nix, niy, niz; + + if(interpolation == INTERPOLATION_CLOSEST) { + frac(x*width, &ix); + frac(y*height, &iy); + frac(z*depth, &iz); + + if(periodic) { + ix = wrap_periodic(ix, width); + iy = wrap_periodic(iy, height); + iz = wrap_periodic(iz, depth); + } + else { + ix = wrap_clamp(ix, width); + iy = wrap_clamp(iy, height); + iz = wrap_clamp(iz, depth); + } + + return read(data[ix + iy*width + iz*width*height]); + } + else { + float tx = frac(x*width - 0.5f, &ix); + float ty = frac(y*height - 0.5f, &iy); + float tz = frac(z*depth - 0.5f, &iz); + + if(periodic) { + ix = wrap_periodic(ix, width); + iy = wrap_periodic(iy, height); + iz = wrap_periodic(iz, depth); + + nix = wrap_periodic(ix+1, width); + niy = wrap_periodic(iy+1, height); + niz = wrap_periodic(iz+1, depth); + } + else { + ix = wrap_clamp(ix, width); + iy = wrap_clamp(iy, height); + iz = wrap_clamp(iz, depth); + + nix = wrap_clamp(ix+1, width); + niy = wrap_clamp(iy+1, height); + niz = wrap_clamp(iz+1, depth); + } + + float4 r; + + r = (1.0f - tz)*(1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width + iz*width*height]); + r += (1.0f - tz)*(1.0f - ty)*tx*read(data[nix + iy*width + iz*width*height]); + r += (1.0f - tz)*ty*(1.0f - tx)*read(data[ix + niy*width + iz*width*height]); + r += (1.0f - tz)*ty*tx*read(data[nix + niy*width + iz*width*height]); + + r += tz*(1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width + niz*width*height]); + r += tz*(1.0f - ty)*tx*read(data[nix + iy*width + niz*width*height]); + r += tz*ty*(1.0f - tx)*read(data[ix + niy*width + niz*width*height]); + r += tz*ty*tx*read(data[nix + niy*width + niz*width*height]); + return r; } } - int interpolation; T *data; - int width, height; + int interpolation; + int width, height, depth; }; typedef texture texture_float4; @@ -161,6 +229,8 @@ typedef texture_image texture_image_uchar4; #define kernel_tex_fetch_m128i(tex, index) (kg->tex.fetch_m128i(index)) #define kernel_tex_lookup(tex, t, offset, size) (kg->tex.lookup(t, offset, size)) #define kernel_tex_image_interp(tex, x, y) ((tex < MAX_FLOAT_IMAGES) ? kg->texture_float_images[tex].interp(x, y) : kg->texture_byte_images[tex - MAX_FLOAT_IMAGES].interp(x, y)) +#define kernel_tex_image_interp_3d(tex, x, y, z) ((tex < MAX_FLOAT_IMAGES) ? kg->texture_float_images[tex].interp_3d(x, y, z) : kg->texture_byte_images[tex - MAX_FLOAT_IMAGES].interp_3d(x, y, z)) + #define kernel_data (kg->__data) CCL_NAMESPACE_END diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index ecccaf54ba9..a0994708ce1 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -90,8 +90,8 @@ bool ImageManager::is_float_image(const string& filename, void *builtin_data, bo if(builtin_data) { if(builtin_image_info_cb) { - int width, height, channels; - builtin_image_info_cb(filename, builtin_data, is_float, width, height, channels); + int width, height, depth, channels; + builtin_image_info_cb(filename, builtin_data, is_float, width, height, depth, channels); } if(is_float) @@ -145,6 +145,13 @@ bool ImageManager::is_float_image(const string& filename, void *builtin_data, bo return is_float; } +static bool image_equals(ImageManager::Image *image, const string& filename, void *builtin_data, bool interpolation) +{ + return image->filename == filename && + image->builtin_data == builtin_data && + image->interpolation == interpolation; +} + int ImageManager::add_image(const string& filename, void *builtin_data, bool animated, bool& is_float, bool& is_linear, InterpolationType interpolation) { Image *img; @@ -156,7 +163,7 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani if(is_float) { /* find existing image */ for(slot = 0; slot < float_images.size(); slot++) { - if(float_images[slot] && float_images[slot]->filename == filename && float_images[slot]->interpolation == interpolation) { + if(float_images[slot] && image_equals(float_images[slot], filename, builtin_data, interpolation)) { float_images[slot]->users++; return slot; } @@ -192,7 +199,7 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani } else { for(slot = 0; slot < images.size(); slot++) { - if(images[slot] && images[slot]->filename == filename && images[slot]->interpolation == interpolation) { + if(images[slot] && image_equals(images[slot], filename, builtin_data, interpolation)) { images[slot]->users++; return slot+tex_image_byte_start; } @@ -233,22 +240,43 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani return slot; } +void ImageManager::remove_image(int slot) +{ + if(slot >= tex_image_byte_start) { + slot -= tex_image_byte_start; + + assert(images[slot] != NULL); + + /* decrement user count */ + images[slot]->users--; + assert(images[slot]->users >= 0); + + /* don't remove immediately, rather do it all together later on. one of + * the reasons for this is that on shader changes we add and remove nodes + * that use them, but we do not want to reload the image all the time. */ + if(images[slot]->users == 0) + need_update = true; + } + else { + /* decrement user count */ + float_images[slot]->users--; + assert(float_images[slot]->users >= 0); + + /* don't remove immediately, rather do it all together later on. one of + * the reasons for this is that on shader changes we add and remove nodes + * that use them, but we do not want to reload the image all the time. */ + if(float_images[slot]->users == 0) + need_update = true; + } +} + void ImageManager::remove_image(const string& filename, void *builtin_data, InterpolationType interpolation) { size_t slot; for(slot = 0; slot < images.size(); slot++) { - if(images[slot] && images[slot]->filename == filename && images[slot]->interpolation == interpolation && images[slot]->builtin_data == builtin_data) { - /* decrement user count */ - images[slot]->users--; - assert(images[slot]->users >= 0); - - /* don't remove immediately, rather do it all together later on. one of - * the reasons for this is that on shader changes we add and remove nodes - * that use them, but we do not want to reload the image all the time. */ - if(images[slot]->users == 0) - need_update = true; - + if(images[slot] && image_equals(images[slot], filename, builtin_data, interpolation)) { + remove_image(slot+tex_image_byte_start); break; } } @@ -256,19 +284,8 @@ void ImageManager::remove_image(const string& filename, void *builtin_data, Inte if(slot == images.size()) { /* see if it's in a float texture slot */ for(slot = 0; slot < float_images.size(); slot++) { - if(float_images[slot] && float_images[slot]->filename == filename - && float_images[slot]->interpolation == interpolation - && float_images[slot]->builtin_data == builtin_data) { - /* decrement user count */ - float_images[slot]->users--; - assert(float_images[slot]->users >= 0); - - /* don't remove immediately, rather do it all together later on. one of - * the reasons for this is that on shader changes we add and remove nodes - * that use them, but we do not want to reload the image all the time. */ - if(float_images[slot]->users == 0) - need_update = true; - + if(float_images[slot] && image_equals(float_images[slot], filename, builtin_data, interpolation)) { + remove_image(slot); break; } } @@ -281,7 +298,7 @@ bool ImageManager::file_load_image(Image *img, device_vector& tex_img) return false; ImageInput *in = NULL; - int width, height, components; + int width, height, depth, components; if(!img->builtin_data) { /* load image from file through OIIO */ @@ -299,6 +316,7 @@ bool ImageManager::file_load_image(Image *img, device_vector& tex_img) width = spec.width; height = spec.height; + depth = spec.depth; components = spec.nchannels; } else { @@ -307,7 +325,7 @@ bool ImageManager::file_load_image(Image *img, device_vector& tex_img) return false; bool is_float; - builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, components); + builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, depth, components); } /* we only handle certain number of components */ @@ -321,15 +339,21 @@ bool ImageManager::file_load_image(Image *img, device_vector& tex_img) } /* read RGBA pixels */ - uchar *pixels = (uchar*)tex_img.resize(width, height); - int scanlinesize = width*components*sizeof(uchar); + uchar *pixels = (uchar*)tex_img.resize(width, height, depth); if(in) { - in->read_image(TypeDesc::UINT8, - (uchar*)pixels + (height-1)*scanlinesize, - AutoStride, - -scanlinesize, - AutoStride); + if(depth <= 1) { + int scanlinesize = width*components*sizeof(uchar); + + in->read_image(TypeDesc::UINT8, + (uchar*)pixels + (height-1)*scanlinesize, + AutoStride, + -scanlinesize, + AutoStride); + } + else { + in->read_image(TypeDesc::UINT8, (uchar*)pixels); + } in->close(); delete in; @@ -339,7 +363,7 @@ bool ImageManager::file_load_image(Image *img, device_vector& tex_img) } if(components == 2) { - for(int i = width*height-1; i >= 0; i--) { + for(int i = width*height*depth-1; i >= 0; i--) { pixels[i*4+3] = pixels[i*2+1]; pixels[i*4+2] = pixels[i*2+0]; pixels[i*4+1] = pixels[i*2+0]; @@ -347,7 +371,7 @@ bool ImageManager::file_load_image(Image *img, device_vector& tex_img) } } else if(components == 3) { - for(int i = width*height-1; i >= 0; i--) { + for(int i = width*height*depth-1; i >= 0; i--) { pixels[i*4+3] = 255; pixels[i*4+2] = pixels[i*3+2]; pixels[i*4+1] = pixels[i*3+1]; @@ -355,7 +379,7 @@ bool ImageManager::file_load_image(Image *img, device_vector& tex_img) } } else if(components == 1) { - for(int i = width*height-1; i >= 0; i--) { + for(int i = width*height*depth-1; i >= 0; i--) { pixels[i*4+3] = 255; pixels[i*4+2] = pixels[i]; pixels[i*4+1] = pixels[i]; @@ -372,7 +396,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector& tex_ return false; ImageInput *in = NULL; - int width, height, components; + int width, height, depth, components; if(!img->builtin_data) { /* load image from file through OIIO */ @@ -391,6 +415,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector& tex_ /* we only handle certain number of components */ width = spec.width; height = spec.height; + depth = spec.depth; components = spec.nchannels; } else { @@ -399,7 +424,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector& tex_ return false; bool is_float; - builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, components); + builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, depth, components); } if(!(components >= 1 && components <= 4)) { @@ -411,15 +436,21 @@ bool ImageManager::file_load_float_image(Image *img, device_vector& tex_ } /* read RGBA pixels */ - float *pixels = (float*)tex_img.resize(width, height); - int scanlinesize = width*components*sizeof(float); + float *pixels = (float*)tex_img.resize(width, height, depth); if(in) { - in->read_image(TypeDesc::FLOAT, - (uchar*)pixels + (height-1)*scanlinesize, - AutoStride, - -scanlinesize, - AutoStride); + if(depth <= 1) { + int scanlinesize = width*components*sizeof(float); + + in->read_image(TypeDesc::FLOAT, + (uchar*)pixels + (height-1)*scanlinesize, + AutoStride, + -scanlinesize, + AutoStride); + } + else { + in->read_image(TypeDesc::FLOAT, (uchar*)pixels); + } in->close(); delete in; @@ -429,7 +460,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector& tex_ } if(components == 2) { - for(int i = width*height-1; i >= 0; i--) { + for(int i = width*height*depth-1; i >= 0; i--) { pixels[i*4+3] = pixels[i*2+1]; pixels[i*4+2] = pixels[i*2+0]; pixels[i*4+1] = pixels[i*2+0]; @@ -437,7 +468,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector& tex_ } } else if(components == 3) { - for(int i = width*height-1; i >= 0; i--) { + for(int i = width*height*depth-1; i >= 0; i--) { pixels[i*4+3] = 1.0f; pixels[i*4+2] = pixels[i*3+2]; pixels[i*4+1] = pixels[i*3+1]; @@ -445,7 +476,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector& tex_ } } else if(components == 1) { - for(int i = width*height-1; i >= 0; i--) { + for(int i = width*height*depth-1; i >= 0; i--) { pixels[i*4+3] = 1.0f; pixels[i*4+2] = pixels[i]; pixels[i*4+1] = pixels[i]; @@ -460,9 +491,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl { if(progress->get_cancel()) return; - if(osl_texture_system) - return; - + Image *img; bool is_float; @@ -475,6 +504,9 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl is_float = true; } + if(osl_texture_system && !img->builtin_data) + return; + if(is_float) { string filename = path_filename(float_images[slot]->filename); progress->set_status("Updating Images", "Loading " + filename); @@ -556,7 +588,7 @@ void ImageManager::device_free_image(Device *device, DeviceScene *dscene, int sl } if(img) { - if(osl_texture_system) { + if(osl_texture_system && !img->builtin_data) { #ifdef WITH_OSL ustring filename(images[slot]->filename); ((OSL::TextureSystem*)osl_texture_system)->invalidate(filename); @@ -606,7 +638,7 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress& device_free_image(device, dscene, slot + tex_image_byte_start); } else if(images[slot]->need_load) { - if(!osl_texture_system) + if(!osl_texture_system || images[slot]->builtin_data) pool.push(function_bind(&ImageManager::device_load_image, this, device, dscene, slot + tex_image_byte_start, &progress)); } } @@ -619,7 +651,7 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress& device_free_image(device, dscene, slot); } else if(float_images[slot]->need_load) { - if(!osl_texture_system) + if(!osl_texture_system || float_images[slot]->builtin_data) pool.push(function_bind(&ImageManager::device_load_image, this, device, dscene, slot, &progress)); } } @@ -657,6 +689,7 @@ void ImageManager::device_pack_images(Device *device, DeviceScene *dscene, Progr device_vector& tex_img = dscene->tex_image[slot]; + /* todo: support 3D textures, only CPU for now */ /* The image options are packed bit 0 -> periodic diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 85b6b512bae..a52ab2853b9 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -50,6 +50,7 @@ public: ~ImageManager(); int add_image(const string& filename, void *builtin_data, bool animated, bool& is_float, bool& is_linear, InterpolationType interpolation); + void remove_image(int slot); void remove_image(const string& filename, void *builtin_data, InterpolationType interpolation); bool is_float_image(const string& filename, void *builtin_data, bool& is_linear); @@ -63,15 +64,9 @@ public: bool need_update; - boost::function builtin_image_info_cb; + boost::function builtin_image_info_cb; boost::function builtin_image_pixels_cb; boost::function builtin_image_float_pixels_cb; -private: - int tex_num_images; - int tex_num_float_images; - int tex_image_byte_start; - thread_mutex device_mutex; - int animation_frame; struct Image { string filename; @@ -84,6 +79,13 @@ private: int users; }; +private: + int tex_num_images; + int tex_num_float_images; + int tex_image_byte_start; + thread_mutex device_mutex; + int animation_frame; + vector images; vector float_images; void *osl_texture_system;