Add 6-bit and 5-bit sRGB conversion.

Bug 20891368

Change-Id: I3b7066f20f0e669dc1d3abe9222654318ae3b011
Reviewed-on: https://swiftshader-review.googlesource.com/3114
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/Shader/Constants.cpp b/src/Shader/Constants.cpp
index 88a6a81..c9965ff 100644
--- a/src/Shader/Constants.cpp
+++ b/src/Shader/Constants.cpp
@@ -22,11 +22,6 @@
 
 	Constants::Constants()
 	{
-		for(int i = 0; i < 256; i++)
-		{
-			sRGBtoLinear8[i] = (unsigned short)(sw::sRGBtoLinear((float)i / 0xFF) * 0x1000 + 0.5f);
-		}
-
 		static const unsigned int transposeBit0[16] =
 		{
 			0x00000000,
@@ -266,10 +261,25 @@
 			invMaskD01X[i][3] =  ~-(i >> 1 & 1);
 		}
 
+		for(int i = 0; i < 256; i++)
+		{
+			sRGBtoLinear8_12[i] = (unsigned short)(sw::sRGBtoLinear((float)i / 0xFF) * 0x1000 + 0.5f);
+		}
+
+		for(int i = 0; i < 64; i++)
+		{
+			sRGBtoLinear6_12[i] = (unsigned short)(sw::sRGBtoLinear((float)i / 0x3F) * 0x1000 + 0.5f);
+		}
+
+		for(int i = 0; i < 32; i++)
+		{
+			sRGBtoLinear5_12[i] = (unsigned short)(sw::sRGBtoLinear((float)i / 0x1F) * 0x1000 + 0.5f);
+		}
+
 		for(int i = 0; i < 0x1000; i++)
 		{
-			linToSRGB12_16[i] = (unsigned short)(clamp(sw::linearToSRGB((float)i / 0x0FFF) * 0xFFFF + 0.5f, 0.0f, (float)0xFFFF));
-			sRGBtoLin12_16[i] = (unsigned short)(clamp(sw::sRGBtoLinear((float)i / 0x0FFF) * 0xFFFF + 0.5f, 0.0f, (float)0xFFFF));
+			linearToSRGB12_16[i] = (unsigned short)(clamp(sw::linearToSRGB((float)i / 0x0FFF) * 0xFFFF + 0.5f, 0.0f, (float)0xFFFF));
+			sRGBtoLinear12_16[i] = (unsigned short)(clamp(sw::sRGBtoLinear((float)i / 0x0FFF) * 0xFFFF + 0.5f, 0.0f, (float)0xFFFF));
 		}
 
 		for(int q = 0; q < 4; q++)
diff --git a/src/Shader/Constants.hpp b/src/Shader/Constants.hpp
index a4adc3e..c556b5e 100644
--- a/src/Shader/Constants.hpp
+++ b/src/Shader/Constants.hpp
@@ -19,9 +19,7 @@
 	struct Constants

 	{

 		Constants();

-

-		unsigned short sRGBtoLinear8[256];

-

+		

 		unsigned int transposeBit0[16];

 		unsigned int transposeBit1[16];

 		unsigned int transposeBit2[16];

@@ -67,8 +65,12 @@
 		dword4 maskD01X[4];

 		dword4 invMaskD01X[4];

 

-		unsigned short linToSRGB12_16[4096];

-		unsigned short sRGBtoLin12_16[4096];

+		unsigned short sRGBtoLinear8_12[256];

+		unsigned short sRGBtoLinear6_12[64];

+		unsigned short sRGBtoLinear5_12[32];

+

+		unsigned short linearToSRGB12_16[4096];

+		unsigned short sRGBtoLinear12_16[4096];

 

 		// Centroid parameters

 		float4 sampleX[4][16];

diff --git a/src/Shader/PixelRoutine.cpp b/src/Shader/PixelRoutine.cpp
index dda011a..773ceaf 100644
--- a/src/Shader/PixelRoutine.cpp
+++ b/src/Shader/PixelRoutine.cpp
@@ -2561,7 +2561,7 @@
 
 		if(postBlendSRGB && state.writeSRGB)
 		{
-			sRGBtoLinear16_16(r, pixel);	
+			sRGBtoLinear16_12_16(r, pixel);	
 		}
 
 		// Final Color = ObjectColor * SourceBlendFactor + PixelColor * DestinationBlendFactor
@@ -2682,7 +2682,7 @@
 
 		if(postBlendSRGB && state.writeSRGB)
 		{
-			linearToSRGB16_16(r, current);
+			linearToSRGB16_12_16(r, current);
 		}
 
 		if(exactColorRounding)
@@ -4365,7 +4365,7 @@
 		return Float4(cs) * Float4(1.0f / 0xFFFF);
 	}
 
-	void PixelRoutine::sRGBtoLinear16_16(Registers &r, Vector4s &c)
+	void PixelRoutine::sRGBtoLinear16_12_16(Registers &r, Vector4s &c)
 	{
 		c.x = As<UShort4>(c.x) >> 4;
 		c.y = As<UShort4>(c.y) >> 4;
@@ -4376,7 +4376,7 @@
 
 	void PixelRoutine::sRGBtoLinear12_16(Registers &r, Vector4s &c)
 	{
-		Pointer<Byte> LUT = r.constants + OFFSET(Constants,sRGBtoLin12_16);
+		Pointer<Byte> LUT = r.constants + OFFSET(Constants,sRGBtoLinear12_16);
 
 		c.x = Insert(c.x, *Pointer<Short>(LUT + 2 * Int(Extract(c.x, 0))), 0);
 		c.x = Insert(c.x, *Pointer<Short>(LUT + 2 * Int(Extract(c.x, 1))), 1);
@@ -4394,7 +4394,7 @@
 		c.z = Insert(c.z, *Pointer<Short>(LUT + 2 * Int(Extract(c.z, 3))), 3);
 	}
 
-	void PixelRoutine::linearToSRGB16_16(Registers &r, Vector4s &c)
+	void PixelRoutine::linearToSRGB16_12_16(Registers &r, Vector4s &c)
 	{
 		c.x = As<UShort4>(c.x) >> 4;
 		c.y = As<UShort4>(c.y) >> 4;
@@ -4405,7 +4405,7 @@
 
 	void PixelRoutine::linearToSRGB12_16(Registers &r, Vector4s &c)
 	{
-		Pointer<Byte> LUT = r.constants + OFFSET(Constants,linToSRGB12_16);
+		Pointer<Byte> LUT = r.constants + OFFSET(Constants,linearToSRGB12_16);
 
 		c.x = Insert(c.x, *Pointer<Short>(LUT + 2 * Int(Extract(c.x, 0))), 0);
 		c.x = Insert(c.x, *Pointer<Short>(LUT + 2 * Int(Extract(c.x, 1))), 1);
diff --git a/src/Shader/PixelRoutine.hpp b/src/Shader/PixelRoutine.hpp
index 8331e43..2bde76f 100644
--- a/src/Shader/PixelRoutine.hpp
+++ b/src/Shader/PixelRoutine.hpp
@@ -198,9 +198,9 @@
 		Float4 convertUnsigned16(UShort4 cs);
 		UShort4 convertFixed16(Float4 &cf, bool saturate = true);
 		void convertFixed16(Vector4s &cs, Vector4f &cf, bool saturate = true);
-		void sRGBtoLinear16_16(Registers &r, Vector4s &c);
+		void sRGBtoLinear16_12_16(Registers &r, Vector4s &c);
 		void sRGBtoLinear12_16(Registers &r, Vector4s &c);
-		void linearToSRGB16_16(Registers &r, Vector4s &c);
+		void linearToSRGB16_12_16(Registers &r, Vector4s &c);
 		void linearToSRGB12_16(Registers &r, Vector4s &c);
 		Float4 sRGBtoLinear(const Float4 &x);
 		Float4 linearToSRGB(const Float4 &x);
diff --git a/src/Shader/SamplerCore.cpp b/src/Shader/SamplerCore.cpp
index b6d5838..d43f775 100644
--- a/src/Shader/SamplerCore.cpp
+++ b/src/Shader/SamplerCore.cpp
@@ -110,7 +110,7 @@
 				{
 					if(state.sRGB && isRGBComponent(component))
 					{
-						sRGBtoLinear16_12(c[component]);   // FIXME: Perform linearization at surface level for read-only textures
+						sRGBtoLinear16_8_12(c[component]);   // FIXME: Perform linearization at surface level for read-only textures
 					}
 					else
 					{
@@ -265,7 +265,7 @@
 				{
 					if(state.sRGB && isRGBComponent(component))
 					{
-						sRGBtoLinear16_12(cs[component]);   // FIXME: Perform linearization at surface level for read-only textures
+						sRGBtoLinear16_8_12(cs[component]);   // FIXME: Perform linearization at surface level for read-only textures
 						convertSigned12(c[component], cs[component]);
 					}
 					else
@@ -1775,11 +1775,35 @@
 		cf = Float4(As<UShort4>(cs)) * Float4(1.0f / 0xFFFF);
 	}
 
-	void SamplerCore::sRGBtoLinear16_12(Short4 &c)
+	void SamplerCore::sRGBtoLinear16_8_12(Short4 &c)
 	{
 		c = As<UShort4>(c) >> 8;
 
-		Pointer<Byte> LUT = Pointer<Byte>(constants + OFFSET(Constants,sRGBtoLinear8));
+		Pointer<Byte> LUT = Pointer<Byte>(constants + OFFSET(Constants,sRGBtoLinear8_12));
+
+		c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 0))), 0);
+		c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 1))), 1);
+		c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 2))), 2);
+		c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 3))), 3);
+	}
+
+	void SamplerCore::sRGBtoLinear16_6_12(Short4 &c)
+	{
+		c = As<UShort4>(c) >> 10;
+
+		Pointer<Byte> LUT = Pointer<Byte>(constants + OFFSET(Constants,sRGBtoLinear6_12));
+
+		c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 0))), 0);
+		c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 1))), 1);
+		c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 2))), 2);
+		c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 3))), 3);
+	}
+
+	void SamplerCore::sRGBtoLinear16_5_12(Short4 &c)
+	{
+		c = As<UShort4>(c) >> 11;
+
+		Pointer<Byte> LUT = Pointer<Byte>(constants + OFFSET(Constants,sRGBtoLinear5_12));
 
 		c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 0))), 0);
 		c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 1))), 1);
diff --git a/src/Shader/SamplerCore.hpp b/src/Shader/SamplerCore.hpp
index 7adb464..8a4874c 100644
--- a/src/Shader/SamplerCore.hpp
+++ b/src/Shader/SamplerCore.hpp
@@ -53,7 +53,9 @@
 		void convertSigned12(Float4 &cf, Short4 &ci);

 		void convertSigned15(Float4 &cf, Short4 &ci);

 		void convertUnsigned16(Float4 &cf, Short4 &ci);

-		void sRGBtoLinear16_12(Short4 &c);

+		void sRGBtoLinear16_8_12(Short4 &c);

+		void sRGBtoLinear16_6_12(Short4 &c);

+		void sRGBtoLinear16_5_12(Short4 &c);

 

 		bool hasFloatTexture() const;

 		bool hasUnsignedTextureComponent(int component) const;