TextureStorage.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using OpenTK.Graphics.OpenGL;
  2. using Ryujinx.Common.Logging;
  3. using Ryujinx.Graphics.GAL;
  4. using System;
  5. namespace Ryujinx.Graphics.OpenGL.Image
  6. {
  7. class TextureStorage
  8. {
  9. public int Handle { get; private set; }
  10. public float ScaleFactor { get; private set; }
  11. public TextureCreateInfo Info { get; }
  12. private readonly Renderer _renderer;
  13. private int _viewsCount;
  14. public TextureStorage(Renderer renderer, TextureCreateInfo info, float scaleFactor)
  15. {
  16. _renderer = renderer;
  17. Info = info;
  18. Handle = GL.GenTexture();
  19. ScaleFactor = scaleFactor;
  20. CreateImmutableStorage();
  21. }
  22. private void CreateImmutableStorage()
  23. {
  24. TextureTarget target = Info.Target.Convert();
  25. GL.ActiveTexture(TextureUnit.Texture0);
  26. GL.BindTexture(target, Handle);
  27. int width = (int)Math.Ceiling(Info.Width * ScaleFactor);
  28. int height = (int)Math.Ceiling(Info.Height * ScaleFactor);
  29. FormatInfo format = FormatTable.GetFormatInfo(Info.Format);
  30. SizedInternalFormat internalFormat;
  31. if (format.IsCompressed)
  32. {
  33. internalFormat = (SizedInternalFormat)format.PixelFormat;
  34. }
  35. else
  36. {
  37. internalFormat = (SizedInternalFormat)format.PixelInternalFormat;
  38. }
  39. switch (Info.Target)
  40. {
  41. case Target.Texture1D:
  42. GL.TexStorage1D(
  43. TextureTarget1d.Texture1D,
  44. Info.Levels,
  45. internalFormat,
  46. width);
  47. break;
  48. case Target.Texture1DArray:
  49. GL.TexStorage2D(
  50. TextureTarget2d.Texture1DArray,
  51. Info.Levels,
  52. internalFormat,
  53. width,
  54. height);
  55. break;
  56. case Target.Texture2D:
  57. GL.TexStorage2D(
  58. TextureTarget2d.Texture2D,
  59. Info.Levels,
  60. internalFormat,
  61. width,
  62. height);
  63. break;
  64. case Target.Texture2DArray:
  65. GL.TexStorage3D(
  66. TextureTarget3d.Texture2DArray,
  67. Info.Levels,
  68. internalFormat,
  69. width,
  70. height,
  71. Info.Depth);
  72. break;
  73. case Target.Texture2DMultisample:
  74. GL.TexStorage2DMultisample(
  75. TextureTargetMultisample2d.Texture2DMultisample,
  76. Info.Samples,
  77. internalFormat,
  78. width,
  79. height,
  80. true);
  81. break;
  82. case Target.Texture2DMultisampleArray:
  83. GL.TexStorage3DMultisample(
  84. TextureTargetMultisample3d.Texture2DMultisampleArray,
  85. Info.Samples,
  86. internalFormat,
  87. width,
  88. height,
  89. Info.Depth,
  90. true);
  91. break;
  92. case Target.Texture3D:
  93. GL.TexStorage3D(
  94. TextureTarget3d.Texture3D,
  95. Info.Levels,
  96. internalFormat,
  97. width,
  98. height,
  99. Info.Depth);
  100. break;
  101. case Target.Cubemap:
  102. GL.TexStorage2D(
  103. TextureTarget2d.TextureCubeMap,
  104. Info.Levels,
  105. internalFormat,
  106. width,
  107. height);
  108. break;
  109. case Target.CubemapArray:
  110. GL.TexStorage3D(
  111. (TextureTarget3d)All.TextureCubeMapArray,
  112. Info.Levels,
  113. internalFormat,
  114. width,
  115. height,
  116. Info.Depth);
  117. break;
  118. default:
  119. Logger.PrintDebug(LogClass.Gpu, $"Invalid or unsupported texture target: {target}.");
  120. break;
  121. }
  122. }
  123. public ITexture CreateDefaultView()
  124. {
  125. return CreateView(Info, 0, 0);
  126. }
  127. public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel)
  128. {
  129. IncrementViewsCount();
  130. return new TextureView(_renderer, this, info, firstLayer, firstLevel);
  131. }
  132. private void IncrementViewsCount()
  133. {
  134. _viewsCount++;
  135. }
  136. public void DecrementViewsCount()
  137. {
  138. // If we don't have any views, then the storage is now useless, delete it.
  139. if (--_viewsCount == 0)
  140. {
  141. Dispose();
  142. }
  143. }
  144. public void Dispose()
  145. {
  146. if (Handle != 0)
  147. {
  148. GL.DeleteTexture(Handle);
  149. Handle = 0;
  150. }
  151. }
  152. }
  153. }