Cycles: Cleanup, de-duplicate image packing of various types
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 28 Apr 2017 13:08:54 +0000 (15:08 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 28 Apr 2017 13:08:54 +0000 (15:08 +0200)
intern/cycles/render/image.cpp
intern/cycles/render/image.h

index 22fe14d1dd22e91bd795f9d089e7eede7b780ff0..50bbcbe8f32c44f37739a7c1a2fe8030ad695c87 100644 (file)
@@ -1036,14 +1036,50 @@ uint8_t ImageManager::pack_image_options(ImageDataType type, size_t slot)
        return options;
 }
 
+template<typename T>
+void ImageManager::device_pack_images_type(
+        ImageDataType type,
+        const vector<device_vector<T>*>& cpu_textures,
+        device_vector<T> *device_image,
+        uint4 *info)
+{
+       size_t size = 0, offset = 0;
+       /* First step is to calculate size of the texture we need. */
+       for(size_t slot = 0; slot < images[type].size(); slot++) {
+               if(images[type][slot] == NULL) {
+                       continue;
+               }
+               device_vector<T>& tex_img = *cpu_textures[slot];
+               size += tex_img.size();
+       }
+       /* Now we know how much memory we need, so we can allocate and fill. */
+       T *pixels = device_image->resize(size);
+       for(size_t slot = 0; slot < images[type].size(); slot++) {
+               if(images[type][slot] == NULL) {
+                       continue;
+               }
+               device_vector<T>& tex_img = *cpu_textures[slot];
+               uint8_t options = pack_image_options(type, slot);
+               const int index = type_index_to_flattened_slot(slot, type) * 2;
+               info[index] = make_uint4(tex_img.data_width,
+                                        tex_img.data_height,
+                                        offset,
+                                        options);
+               info[index+1] = make_uint4(tex_img.data_depth, 0, 0, 0);
+               memcpy(pixels + offset,
+                      (void*)tex_img.data_pointer,
+                      tex_img.memory_size());
+               offset += tex_img.size();
+       }
+}
+
 void ImageManager::device_pack_images(Device *device,
                                       DeviceScene *dscene,
                                       Progress& /*progess*/)
 {
        /* For OpenCL, we pack all image textures into a single large texture, and
-        * do our own interpolation in the kernel. */
-       size_t size = 0, offset = 0;
-       ImageDataType type;
+        * do our own interpolation in the kernel.
+        */
 
        /* TODO(sergey): This will over-allocate a bit, but this is constant memory
         * so should be fine for a short term.
@@ -1058,129 +1094,28 @@ void ImageManager::device_pack_images(Device *device,
                                                             IMAGE_DATA_TYPE_BYTE));
        uint4 *info = dscene->tex_image_packed_info.resize(info_size*2);
 
-       /* Byte4 Textures*/
-       type = IMAGE_DATA_TYPE_BYTE4;
-
-       for(size_t slot = 0; slot < images[type].size(); slot++) {
-               if(!images[type][slot])
-                       continue;
-
-               device_vector<uchar4>& tex_img = *dscene->tex_byte4_image[slot];
-               size += tex_img.size();
-       }
-
-       uchar4 *pixels_byte4 = dscene->tex_image_byte4_packed.resize(size);
-
-       for(size_t slot = 0; slot < images[type].size(); slot++) {
-               if(!images[type][slot])
-                       continue;
-
-               device_vector<uchar4>& tex_img = *dscene->tex_byte4_image[slot];
-
-               uint8_t options = pack_image_options(type, slot);
-
-               int index = type_index_to_flattened_slot(slot, type) * 2;
-               info[index] = make_uint4(tex_img.data_width, tex_img.data_height, offset, options);
-               info[index+1] = make_uint4(tex_img.data_depth, 0, 0, 0);
-
-               memcpy(pixels_byte4+offset, (void*)tex_img.data_pointer, tex_img.memory_size());
-               offset += tex_img.size();
-       }
-
-       /* Float4 Textures*/
-       type = IMAGE_DATA_TYPE_FLOAT4;
-       size = 0, offset = 0;
-
-       for(size_t slot = 0; slot < images[type].size(); slot++) {
-               if(!images[type][slot])
-                       continue;
-
-               device_vector<float4>& tex_img = *dscene->tex_float4_image[slot];
-               size += tex_img.size();
-       }
-
-       float4 *pixels_float4 = dscene->tex_image_float4_packed.resize(size);
-
-       for(size_t slot = 0; slot < images[type].size(); slot++) {
-               if(!images[type][slot])
-                       continue;
-
-               device_vector<float4>& tex_img = *dscene->tex_float4_image[slot];
-
-               /* todo: support 3D textures, only CPU for now */
-
-               uint8_t options = pack_image_options(type, slot);
-
-               int index = type_index_to_flattened_slot(slot, type) * 2;
-               info[index] = make_uint4(tex_img.data_width, tex_img.data_height, offset, options);
-               info[index+1] = make_uint4(tex_img.data_depth, 0, 0, 0);
-
-               memcpy(pixels_float4+offset, (void*)tex_img.data_pointer, tex_img.memory_size());
-               offset += tex_img.size();
-       }
-
-       /* Byte Textures*/
-       type = IMAGE_DATA_TYPE_BYTE;
-       size = 0, offset = 0;
-
-       for(size_t slot = 0; slot < images[type].size(); slot++) {
-               if(!images[type][slot])
-                       continue;
-
-               device_vector<uchar>& tex_img = *dscene->tex_byte_image[slot];
-               size += tex_img.size();
-       }
-
-       uchar *pixels_byte = dscene->tex_image_byte_packed.resize(size);
-
-       for(size_t slot = 0; slot < images[type].size(); slot++) {
-               if(!images[type][slot])
-                       continue;
-
-               device_vector<uchar>& tex_img = *dscene->tex_byte_image[slot];
-
-               uint8_t options = pack_image_options(type, slot);
-
-               int index = type_index_to_flattened_slot(slot, type) * 2;
-               info[index] = make_uint4(tex_img.data_width, tex_img.data_height, offset, options);
-               info[index+1] = make_uint4(tex_img.data_depth, 0, 0, 0);
-
-               memcpy(pixels_byte+offset, (void*)tex_img.data_pointer, tex_img.memory_size());
-               offset += tex_img.size();
-       }
-
-       /* Float Textures*/
-       type = IMAGE_DATA_TYPE_FLOAT;
-       size = 0, offset = 0;
-
-       for(size_t slot = 0; slot < images[type].size(); slot++) {
-               if(!images[type][slot])
-                       continue;
-
-               device_vector<float>& tex_img = *dscene->tex_float_image[slot];
-               size += tex_img.size();
-       }
-
-       float *pixels_float = dscene->tex_image_float_packed.resize(size);
-
-       for(size_t slot = 0; slot < images[type].size(); slot++) {
-               if(!images[type][slot])
-                       continue;
-
-               device_vector<float>& tex_img = *dscene->tex_float_image[slot];
-
-               /* todo: support 3D textures, only CPU for now */
-
-               uint8_t options = pack_image_options(type, slot);
-
-               int index = type_index_to_flattened_slot(slot, type) * 2;
-               info[index] = make_uint4(tex_img.data_width, tex_img.data_height, offset, options);
-               info[index+1] = make_uint4(tex_img.data_depth, 0, 0, 0);
-
-               memcpy(pixels_float+offset, (void*)tex_img.data_pointer, tex_img.memory_size());
-               offset += tex_img.size();
-       }
-
+       /* Pack byte4 textures. */
+       device_pack_images_type(IMAGE_DATA_TYPE_BYTE4,
+                               dscene->tex_byte4_image,
+                               &dscene->tex_image_byte4_packed,
+                               info);
+       /* Pack float4 textures. */
+       device_pack_images_type(IMAGE_DATA_TYPE_FLOAT4,
+                               dscene->tex_float4_image,
+                               &dscene->tex_image_float4_packed,
+                               info);
+       /* Pack byte textures. */
+       device_pack_images_type(IMAGE_DATA_TYPE_BYTE,
+                               dscene->tex_byte_image,
+                               &dscene->tex_image_byte_packed,
+                               info);
+       /* Pack float textures. */
+       device_pack_images_type(IMAGE_DATA_TYPE_FLOAT,
+                               dscene->tex_float_image,
+                               &dscene->tex_image_float_packed,
+                               info);
+
+       /* Push textures to the device. */
        if(dscene->tex_image_byte4_packed.size()) {
                if(dscene->tex_image_byte4_packed.device_pointer) {
                        thread_scoped_lock device_lock(device_mutex);
index 76c2cc46f1265c7682b9ff1e81c8f8995a329682..0d457c144fea45312b72e18c1cf40ecf3865e43b 100644 (file)
@@ -151,6 +151,13 @@ private:
                               ImageDataType type,
                               int slot);
 
+       template<typename T>
+       void device_pack_images_type(
+               ImageDataType type,
+               const vector<device_vector<T>*>& cpu_textures,
+               device_vector<T> *device_image,
+               uint4 *info);
+
        void device_pack_images(Device *device,
                                DeviceScene *dscene,
                                Progress& progess);