TextureReader.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. using ChocolArm64.Memory;
  2. using Ryujinx.Graphics.Gal;
  3. using System;
  4. namespace Ryujinx.Graphics.Texture
  5. {
  6. delegate byte[] TextureReaderDelegate(IAMemory Memory, TextureInfo Texture);
  7. public static class TextureReader
  8. {
  9. public static byte[] Read(IAMemory Memory, TextureInfo Texture)
  10. {
  11. TextureReaderDelegate Reader = ImageUtils.GetReader(Texture.Format);
  12. return Reader(Memory, Texture);
  13. }
  14. internal unsafe static byte[] Read1Bpp(IAMemory Memory, TextureInfo Texture)
  15. {
  16. int Width = Texture.Width;
  17. int Height = Texture.Height;
  18. byte[] Output = new byte[Width * Height];
  19. ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 1);
  20. (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition(
  21. Memory,
  22. Texture.Position);
  23. fixed (byte* BuffPtr = Output)
  24. {
  25. long OutOffs = 0;
  26. for (int Y = 0; Y < Height; Y++)
  27. for (int X = 0; X < Width; X++)
  28. {
  29. long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);
  30. byte Pixel = CpuMem.ReadByte(Position + Offset);
  31. *(BuffPtr + OutOffs) = Pixel;
  32. OutOffs++;
  33. }
  34. }
  35. return Output;
  36. }
  37. internal unsafe static byte[] Read5551(IAMemory Memory, TextureInfo Texture)
  38. {
  39. int Width = Texture.Width;
  40. int Height = Texture.Height;
  41. byte[] Output = new byte[Width * Height * 2];
  42. ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 2);
  43. (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition(
  44. Memory,
  45. Texture.Position);
  46. fixed (byte* BuffPtr = Output)
  47. {
  48. long OutOffs = 0;
  49. for (int Y = 0; Y < Height; Y++)
  50. for (int X = 0; X < Width; X++)
  51. {
  52. long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);
  53. uint Pixel = (uint)CpuMem.ReadInt16(Position + Offset);
  54. Pixel = (Pixel & 0x001f) << 11 |
  55. (Pixel & 0x03e0) << 1 |
  56. (Pixel & 0x7c00) >> 9 |
  57. (Pixel & 0x8000) >> 15;
  58. *(short*)(BuffPtr + OutOffs) = (short)Pixel;
  59. OutOffs += 2;
  60. }
  61. }
  62. return Output;
  63. }
  64. internal unsafe static byte[] Read565(IAMemory Memory, TextureInfo Texture)
  65. {
  66. int Width = Texture.Width;
  67. int Height = Texture.Height;
  68. byte[] Output = new byte[Width * Height * 2];
  69. ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 2);
  70. (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition(
  71. Memory,
  72. Texture.Position);
  73. fixed (byte* BuffPtr = Output)
  74. {
  75. long OutOffs = 0;
  76. for (int Y = 0; Y < Height; Y++)
  77. for (int X = 0; X < Width; X++)
  78. {
  79. long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);
  80. uint Pixel = (uint)CpuMem.ReadInt16(Position + Offset);
  81. Pixel = (Pixel & 0x001f) << 11 |
  82. (Pixel & 0x07e0) |
  83. (Pixel & 0xf800) >> 11;
  84. *(short*)(BuffPtr + OutOffs) = (short)Pixel;
  85. OutOffs += 2;
  86. }
  87. }
  88. return Output;
  89. }
  90. internal unsafe static byte[] Read2Bpp(IAMemory Memory, TextureInfo Texture)
  91. {
  92. int Width = Texture.Width;
  93. int Height = Texture.Height;
  94. byte[] Output = new byte[Width * Height * 2];
  95. ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 2);
  96. (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition(
  97. Memory,
  98. Texture.Position);
  99. fixed (byte* BuffPtr = Output)
  100. {
  101. long OutOffs = 0;
  102. for (int Y = 0; Y < Height; Y++)
  103. for (int X = 0; X < Width; X++)
  104. {
  105. long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);
  106. short Pixel = CpuMem.ReadInt16(Position + Offset);
  107. *(short*)(BuffPtr + OutOffs) = Pixel;
  108. OutOffs += 2;
  109. }
  110. }
  111. return Output;
  112. }
  113. internal unsafe static byte[] Read4Bpp(IAMemory Memory, TextureInfo Texture)
  114. {
  115. int Width = Texture.Width;
  116. int Height = Texture.Height;
  117. byte[] Output = new byte[Width * Height * 4];
  118. ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 4);
  119. (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition(
  120. Memory,
  121. Texture.Position);
  122. fixed (byte* BuffPtr = Output)
  123. {
  124. long OutOffs = 0;
  125. for (int Y = 0; Y < Height; Y++)
  126. for (int X = 0; X < Width; X++)
  127. {
  128. long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);
  129. int Pixel = CpuMem.ReadInt32(Position + Offset);
  130. *(int*)(BuffPtr + OutOffs) = Pixel;
  131. OutOffs += 4;
  132. }
  133. }
  134. return Output;
  135. }
  136. internal unsafe static byte[] Read8Bpp(IAMemory Memory, TextureInfo Texture)
  137. {
  138. int Width = Texture.Width;
  139. int Height = Texture.Height;
  140. byte[] Output = new byte[Width * Height * 8];
  141. ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 8);
  142. (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition(
  143. Memory,
  144. Texture.Position);
  145. fixed (byte* BuffPtr = Output)
  146. {
  147. long OutOffs = 0;
  148. for (int Y = 0; Y < Height; Y++)
  149. for (int X = 0; X < Width; X++)
  150. {
  151. long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);
  152. long Pixel = CpuMem.ReadInt64(Position + Offset);
  153. *(long*)(BuffPtr + OutOffs) = Pixel;
  154. OutOffs += 8;
  155. }
  156. }
  157. return Output;
  158. }
  159. internal unsafe static byte[] Read16Bpp(IAMemory Memory, TextureInfo Texture)
  160. {
  161. int Width = Texture.Width;
  162. int Height = Texture.Height;
  163. byte[] Output = new byte[Width * Height * 16];
  164. ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 16);
  165. (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition(
  166. Memory,
  167. Texture.Position);
  168. fixed (byte* BuffPtr = Output)
  169. {
  170. long OutOffs = 0;
  171. for (int Y = 0; Y < Height; Y++)
  172. for (int X = 0; X < Width; X++)
  173. {
  174. long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);
  175. long PxLow = CpuMem.ReadInt64(Position + Offset + 0);
  176. long PxHigh = CpuMem.ReadInt64(Position + Offset + 8);
  177. *(long*)(BuffPtr + OutOffs + 0) = PxLow;
  178. *(long*)(BuffPtr + OutOffs + 8) = PxHigh;
  179. OutOffs += 16;
  180. }
  181. }
  182. return Output;
  183. }
  184. internal unsafe static byte[] Read8Bpt4x4(IAMemory Memory, TextureInfo Texture)
  185. {
  186. int Width = (Texture.Width + 3) / 4;
  187. int Height = (Texture.Height + 3) / 4;
  188. byte[] Output = new byte[Width * Height * 8];
  189. ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 4, 8);
  190. (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition(
  191. Memory,
  192. Texture.Position);
  193. fixed (byte* BuffPtr = Output)
  194. {
  195. long OutOffs = 0;
  196. for (int Y = 0; Y < Height; Y++)
  197. for (int X = 0; X < Width; X++)
  198. {
  199. long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);
  200. long Tile = CpuMem.ReadInt64(Position + Offset);
  201. *(long*)(BuffPtr + OutOffs) = Tile;
  202. OutOffs += 8;
  203. }
  204. }
  205. return Output;
  206. }
  207. internal unsafe static byte[] Read16BptCompressedTexture(IAMemory Memory, TextureInfo Texture, int BlockWidth, int BlockHeight)
  208. {
  209. int Width = (Texture.Width + (BlockWidth - 1)) / BlockWidth;
  210. int Height = (Texture.Height + (BlockHeight - 1)) / BlockHeight;
  211. byte[] Output = new byte[Width * Height * 16];
  212. ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, BlockWidth, 16);
  213. (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition(
  214. Memory,
  215. Texture.Position);
  216. fixed (byte* BuffPtr = Output)
  217. {
  218. long OutOffs = 0;
  219. for (int Y = 0; Y < Height; Y++)
  220. for (int X = 0; X < Width; X++)
  221. {
  222. long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);
  223. long Tile0 = CpuMem.ReadInt64(Position + Offset + 0);
  224. long Tile1 = CpuMem.ReadInt64(Position + Offset + 8);
  225. *(long*)(BuffPtr + OutOffs + 0) = Tile0;
  226. *(long*)(BuffPtr + OutOffs + 8) = Tile1;
  227. OutOffs += 16;
  228. }
  229. }
  230. return Output;
  231. }
  232. internal static byte[] Read16BptCompressedTexture4x4(IAMemory Memory, TextureInfo Texture)
  233. {
  234. return Read16BptCompressedTexture(Memory, Texture, 4, 4);
  235. }
  236. internal static byte[] Read16BptCompressedTexture5x5(IAMemory Memory, TextureInfo Texture)
  237. {
  238. return Read16BptCompressedTexture(Memory, Texture, 5, 5);
  239. }
  240. internal static byte[] Read16BptCompressedTexture6x6(IAMemory Memory, TextureInfo Texture)
  241. {
  242. return Read16BptCompressedTexture(Memory, Texture, 6, 6);
  243. }
  244. internal static byte[] Read16BptCompressedTexture8x8(IAMemory Memory, TextureInfo Texture)
  245. {
  246. return Read16BptCompressedTexture(Memory, Texture, 8, 8);
  247. }
  248. internal static byte[] Read16BptCompressedTexture10x10(IAMemory Memory, TextureInfo Texture)
  249. {
  250. return Read16BptCompressedTexture(Memory, Texture, 10, 10);
  251. }
  252. internal static byte[] Read16BptCompressedTexture12x12(IAMemory Memory, TextureInfo Texture)
  253. {
  254. return Read16BptCompressedTexture(Memory, Texture, 12, 12);
  255. }
  256. internal static byte[] Read16BptCompressedTexture5x4(IAMemory Memory, TextureInfo Texture)
  257. {
  258. return Read16BptCompressedTexture(Memory, Texture, 5, 4);
  259. }
  260. internal static byte[] Read16BptCompressedTexture6x5(IAMemory Memory, TextureInfo Texture)
  261. {
  262. return Read16BptCompressedTexture(Memory, Texture, 6, 5);
  263. }
  264. internal static byte[] Read16BptCompressedTexture8x6(IAMemory Memory, TextureInfo Texture)
  265. {
  266. return Read16BptCompressedTexture(Memory, Texture, 8, 6);
  267. }
  268. internal static byte[] Read16BptCompressedTexture10x8(IAMemory Memory, TextureInfo Texture)
  269. {
  270. return Read16BptCompressedTexture(Memory, Texture, 10, 8);
  271. }
  272. internal static byte[] Read16BptCompressedTexture12x10(IAMemory Memory, TextureInfo Texture)
  273. {
  274. return Read16BptCompressedTexture(Memory, Texture, 12, 10);
  275. }
  276. internal static byte[] Read16BptCompressedTexture8x5(IAMemory Memory, TextureInfo Texture)
  277. {
  278. return Read16BptCompressedTexture(Memory, Texture, 5, 5);
  279. }
  280. internal static byte[] Read16BptCompressedTexture10x5(IAMemory Memory, TextureInfo Texture)
  281. {
  282. return Read16BptCompressedTexture(Memory, Texture, 10, 5);
  283. }
  284. internal static byte[] Read16BptCompressedTexture10x6(IAMemory Memory, TextureInfo Texture)
  285. {
  286. return Read16BptCompressedTexture(Memory, Texture, 10, 6);
  287. }
  288. }
  289. }