Turn BC6 constructors into constexpr

jmadill pointed out that we could do away with runtime construction of
BC6 entirely by using constexpr constructors. This way we can have a
global object that doesn't incur runtime overhead or invoke a destructor
upon program exit.

Bug: b/174782098
Tests: dEQP-VK.*bc6*
Change-Id: I98fc2082232fdf2c485242be5ac94c97ebfd1bd8
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/56668
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Sean Risser <srisser@google.com>
Commit-Queue: Sean Risser <srisser@google.com>
diff --git a/src/Device/BC_Decoder.cpp b/src/Device/BC_Decoder.cpp
index 865c356..325efdb 100644
--- a/src/Device/BC_Decoder.cpp
+++ b/src/Device/BC_Decoder.cpp
@@ -649,18 +649,14 @@
 {
 	size_t channel[3];
 
-	DeltaBits()
+	constexpr DeltaBits()
+	    : channel{ 0, 0, 0 }
 	{
-		channel[R] = 0;
-		channel[G] = 0;
-		channel[B] = 0;
 	}
 
-	DeltaBits(int r, int g, int b)
+	constexpr DeltaBits(size_t r, size_t g, size_t b)
+	    : channel{ r, g, b }
 	{
-		channel[R] = r;
-		channel[G] = g;
-		channel[B] = b;
 	}
 };
 
@@ -670,26 +666,23 @@
 	bool hasDelta;
 	int partitionCount;
 	int endpointBits;
-	int numEndpoints;
 	DeltaBits deltaBits;
 
-	ModeDesc()
+	constexpr ModeDesc()
 	    : number(-1)
 	    , hasDelta(false)
 	    , partitionCount(0)
 	    , endpointBits(0)
-	    , numEndpoints(0)
 	{
 	}
 
-	ModeDesc(int number, bool hasDelta, int partitionCount, int endpointBits, DeltaBits deltaBits)
+	constexpr ModeDesc(int number, bool hasDelta, int partitionCount, int endpointBits, DeltaBits deltaBits)
 	    : number(number)
 	    , hasDelta(hasDelta)
 	    , partitionCount(partitionCount)
 	    , endpointBits(endpointBits)
 	    , deltaBits(deltaBits)
 	{
-		numEndpoints = partitionCount * 2;
 	}
 };
 
@@ -701,9 +694,16 @@
 	int LSB;
 	ModeDesc modeDesc;
 
-	BlockDesc() = default;
+	constexpr BlockDesc()
+	    : type(End)
+	    , channel(None)
+	    , MSB(0)
+	    , LSB(0)
+	    , modeDesc()
+	{
+	}
 
-	BlockDesc(DataType type, Channel channel, int MSB, int LSB, ModeDesc modeDesc)
+	constexpr BlockDesc(const DataType type, Channel channel, int MSB, int LSB, ModeDesc modeDesc)
 	    : type(type)
 	    , channel(channel)
 	    , MSB(MSB)
@@ -712,11 +712,12 @@
 	{
 	}
 
-	BlockDesc(DataType type, Channel channel, int MSB, int LSB)
+	constexpr BlockDesc(DataType type, Channel channel, int MSB, int LSB)
 	    : type(type)
 	    , channel(channel)
 	    , MSB(MSB)
 	    , LSB(LSB)
+	    , modeDesc()
 	{
 	}
 };
@@ -763,183 +764,173 @@
 //     the variable is min(LSB, MSB).
 //
 // Invalid or reserved modes return an empty list.
