OGLTexture.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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. 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 void ConvertAstcTextureToRgba(GalTexture Texture)
  61. {
  62. Texture.Data = ASTCDecoder.DecodeToRGBA8888(
  63. Texture.Data,
  64. GetAstcBlockWidth(Texture.Format),
  65. GetAstcBlockHeight(Texture.Format), 1,
  66. Texture.Width,
  67. Texture.Height, 1);
  68. }
  69. private int GetAstcBlockWidth(GalTextureFormat Format)
  70. {
  71. switch (Format)
  72. {
  73. case GalTextureFormat.Astc2D4x4: return 4;
  74. case GalTextureFormat.Astc2D5x5: return 5;
  75. case GalTextureFormat.Astc2D6x6: return 6;
  76. case GalTextureFormat.Astc2D8x8: return 8;
  77. case GalTextureFormat.Astc2D10x10: return 10;
  78. case GalTextureFormat.Astc2D12x12: return 12;
  79. case GalTextureFormat.Astc2D5x4: return 5;
  80. case GalTextureFormat.Astc2D6x5: return 6;
  81. case GalTextureFormat.Astc2D8x6: return 8;
  82. case GalTextureFormat.Astc2D10x8: return 10;
  83. case GalTextureFormat.Astc2D12x10: return 12;
  84. case GalTextureFormat.Astc2D8x5: return 8;
  85. case GalTextureFormat.Astc2D10x5: return 10;
  86. case GalTextureFormat.Astc2D10x6: return 10;
  87. }
  88. throw new ArgumentException(nameof(Format));
  89. }
  90. private int GetAstcBlockHeight(GalTextureFormat Format)
  91. {
  92. switch (Format)
  93. {
  94. case GalTextureFormat.Astc2D4x4: return 4;
  95. case GalTextureFormat.Astc2D5x5: return 5;
  96. case GalTextureFormat.Astc2D6x6: return 6;
  97. case GalTextureFormat.Astc2D8x8: return 8;
  98. case GalTextureFormat.Astc2D10x10: return 10;
  99. case GalTextureFormat.Astc2D12x12: return 12;
  100. case GalTextureFormat.Astc2D5x4: return 4;
  101. case GalTextureFormat.Astc2D6x5: return 5;
  102. case GalTextureFormat.Astc2D8x6: return 6;
  103. case GalTextureFormat.Astc2D10x8: return 8;
  104. case GalTextureFormat.Astc2D12x10: return 10;
  105. case GalTextureFormat.Astc2D8x5: return 5;
  106. case GalTextureFormat.Astc2D10x5: return 5;
  107. case GalTextureFormat.Astc2D10x6: return 6;
  108. }
  109. throw new ArgumentException(nameof(Format));
  110. }
  111. public void Bind(int Index)
  112. {
  113. int Handle = EnsureTextureInitialized(Index);
  114. GL.BindTexture(TextureTarget.Texture2D, Handle);
  115. }
  116. public static void Set(GalTextureSampler Sampler)
  117. {
  118. int WrapS = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressU);
  119. int WrapT = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressV);
  120. int MinFilter = (int)OGLEnumConverter.GetTextureMinFilter(Sampler.MinFilter, Sampler.MipFilter);
  121. int MagFilter = (int)OGLEnumConverter.GetTextureMagFilter(Sampler.MagFilter);
  122. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, WrapS);
  123. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, WrapT);
  124. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, MinFilter);
  125. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, MagFilter);
  126. float[] Color = new float[]
  127. {
  128. Sampler.BorderColor.Red,
  129. Sampler.BorderColor.Green,
  130. Sampler.BorderColor.Blue,
  131. Sampler.BorderColor.Alpha
  132. };
  133. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBorderColor, Color);
  134. }
  135. private static bool IsCompressedTextureFormat(GalTextureFormat Format)
  136. {
  137. switch (Format)
  138. {
  139. case GalTextureFormat.BC1:
  140. case GalTextureFormat.BC2:
  141. case GalTextureFormat.BC3:
  142. case GalTextureFormat.BC4:
  143. case GalTextureFormat.BC5:
  144. return true;
  145. }
  146. return false;
  147. }
  148. private int EnsureTextureInitialized(int TexIndex)
  149. {
  150. int Handle = Textures[TexIndex];
  151. if (Handle == 0)
  152. {
  153. Handle = Textures[TexIndex] = GL.GenTexture();
  154. }
  155. return Handle;
  156. }
  157. }
  158. }