[Bf-blender-cvs] [3c85e1c] master: Cycles: Add support for single channel byte textures.

Thomas Dinges noreply at git.blender.org
Thu May 12 14:55:07 CEST 2016


Commit: 3c85e1ca1a916fe2ded9ab508f4cd55a2ee22549
Author: Thomas Dinges
Date:   Thu May 12 14:51:42 2016 +0200
Branches: master
https://developer.blender.org/rB3c85e1ca1a916fe2ded9ab508f4cd55a2ee22549

Cycles: Add support for single channel byte textures.

This way, we also save 3/4th of memory for single channel byte textures (e.g. Bump Maps).

Note: In order for this to work, the texture *must* have 1 channel only.
In Gimp you can e.g. do that via the menu: Image -> Mode -> Grayscale

===================================================================

M	intern/cycles/kernel/kernel_compat_cpu.h
M	intern/cycles/kernel/kernel_globals.h
M	intern/cycles/kernel/kernels/cpu/kernel.cpp
M	intern/cycles/render/image.cpp
M	intern/cycles/render/image.h
M	intern/cycles/render/scene.h
M	intern/cycles/util/util_texture.h

===================================================================

diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h
index 7fc8d2b..46bef96 100644
--- a/intern/cycles/kernel/kernel_compat_cpu.h
+++ b/intern/cycles/kernel/kernel_compat_cpu.h
@@ -109,6 +109,12 @@ template<typename T> struct texture_image  {
 		return make_float4(r.x*f, r.y*f, r.z*f, r.w*f);
 	}
 