-const BlockDesc *getBlockDesc(uint8_t mode)
-{
-	static constexpr int NumBlocks = 14;
-	// The largest number of descriptions within a block.
-	static constexpr int MaxBlockDescIndex = 26;
-	static const BlockDesc blockDescs[NumBlocks][MaxBlockDescIndex] = {
-		// clang-format off
-		// Mode 0, Index 0
-		{
-			{ Mode, None, 1, 0, { 0, true, 2, 10, { 5, 5, 5 } } },
-			{ EP2, G, 4, 4 }, { EP2, B, 4, 4 }, { EP3, B, 4, 4 },
-			{ EP0, R, 9, 0 }, { EP0, G, 9, 0 }, { EP0, B, 9, 0 },
-			{ EP1, R, 4, 0 }, { EP3, G, 4, 4 }, { EP2, G, 3, 0 },
-			{ EP1, G, 4, 0 }, { EP3, B, 0, 0 }, { EP3, G, 3, 0 },
-			{ EP1, B, 4, 0 }, { EP3, B, 1, 1 }, { EP2, B, 3, 0 },
-			{ EP2, R, 4, 0 }, { EP3, B, 2, 2 }, { EP3, R, 4, 0 },
-			{ EP3, B, 3, 3 },
-			{ Partition, None, 4, 0 },
-			{ End, None, 0, 0},
-		},
-		// Mode 1, Index 1
-		{
-			{ Mode, None, 1, 0, { 1, true, 2, 7, { 6, 6, 6 } } },
-			{ EP2, G, 5, 5 }, { EP3, G, 5, 4 }, { EP0, R, 6, 0 },
-			{ EP3, B, 1, 0 }, { EP2, B, 4, 4 }, { EP0, G, 6, 0 },
-			{ EP2, B, 5, 5 }, { EP3, B, 2, 2 }, { EP2, G, 4, 4 },
-			{ EP0, B, 6, 0 }, { EP3, B, 3, 3 }, { EP3, B, 5, 5 },
-			{ EP3, B, 4, 4 }, { EP1, R, 5, 0 }, { EP2, G, 3, 0 },
-			{ EP1, G, 5, 0 }, { EP3, G, 3, 0 }, { EP1, B, 5, 0 },
-			{ EP2, B, 3, 0 }, { EP2, R, 5, 0 }, { EP3, R, 5, 0 },
-			{ Partition, None, 4, 0 },
-			{ End, None, 0, 0},
-		},
-		// Mode 2, Index 2
-		{
-			{ Mode, None, 4, 0, { 2, true, 2, 11, { 5, 4, 4 } } },
-			{ EP0, R, 9, 0 }, { EP0, G, 9, 0 }, { EP0, B, 9, 0 },
-			{ EP1, R, 4, 0 }, { EP0, R, 10, 10 }, { EP2, G, 3, 0 },
-			{ EP1, G, 3, 0 }, { EP0, G, 10, 10 }, { EP3, B, 0, 0 },
-			{ EP3, G, 3, 0 }, { EP1, B, 3, 0 }, { EP0, B, 10, 10 },
-			{ EP3, B, 1, 1 }, { EP2, B, 3, 0 }, { EP2, R, 4, 0 },
-			{ EP3, B, 2, 2 }, { EP3, R, 4, 0 }, { EP3, B, 3, 3 },
-			{ Partition, None, 4, 0 },
-			{ End, None, 0, 0},
-		},
-		// Mode 3, Index 3
-		{
-			{ Mode, None, 4, 0, { 3, false, 1, 10, { 0, 0, 0 } } },
-			{ EP0, R, 9, 0 }, { EP0, G, 9, 0 }, { EP0, B, 9, 0 },
-			{ EP1, R, 9, 0 }, { EP1, G, 9, 0 }, { EP1, B, 9, 0 },
-			{ End, None, 0, 0},
-		},
-		// Mode 6, Index 4
-		{
-			{ Mode, None, 4, 0, { 6, true, 2, 11, { 4, 5, 4 } } }, // 1 1
-			{ EP0, R, 9, 0 }, { EP0, G, 9, 0 }, { EP0, B, 9, 0 },
-			{ EP1, R, 3, 0 }, { EP0, R, 10, 10 }, { EP3, G, 4, 4 },
-			{ EP2, G, 3, 0 }, { EP1, G, 4, 0 }, { EP0, G, 10, 10 },
-			{ EP3, G, 3, 0 }, { EP1, B, 3, 0 }, { EP0, B, 10, 10 },
-			{ EP3, B, 1, 1 }, { EP2, B, 3, 0 }, { EP2, R, 3, 0 },
-			{ EP3, B, 0, 0 }, { EP3, B, 2, 2 }, { EP3, R, 3, 0 }, // 18 19
-			{ EP2, G, 4, 4 }, { EP3, B, 3, 3 }, // 2 21
-			{ Partition, None, 4, 0 },
-			{ End, None, 0, 0},
-		},
-		// Mode 7, Index 5
-		{
-			{ Mode, None, 4, 0, { 7, true, 1, 11, { 9, 9, 9 } } },
-			{ EP0, R, 9, 0 }, { EP0, G, 9, 0 }, { EP0, B, 9, 0 },
-			{ EP1, R, 8, 0 }, { EP0, R, 10, 10 }, { EP1, G, 8, 0 },
-			{ EP0, G, 10, 10 }, { EP1, B, 8, 0 }, { EP0, B, 10, 10 },
-			{ End, None, 0, 0},
-		},
-		// Mode 10, Index 6
-		{
-			{ Mode, None, 4, 0, { 10, true, 2, 11, { 4, 4, 5 } } },
-			{ EP0, R, 9, 0 }, { EP0, G, 9, 0 }, { EP0, B, 9, 0 },
-			{ EP1, R, 3, 0 }, { EP0, R, 10, 10 }, { EP2, B, 4, 4 },
-			{ EP2, G, 3, 0 }, { EP1, G, 3, 0 }, { EP0, G, 10, 10 },
-			{ EP3, B, 0, 0 }, { EP3, G, 3, 0 }, { EP1, B, 4, 0 },
-			{ EP0, B, 10, 10 }, { EP2, B, 3, 0 }, { EP2, R, 3, 0 },
-			{ EP3, B, 1, 1 }, { EP3, B, 2, 2 }, { EP3, R, 3, 0 },
-			{ EP3, B, 4, 4 }, { EP3, B, 3, 3 },
-			{ Partition, None, 4, 0 },
-			{ End, None, 0, 0},
-		},
-		// Mode 11, Index 7
-		{
-			{ Mode, None, 4, 0, { 11, true, 1, 12, { 8, 8, 8 } } },
-			{ EP0, R, 9, 0 }, { EP0, G, 9, 0 }, { EP0, B, 9, 0 },
-			{ EP1, R, 7, 0 }, { EP0, R, 10, 11 }, { EP1, G, 7, 0 },
-			{ EP0, G, 10, 11 }, { EP1, B, 7, 0 }, { EP0, B, 10, 11 },
-			{ End, None, 0, 0},
-		},
-		// Mode 14, Index 8
-		{
-			{ Mode, None, 4, 0, { 14, true, 2, 9, { 5, 5, 5 } } },
-			{ EP0, R, 8, 0 }, { EP2, B, 4, 4 }, { EP0, G, 8, 0 },
-			{ EP2, G, 4, 4 }, { EP0, B, 8, 0 }, { EP3, B, 4, 4 },
-			{ EP1, R, 4, 0 }, { EP3, G, 4, 4 }, { EP2, G, 3, 0 },
-			{ EP1, G, 4, 0 }, { EP3, B, 0, 0 }, { EP3, G, 3, 0 },
-			{ EP1, B, 4, 0 }, { EP3, B, 1, 1 }, { EP2, B, 3, 0 },
-			{ EP2, R, 4, 0 }, { EP3, B, 2, 2 }, { EP3, R, 4, 0 },
-			{ EP3, B, 3, 3 },
-			{ Partition, None, 4, 0 },
-			{ End, None, 0, 0},
-		},
-		// Mode 15, Index 9
-		{
-			{ Mode, None, 4, 0, { 15, true, 1, 16, { 4, 4, 4 } } },
-			{ EP0, R, 9, 0 }, { EP0, G, 9, 0 }, { EP0, B, 9, 0 },
-			{ EP1, R, 3, 0 }, { EP0, R, 10, 15 }, { EP1, G, 3, 0 },
-			{ EP0, G, 10, 15 }, { EP1, B, 3, 0 }, { EP0, B, 10, 15 },
-			{ End, None, 0, 0},
-		},
-		// Mode 18, Index 10
-		{
-			{ Mode, None, 4, 0, { 18, true, 2, 8, { 6, 5, 5 } } },
-			{ EP0, R, 7, 0 }, { EP3, G, 4, 4 }, { EP2, B, 4, 4 },
-			{ EP0, G, 7, 0 }, { EP3, B, 2, 2 }, { EP2, G, 4, 4 },
-			{ EP0, B, 7, 0 }, { EP3, B, 3, 3 }, { EP3, B, 4, 4 },
-			{ EP1, R, 5, 0 }, { EP2, G, 3, 0 }, { EP1, G, 4, 0 },
-			{ EP3, B, 0, 0 }, { EP3, G, 3, 0 }, { EP1, B, 4, 0 },
-			{ EP3, B, 1, 1 }, { EP2, B, 3, 0 }, { EP2, R, 5, 0 },
-			{ EP3, R, 5, 0 },
-			{ Partition, None, 4, 0 },
-			{ End, None, 0, 0},
-		},
-		// Mode 22, Index 11
-		{
-			{ Mode, None, 4, 0, { 22, true, 2, 8, { 5, 6, 5 } } },
-			{ EP0, R, 7, 0 }, { EP3, B, 0, 0 }, { EP2, B, 4, 4 },
-			{ EP0, G, 7, 0 }, { EP2, G, 5, 5 }, { EP2, G, 4, 4 },
-			{ EP0, B, 7, 0 }, { EP3, G, 5, 5 }, { EP3, B, 4, 4 },
-			{ EP1, R, 4, 0 }, { EP3, G, 4, 4 }, { EP2, G, 3, 0 },
-			{ EP1, G, 5, 0 }, { EP3, G, 3, 0 }, { EP1, B, 4, 0 },
-			{ EP3, B, 1, 1 }, { EP2, B, 3, 0 }, { EP2, R, 4, 0 },
-			{ EP3, B, 2, 2 }, { EP3, R, 4, 0 }, { EP3, B, 3, 3 },
-			{ Partition, None, 4, 0 },
-			{ End, None, 0, 0},
-		},
-		// Mode 26, Index 12
-		{
-			{ Mode, None, 4, 0, { 26, true, 2, 8, { 5, 5, 6 } } },
-			{ EP0, R, 7, 0 }, { EP3, B, 1, 1 }, { EP2, B, 4, 4 },
-			{ EP0, G, 7, 0 }, { EP2, B, 5, 5 }, { EP2, G, 4, 4 },
-			{ EP0, B, 7, 0 }, { EP3, B, 5, 5 }, { EP3, B, 4, 4 },
-			{ EP1, R, 4, 0 }, { EP3, G, 4, 4 }, { EP2, G, 3, 0 },
-			{ EP1, G, 4, 0 }, { EP3, B, 0, 0 }, { EP3, G, 3, 0 },
-			{ EP1, B, 5, 0 }, { EP2, B, 3, 0 }, { EP2, R, 4, 0 },
-			{ EP3, B, 2, 2 }, { EP3, R, 4, 0 }, { EP3, B, 3, 3 },
-			{ Partition, None, 4, 0 },
-			{ End, None, 0, 0},
-		},
-		// Mode 30, Index 13
-		{
-			{ Mode, None, 4, 0, { 30, false, 2, 6, { 0, 0, 0 } } },
-			{ EP0, R, 5, 0 }, { EP3, G, 4, 4 }, { EP3, B, 0, 0 },
-			{ EP3, B, 1, 1 }, { EP2, B, 4, 4 }, { EP0, G, 5, 0 },
-			{ EP2, G, 5, 5 }, { EP2, B, 5, 5 }, { EP3, B, 2, 2 },
-			{ EP2, G, 4, 4 }, { EP0, B, 5, 0 }, { EP3, G, 5, 5 },
-			{ EP3, B, 3, 3 }, { EP3, B, 5, 5 }, { EP3, B, 4, 4 },
-			{ EP1, R, 5, 0 }, { EP2, G, 3, 0 }, { EP1, G, 5, 0 },
-			{ EP3, G, 3, 0 }, { EP1, B, 5, 0 }, { EP2, B, 3, 0 },
-			{ EP2, R, 5, 0 }, { EP3, R, 5, 0 },
-			{ Partition, None, 4, 0 },
-			{ End, None, 0, 0},
-		}
-		// clang-format on
-	};
-
-	int index = modeToIndex(mode);
-	if(index < 0)
+static constexpr int NumBlocks = 14;
+// The largest number of descriptions within a block.
+static constexpr int MaxBlockDescIndex = 26;
+static constexpr BlockDesc blockDescs[NumBlocks][MaxBlockDescIndex] = {
+	// clang-format off
+	// Mode 0, Index 0
 	{
-		return nullptr;
+		{ Mode, None, 1, 0, { 0, true, 2, 10, { 5, 5, 5 } } },
+		{ EP2, G, 4, 4 }, { EP2, B, 4, 4 }, { EP3, B, 4, 4 },
+		{ EP0, R, 9, 0 }, { EP0, G, 9, 0 }, { EP0, B, 9, 0 },
+		{ EP1, R, 4, 0 }, { EP3, G, 4, 4 }, { EP2, G, 3, 0 },
+		{ EP1, G, 4, 0 }, { EP3, B, 0, 0 }, { EP3, G, 3, 0 },
+		{ EP1, B, 4, 0 }, { EP3, B, 1, 1 }, { EP2, B, 3, 0 },
+		{ EP2, R, 4, 0 }, { EP3, B, 2, 2 }, { EP3, R, 4, 0 },
+		{ EP3, B, 3, 3 },
+		{ Partition, None, 4, 0 },
+		{ End, None, 0, 0},
+	},
+	// Mode 1, Index 1
+	{
+		{ Mode, None, 1, 0, { 1, true, 2, 7, { 6, 6, 6 } } },
+		{ EP2, G, 5, 5 }, { EP3, G, 5, 4 }, { EP0, R, 6, 0 },
+		{ EP3, B, 1, 0 }, { EP2, B, 4, 4 }, { EP0, G, 6, 0 },
+		{ EP2, B, 5, 5 }, { EP3, B, 2, 2 }, { EP2, G, 4, 4 },
+		{ EP0, B, 6, 0 }, { EP3, B, 3, 3 }, { EP3, B, 5, 5 },
+		{ EP3, B, 4, 4 }, { EP1, R, 5, 0 }, { EP2, G, 3, 0 },
+		{ EP1, G, 5, 0 }, { EP3, G, 3, 0 }, { EP1, B, 5, 0 },
+		{ EP2, B, 3, 0 }, { EP2, R, 5, 0 }, { EP3, R, 5, 0 },
+		{ Partition, None, 4, 0 },
+		{ End, None, 0, 0},
+	},
+	// Mode 2, Index 2
+	{
+		{ Mode, None, 4, 0, { 2, true, 2, 11, { 5, 4, 4 } } },
+		{ EP0, R, 9, 0 }, { EP0, G, 9, 0 }, { EP0, B, 9, 0 },
+		{ EP1, R, 4, 0 }, { EP0, R, 10, 10 }, { EP2, G, 3, 0 },
+		{ EP1, G, 3, 0 }, { EP0, G, 10, 10 }, { EP3, B, 0, 0 },
+		{ EP3, G, 3, 0 }, { EP1, B, 3, 0 }, { EP0, B, 10, 10 },
+		{ EP3, B, 1, 1 }, { EP2, B, 3, 0 }, { EP2, R, 4, 0 },
+		{ EP3, B, 2, 2 }, { EP3, R, 4, 0 }, { EP3, B, 3, 3 },
+		{ Partition, None, 4, 0 },
+		{ End, None, 0, 0},
+	},
+	// Mode 3, Index 3
+	{
+		{ Mode, None, 4, 0, { 3, false, 1, 10, { 0, 0, 0 } } },
+		{ EP0, R, 9, 0 }, { EP0, G, 9, 0 }, { EP0, B, 9, 0 },
+		{ EP1, R, 9, 0 }, { EP1, G, 9, 0 }, { EP1, B, 9, 0 },
+		{ End, None, 0, 0},
+	},
+	// Mode 6, Index 4
+	{
+		{ Mode, None, 4, 0, { 6, true, 2, 11, { 4, 5, 4 } } }, // 1 1
+		{ EP0, R, 9, 0 }, { EP0, G, 9, 0 }, { EP0, B, 9, 0 },
+		{ EP1, R, 3, 0 }, { EP0, R, 10, 10 }, { EP3, G, 4, 4 },
+		{ EP2, G, 3, 0 }, { EP1, G, 4, 0 }, { EP0, G, 10, 10 },
+		{ EP3, G, 3, 0 }, { EP1, B, 3, 0 }, { EP0, B, 10, 10 },
+		{ EP3, B, 1, 1 }, { EP2, B, 3, 0 }, { EP2, R, 3, 0 },
+		{ EP3, B, 0, 0 }, { EP3, B, 2, 2 }, { EP3, R, 3, 0 }, // 18 19
+		{ EP2, G, 4, 4 }, { EP3, B, 3, 3 }, // 2 21
+		{ Partition, None, 4, 0 },
+		{ End, None, 0, 0},
+	},
+	// Mode 7, Index 5
+	{
+		{ Mode, None, 4, 0, { 7, true, 1, 11, { 9, 9, 9 } } },
+		{ EP0, R, 9, 0 }, { EP0, G, 9, 0 }, { EP0, B, 9, 0 },
+		{ EP1, R, 8, 0 }, { EP0, R, 10, 10 }, { EP1, G, 8, 0 },
+		{ EP0, G, 10, 10 }, { EP1, B, 8, 0 }, { EP0, B, 10, 10 },
+		{ End, None, 0, 0},
+	},
+	// Mode 10, Index 6
+	{
+		{ Mode, None, 4, 0, { 10, true, 2, 11, { 4, 4, 5 } } },
+		{ EP0, R, 9, 0 }, { EP0, G, 9, 0 }, { EP0, B, 9, 0 },
+		{ EP1, R, 3, 0 }, { EP0, R, 10, 10 }, { EP2, B, 4, 4 },
+		{ EP2, G, 3, 0 }, { EP1, G, 3, 0 }, { EP0, G, 10, 10 },
+		{ EP3, B, 0, 0 }, { EP3, G, 3, 0 }, { EP1, B, 4, 0 },
+		{ EP0, B, 10, 10 }, { EP2, B, 3, 0 }, { EP2, R, 3, 0 },
+		{ EP3, B, 1, 1 }, { EP3, B, 2, 2 }, { EP3, R, 3, 0 },
+		{ EP3, B, 4, 4 }, { EP3, B, 3, 3 },
+		{ Partition, None, 4, 0 },
+		{ End, None, 0, 0},
+	},
+	// Mode 11, Index 7
+	{
+		{ Mode, None, 4, 0, { 11, true, 1, 12, { 8, 8, 8 } } },
+		{ EP0, R, 9, 0 }, { EP0, G, 9, 0 }, { EP0, B, 9, 0 },
+		{ EP1, R, 7, 0 }, { EP0, R, 10, 11 }, { EP1, G, 7, 0 },
+		{ EP0, G, 10, 11 }, { EP1, B, 7, 0 }, { EP0, B, 10, 11 },
+		{ End, None, 0, 0},
+	},
+	// Mode 14, Index 8
+	{
+		{ Mode, None, 4, 0, { 14, true, 2, 9, { 5, 5, 5 } } },
+		{ EP0, R, 8, 0 }, { EP2, B, 4, 4 }, { EP0, G, 8, 0 },
+		{ EP2, G, 4, 4 }, { EP0, B, 8, 0 }, { EP3, B, 4, 4 },
+		{ EP1, R, 4, 0 }, { EP3, G, 4, 4 }, { EP2, G, 3, 0 },
+		{ EP1, G, 4, 0 }, { EP3, B, 0, 0 }, { EP3, G, 3, 0 },
+		{ EP1, B, 4, 0 }, { EP3, B, 1, 1 }, { EP2, B, 3, 0 },
+		{ EP2, R, 4, 0 }, { EP3, B, 2, 2 }, { EP3, R, 4, 0 },
+		{ EP3, B, 3, 3 },
+		{ Partition, None, 4, 0 },
+		{ End, None, 0, 0},
+	},
+	// Mode 15, Index 9
+	{
+		{ Mode, None, 4, 0, { 15, true, 1, 16, { 4, 4, 4 } } },
+		{ EP0, R, 9, 0 }, { EP0, G, 9, 0 }, { EP0, B, 9, 0 },
+		{ EP1, R, 3, 0 }, { EP0, R, 10, 15 }, { EP1, G, 3, 0 },
+		{ EP0, G, 10, 15 }, { EP1, B, 3, 0 }, { EP0, B, 10, 15 },
+		{ End, None, 0, 0},
+	},
+	// Mode 18, Index 10
+	{
+		{ Mode, None, 4, 0, { 18, true, 2, 8, { 6, 5, 5 } } },
+		{ EP0, R, 7, 0 }, { EP3, G, 4, 4 }, { EP2, B, 4, 4 },
+		{ EP0, G, 7, 0 }, { EP3, B, 2, 2 }, { EP2, G, 4, 4 },
+		{ EP0, B, 7, 0 }, { EP3, B, 3, 3 }, { EP3, B, 4, 4 },
+		{ EP1, R, 5, 0 }, { EP2, G, 3, 0 }, { EP1, G, 4, 0 },
+		{ EP3, B, 0, 0 }, { EP3, G, 3, 0 }, { EP1, B, 4, 0 },
+		{ EP3, B, 1, 1 }, { EP2, B, 3, 0 }, { EP2, R, 5, 0 },
+		{ EP3, R, 5, 0 },
+		{ Partition, None, 4, 0 },
+		{ End, None, 0, 0},
+	},
+	// Mode 22, Index 11
+	{
+		{ Mode, None, 4, 0, { 22, true, 2, 8, { 5, 6, 5 } } },
+		{ EP0, R, 7, 0 }, { EP3, B, 0, 0 }, { EP2, B, 4, 4 },
+		{ EP0, G, 7, 0 }, { EP2, G, 5, 5 }, { EP2, G, 4, 4 },
+		{ EP0, B, 7, 0 }, { EP3, G, 5, 5 }, { EP3, B, 4, 4 },
+		{ EP1, R, 4, 0 }, { EP3, G, 4, 4 }, { EP2, G, 3, 0 },
+		{ EP1, G, 5, 0 }, { EP3, G, 3, 0 }, { EP1, B, 4, 0 },
+		{ EP3, B, 1, 1 }, { EP2, B, 3, 0 }, { EP2, R, 4, 0 },
+		{ EP3, B, 2, 2 }, { EP3, R, 4, 0 }, { EP3, B, 3, 3 },
+		{ Partition, None, 4, 0 },
+		{ End, None, 0, 0},
+	},
+	// Mode 26, Index 12
+	{
+		{ Mode, None, 4, 0, { 26, true, 2, 8, { 5, 5, 6 } } },
+		{ EP0, R, 7, 0 }, { EP3, B, 1, 1 }, { EP2, B, 4, 4 },
+		{ EP0, G, 7, 0 }, { EP2, B, 5, 5 }, { EP2, G, 4, 4 },
+		{ EP0, B, 7, 0 }, { EP3, B, 5, 5 }, { EP3, B, 4, 4 },
+		{ EP1, R, 4, 0 }, { EP3, G, 4, 4 }, { EP2, G, 3, 0 },
+		{ EP1, G, 4, 0 }, { EP3, B, 0, 0 }, { EP3, G, 3, 0 },
+		{ EP1, B, 5, 0 }, { EP2, B, 3, 0 }, { EP2, R, 4, 0 },
+		{ EP3, B, 2, 2 }, { EP3, R, 4, 0 }, { EP3, B, 3, 3 },
+		{ Partition, None, 4, 0 },
+		{ End, None, 0, 0},
+	},
+	// Mode 30, Index 13
+	{
+		{ Mode, None, 4, 0, { 30, false, 2, 6, { 0, 0, 0 } } },
+		{ EP0, R, 5, 0 }, { EP3, G, 4, 4 }, { EP3, B, 0, 0 },
+		{ EP3, B, 1, 1 }, { EP2, B, 4, 4 }, { EP0, G, 5, 0 },
+		{ EP2, G, 5, 5 }, { EP2, B, 5, 5 }, { EP3, B, 2, 2 },
+		{ EP2, G, 4, 4 }, { EP0, B, 5, 0 }, { EP3, G, 5, 5 },
+		{ EP3, B, 3, 3 }, { EP3, B, 5, 5 }, { EP3, B, 4, 4 },
+		{ EP1, R, 5, 0 }, { EP2, G, 3, 0 }, { EP1, G, 5, 0 },
+		{ EP3, G, 3, 0 }, { EP1, B, 5, 0 }, { EP2, B, 3, 0 },
+		{ EP2, R, 5, 0 }, { EP3, R, 5, 0 },
+		{ Partition, None, 4, 0 },
+		{ End, None, 0, 0},
 	}
-	return blockDescs[index];
+	// clang-format on
 };
 
 struct Block
@@ -962,9 +953,9 @@
 			mode = data.consumeBits(4, 0);
 		}
 
