TextureStorage.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. using OpenTK.Graphics.OpenGL;
  2. using Ryujinx.Common.Logging;
  3. using Ryujinx.Graphics.GAL;
  4. namespace Ryujinx.Graphics.OpenGL.Image
  5. {
  6. class TextureStorage : ITextureInfo
  7. {
  8. public ITextureInfo Storage => this;
  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. internal ITexture DefaultView { get; private set; }
  15. public TextureStorage(Renderer renderer, TextureCreateInfo info, float scaleFactor)
  16. {
  17. _renderer = renderer;
  18. Info = info;
  19. Handle = GL.GenTexture();
  20. ScaleFactor = scaleFactor;
  21. CreateImmutableStorage();
  22. }
  23. private void CreateImmutableStorage()
  24. {
  25. TextureTarget target = Info.Target.Convert();
  26. GL.ActiveTexture(TextureUnit.Texture0);
  27. GL.BindTexture(target, Handle);
  28. FormatInfo format = FormatTable.GetFormatInfo(Info.Format);
  29. SizedInternalFormat internalFormat;
  30. if (format.IsCompressed)
  31. {
  32. internalFormat = (SizedInternalFormat)format.PixelFormat;
  33. }
  34. else
  35. {
  36. internalFormat = (SizedInternalFormat)format.PixelInternalFormat;
  37. }
  38. switch (Info.Target)
  39. {
  40. case Target.Texture1D:
  41. GL.TexStorage1D(
  42. TextureTarget1d.Texture1D,
  43. Info.Levels,
  44. internalFormat,
  45. Info.Width);
  46. break;
  47. case Target.Texture1DArray:
  48. GL.TexStorage2D(
  49. TextureTarget2d.Texture1DArray,
  50. Info.Levels,
  51. internalFormat,
  52. Info.Width,
  53. Info.Height);
  54. break;
  55. case Target.Texture2D:
  56. GL.TexStorage2D(
  57. TextureTarget2d.Texture2D,
  58. Info.Levels,
  59. internalFormat,
  60. Info.Width,
  61. Info.Height);
  62. break;
  63. case Target.Texture2DArray:
  64. GL.TexStorage3D(
  65. TextureTarget3d.Texture2DArray,
  66. Info.Levels,
  67. internalFormat,
  68. Info.Width,
  69. Info.Height,
  70. Info.Depth);
  71. break;
  72. case Target.Texture2DMultisample:
  73. GL.TexStorage2DMultisample(
  74. TextureTargetMultisample2d.Texture2DMultisample,
  75. Info.Samples,
  76. internalFormat,
  77. Info.Width,
  78. Info.Height,
  79. true);
  80. break;
  81. case Target.Texture2DMultisampleArray:
  82. GL.TexStorage3DMultisample(
  83. TextureTargetMultisample3d.Texture2DMultisampleArray,
  84. Info.Samples,
  85. internalFormat,
  86. Info.Width,
  87. Info.Height,
  88. Info.Depth,
  89. true);
  90. break;
  91. case Target.Texture3D:
  92. GL.TexStorage3D(
  93. TextureTarget3d.Texture3D,
  94. Info.Levels,
  95. internalFormat,
  96. Info.Width,
  97. Info.Height,
  98. Info.Depth);
  99. break;
  100. case Target.Cubemap:
  101. GL.TexStorage2D(
  102. TextureTarget2d.TextureCubeMap,
  103. Info.Levels,
  104. internalFormat,
  105. Info.Width,
  106. Info.Height);
  107. break;
  108. case Target.CubemapArray:
  109. GL.TexStorage3D(
  110. (TextureTarget3d)All.TextureCubeMapArray,
  111. Info.Levels,
  112. internalFormat,
  113. Info.Width,
  114. Info.Height,
  115. Info.Depth);
  116. break;
  117. default:
  118. Logger.Debug?.Print(LogClass.Gpu, $"Invalid or unsupported texture target: {target}.");
  119. break;
  120. }
  121. }
  122. public ITexture CreateDefaultView()
  123. {
  124. DefaultView = CreateView(Info, 0, 0);
  125. return DefaultView;
  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. if (DefaultView == null)
  142. {
  143. Dispose();
  144. }
  145. else
  146. {
  147. // If the default view still exists, we can put it into the resource pool.
  148. Release();
  149. }
  150. }
  151. }
  152. /// <summary>
  153. /// Release the TextureStorage to the resource pool without disposing its handle.
  154. /// </summary>
  155. public void Release()
  156. {
  157. _viewsCount = 1; // When we are used again, we will have the default view.
  158. _renderer.ResourcePool.AddTexture((TextureView)DefaultView);
  159. }
  160. public void DeleteDefault()
  161. {
  162. DefaultView = null;
  163. }
  164. public void Dispose()
  165. {
  166. DefaultView = null;
  167. if (Handle != 0)
  168. {
  169. GL.DeleteTexture(Handle);
  170. Handle = 0;
  171. }
  172. }
  173. }
  174. }