+	ccl_always_inline float4 read(uchar r)
+	{
+		float f = r*(1.0f/255.0f);
+		return make_float4(f, f, f, 1.0);
+	}
+
 	ccl_always_inline float4 read(float r)
 	{
 		/* TODO(dingto): Optimize this, so interpolation
@@ -479,6 +485,7 @@ typedef texture<int> texture_int;
 typedef texture<uint4> texture_uint4;
 typedef texture<uchar4> texture_uchar4;
 typedef texture_image<float> texture_image_float;
+typedef texture_image<uchar> texture_image_uchar;
 typedef texture_image<float4> texture_image_float4;
 typedef texture_image<uchar4> texture_image_uchar4;
 
@@ -490,17 +497,20 @@ typedef texture_image<uchar4> texture_image_uchar4;
 #define kernel_tex_lookup(tex, t, offset, size) (kg->tex.lookup(t, offset, size))
 
 #define kernel_tex_image_interp(tex, x, y) \
-	((tex >= TEX_IMAGE_FLOAT_START_CPU) ? kg->texture_float_images[tex - TEX_IMAGE_FLOAT_START_CPU].interp(x, y) : \
+	((tex >= TEX_IMAGE_BYTE_START_CPU) ? kg->texture_byte_images[tex - TEX_IMAGE_BYTE_START_CPU].interp(x, y) : \
+	(tex >= TEX_IMAGE_FLOAT_START_CPU) ? kg->texture_float_images[tex - TEX_IMAGE_FLOAT_START_CPU].interp(x, y) : \
 	(tex >= TEX_IMAGE_BYTE4_START_CPU) ? kg->texture_byte4_images[tex - TEX_IMAGE_BYTE4_START_CPU].interp(x, y) : \
 	kg->texture_float4_images[tex].interp(x, y))
 
 #define kernel_tex_image_interp_3d(tex, x, y, z) \
-	((tex >= TEX_IMAGE_FLOAT_START_CPU) ? kg->texture_float_images[tex - TEX_IMAGE_FLOAT_START_CPU].interp_3d(x, y, z) : \
+	((tex >= TEX_IMAGE_BYTE_START_CPU) ? kg->texture_byte_images[tex - TEX_IMAGE_BYTE_START_CPU].interp_3d(x, y, z) : \
+	(tex >= TEX_IMAGE_FLOAT_START_CPU) ? kg->texture_float_images[tex - TEX_IMAGE_FLOAT_START_CPU].interp_3d(x, y, z) : \
 	(tex >= TEX_IMAGE_BYTE4_START_CPU) ? kg->texture_byte4_images[tex - TEX_IMAGE_BYTE4_START_CPU].interp_3d(x, y, z) : \
 	kg->texture_float4_images[tex].interp_3d(x, y, z))
 
 #define kernel_tex_image_interp_3d_ex(tex, x, y, z, interpolation) \
-	((tex >= TEX_IMAGE_FLOAT_START_CPU) ? kg->texture_float_images[tex - TEX_IMAGE_FLOAT_START_CPU].interp_3d_ex(x, y, z, interpolation) : \
+	((tex >= TEX_IMAGE_BYTE_START_CPU) ? kg->texture_byte_images[tex - TEX_IMAGE_BYTE_START_CPU].interp_3d_ex(x, y, z, interpolation) : \
+	(tex >= TEX_IMAGE_FLOAT_START_CPU) ? kg->texture_float_images[tex - TEX_IMAGE_FLOAT_START_CPU].interp_3d_ex(x, y, z, interpolation) : \
 	(tex >= TEX_IMAGE_BYTE4_START_CPU) ? kg->texture_byte4_images[tex - TEX_IMAGE_BYTE4_START_CPU].interp_3d_ex(x, y, z, interpolation) : \
 	kg->texture_float4_images[tex].interp_3d_ex(x, y, z, interpolation))
 
diff --git a/intern/cycles/kernel/kernel_globals.h b/intern/cycles/kernel/kernel_globals.h
index 3af44e0..c44ea1b 100644
--- a/intern/cycles/kernel/kernel_globals.h
+++ b/intern/cycles/kernel/kernel_globals.h
@@ -35,6 +35,7 @@ typedef struct KernelGlobals {
 	texture_image_uchar4 texture_byte4_images[TEX_NUM_BYTE4_IMAGES_CPU];
 	texture_image_float4 texture_float4_images[TEX_NUM_FLOAT4_IMAGES_CPU];
 	texture_image_float texture_float_images[TEX_NUM_FLOAT_IMAGES_CPU];
+	texture_image_uchar texture_byte_images[TEX_NUM_BYTE_IMAGES_CPU];
 
 #  define KERNEL_TEX(type, ttype, name) ttype name;
 #  define KERNEL_IMAGE_TEX(type, ttype, name)
diff --git a/intern/cycles/kernel/kernels/cpu/kernel.cpp b/intern/cycles/kernel/kernels/cpu/kernel.cpp
index 960012e..365ce89 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel.cpp
+++ b/intern/cycles/kernel/kernels/cpu/kernel.cpp
@@ -138,6 +138,22 @@ void kernel_tex_copy(KernelGlobals *kg,
 			tex->extension = extension;
 		}
 	}
+	else if(strstr(name, "__tex_image_byte")) {
+		texture_image_uchar *tex = NULL;
+		int id = atoi(name + strlen("__tex_image_byte_"));
+		int array_index = id - TEX_IMAGE_BYTE_START_CPU;
+
+		if(array_index >= 0 && array_index < TEX_NUM_BYTE_IMAGES_CPU) {
+			tex = &kg->texture_byte_images[array_index];
+		}
+
+		if(tex) {
+			tex->data = (uchar*)mem;
+			tex->dimensions_set(width, height, depth);
+			tex->interpolation = interpolation;
+			tex->extension = extension;
+		}
+	}
 	else
 		assert(0);
 }
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 0985cca..23e0708 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -43,40 +43,50 @@ ImageManager::ImageManager(const DeviceInfo& info)
 		tex_num_images[IMAGE_DATA_TYPE_BYTE4] = TEX_NUM_BYTE4_IMAGES_CPU;
 		tex_num_images[IMAGE_DATA_TYPE_FLOAT4] = TEX_NUM_FLOAT4_IMAGES_CPU;
 		tex_num_images[IMAGE_DATA_TYPE_FLOAT] = TEX_NUM_FLOAT_IMAGES_CPU;
+		tex_num_images[IMAGE_DATA_TYPE_BYTE] = TEX_NUM_BYTE_IMAGES_CPU;
 		tex_image_byte4_start = TEX_IMAGE_BYTE4_START_CPU;
 		tex_image_float_start = TEX_IMAGE_FLOAT_START_CPU;
+		tex_image_byte_start = TEX_IMAGE_BYTE_START_CPU;
 	}
 	/* CUDA (Fermi) */
 	else if((info.type == DEVICE_CUDA || info.type == DEVICE_MULTI) && !info.extended_images) {
 		tex_num_images[IMAGE_DATA_TYPE_BYTE4] = TEX_NUM_BYTE4_IMAGES_CUDA;
 		tex_num_images[IMAGE_DATA_TYPE_FLOAT4] = TEX_NUM_FLOAT4_IMAGES_CUDA;
 		tex_num_images[IMAGE_DATA_TYPE_FLOAT] = TEX_NUM_FLOAT_IMAGES_CUDA;
+		tex_num_images[IMAGE_DATA_TYPE_BYTE] = TEX_NUM_BYTE_IMAGES_CUDA;
 		tex_image_byte4_start = TEX_IMAGE_BYTE4_START_CUDA;
 		tex_image_float_start = TEX_IMAGE_FLOAT_START_CUDA;
+		tex_image_byte_start = TEX_IMAGE_BYTE_START_CUDA;
 	}
 	/* CUDA (Kepler and above) */
 	else if((info.type == DEVICE_CUDA || info.type == DEVICE_MULTI) && info.extended_images) {
 		tex_num_images[IMAGE_DATA_TYPE_BYTE4] = TEX_NUM_BYTE4_IMAGES_CUDA_KEPLER;
 		tex_num_images[IMAGE_DATA_TYPE_FLOAT4] = TEX_NUM_FLOAT4_IMAGES_CUDA_KEPLER;
 		tex_num_images[IMAGE_DATA_TYPE_FLOAT] = TEX_NUM_FLOAT_IMAGES_CUDA_KEPLER;
+		tex_num_images[IMAGE_DATA_TYPE_BYTE] = TEX_NUM_BYTE_IMAGES_CUDA_KEPLER;
 		tex_image_byte4_start = TEX_IMAGE_BYTE4_START_CUDA_KEPLER;
 		tex_image_float_start = TEX_IMAGE_FLOAT_START_CUDA_KEPLER;
+		tex_image_byte_start = TEX_IMAGE_BYTE_START_CUDA_KEPLER;
 	}
 	/* OpenCL */
 	else if(info.pack_images) {
 		tex_num_images[IMAGE_DATA_TYPE_BYTE4] = TEX_NUM_BYTE4_IMAGES_OPENCL;
 		tex_num_images[IMAGE_DATA_TYPE_FLOAT4] = TEX_NUM_FLOAT4_IMAGES_OPENCL;
 		tex_num_images[IMAGE_DATA_TYPE_FLOAT] = TEX_NUM_FLOAT_IMAGES_OPENCL;
+		tex_num_images[IMAGE_DATA_TYPE_BYTE] = TEX_NUM_BYTE_IMAGES_OPENCL;
 		tex_image_byte4_start = TEX_IMAGE_BYTE4_START_OPENCL;
 		tex_image_float_start = TEX_IMAGE_FLOAT_START_OPENCL;
+		tex_image_byte_start = TEX_IMAGE_BYTE_START_OPENCL;
 	}
 	/* Should never happen */
 	else {
 		tex_num_images[IMAGE_DATA_TYPE_BYTE4] = 0;
 		tex_num_images[IMAGE_DATA_TYPE_FLOAT4] = 0;
 		tex_num_images[IMAGE_DATA_TYPE_FLOAT] = 0;
+		tex_num_images[IMAGE_DATA_TYPE_BYTE] = 0;
 		tex_image_byte4_start = 0;
 		tex_image_float_start = 0;
+		tex_image_byte_start = 0;
 		assert(0);
 	}
 }
