TextureFactory.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. using Ryujinx.Graphics.Gal;
  2. using Ryujinx.HLE.Gpu.Memory;
  3. using System;
  4. namespace Ryujinx.HLE.Gpu.Texture
  5. {
  6. static class TextureFactory
  7. {
  8. public static GalImage MakeTexture(NvGpuVmm Vmm, long TicPosition)
  9. {
  10. int[] Tic = ReadWords(Vmm, TicPosition, 8);
  11. GalTextureType RType = (GalTextureType)((Tic[0] >> 7) & 7);
  12. GalTextureType GType = (GalTextureType)((Tic[0] >> 10) & 7);
  13. GalTextureType BType = (GalTextureType)((Tic[0] >> 13) & 7);
  14. GalTextureType AType = (GalTextureType)((Tic[0] >> 16) & 7);
  15. GalImageFormat Format = ImageFormatConverter.ConvertTexture((GalTextureFormat)(Tic[0] & 0x7f), RType, GType, BType, AType);
  16. GalTextureSource XSource = (GalTextureSource)((Tic[0] >> 19) & 7);
  17. GalTextureSource YSource = (GalTextureSource)((Tic[0] >> 22) & 7);
  18. GalTextureSource ZSource = (GalTextureSource)((Tic[0] >> 25) & 7);
  19. GalTextureSource WSource = (GalTextureSource)((Tic[0] >> 28) & 7);
  20. int Width = (Tic[4] & 0xffff) + 1;
  21. int Height = (Tic[5] & 0xffff) + 1;
  22. return new GalImage(
  23. Width,
  24. Height,
  25. Format,
  26. XSource,
  27. YSource,
  28. ZSource,
  29. WSource);
  30. }
  31. public static byte[] GetTextureData(NvGpuVmm Vmm, long TicPosition)
  32. {
  33. int[] Tic = ReadWords(Vmm, TicPosition, 8);
  34. GalTextureFormat Format = (GalTextureFormat)(Tic[0] & 0x7f);
  35. long TextureAddress = (uint)Tic[1];
  36. TextureAddress |= (long)((ushort)Tic[2]) << 32;
  37. TextureSwizzle Swizzle = (TextureSwizzle)((Tic[2] >> 21) & 7);
  38. if (Swizzle == TextureSwizzle.BlockLinear ||
  39. Swizzle == TextureSwizzle.BlockLinearColorKey)
  40. {
  41. TextureAddress &= ~0x1ffL;
  42. }
  43. else if (Swizzle == TextureSwizzle.Pitch ||
  44. Swizzle == TextureSwizzle.PitchColorKey)
  45. {
  46. TextureAddress &= ~0x1fL;
  47. }
  48. int Pitch = (Tic[3] & 0xffff) << 5;
  49. int BlockHeightLog2 = (Tic[3] >> 3) & 7;
  50. int TileWidthLog2 = (Tic[3] >> 10) & 7;
  51. int BlockHeight = 1 << BlockHeightLog2;
  52. int TileWidth = 1 << TileWidthLog2;
  53. int Width = (Tic[4] & 0xffff) + 1;
  54. int Height = (Tic[5] & 0xffff) + 1;
  55. TextureInfo Texture = new TextureInfo(
  56. TextureAddress,
  57. Width,
  58. Height,
  59. Pitch,
  60. BlockHeight,
  61. TileWidth,
  62. Swizzle,
  63. Format);
  64. return TextureReader.Read(Vmm, Texture);
  65. }
  66. public static GalTextureSampler MakeSampler(NvGpu Gpu, NvGpuVmm Vmm, long TscPosition)
  67. {
  68. int[] Tsc = ReadWords(Vmm, TscPosition, 8);
  69. GalTextureWrap AddressU = (GalTextureWrap)((Tsc[0] >> 0) & 7);
  70. GalTextureWrap AddressV = (GalTextureWrap)((Tsc[0] >> 3) & 7);
  71. GalTextureWrap AddressP = (GalTextureWrap)((Tsc[0] >> 6) & 7);
  72. GalTextureFilter MagFilter = (GalTextureFilter) ((Tsc[1] >> 0) & 3);
  73. GalTextureFilter MinFilter = (GalTextureFilter) ((Tsc[1] >> 4) & 3);
  74. GalTextureMipFilter MipFilter = (GalTextureMipFilter)((Tsc[1] >> 6) & 3);
  75. GalColorF BorderColor = new GalColorF(
  76. BitConverter.Int32BitsToSingle(Tsc[4]),
  77. BitConverter.Int32BitsToSingle(Tsc[5]),
  78. BitConverter.Int32BitsToSingle(Tsc[6]),
  79. BitConverter.Int32BitsToSingle(Tsc[7]));
  80. return new GalTextureSampler(
  81. AddressU,
  82. AddressV,
  83. AddressP,
  84. MinFilter,
  85. MagFilter,
  86. MipFilter,
  87. BorderColor);
  88. }
  89. private static int[] ReadWords(NvGpuVmm Vmm, long Position, int Count)
  90. {
  91. int[] Words = new int[Count];
  92. for (int Index = 0; Index < Count; Index++, Position += 4)
  93. {
  94. Words[Index] = Vmm.ReadInt32(Position);
  95. }
  96. return Words;
  97. }
  98. }
  99. }