[Bf-blender-cvs] [f591e82] soc-2016-cycles_images: Half float: Half EXR now uses a half4 slot on CPU.

Thomas Dinges noreply at git.blender.org
Thu Jun 2 00:45:00 CEST 2016


Commit: f591e825675472a317cff6ded43dab84689e9ee7
Author: Thomas Dinges
Date:   Thu Jun 2 00:43:01 2016 +0200
Branches: soc-2016-cycles_images
https://developer.blender.org/rBf591e825675472a317cff6ded43dab84689e9ee7

Half float: Half EXR now uses a half4 slot on CPU.

Code in util_half.h inspired by work from Lukas Stockner.

Still a lot missing (GPU, Data Textures...).

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

M	intern/cycles/kernel/kernel_compat_cpu.h
M	intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h
M	intern/cycles/render/image.cpp
M	intern/cycles/util/util_half.h

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

diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h
index b7177ab..c882b47 100644
--- a/intern/cycles/kernel/kernel_compat_cpu.h
+++ b/intern/cycles/kernel/kernel_compat_cpu.h
@@ -122,6 +122,17 @@ template<typename T> struct texture_image  {
 		return make_float4(r, r, r, 1.0f);
 	}
 
+	ccl_always_inline float4 read(half4 r)
+	{
+		return half4_to_float4(r);
+	}
+
+	ccl_always_inline float4 read(half r)
+	{
+		float f = half_to_float(r);
+		return make_float4(f, f, f, 1.0f);
+	}
+
 	ccl_always_inline int wrap_periodic(int x, int width)
 	{
 		x %= width;
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h
index b10861a..4738314 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h
+++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h
@@ -23,7 +23,11 @@ CCL_NAMESPACE_BEGIN
 
 ccl_device float4 kernel_tex_image_interp_impl(KernelGlobals *kg, int tex, float x, float y)
 {
-	if(tex >= TEX_START_BYTE_CPU)
+	if(tex >= TEX_START_HALF_CPU)
+		return kg->texture_half_images[tex - TEX_START_HALF_CPU].interp(x, y);
+	else if(tex >= TEX_START_HALF4_CPU)
+		return kg->texture_half4_images[tex - TEX_START_HALF4_CPU].interp(x, y);
+	else if(tex >= TEX_START_BYTE_CPU)
 		return kg->texture_byte_images[tex - TEX_START_BYTE_CPU].interp(x, y);
 	else if(tex >= TEX_START_FLOAT_CPU)
 		return kg->texture_float_images[tex - TEX_START_FLOAT_CPU].interp(x, y);
@@ -35,7 +39,11 @@ ccl_device float4 kernel_tex_image_interp_impl(KernelGlobals *kg, int tex, float
 
 ccl_device float4 kernel_tex_image_interp_3d_impl(KernelGlobals *kg, int tex, float x, float y, float z)
 {
-	if(tex >= TEX_START_BYTE_CPU)
+	if(tex >= TEX_START_HALF_CPU)
+		return kg->texture_half_images[tex - TEX_START_HALF_CPU].interp_3d(x, y, z);
+	else if(tex >= TEX_START_HALF4_CPU)
+		return kg->texture_half4_images[tex - TEX_START_HALF4_CPU].interp_3d(x, y, z);
+	else if(tex >= TEX_START_BYTE_CPU)
 		return kg->texture_byte_images[tex - TEX_START_BYTE_CPU].interp_3d(x, y, z);
 	else if(tex >= TEX_START_FLOAT_CPU)
 		return kg->texture_float_images[tex - TEX_START_FLOAT_CPU].interp_3d(x, y, z);
@@ -48,7 +56,11 @@ ccl_device float4 kernel_tex_image_interp_3d_impl(KernelGlobals *kg, int tex, fl
 
 ccl_device float4 kernel_tex_image_interp_3d_ex_impl(KernelGlobals *kg, int tex, float x, float y, float z, int interpolation)
 {
-	if(tex >= TEX_START_BYTE_CPU)
+	if(tex >= TEX_START_HALF_CPU)
+		return kg->texture_half4_images[tex - TEX_START_HALF_CPU].interp_3d_ex(x, y, z, interpolation);
+	else if(tex >= TEX_START_HALF4_CPU)
+		return kg->texture_half_images[tex - TEX_START_HALF4_CPU].interp_3d_ex(x, y, z, interpolation);
+	else if(tex >= TEX_START_BYTE_CPU)
 		return kg->texture_byte_images[tex - TEX_START_BYTE_CPU].interp_3d_ex(x, y, z, interpolation);
 	else if(tex >= TEX_START_FLOAT_CPU)
 		return kg->texture_float_images[tex - TEX_START_FLOAT_CPU].interp_3d_ex(x, y, z, interpolation);
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 892a33b..0332aa5 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -136,7 +136,7 @@ ImageManager::ImageDataType ImageManager::get_image_metadata(const string& filen
                                                              void *builtin_data,
                                                              bool& is_linear)
 {
-	bool is_float = false;
+	bool is_float = false, is_half = false;
 	is_linear = false;
 	int channels = 4;
 
@@ -175,6 +175,10 @@ ImageManager::ImageDataType ImageManager::get_image_metadata(const string& filen
 				}
 			}
 
+			/* check if it's half float */
+			if(spec.format == TypeDesc::HALF)
+				is_half = true;
+
 			channels = spec.nchannels;
 
 			/* basic color space detection, not great but better than nothing
@@ -200,7 +204,10 @@ ImageManager::ImageDataType ImageManager::get_image_metadata(const string& filen
 		delete in;
 	}
 
-	if(is_float) {
+	if(is_half) {
+		return IMAGE_DATA_TYPE_HALF4;
+	}
+	else if(is_float) {
 		return (channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
 	}
 	else {
@@ -894,7 +901,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
 			device->tex_free(tex_img);
 		}
 
-		if(!file_load_float_image(img, type, tex_img)) {
+		if(!file_load_half_image(img, type, tex_img)) {
 			/* on failure to load, we set a 1x1 pixels pink image */
 			half *pixels = (half*)tex_img.resize(1, 1);
 
@@ -920,7 +927,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
 			device->tex_free(tex_img);
 		}
 
-		if(!file_load_float_image(img, type, tex_img)) {
+		if(!file_load_half_image(img, type, tex_img)) {
 			/* on failure to load, we set a 1x1 pixels pink image */
 			half *pixels = (half*)tex_img.resize(1, 1);
 
diff --git a/intern/cycles/util/util_half.h b/intern/cycles/util/util_half.h
index f4bac98..dc02135 100644
--- a/intern/cycles/util/util_half.h
+++ b/intern/cycles/util/util_half.h
@@ -30,6 +30,7 @@ CCL_NAMESPACE_BEGIN
 #ifdef __KERNEL_OPENCL__
 
 #define float4_store_half(h, f, scale) vstore_half4(f * (scale), 0, h);
+#define half4_to_float4(h) vload_half4(0, h);
 
 #else
 
@@ -46,6 +47,11 @@ ccl_device_inline void float4_store_half(half *h, float4 f, float scale)
 	h[3] = __float2half_rn(f.w * scale);
 }
 
+ccl_device_inline float4 half4_to_float4(half *h)
+{
+    return make_float4(__half2float(h[0]), __half2float(h[1]), __half2float(h[2]), __half2float(h[3]));
+}
+
 #else
 
 ccl_device_inline void float4_store_half(half *h, float4 f, float scale)
@@ -85,6 +91,28 @@ ccl_device_inline void float4_store_half(half *h, float4 f, float scale)
 #endif
 }
 
+/* TODO(dingto) Verify this */
+ccl_device_inline float4 half4_to_float4(half4 h)
+{
+	float4 f;
+
+	*((int*) &f.x) = ((h.x & 0x8000) << 16) | (((h.x & 0x7c00) + 0x1C000) << 13) | ((h.x & 0x03FF) << 13);
+	*((int*) &f.y) = ((h.y & 0x8000) << 16) | (((h.y & 0x7c00) + 0x1C000) << 13) | ((h.y & 0x03FF) << 13);
+	*((int*) &f.z) = ((h.z & 0x8000) << 16) | (((h.z & 0x7c00) + 0x1C000) << 13) | ((h.z & 0x03FF) << 13);
+	*((int*) &f.w) = ((h.w & 0x8000) << 16) | (((h.w & 0x7c00) + 0x1C000) << 13) | ((h.w & 0x03FF) << 13);
+
+	return f;
+}
+
+ccl_device_inline float half_to_float(half h)
+{
+	float f;
+
+	*((int*) &f) = ((h & 0x8000) << 16) | (((h & 0x7c00) + 0x1C000) << 13) | ((h & 0x03FF) << 13);
+
+	return f;
+}
+
 #endif
 
 #endif




More information about the Bf-blender-cvs mailing list