Skip to content

Commit b1803e8

Browse files
committed
Greatly reduce Bc7 allocations
1 parent 5ec29c6 commit b1803e8

File tree

1 file changed

+29
-40
lines changed

1 file changed

+29
-40
lines changed

AssetRipper.TextureDecoder/Bc/BcHelpers.cs

+29-40
Original file line numberDiff line numberDiff line change
@@ -564,8 +564,8 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
564564
low = BinaryPrimitives.ReadUInt64LittleEndian(compressedBlock),
565565
high = BinaryPrimitives.ReadUInt64LittleEndian(compressedBlock.Slice(sizeof(ulong)))
566566
};
567-
int[][] endpoints = CreateRectangularArray<int>(6, 4);
568-
int[][] indices = CreateRectangularArray<int>(4, 4);
567+
Span2D<int> endpoints = new(stackalloc int[6 * 4], 6, 4);
568+
Span2D<int> indices = new(stackalloc int[4 * 4], 4, 4);
569569

570570
int decompressedOffset = 0;
571571

@@ -618,15 +618,15 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
618618
{
619619
for (int j = 0; j < numEndpoints; ++j)
620620
{
621-
endpoints[j][i] = bstream.ReadBits(Bc7Tables.ActualBitsCount[0][mode]);
621+
endpoints[j, i] = bstream.ReadBits(Bc7Tables.ActualBitsCount[0][mode]);
622622
}
623623
}
624624
// Alpha (if any)
625625
if (Bc7Tables.ActualBitsCount[1][mode] > 0)
626626
{
627627
for (int j = 0; j < numEndpoints; ++j)
628628
{
629-
endpoints[j][3] = bstream.ReadBits(Bc7Tables.ActualBitsCount[1][mode]);
629+
endpoints[j, 3] = bstream.ReadBits(Bc7Tables.ActualBitsCount[1][mode]);
630630
}
631631
}
632632

@@ -639,7 +639,7 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
639639
// component-wise left-shift
640640
for (int j = 0; j < 4; ++j)
641641
{
642-
endpoints[i][j] <<= 1;
642+
endpoints[i, j] <<= 1;
643643
}
644644
}
645645

@@ -652,10 +652,10 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
652652
// rgb component-wise insert pbits
653653
for (int k = 0; k < 3; ++k)
654654
{
655-
endpoints[0][k] |= i;
656-
endpoints[1][k] |= i;
657-
endpoints[2][k] |= j;
658-
endpoints[3][k] |= j;
655+
endpoints[0, k] |= i;
656+
endpoints[1, k] |= i;
657+
endpoints[2, k] |= j;
658+
endpoints[3, k] |= j;
659659
}
660660
}
661661
else if ((Bc7Tables.bcdec_bc7_sModeHasPBits & (1 << mode)) != 0)
@@ -666,7 +666,7 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
666666
int j = bstream.ReadBit();
667667
for (int k = 0; k < 4; ++k)
668668
{
669-
endpoints[i][k] |= j;
669+
endpoints[i, k] |= j;
670670
}
671671
}
672672
}
@@ -680,18 +680,18 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
680680
for (int k = 0; k < 3; ++k)
681681
{
682682
// left shift endpoint components so that their MSB lies in bit 7
683-
endpoints[i][k] = endpoints[i][k] << (8 - j);
683+
endpoints[i, k] = endpoints[i, k] << (8 - j);
684684
// Replicate each component's MSB into the LSBs revealed by the left-shift operation above
685-
endpoints[i][k] = endpoints[i][k] | (endpoints[i][k] >> j);
685+
endpoints[i, k] = endpoints[i, k] | (endpoints[i, k] >> j);
686686
}
687687

688688
// get alpha component precision including pbit
689689
j = Bc7Tables.ActualBitsCount[1][mode] + ((Bc7Tables.bcdec_bc7_sModeHasPBits >> mode) & 1);
690690

691691
// left shift endpoint components so that their MSB lies in bit 7
692-
endpoints[i][3] = endpoints[i][3] << (8 - j);
692+
endpoints[i, 3] = endpoints[i, 3] << (8 - j);
693693
// Replicate each component's MSB into the LSBs revealed by the left-shift operation above
694-
endpoints[i][3] = endpoints[i][3] | (endpoints[i][3] >> j);
694+
endpoints[i, 3] = endpoints[i, 3] | (endpoints[i, 3] >> j);
695695
}
696696

697697
// If this mode does not explicitly define the alpha component
@@ -700,7 +700,7 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
700700
{
701701
for (int j = 0; j < numEndpoints; ++j)
702702
{
703-
endpoints[j][3] = 0xFF;
703+
endpoints[j, 3] = 0xFF;
704704
}
705705
}
706706

@@ -726,7 +726,7 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
726726
indexBits--;
727727
}
728728