@@ -137,8 +147,13 @@ ImageManager::ImageDataType ImageManager::get_image_metadata(const string& filen
 			else
 				return IMAGE_DATA_TYPE_FLOAT;
 		}
-		else
-			return IMAGE_DATA_TYPE_BYTE4;
+		else {
+			if(channels > 1)
+				return IMAGE_DATA_TYPE_BYTE4;
+			else
+				return IMAGE_DATA_TYPE_BYTE;
+		}
+
 	}
 
 	ImageInput *in = ImageInput::create(filename);
@@ -192,12 +207,16 @@ ImageManager::ImageDataType ImageManager::get_image_metadata(const string& filen
 		else
 			return IMAGE_DATA_TYPE_FLOAT;
 	}
-	else
-		return IMAGE_DATA_TYPE_BYTE4;
+	else {
+		if(channels > 1)
+			return IMAGE_DATA_TYPE_BYTE4;
+		else
+			return IMAGE_DATA_TYPE_BYTE;
+	}
 }
 
 /* We use a consecutive slot counting scheme on the devices, in order
- * float4, byte4, float.
+ * float4, byte4, float, byte.
  * These functions convert the slot ids from ImageManager "images" ones
  * to device ones and vice versa. */
 int ImageManager::type_index_to_flattened_slot(int slot, ImageDataType type)
