/ src / Ryujinx.Graphics.Texture / BCnEncoder.cs
BCnEncoder.cs
 1  using Ryujinx.Common;
 2  using Ryujinx.Common.Memory;
 3  using Ryujinx.Graphics.Texture.Encoders;
 4  using System;
 5  
 6  namespace Ryujinx.Graphics.Texture
 7  {
 8      public static class BCnEncoder
 9      {
10          private const int BlockWidth = 4;
11          private const int BlockHeight = 4;
12  
13          public static MemoryOwner<byte> EncodeBC7(Memory<byte> data, int width, int height, int depth, int levels, int layers)
14          {
15              int size = 0;
16  
17              for (int l = 0; l < levels; l++)
18              {
19                  int w = BitUtils.DivRoundUp(Math.Max(1, width >> l), BlockWidth);
20                  int h = BitUtils.DivRoundUp(Math.Max(1, height >> l), BlockHeight);
21  
22                  size += w * h * 16 * Math.Max(1, depth >> l) * layers;
23              }
24  
25              MemoryOwner<byte> output = MemoryOwner<byte>.Rent(size);
26              Memory<byte> outputMemory = output.Memory;
27  
28              int imageBaseIOffs = 0;
29              int imageBaseOOffs = 0;
30  
31              for (int l = 0; l < levels; l++)
32              {
33                  int w = BitUtils.DivRoundUp(width, BlockWidth);
34                  int h = BitUtils.DivRoundUp(height, BlockHeight);
35  
36                  for (int l2 = 0; l2 < layers; l2++)
37                  {
38                      for (int z = 0; z < depth; z++)
39                      {
40                          BC7Encoder.Encode(
41                              outputMemory[imageBaseOOffs..],
42                              data[imageBaseIOffs..],
43                              width,
44                              height,
45                              EncodeMode.Fast | EncodeMode.Multithreaded);
46  
47                          imageBaseIOffs += width * height * 4;
48                          imageBaseOOffs += w * h * 16;
49                      }
50                  }
51  
52                  width = Math.Max(1, width >> 1);
53                  height = Math.Max(1, height >> 1);
54                  depth = Math.Max(1, depth >> 1);
55              }
56  
57              return output;
58          }
59      }
60  }