[Bf-blender-cvs] [9ddbf6a] soc-2016-cycles_images: Cycles: Add some basic code for half4 and half image textures.

Thomas Dinges noreply at git.blender.org
Sat May 28 01:36:29 CEST 2016


Commit: 9ddbf6ab5b36f459c71d86a3a39e8489ac039601
Author: Thomas Dinges
Date:   Sat May 28 01:35:20 2016 +0200
Branches: soc-2016-cycles_images
https://developer.blender.org/rB9ddbf6ab5b36f459c71d86a3a39e8489ac039601

Cycles: Add some basic code for half4 and half image textures.

Not finished yet, so noting to see here yet.

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

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 bb303b3..b7177ab 100644
--- a/intern/cycles/kernel/kernel_compat_cpu.h
+++ b/intern/cycles/kernel/kernel_compat_cpu.h
@@ -486,8 +486,10 @@ 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<half> texture_image_half;
 typedef texture_image<float4> texture_image_float4;
 typedef texture_image<uchar4> texture_image_uchar4;
+typedef texture_image<half4> texture_image_half4;
 
 /* Macros to handle different memory storage on different devices */
 
diff --git a/intern/cycles/kernel/kernel_globals.h b/intern/cycles/kernel/kernel_globals.h
index e06c68f..8e66a3a 100644
--- a/intern/cycles/kernel/kernel_globals.h
+++ b/intern/cycles/kernel/kernel_globals.h
@@ -37,8 +37,10 @@ struct VolumeStep;
 typedef struct KernelGlobals {
 	texture_image_uchar4 texture_byte4_images[TEX_NUM_BYTE4_CPU];
 	texture_image_float4 texture_float4_images[TEX_NUM_FLOAT4_CPU];
+	texture_image_half4 texture_half4_images[TEX_NUM_HALF4_CPU];
 	texture_image_float texture_float_images[TEX_NUM_FLOAT_CPU];
 	texture_image_uchar texture_byte_images[TEX_NUM_BYTE_CPU];
+	texture_image_half texture_half_images[TEX_NUM_HALF_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 d8a83f6..f11c85d 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel.cpp
+++ b/intern/cycles/kernel/kernels/cpu/kernel.cpp
@@ -154,6 +154,38 @@ void kernel_tex_copy(KernelGlobals *kg,
 			tex->extension = extension;
 		}
 	}
+	else if(strstr(name, "__tex_image_half4")) {
+		texture_image_half4 *tex = NULL;
+		int id = atoi(name + strlen("__tex_image_half4_"));
+		int array_index = id - TEX_START_HALF4_CPU;
+
+		if(array_index >= 0 && array_index < TEX_NUM_HALF4_CPU) {
+			tex = &kg->texture_half4_images[array_index];
+		}
+
+		if(tex) {
+			tex->data = (half4*)mem;
+			tex->dimensions_set(width, height, depth);
+			tex->interpolation = interpolation;
+			tex->extension = extension;
+		}
+	}
+	else if(strstr(name, "__tex_image_half")) {
+		texture_image_half *tex = NULL;
+		int id = atoi(name + strlen("__tex_image_half_"));
+		int array_index = id - TEX_START_HALF_CPU;
+
+		if(array_index >= 0 && array_index < TEX_NUM_HALF_CPU) {
+			tex = &kg->texture_half_images[array_index];
+		}
+
+		if(tex) {
+			tex->data = (half*)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 71dc85f..bdcb8c4 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -54,10 +54,14 @@ ImageManager::ImageManager(const DeviceInfo& info)
 		tex_num_images[IMAGE_DATA_TYPE_BYTE4] = TEX_NUM_BYTE4_ ## ARCH; \
 		tex_num_images[IMAGE_DATA_TYPE_FLOAT] = TEX_NUM_FLOAT_ ## ARCH; \
 		tex_num_images[IMAGE_DATA_TYPE_BYTE] = TEX_NUM_BYTE_ ## ARCH; \
+		tex_num_images[IMAGE_DATA_TYPE_HALF4] = TEX_NUM_HALF4_ ## ARCH; \
+		tex_num_images[IMAGE_DATA_TYPE_HALF] = TEX_NUM_HALF_ ## ARCH; \
 		tex_start_images[IMAGE_DATA_TYPE_FLOAT4] = TEX_START_FLOAT4_ ## ARCH; \
 		tex_start_images[IMAGE_DATA_TYPE_BYTE4] = TEX_START_BYTE4_ ## ARCH; \
 		tex_start_images[IMAGE_DATA_TYPE_FLOAT] = TEX_START_FLOAT_ ## ARCH; \
 		tex_start_images[IMAGE_DATA_TYPE_BYTE] = TEX_START_BYTE_ ## ARCH; \
+		tex_start_images[IMAGE_DATA_TYPE_HALF4] = TEX_START_HALF4_ ## ARCH; \
+		tex_start_images[IMAGE_DATA_TYPE_HALF] = TEX_START_HALF_ ## ARCH; \
 	}
 
 	if(device_type == DEVICE_CPU) {
@@ -80,10 +84,14 @@ ImageManager::ImageManager(const DeviceInfo& info)
 		tex_num_images[IMAGE_DATA_TYPE_BYTE4] = 0;
 		tex_num_images[IMAGE_DATA_TYPE_FLOAT] = 0;
 		tex_num_images[IMAGE_DATA_TYPE_BYTE] = 0;
+		tex_num_images[IMAGE_DATA_TYPE_HALF4] = 0;
+		tex_num_images[IMAGE_DATA_TYPE_HALF] = 0;
 		tex_start_images[IMAGE_DATA_TYPE_FLOAT4] = 0;
 		tex_start_images[IMAGE_DATA_TYPE_BYTE4] = 0;
 		tex_start_images[IMAGE_DATA_TYPE_FLOAT] = 0;
 		tex_start_images[IMAGE_DATA_TYPE_BYTE] = 0;
+		tex_start_images[IMAGE_DATA_TYPE_HALF4] = 0;
+		tex_start_images[IMAGE_DATA_TYPE_HALF] = 0;
 		assert(0);
 	}
 
@@ -230,6 +238,10 @@ string ImageManager::name_from_type(int type)
 		return "float";
 	else if(type == IMAGE_DATA_TYPE_BYTE)
 		return "byte";
+	else if(type == IMAGE_DATA_TYPE_HALF4)
+		return "half4";
+	else if(type == IMAGE_DATA_TYPE_HALF)
+		return "half";
 	else
 		return "byte4";
 }
@@ -265,11 +277,16 @@ int ImageManager::add_image(const string& filename,
 	if(type == IMAGE_DATA_TYPE_FLOAT || type == IMAGE_DATA_TYPE_FLOAT4)
 		is_float = true;
 
-	/* No single channel textures on CUDA (Fermi) and OpenCL, use available slots */
-	if(type == IMAGE_DATA_TYPE_FLOAT && tex_num_images[type] == 0)
+	/* No single channel and half textures on CUDA (Fermi) and OpenCL, use available slots */
+	if((type == IMAGE_DATA_TYPE_FLOAT ||
+	    type == IMAGE_DATA_TYPE_HALF4 ||
+	    type == IMAGE_DATA_TYPE_HALF) &&
+	    tex_num_images[type] == 0) {
 		type = IMAGE_DATA_TYPE_FLOAT4;
-	if(type == IMAGE_DATA_TYPE_BYTE && tex_num_images[type] == 0)
+	}
+	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++) {
@@ -645,6 +662,118 @@ bool ImageManager::file_load_float_image(Image *img, ImageDataType type, device_
 	return true;
 }
 
+template<typename T>
+bool ImageManager::file_load_half_image(Image *img, ImageDataType type, device_vector<T>& tex_img)
+{
+	ImageInput *in = NULL;
+	int width, height, depth, components;
+
+	if(!file_load_image_generic(img, &in, width, height, depth, components))
+		return false;
+
+	/* read RGBA pixels */
+	half *pixels = (half*)tex_img.resize(width, height, depth);
+	if(pixels == NULL) {
+		return false;
+	}
+	bool cmyk = false;
+
+	if(in) {
+		half *readpixels = pixels;
+		vector<half> tmppixels;
+
+		if(components > 4) {
+			tmppixels.resize(((size_t)width)*height*components);
+			readpixels = &tmppixels[0];
+		}
+
+		if(depth <= 1) {
+			int scanlinesize = width*components*sizeof(half);
+
+			in->read_image(TypeDesc::HALF,
+			               (uchar*)readpixels + (height-1)*scanlinesize, /*TODO(dingto): why uchar cast? */
+			               AutoStride,
+			               -scanlinesize,
+			               AutoStride);
+		}
+		else {
+			in->read_image(TypeDesc::HALF, (uchar*)readpixels);
+		}
+
+		if(components > 4) {
+			size_t dimensions = ((size_t)width)*height;
+			for(size_t i = dimensions-1, pixel = 0; pixel < dimensions; pixel++, i--) {
+				pixels[i*4+3] = tmppixels[i*components+3];
+				pixels[i*4+2] = tmppixels[i*components+2];
+				pixels[i*4+1] = tmppixels[i*components+1];
+				pixels[i*4+0] = tmppixels[i*components+0];
+			}
+
+			tmppixels.clear();
+		}
+
+		cmyk = strcmp(in->format_name(), "jpeg") == 0 && components == 4; /*TODO(dingto): kick, we wont have jpeg in half format ? */
+
+		in->close();
+		delete in;
+	}
+#if 0 /* TODO(dingto): add support for half here ? */
+	else {
+		builtin_image_float_pixels_cb(img->filename, img->builtin_data, pixels);
+	}
+#endif
+
+	/* Check if we actually have a half4 slot, in case components == 1, but device
+	 * doesn't support single channel textures. */
+	if(type == IMAGE_DATA_TYPE_FLOAT4) {
+		size_t num_pixels = ((size_t)width) * height * depth;
+		if(cmyk) {
+			/* CMYK */
+			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
+				pixels[i*4+3] = 255;
+				pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255;
+				pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255;
+				pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255;
+			}
+		}
+		else if(components == 2) {
+			/* grayscale + alpha */
+			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
+				pixels[i*4+3] = pixels[i*2+1];
+				pixels[i*4+2] = pixels[i*2+0];
+				pixels[i*4+1] = pixels[i*2+0];
+				pixels[i*4+0] = pixels[i*2+0];
+			}
+		}
+		else if(components == 3) {
+			/* RGB */
+			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
+				pixels[i*4+3] = 1.0f;
+				pixels[i*4+2] = pixels[i*3+2];
+				pixels[i*4+1] = pixels[i*3+1];
+				pixels[i*4+0] = pixels[i*3+0];
+			}
+		}
+		else if(components == 1) {
+			/* grayscale */
+			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
+				pixels[i*4+3] = 1.0f;
+				pixels[i*4+2] = pixels[i];
+				pixels[i*4+1] = pixels[i];
+				pixels[i*4+0] = pixels[i];
+			}
+		}
+
+		if(img->use_alpha == false) {
+			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
+				pixels[i*4+3] = 1.0f;
+			}
+		}
+	}
+
+	return true;
+}
+
 void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageDataType type, int slot, Progress *progress)
 {
 	if(progress->get_cancel())
@@ -744,7 +873,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
 			                  img->extension);
 		}
 	}
-	else {
+	else if(type == IMAGE_DATA_TYPE_BYTE){
 		device_vector<uchar>& tex_img = dscene->tex_byte_image[slot];
 
 		if(tex_img.device_pointer) {
@@ -767,6 +896,57 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
 			                  img->extension);
 		}
 	}
+	else if(type == IMAGE_DATA_TYPE_HALF4){
+		device_vector<half4>& tex_img = dscene->tex_half4_image[slot];
+
+		if(tex_img.device_pointer) {
+			thread_scoped_lock device_lock(device_mutex);
+			device->tex_free(tex_img);
+		}
+
+		if(!file_load_float_image(img, type, tex_img)) {
+			/* on failure to load, we set a 1x1 pixels pink image */
+			half4 *pixels = (half4*)tex_img.resize(1, 1);
+
+#if 0 /* TODO(dingto): Fix this... */
+			pixels[0] = (half)TEX_IMAGE_MISSING_R;
+			pixels[1] = (half)TEX_IMAGE_MISSING_G;
+			pixels[2] = (half)TEX_IMAGE_MISSING_B;
+			pixels[3] = (half)TEX_IMAGE_MISSING_A;
+#endif
+		}
+
+		if(!pack_images) {
+			thread_scoped_lock device_

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list