@@ -206,13 +225,20 @@ int ImageManager::type_index_to_flattened_slot(int slot, ImageDataType type)
 		return slot + tex_image_byte4_start;
 	else if(type == IMAGE_DATA_TYPE_FLOAT)
 		return slot + tex_image_float_start;
+	else if(type == IMAGE_DATA_TYPE_BYTE)
+		return slot + tex_image_byte_start;
 	else
 		return slot;
 }
 
 int ImageManager::flattened_slot_to_type_index(int flat_slot, ImageDataType *type)
 {
-	if(flat_slot >= tex_image_float_start)
+	if(flat_slot >= tex_image_byte_start)
+	{
+		*type = IMAGE_DATA_TYPE_BYTE;
+		return flat_slot - tex_image_byte_start;
+	}
+	else if(flat_slot >= tex_image_float_start)
 	{
 		*type = IMAGE_DATA_TYPE_FLOAT;
 		return flat_slot - tex_image_float_start;
@@ -233,6 +259,8 @@ string ImageManager::name_from_type(int type)
 		return "float4";
 	else if(type == IMAGE_DATA_TYPE_FLOAT)
 		return "float";
+	else if(type == IMAGE_DATA_TYPE_BYTE)
+		return "byte";
 	else
 		return "byte4";
 }
@@ -268,9 +296,11 @@ int ImageManager::add_image(const string& filename,
 	if(type == IMAGE_DATA_TYPE_FLOAT || type == IMAGE_DATA_TYPE_FLOAT4)
 		is_float = true;
 
-	/* No float textures on GPU yet */
+	/* No float and byte textures on GPU yet */
 	if(type == IMAGE_DATA_TYPE_FLOAT && tex_num_images[type] == 0)
 		type = IMAGE_DATA_TYPE_FLOAT4;
+	if(type == IMAGE_DATA_TYPE_BYTE && tex_num_images[type] == 0)
+		type = IMAGE_DATA_TYPE_BYTE4;
 
 	/* Fnd existing image. */
 	for(slot = 0; slot < images[type].size(); slot++) {
@@ -531,6 +561,44 @@ bool ImageManager::file_load_byte4_image(Image *img, device_vector<uchar4>& tex_
 	return true;
 }
 
+bool ImageManager::file_load_byte_image(Image *img, device_vector<uchar>& tex_img)
+{
+	ImageInput *in = NULL;
+	int width, height, depth, components;
+
+	if(!file_load_image_generic(img, &in, width, height, depth, components))
+		return false;
+
+	/* read BW pixels */
+	uchar *pixels = (uchar*)tex_img.resize(width, height, depth);
+	if(pixels == NULL) {
+		return false;
+	}
+
+	if(in) {
+		if(depth <= 1) {
+			int scanlinesize = width*components*sizeof(uchar);
+
+			in->read_image(TypeDesc::UINT8,
+				(uchar*)pixels + (((size_t)height)-1)*scanlinesize,
+				AutoStrid

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list