Implemented support for RGB10_A2 in blitter

Added RGB10_A2 implementation in the Blitter and cases in
related Surface utility functions.

Change-Id: I2b1a9cdc1acc605085fb0f853741cc2f75bf1c9b
Reviewed-on: https://swiftshader-review.googlesource.com/4420
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/Renderer/Blitter.cpp b/src/Renderer/Blitter.cpp
index c53d9c7..df934f3 100644
--- a/src/Renderer/Blitter.cpp
+++ b/src/Renderer/Blitter.cpp
@@ -276,6 +276,12 @@
 			c.y = Float(Int((*Pointer<UShort>(element) & UShort(0x07E0)) >> UShort(5)));
 			c.z = Float(Int(*Pointer<UShort>(element) & UShort(0x001F)));
 			break;
+		case FORMAT_A2B10G10R10:
+			c.x = Float(Int((*Pointer<UInt>(element) & UInt(0x000003FF))));
+			c.y = Float(Int((*Pointer<UInt>(element) & UInt(0x000FFC00)) >> 10));
+			c.z = Float(Int((*Pointer<UInt>(element) & UInt(0x3FF00000)) >> 20));
+			c.w = Float(Int((*Pointer<UInt>(element) & UInt(0xC0000000)) >> 30));
+			break;
 		default:
 			return false;
 		}
@@ -589,6 +595,28 @@
 				                                   (RoundInt(Float(c.x)) << Int(11))) & UShort(mask));
 			}
 			break;
+		case FORMAT_A2B10G10R10:
+			if(writeRGBA)
+			{
+				*Pointer<UInt>(element) = UInt(RoundInt(Float(c.x)) |
+				                              (RoundInt(Float(c.y)) << 10) |
+				                              (RoundInt(Float(c.z)) << 20) |
+				                              (RoundInt(Float(c.w)) << 30));
+			}
+			else
+			{
+				unsigned int mask = (writeA ? 0xC0000000 : 0x0000) |
+				                    (writeB ? 0x3FF00000 : 0x0000) |
+				                    (writeG ? 0x000FFC00 : 0x0000) |
+				                    (writeR ? 0x000003FF : 0x0000);
+				unsigned int unmask = ~mask;
+				*Pointer<UInt>(element) = (*Pointer<UInt>(element) & UInt(unmask)) |
+				                            (UInt(RoundInt(Float(c.x)) |
+				                                  (RoundInt(Float(c.y)) << 10) |
+				                                  (RoundInt(Float(c.z)) << 20) |
+				                                  (RoundInt(Float(c.w)) << 30)) & UInt(mask));
+			}
+			break;
 		default:
 			return false;
 		}
@@ -839,6 +867,9 @@
 		case FORMAT_A8B8G8R8I_SNORM:
 			scale = vector(0x7F, 0x7F, 0x7F, 0x7F);
 			break;
+		case FORMAT_A16B16G16R16:
+			scale = vector(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
+			break;
 		case FORMAT_R8I:
 		case FORMAT_R8UI:
 		case FORMAT_G8R8I:
@@ -854,7 +885,6 @@
 		case FORMAT_G16R16UI:
 		case FORMAT_X16B16G16R16I:
 		case FORMAT_X16B16G16R16UI:
-		case FORMAT_A16B16G16R16:
 		case FORMAT_A16B16G16R16I:
 		case FORMAT_A16B16G16R16UI:
 		case FORMAT_R32I:
@@ -873,6 +903,9 @@
 		case FORMAT_R5G6B5:
 			scale = vector(0x1F, 0x3F, 0x1F, 1.0f);
 			break;
+		case FORMAT_A2B10G10R10:
+			scale = vector(0x3FF, 0x3FF, 0x3FF, 0x03);
+			break;
 		default:
 			return false;
 		}
diff --git a/src/Renderer/Surface.cpp b/src/Renderer/Surface.cpp
index a1b3ef7..a86e3c4 100644
--- a/src/Renderer/Surface.cpp
+++ b/src/Renderer/Surface.cpp
@@ -2649,6 +2649,7 @@
 		case FORMAT_A8B8G8R8:
 		case FORMAT_G8R8I:
 		case FORMAT_G8R8:
+		case FORMAT_A2B10G10R10:
 		case FORMAT_R8I_SNORM:
 		case FORMAT_G8R8I_SNORM:
 		case FORMAT_X8B8G8R8I_SNORM:
@@ -2720,6 +2721,7 @@
 		case FORMAT_A8R8G8B8:
 		case FORMAT_A8B8G8R8:
 		case FORMAT_G8R8:
+		case FORMAT_A2B10G10R10:
 		case FORMAT_R16UI:
 		case FORMAT_G16R16:
 		case FORMAT_G16R16UI:
@@ -2943,6 +2945,7 @@
 		case FORMAT_G8R8UI:         return 2;
 		case FORMAT_X8B8G8R8UI:     return 3;
 		case FORMAT_A8B8G8R8UI:     return 4;
+		case FORMAT_A2B10G10R10:    return 4;
 		case FORMAT_G16R16I:        return 2;
 		case FORMAT_G16R16UI:       return 2;
 		case FORMAT_G16R16:         return 2;
@@ -3461,14 +3464,14 @@
 			return FORMAT_R32I;
 		case FORMAT_R32UI:
 			return FORMAT_R32UI;
-		case FORMAT_A2R10G10B10:
-		case FORMAT_A2B10G10R10:
 		case FORMAT_X16B16G16R16I:
 		case FORMAT_A16B16G16R16I:
 			return FORMAT_A16B16G16R16I;
 		case FORMAT_X16B16G16R16UI:
 		case FORMAT_A16B16G16R16UI:
 			return FORMAT_A16B16G16R16UI;
+		case FORMAT_A2R10G10B10:
+		case FORMAT_A2B10G10R10:
 		case FORMAT_A16B16G16R16:
 			return FORMAT_A16B16G16R16;
 		case FORMAT_X32B32G32R32I: