TextureFactory.cs 3.9 KB

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