OGLTexture.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. using OpenTK.Graphics.OpenGL;
  2. using Ryujinx.Graphics.Gal.Texture;
  3. using System;
  4. namespace Ryujinx.Graphics.Gal.OpenGL
  5. {
  6. class OGLTexture
  7. {
  8. private int[] Textures;
  9. public OGLTexture()
  10. {
  11. Textures = new int[80];
  12. }
  13. public void Set(int Index, GalTexture Texture)
  14. {
  15. GL.ActiveTexture(TextureUnit.Texture0 + Index);
  16. Bind(Index);
  17. const int Level = 0; //TODO: Support mipmap textures.
  18. const int Border = 0;
  19. if (IsCompressedTextureFormat(Texture.Format))
  20. {
  21. PixelInternalFormat InternalFmt = OGLEnumConverter.GetCompressedTextureFormat(Texture.Format);
  22. GL.CompressedTexImage2D(
  23. TextureTarget.Texture2D,
  24. Level,
  25. InternalFmt,
  26. Texture.Width,
  27. Texture.Height,
  28. Border,
  29. Texture.Data.Length,
  30. Texture.Data);
  31. }
  32. else
  33. {
  34. if (Texture.Format >= GalTextureFormat.Astc2D4x4)
  35. {
  36. Texture = ConvertAstcTextureToRgba(Texture);
  37. }
  38. const PixelInternalFormat InternalFmt = PixelInternalFormat.Rgba;
  39. (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(Texture.Format);
  40. GL.TexImage2D(
  41. TextureTarget.Texture2D,
  42. Level,
  43. InternalFmt,
  44. Texture.Width,
  45. Texture.Height,
  46. Border,
  47. Format,
  48. Type,
  49. Texture.Data);
  50. }
  51. int SwizzleR = (int)OGLEnumConverter.GetTextureSwizzle(Texture.XSource);
  52. int SwizzleG = (int)OGLEnumConverter.GetTextureSwizzle(Texture.YSource);
  53. int SwizzleB = (int)OGLEnumConverter.GetTextureSwizzle(Texture.ZSource);
  54. int SwizzleA = (int)OGLEnumConverter.GetTextureSwizzle(Texture.WSource);
  55. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleR, SwizzleR);
  56. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleG, SwizzleG);
  57. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleB, SwizzleB);
  58. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, SwizzleA);
  59. }
  60. private static GalTexture ConvertAstcTextureToRgba(GalTexture Texture)
  61. {
  62. int TextureBlockWidth = GetAstcBlockWidth(Texture.Format);
  63. int TextureBlockHeight = GetAstcBlockHeight(Texture.Format);
  64. Texture.Data = ASTCDecoder.DecodeToRGBA8888(
  65. Texture.Data,
  66. TextureBlockWidth,
  67. TextureBlockHeight, 1,
  68. Texture.Width,
  69. Texture.Height, 1);
  70. Texture.Format = GalTextureFormat.A8B8G8R8;
  71. return Texture;
  72. }
  73. private static int GetAstcBlockWidth(GalTextureFormat Format)
  74. {
  75. switch (Format)
  76. {
  77. case GalTextureFormat.Astc2D4x4: return 4;
  78. case GalTextureFormat.Astc2D5x5: return 5;
  79. case GalTextureFormat.Astc2D6x6: return 6;
  80. case GalTextureFormat.Astc2D8x8: return 8;
  81. case GalTextureFormat.Astc2D10x10: return 10;
  82. case GalTextureFormat.Astc2D12x12: return 12;
  83. case GalTextureFormat.Astc2D5x4: return 5;
  84. case GalTextureFormat.Astc2D6x5: return 6;
  85. case GalTextureFormat.Astc2D8x6: return 8;
  86. case GalTextureFormat.Astc2D10x8: return 10;
  87. case GalTextureFormat.Astc2D12x10: return 12;
  88. case GalTextureFormat.Astc2D8x5: return 8;
  89. case GalTextureFormat.Astc2D10x5: return 10;
  90. case GalTextureFormat.Astc2D10x6: return 10;
  91. }
  92. throw new ArgumentException(nameof(Format));
  93. }
  94. private static int GetAstcBlockHeight(GalTextureFormat Format)
  95. {
  96. switch (Format)
  97. {
  98. case GalTextureFormat.Astc2D4x4: return 4;
  99. case GalTextureFormat.Astc2D5x5: return 5;
  100. case GalTextureFormat.Astc2D6x6: return 6;
  101. case GalTextureFormat.Astc2D8x8: return 8;
  102. case GalTextureFormat.Astc2D10x10: return 10;
  103. case GalTextureFormat.Astc2D12x12: return 12;
  104. case GalTextureFormat.Astc2D5x4: return 4;
  105. case GalTextureFormat.Astc2D6x5: return 5;
  106. case GalTextureFormat.Astc2D8x6: return 6;
  107. case GalTextureFormat.Astc2D10x8: return 8;
  108. case GalTextureFormat.Astc2D12x10: return 10;
  109. case GalTextureFormat.Astc2D8x5: return 5;
  110. case GalTextureFormat.Astc2D10x5: return 5;
  111. case GalTextureFormat.Astc2D10x6: return 6;
  112. }
  113. throw new ArgumentException(nameof(Format));
  114. }
  115. public void Bind(int Index)
  116. {
  117. int Handle = EnsureTextureInitialized(Index);
  118. GL.BindTexture(TextureTarget.Texture2D, Handle);
  119. }
  120. public static void Set(GalTextureSampler Sampler)
  121. {
  122. int WrapS = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressU);
  123. int WrapT = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressV);
  124. int MinFilter = (int)OGLEnumConverter.GetTextureMinFilter(Sampler.MinFilter, Sampler.MipFilter);
  125. int MagFilter = (int)OGLEnumConverter.GetTextureMagFilter(Sampler.MagFilter);
  126. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, WrapS);
  127. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, WrapT);
  128. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, MinFilter);
  129. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, MagFilter);
  130. float[] Color = new float[]
  131. {
  132. Sampler.BorderColor.Red,
  133. Sampler.BorderColor.Green,
  134. Sampler.BorderColor.Blue,
  135. Sampler.BorderColor.Alpha
  136. };
  137. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBorderColor, Color);
  138. }
  139. private static bool IsCompressedTextureFormat(GalTextureFormat Format)
  140. {
  141. switch (Format)
  142. {
  143. case GalTextureFormat.BC1:
  144. case GalTextureFormat.BC2:
  145. case GalTextureFormat.BC3:
  146. case GalTextureFormat.BC4:
  147. case GalTextureFormat.BC5:
  148. return true;
  149. }
  150. return false;
  151. }
  152. private int EnsureTextureInitialized(int TexIndex)
  153. {
  154. int Handle = Textures[TexIndex];
  155. if (Handle == 0)
  156. {
  157. Handle = Textures[TexIndex] = GL.GenTexture();
  158. }
  159. return Handle;
  160. }
  161. }
  162. }