Cycles: Cleanup, de-duplicate image packing of various types

This commit is contained in:
Sergey Sharybin 2017-04-28 15:08:54 +02:00
parent 0f339a748e
commit 407fd66d0a
2 changed files with 67 additions and 125 deletions

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

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