Commit: 68d41c95aed7a212edb3766ec85358daf294aec4
Author: Thomas Dinges
Date:   Fri Jun 17 23:16:31 2016 +0200
Branches: soc-2016-cycles_images
https://developer.blender.org/rB68d41c95aed7a212edb3766ec85358daf294aec4

Add float to half conversion code, which can be used on CPU to convert float 
textures slots to half.

Still need to hook these up with actual Image Manager.

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

M       intern/cycles/util/util_half.h

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

diff --git a/intern/cycles/util/util_half.h b/intern/cycles/util/util_half.h
index 724c406..114cc55 100644
--- a/intern/cycles/util/util_half.h
+++ b/intern/cycles/util/util_half.h
@@ -38,11 +38,14 @@ struct half4 { half x, y, z, w; };
 #endif
 
 /* Float <-> Half conversion.
- * We define three main functions for each architecture.
- * Half data is always loaded / written via pointers.
+ * We define three main functions for each architecture:
  * float4_store_half()
  * half_to_float()
  * half_to_float4()
+ *
+ * Additionally we have a function which only run on the CPU, and converts 
float to half data,
+ * as used for textures.
+ * float_to_half()
  */
 
 /* OpenCL */
@@ -139,6 +142,115 @@ ccl_device_inline float4 half4_to_float4(half4 h)
 
        return f;
 }
+#endif
+
+/* Float to half conversion, CPU only */
+#ifndef __KERNEL_GPU__
+
+/* Code from https://gist.github.com/rygorous/2156668, CC0 */
+union FP32
+{
+       uint u;
+       float f;
+       struct
+       {
+               uint Mantissa : 23;
+               uint Exponent : 8;
+               uint Sign : 1;
+       };
+};
+
+union FP16
+{
+       half u;
+       struct
+       {
+               uint Mantissa : 10;
+               uint Exponent : 5;
+               uint Sign : 1;
+       };
+};
+
+static FP16 float_to_half_fast(FP32 f)
+{
+       FP16 o = { 0 };
+
+       /* Based on ISPC reference code (with minor modifications) */
+       if(f.Exponent == 255) { /* Inf or NaN (all exponent bits set) */
+               o.Exponent = 31;
+               o.Mantissa = f.Mantissa ? 0x200 : 0; // NaN->qNaN and Inf->Inf
+       }
+       else { /* Normalized number */
+               /* Exponent unbias the single, then bias the halfp */
+               int newexp = f.Exponent - 127 + 15;
+
+               if(newexp >= 31) /* Overflow, return signed infinity */
+                       o.Exponent = 31;
+               else if(newexp <= 0) { /* Underflow */
+                       if((14 - newexp) <= 24) { /* Mantissa might be non-zero 
*/
+                               uint mant = f.Mantissa | 0x800000; /* Hidden 1 
bit */
+                               o.Mantissa = mant >> (14 - newexp);
+                               if((mant >> (13 - newexp)) & 1) /* Check for 
rounding */
+                                       o.u++; /* Round, might overflow into 
exp bit, but this is OK */
+                       }
+               }
+               else {
+                       o.Exponent = newexp;
+                       o.Mantissa = f.Mantissa >> 13;
+                       if(f.Mantissa & 0x1000) /* Check for rounding */
+                               o.u++; /* Round, might overflow to inf, this is 
OK */
+               }
+       }
+
+       o.Sign = f.Sign;
+       return o;
+}
+
+static FP16 float_to_half_fast2(FP32 f)
+{
+       FP32 infty = { 31 << 23 };
+       FP32 magic = { 15 << 23 };
+       FP16 o = { 0 };
+
+       uint sign = f.Sign;
+       f.Sign = 0;
+
+       /* Based on ISPC reference code (with minor modifications) */
+    if(f.Exponent == 255) { /* Inf or NaN (all exponent bits set) */
+               o.Exponent = 31;
+               o.Mantissa = f.Mantissa ? 0x200 : 0; // NaN->qNaN and Inf->Inf
+       }
+       else { /* (De)normalized number or zero */
+               f.u &= ~0xfff; // Make sure we don't get sticky bits
+
+               f.f *= magic.f;
+
+               f.u += 0x1000; /* Rounding bias */
+               if(f.u > infty.u) f.u = infty.u; /* Clamp to signed infinity if 
overflowed */
+
+               o.u = f.u >> 13; /* Take the bits! */
+       }
+
+       o.Sign = sign;
+       return o;
+}
+
+
+ccl_device_inline half float_to_half(float f)
+{
+       FP32 fp;
+       fp.f = f;
+
+       FP16 h = float_to_half_fast(fp);
+
+       return h.u;
+}
+
+ccl_device void print_half(float f)
+{
+       std::cout << "Float" << f << std::endl;
+       std::cout << "Half" << float_to_half(f) << std::endl;
+}
 
 #endif

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to