-		const BlockDesc *blockDesc = getBlockDesc(mode);
+		int blockIndex = modeToIndex(mode);
 		// Handle illegal or reserved mode
-		if(!blockDesc)
+		if(blockIndex == -1)
 		{
 			for(int y = 0; y < 4 && y + dstY < dstHeight; y++)
 			{
@@ -976,6 +967,7 @@
 			}
 			return;
 		}
+		const BlockDesc *blockDesc = blockDescs[blockIndex];
 
 		RGBf e[4];
 		e[0].isSigned = e[1].isSigned = e[2].isSigned = e[3].isSigned = isSigned;
@@ -1023,7 +1015,7 @@
 		// Sign extension
 		if(isSigned)
 		{
-			for(int ep = 0; ep < modeDesc.numEndpoints; ep++)
+			for(int ep = 0; ep < modeDesc.partitionCount * 2; ep++)
 			{
 				e[ep].extendSign();
 			}
@@ -1031,7 +1023,7 @@
 		else if(modeDesc.hasDelta)
 		{
 			// Don't sign-extend the base endpoint in an unsigned format.
-			for(int ep = 1; ep < modeDesc.numEndpoints; ep++)
+			for(int ep = 1; ep < modeDesc.partitionCount * 2; ep++)
 			{
 				e[ep].extendSign();
 			}
@@ -1040,13 +1032,13 @@
 		// Turn the deltas into endpoints
 		if(modeDesc.hasDelta)
 		{
-			for(int ep = 1; ep < modeDesc.numEndpoints; ep++)
+			for(int ep = 1; ep < modeDesc.partitionCount * 2; ep++)
 			{
 				e[ep].resolveDelta(e[0]);
 			}
 		}
 
-		for(int ep = 0; ep < modeDesc.numEndpoints; ep++)
+		for(int ep = 0; ep < modeDesc.partitionCount * 2; ep++)
 		{
 			e[ep].unquantize();
 		}