[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