729-
indices[i][j] = bstream.ReadBits(indexBits);
729+
indices[i, j] = bstream.ReadBits(indexBits);
730730
}
731731
}
732732

@@ -740,7 +740,7 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
740740
: Bc7Tables.PartitionSets[numPartitions - 2][partition][i][j];
741741
partitionSet &= 0x03;
742742

743-
int index = indices[i][j];
743+
int index = indices[i, j];
744744

745745
int r;
746746
int g;
@@ -749,10 +749,10 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
749749

750750
if (indexBits2 == 0)
751751
{
752-
r = Interpolate(endpoints[partitionSet * 2][0], endpoints[(partitionSet * 2) + 1][0], weights, index);
753-
g = Interpolate(endpoints[partitionSet * 2][1], endpoints[(partitionSet * 2) + 1][1], weights, index);
754-
b = Interpolate(endpoints[partitionSet * 2][2], endpoints[(partitionSet * 2) + 1][2], weights, index);
755-
a = Interpolate(endpoints[partitionSet * 2][3], endpoints[(partitionSet * 2) + 1][3], weights, index);
752+
r = Interpolate(endpoints[partitionSet * 2, 0], endpoints[(partitionSet * 2) + 1, 0], weights, index);
753+
g = Interpolate(endpoints[partitionSet * 2, 1], endpoints[(partitionSet * 2) + 1, 1], weights, index);
754+
b = Interpolate(endpoints[partitionSet * 2, 2], endpoints[(partitionSet * 2) + 1, 2], weights, index);
755+
a = Interpolate(endpoints[partitionSet * 2, 3], endpoints[(partitionSet * 2) + 1, 3], weights, index);
756756
}
757757
else
758758
{
@@ -764,17 +764,17 @@ public static void DecompressBc7(ReadOnlySpan<byte> compressedBlock, Span<byte>
764764
// and from the primary index bits otherwise.
765765
if (indexSelectionBit == 0)
766766
{
767-
r = Interpolate(endpoints[partitionSet * 2][0], endpoints[(partitionSet * 2) + 1][0], weights, index);
768-
g = Interpolate(endpoints[partitionSet * 2][1], endpoints[(partitionSet * 2) + 1][1], weights, index);
769-
b = Interpolate(endpoints[partitionSet * 2][2], endpoints[(partitionSet * 2) + 1][2], weights, index);
770-
a = Interpolate(endpoints[partitionSet * 2][3], endpoints[(partitionSet * 2) + 1][3], weights2, index2);
767+
r = Interpolate(endpoints[partitionSet * 2, 0], endpoints[(partitionSet * 2) + 1, 0], weights, index);
768+
g = Interpolate(endpoints[partitionSet * 2, 1], endpoints[(partitionSet * 2) + 1, 1], weights, index);
769+
b = Interpolate(endpoints[partitionSet * 2, 2], endpoints[(partitionSet * 2) + 1, 2], weights, index);
770+
a = Interpolate(endpoints[partitionSet * 2, 3], endpoints[(partitionSet * 2) + 1, 3], weights2, index2);
771771
}
772772
else
773773
{
774-
r = Interpolate(endpoints[partitionSet * 2][0], endpoints[(partitionSet * 2) + 1][0], weights2, index2);
775-
g = Interpolate(endpoints[partitionSet * 2][1], endpoints[(partitionSet * 2) + 1][1], weights2, index2);
776-
b = Interpolate(endpoints[partitionSet * 2][2], endpoints[(partitionSet * 2) + 1][2], weights2, index2);
777-
a = Interpolate(endpoints[partitionSet * 2][3], endpoints[(partitionSet * 2) + 1][3], weights, index);
774+
r = Interpolate(endpoints[partitionSet * 2, 0], endpoints[(partitionSet * 2) + 1, 0], weights2, index2);
775+
g = Interpolate(endpoints[partitionSet * 2, 1], endpoints[(partitionSet * 2) + 1, 1], weights2, index2);
776+
b = Interpolate(endpoints[partitionSet * 2, 2], endpoints[(partitionSet * 2) + 1, 2], weights2, index2);
777+
a = Interpolate(endpoints[partitionSet * 2, 3], endpoints[(partitionSet * 2) + 1, 3], weights, index);
778778
}
779779
}
780780

@@ -1056,15 +1056,4 @@ public static void SwapValues(ref int a, ref int b)
10561056
{
10571057
(a, b) = (b, a);
10581058
}
1059-
1060-
public static T[][] CreateRectangularArray<T>(int size1, int size2)
1061-
{
1062-
T[][] newArray = new T[size1][];
1063-
for (int array1 = 0; array1 < size1; array1++)
1064-
{
1065-
newArray[array1] = new T[size2];
1066-
}
1067-
1068-
return newArray;
1069-
}
10701059
}

0 commit comments

Comments
 (0)