Clamp unsigned floating-point formats.

GL_R11F_G11F_B10F is a renderable format (in the EXT_color_buffer_float
extension) with unsigned floating-point values, which we implement using
(signed) half- or single-precision floating-point types. So we need to
clamp values to a positive range before writing to them.

Change-Id: Ic21a5b0b33905c0aeab35299fc268158f8c679f9
Reviewed-on: https://swiftshader-review.googlesource.com/15448
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Renderer/Surface.cpp b/src/Renderer/Surface.cpp
index 4a4d543..4e2e26b 100644
--- a/src/Renderer/Surface.cpp
+++ b/src/Renderer/Surface.cpp
@@ -304,8 +304,12 @@
 			((half*)element)[0] = (half)r;
 			((half*)element)[1] = (half)g;
 			break;
+		case FORMAT_X16B16G16R16F_UNSIGNED:
+			r = max(r, 0.0f); g = max(g, 0.0f); b = max(b, 0.0f);
+			// Fall through to FORMAT_X16B16G16R16F.
 		case FORMAT_X16B16G16R16F:
 			((half*)element)[3] = 1.0f;
+			// Fall through to FORMAT_B16G16R16F.
 		case FORMAT_B16G16R16F:
 			((half*)element)[0] = (half)r;
 			((half*)element)[1] = (half)g;
@@ -327,8 +331,12 @@
 			((float*)element)[0] = r;
 			((float*)element)[1] = g;
 			break;
+		case FORMAT_X32B32G32R32F_UNSIGNED:
+			r = max(r, 0.0f); g = max(g, 0.0f); b = max(b, 0.0f);
+			// Fall through to FORMAT_X32B32G32R32F.
 		case FORMAT_X32B32G32R32F:
 			((float*)element)[3] = 1.0f;
+			// Fall through to FORMAT_B32G32R32F.
 		case FORMAT_B32G32R32F:
 			((float*)element)[0] = r;
 			((float*)element)[1] = g;
@@ -965,6 +973,7 @@
 			g = ((half*)element)[1];
 			break;
 		case FORMAT_X16B16G16R16F:
+		case FORMAT_X16B16G16R16F_UNSIGNED:
 		case FORMAT_B16G16R16F:
 			r = ((half*)element)[0];
 			g = ((half*)element)[1];
@@ -987,6 +996,7 @@
 			g = ((float*)element)[1];
 			break;
 		case FORMAT_X32B32G32R32F:
+		case FORMAT_X32B32G32R32F_UNSIGNED:
 		case FORMAT_B32G32R32F:
 			r = ((float*)element)[0];
 			g = ((float*)element)[1];
@@ -1659,12 +1669,14 @@
 		case FORMAT_B16G16R16F:			return 6;
 		case FORMAT_X16B16G16R16F:		return 8;
 		case FORMAT_A16B16G16R16F:		return 8;
+		case FORMAT_X16B16G16R16F_UNSIGNED: return 8;
 		case FORMAT_A32F:				return 4;
 		case FORMAT_R32F:				return 4;
 		case FORMAT_G32R32F:			return 8;
 		case FORMAT_B32G32R32F:			return 12;
 		case FORMAT_X32B32G32R32F:		return 16;
 		case FORMAT_A32B32G32R32F:		return 16;
+		case FORMAT_X32B32G32R32F_UNSIGNED: return 16;
 		// Depth/stencil formats
 		case FORMAT_D16:				return 2;
 		case FORMAT_D32:				return 4;
@@ -2897,11 +2909,13 @@
 		case FORMAT_B16G16R16F:
 		case FORMAT_X16B16G16R16F:
 		case FORMAT_A16B16G16R16F:
+		case FORMAT_X16B16G16R16F_UNSIGNED:
 		case FORMAT_R32F:
 		case FORMAT_G32R32F:
 		case FORMAT_B32G32R32F:
 		case FORMAT_X32B32G32R32F:
 		case FORMAT_A32B32G32R32F:
+		case FORMAT_X32B32G32R32F_UNSIGNED:
 		case FORMAT_D32F:
 		case FORMAT_D32FS8:
 		case FORMAT_D32F_COMPLEMENTARY:
@@ -2949,6 +2963,7 @@
 		case FORMAT_G32R32UI:
 		case FORMAT_X32B32G32R32UI:
 		case FORMAT_A32B32G32R32UI:
+		case FORMAT_X32B32G32R32F_UNSIGNED:
 		case FORMAT_R8UI:
 		case FORMAT_G8R8UI:
 		case FORMAT_X8B8G8R8UI:
@@ -3234,6 +3249,7 @@
 		case FORMAT_G32R32F:        return 2;
 		case FORMAT_X32B32G32R32F:  return 3;
 		case FORMAT_A32B32G32R32F:  return 4;
+		case FORMAT_X32B32G32R32F_UNSIGNED: return 3;
 		case FORMAT_D32F:           return 1;
 		case FORMAT_D32FS8:         return 1;
 		case FORMAT_D32F_LOCKABLE:  return 1;
@@ -3954,12 +3970,14 @@
 		case FORMAT_B16G16R16F:     return FORMAT_X32B32G32R32F;
 		case FORMAT_X16B16G16R16F:	return FORMAT_X32B32G32R32F;
 		case FORMAT_A16B16G16R16F:	return FORMAT_A32B32G32R32F;
+		case FORMAT_X16B16G16R16F_UNSIGNED: return FORMAT_X32B32G32R32F_UNSIGNED;
 		case FORMAT_A32F:			return FORMAT_A32B32G32R32F;
 		case FORMAT_R32F:			return FORMAT_R32F;
 		case FORMAT_G32R32F:		return FORMAT_G32R32F;
 		case FORMAT_B32G32R32F:     return FORMAT_X32B32G32R32F;
 		case FORMAT_X32B32G32R32F:  return FORMAT_X32B32G32R32F;
 		case FORMAT_A32B32G32R32F:	return FORMAT_A32B32G32R32F;
+		case FORMAT_X32B32G32R32F_UNSIGNED: return FORMAT_X32B32G32R32F_UNSIGNED;
 		// Luminance formats
 		case FORMAT_L8:				return FORMAT_L8;
 		case FORMAT_A4L4:			return FORMAT_A8L8;
@@ -5533,7 +5551,9 @@
 				else ASSERT(false);
 			}
 		}
-		else if(internal.format == FORMAT_A32B32G32R32F || internal.format == FORMAT_X32B32G32R32F)
+		else if(internal.format == FORMAT_A32B32G32R32F ||
+		        internal.format == FORMAT_X32B32G32R32F ||
+		        internal.format == FORMAT_X32B32G32R32F_UNSIGNED)
 		{
 			#if defined(__i386__) || defined(__x86_64__)
 				if(CPUID::supportsSSE())