diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-05-13 16:32:44 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-05-13 16:32:44 +0400 |
commit | dd9c1b7fbf501ef58c9952150698fb5ce3c45903 (patch) | |
tree | f52d353e3dc36a33a3a8b6609fa8a2ffe39b2d4c /intern/cycles/render | |
parent | f9642926303ec89679e61076ca9e4b9f0be3afe9 (diff) |
Cycles: OpenCL image texture support, fix an attribute node issue and refactor
feature enabling #defines a bit.
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/image.cpp | 60 | ||||
-rw-r--r-- | intern/cycles/render/image.h | 4 | ||||
-rw-r--r-- | intern/cycles/render/mesh.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/render/scene.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/render/scene.h | 4 |
5 files changed, 68 insertions, 4 deletions
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index b9e02467450..6417d0e2103 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -34,6 +34,7 @@ CCL_NAMESPACE_BEGIN ImageManager::ImageManager() { need_update = true; + pack_images = false; osl_texture_system = NULL; } @@ -45,6 +46,11 @@ ImageManager::~ImageManager() assert(!float_images[slot]); } +void ImageManager::set_pack_images(bool pack_images_) +{ + pack_images = pack_images_; +} + void ImageManager::set_osl_texture_system(void *texture_system) { osl_texture_system = texture_system; @@ -84,7 +90,7 @@ int ImageManager::add_image(const string& filename, bool& is_float) size_t slot; /* load image info and find out if we need a float texture */ - is_float = is_float_image(filename); + is_float = (pack_images)? false: is_float_image(filename); if(is_float) { /* find existing image */ @@ -361,7 +367,8 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl if(slot >= 10) name = string_printf("__tex_image_float_0%d", slot); else name = string_printf("__tex_image_float_00%d", slot); - device->tex_alloc(name.c_str(), tex_img, true, true); + if(!pack_images) + device->tex_alloc(name.c_str(), tex_img, true, true); } else { string filename = path_filename(images[slot]->filename); @@ -387,7 +394,8 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl if(slot >= 10) name = string_printf("__tex_image_0%d", slot); else name = string_printf("__tex_image_00%d", slot); - device->tex_alloc(name.c_str(), tex_img, true, true); + if(!pack_images) + device->tex_alloc(name.c_str(), tex_img, true, true); } img->need_load = false; @@ -466,9 +474,49 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress& pool.wait_work(); + if(pack_images) + device_pack_images(device, dscene, progress); + need_update = false; } +void ImageManager::device_pack_images(Device *device, DeviceScene *dscene, Progress& progess) +{ + /* for OpenCL, we pack all image textures inside a single big texture, and + will do our own interpolation in the kernel */ + size_t size = 0; + + for(size_t slot = 0; slot < images.size(); slot++) { + if(!images[slot]) + continue; + + device_vector<uchar4>& tex_img = dscene->tex_image[slot]; + size += tex_img.size(); + } + + uint4 *info = dscene->tex_image_packed_info.resize(images.size()); + uchar4 *pixels = dscene->tex_image_packed.resize(size); + + size_t offset = 0; + + for(size_t slot = 0; slot < images.size(); slot++) { + if(!images[slot]) + continue; + + device_vector<uchar4>& tex_img = dscene->tex_image[slot]; + + info[slot] = make_uint4(tex_img.data_width, tex_img.data_height, offset, 1); + + memcpy(pixels+offset, (void*)tex_img.data_pointer, tex_img.memory_size()); + offset += tex_img.size(); + } + + if(dscene->tex_image_packed.size()) + device->tex_alloc("__tex_image_packed", dscene->tex_image_packed); + if(dscene->tex_image_packed_info.size()) + device->tex_alloc("__tex_image_packed_info", dscene->tex_image_packed_info); +} + void ImageManager::device_free(Device *device, DeviceScene *dscene) { for(size_t slot = 0; slot < images.size(); slot++) @@ -476,6 +524,12 @@ void ImageManager::device_free(Device *device, DeviceScene *dscene) for(size_t slot = 0; slot < float_images.size(); slot++) device_free_image(device, dscene, slot + TEX_IMAGE_FLOAT_START); + device->tex_free(dscene->tex_image_packed); + dscene->tex_image_packed.clear(); + + device->tex_free(dscene->tex_image_packed_info); + dscene->tex_image_packed_info.clear(); + images.clear(); float_images.clear(); } diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index cc01b4a8e4c..2b5e53cabe1 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -47,6 +47,7 @@ public: void device_free(Device *device, DeviceScene *dscene); void set_osl_texture_system(void *texture_system); + void set_pack_images(bool pack_images_); bool need_update; @@ -61,12 +62,15 @@ private: vector<Image*> images; vector<Image*> float_images; void *osl_texture_system; + bool pack_images; bool file_load_image(Image *img, device_vector<uchar4>& tex_img); bool file_load_float_image(Image *img, device_vector<float4>& tex_img); void device_load_image(Device *device, DeviceScene *dscene, int slot, Progress *progess); void device_free_image(Device *device, DeviceScene *dscene, int slot); + + void device_pack_images(Device *device, DeviceScene *dscene, Progress& progess); }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 0422f97a706..cabbd5760c2 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -421,7 +421,7 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce attr_map[index].x = id; attr_map[index].y = req.element; - attr_map[index].z = req.offset; + attr_map[index].z = as_uint(req.offset); if(req.type == TypeDesc::TypeFloat) attr_map[index].w = NODE_ATTR_FLOAT; diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index b6453339d41..a5f90bfe34b 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -111,6 +111,8 @@ void Scene::device_update(Device *device_, Progress& progress) * - Displacement shader must have all shader data available. * - Light manager needs final mesh data to compute emission CDF. */ + + image_manager->set_pack_images(device->info.pack_images); progress.set_status("Updating Background"); background->device_update(device, &dscene, this); diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index ca4d9fc9625..90bc47d5c8e 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -97,6 +97,10 @@ public: device_vector<uchar4> tex_image[TEX_NUM_IMAGES]; device_vector<float4> tex_float_image[TEX_NUM_FLOAT_IMAGES]; + /* opencl images */ + device_vector<uchar4> tex_image_packed; + device_vector<uint4> tex_image_packed_info; + KernelData data; }; |