Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Werner <stefan.werner@tangent-animation.com>2018-07-05 13:37:52 +0300
committerStefan Werner <stefan.werner@tangent-animation.com>2018-07-05 14:53:34 +0300
commit4d00e95ee3ed91f86262bb218f1c5df901da724c (patch)
tree5d9af704609b38cca76a5786189c126ac7072332 /intern/cycles/render/image.cpp
parentcd17b3258327522b8c6f56a3ee7239a91f2be149 (diff)
Cycles: Adding native support for UINT16 textures.
Textures in 16 bit integer format are sometimes used for displacement, bump and normal maps and can be exported by tools like Substance Painter. Without this patch, Cycles would promote those textures to single precision floating point, causing them to take up twice as much memory as needed. Reviewers: #cycles, brecht, sergey Reviewed By: #cycles, brecht, sergey Subscribers: sergey, dingto, #cycles Tags: #cycles Differential Revision: https://developer.blender.org/D3523
Diffstat (limited to 'intern/cycles/render/image.cpp')
-rw-r--r--intern/cycles/render/image.cpp82
1 files changed, 72 insertions, 10 deletions
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 9c6536edc4f..3c49d17aa82 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -39,6 +39,10 @@ static bool isfinite(half /*value*/)
{
return false;
}
+static bool isfinite(uint16_t /*value*/)
+{
+ return false;
+}
ImageManager::ImageManager(const DeviceInfo& info)
{
@@ -164,23 +168,27 @@ bool ImageManager::get_image_metadata(const string& filename,
metadata.height = spec.height;
metadata.depth = spec.depth;
- /* check the main format, and channel formats;
- * if any take up more than one byte, we'll need a float texture slot */
- if(spec.format.basesize() > 1) {
+
+ /* Check the main format, and channel formats. */
+ size_t channel_size = spec.format.basesize();
+
+ if(spec.format.is_floating_point()) {
metadata.is_float = true;
metadata.is_linear = true;
}
for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
- if(spec.channelformats[channel].basesize() > 1) {
+ channel_size = max(channel_size, spec.channelformats[channel].basesize());
+ if(spec.channelformats[channel].is_floating_point()) {
metadata.is_float = true;
metadata.is_linear = true;
}
}
/* check if it's half float */
- if(spec.format == TypeDesc::HALF)
+ if(spec.format == TypeDesc::HALF) {
metadata.is_half = true;
+ }
/* basic color space detection, not great but better than nothing
* before we do OpenColorIO integration */
@@ -208,6 +216,9 @@ bool ImageManager::get_image_metadata(const string& filename,
else if(metadata.is_float) {
metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
}
+ else if(spec.format == TypeDesc::USHORT) {
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_USHORT4 : IMAGE_DATA_TYPE_USHORT;
+ }
else {
metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
}
@@ -254,6 +265,10 @@ string ImageManager::name_from_type(int type)
return "half4";
else if(type == IMAGE_DATA_TYPE_HALF)
return "half";
+ else if(type == IMAGE_DATA_TYPE_USHORT)
+ return "ushort";
+ else if(type == IMAGE_DATA_TYPE_USHORT4)
+ return "ushort4";
else
return "byte4";
}
@@ -583,7 +598,8 @@ bool ImageManager::file_load_image(Image *img,
*/
bool is_rgba = (type == IMAGE_DATA_TYPE_FLOAT4 ||
type == IMAGE_DATA_TYPE_HALF4 ||
- type == IMAGE_DATA_TYPE_BYTE4);
+ type == IMAGE_DATA_TYPE_BYTE4 ||
+ type == IMAGE_DATA_TYPE_USHORT4);
if(is_rgba) {
if(cmyk) {
/* CMYK */
@@ -843,14 +859,61 @@ void ImageManager::device_load_image(Device *device,
thread_scoped_lock device_lock(device_mutex);
tex_img->copy_to_device();
}
+ else if(type == IMAGE_DATA_TYPE_USHORT) {
+ device_vector<uint16_t> *tex_img
+ = new device_vector<uint16_t>(device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if(!file_load_image<TypeDesc::USHORT, uint16_t>(img,
+ type,
+ texture_limit,
+ *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ uint16_t *pixels = (uint16_t*)tex_img->alloc(1, 1);
+
+ pixels[0] = TEX_IMAGE_MISSING_R;
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ else if(type == IMAGE_DATA_TYPE_USHORT4) {
+ device_vector<ushort4> *tex_img
+ = new device_vector<ushort4>(device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if(!file_load_image<TypeDesc::USHORT, uint16_t>(img,
+ type,
+ texture_limit,
+ *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ uint16_t *pixels = (uint16_t*)tex_img->alloc(1, 1);
+
+ pixels[0] = TEX_IMAGE_MISSING_R;
+ pixels[1] = TEX_IMAGE_MISSING_G;
+ pixels[2] = TEX_IMAGE_MISSING_B;
+ pixels[3] = TEX_IMAGE_MISSING_A;
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
else if(type == IMAGE_DATA_TYPE_HALF) {
device_vector<half> *tex_img
= new device_vector<half>(device, img->mem_name.c_str(), MEM_TEXTURE);
if(!file_load_image<TypeDesc::HALF, half>(img,
- type,
- texture_limit,
- *tex_img)) {
+ type,
+ texture_limit,
+ *tex_img)) {
/* on failure to load, we set a 1x1 pixels pink image */
thread_scoped_lock device_lock(device_mutex);
half *pixels = (half*)tex_img->alloc(1, 1);
@@ -865,7 +928,6 @@ void ImageManager::device_load_image(Device *device,
thread_scoped_lock device_lock(device_mutex);
tex_img->copy_to_device();
}
-
img->need_load = false;
}