TextureFormatUtilities.cs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine.Assertions;
  4. namespace UnityEngine.Rendering.PostProcessing
  5. {
  6. // Temporary code dump until the texture format refactor goes into trunk...
  7. /// <summary>
  8. /// A set of utilities to deal with texture formats.
  9. /// </summary>
  10. public static class TextureFormatUtilities
  11. {
  12. static Dictionary<int, RenderTextureFormat> s_FormatAliasMap;
  13. static Dictionary<int, bool> s_SupportedRenderTextureFormats;
  14. static Dictionary<int, bool> s_SupportedTextureFormats;
  15. static TextureFormatUtilities()
  16. {
  17. s_FormatAliasMap = new Dictionary<int, RenderTextureFormat>
  18. {
  19. { (int)TextureFormat.Alpha8, RenderTextureFormat.ARGB32 },
  20. { (int)TextureFormat.ARGB4444, RenderTextureFormat.ARGB4444 },
  21. { (int)TextureFormat.RGB24, RenderTextureFormat.ARGB32 },
  22. { (int)TextureFormat.RGBA32, RenderTextureFormat.ARGB32 },
  23. { (int)TextureFormat.ARGB32, RenderTextureFormat.ARGB32 },
  24. { (int)TextureFormat.RGB565, RenderTextureFormat.RGB565 },
  25. { (int)TextureFormat.R16, RenderTextureFormat.RHalf },
  26. { (int)TextureFormat.DXT1, RenderTextureFormat.ARGB32 },
  27. { (int)TextureFormat.DXT5, RenderTextureFormat.ARGB32 },
  28. { (int)TextureFormat.RGBA4444, RenderTextureFormat.ARGB4444 },
  29. { (int)TextureFormat.BGRA32, RenderTextureFormat.ARGB32 },
  30. { (int)TextureFormat.RHalf, RenderTextureFormat.RHalf },
  31. { (int)TextureFormat.RGHalf, RenderTextureFormat.RGHalf },
  32. { (int)TextureFormat.RGBAHalf, RenderTextureFormat.ARGBHalf },
  33. { (int)TextureFormat.RFloat, RenderTextureFormat.RFloat },
  34. { (int)TextureFormat.RGFloat, RenderTextureFormat.RGFloat },
  35. { (int)TextureFormat.RGBAFloat, RenderTextureFormat.ARGBFloat },
  36. { (int)TextureFormat.RGB9e5Float, RenderTextureFormat.ARGBHalf },
  37. { (int)TextureFormat.BC4, RenderTextureFormat.R8 },
  38. { (int)TextureFormat.BC5, RenderTextureFormat.RGHalf },
  39. { (int)TextureFormat.BC6H, RenderTextureFormat.ARGBHalf },
  40. { (int)TextureFormat.BC7, RenderTextureFormat.ARGB32 },
  41. #if !UNITY_IOS && !UNITY_TVOS
  42. { (int)TextureFormat.DXT1Crunched, RenderTextureFormat.ARGB32 },
  43. { (int)TextureFormat.DXT5Crunched, RenderTextureFormat.ARGB32 },
  44. #endif
  45. { (int)TextureFormat.PVRTC_RGB2, RenderTextureFormat.ARGB32 },
  46. { (int)TextureFormat.PVRTC_RGBA2, RenderTextureFormat.ARGB32 },
  47. { (int)TextureFormat.PVRTC_RGB4, RenderTextureFormat.ARGB32 },
  48. { (int)TextureFormat.PVRTC_RGBA4, RenderTextureFormat.ARGB32 },
  49. #if !UNITY_2018_1_OR_NEWER
  50. { (int)TextureFormat.ATC_RGB4, RenderTextureFormat.ARGB32 },
  51. { (int)TextureFormat.ATC_RGBA8, RenderTextureFormat.ARGB32 },
  52. #endif
  53. { (int)TextureFormat.ETC_RGB4, RenderTextureFormat.ARGB32 },
  54. { (int)TextureFormat.ETC2_RGB, RenderTextureFormat.ARGB32 },
  55. { (int)TextureFormat.ETC2_RGBA1, RenderTextureFormat.ARGB32 },
  56. { (int)TextureFormat.ETC2_RGBA8, RenderTextureFormat.ARGB32 },
  57. #if UNITY_2019_1_OR_NEWER
  58. { (int)TextureFormat.ASTC_4x4, RenderTextureFormat.ARGB32 },
  59. { (int)TextureFormat.ASTC_5x5, RenderTextureFormat.ARGB32 },
  60. { (int)TextureFormat.ASTC_6x6, RenderTextureFormat.ARGB32 },
  61. { (int)TextureFormat.ASTC_8x8, RenderTextureFormat.ARGB32 },
  62. { (int)TextureFormat.ASTC_10x10, RenderTextureFormat.ARGB32 },
  63. { (int)TextureFormat.ASTC_12x12, RenderTextureFormat.ARGB32 },
  64. #else
  65. { (int)TextureFormat.ASTC_RGB_4x4, RenderTextureFormat.ARGB32 },
  66. { (int)TextureFormat.ASTC_RGB_5x5, RenderTextureFormat.ARGB32 },
  67. { (int)TextureFormat.ASTC_RGB_6x6, RenderTextureFormat.ARGB32 },
  68. { (int)TextureFormat.ASTC_RGB_8x8, RenderTextureFormat.ARGB32 },
  69. { (int)TextureFormat.ASTC_RGB_10x10, RenderTextureFormat.ARGB32 },
  70. { (int)TextureFormat.ASTC_RGB_12x12, RenderTextureFormat.ARGB32 },
  71. { (int)TextureFormat.ASTC_RGBA_4x4, RenderTextureFormat.ARGB32 },
  72. { (int)TextureFormat.ASTC_RGBA_5x5, RenderTextureFormat.ARGB32 },
  73. { (int)TextureFormat.ASTC_RGBA_6x6, RenderTextureFormat.ARGB32 },
  74. { (int)TextureFormat.ASTC_RGBA_8x8, RenderTextureFormat.ARGB32 },
  75. { (int)TextureFormat.ASTC_RGBA_10x10, RenderTextureFormat.ARGB32 },
  76. { (int)TextureFormat.ASTC_RGBA_12x12, RenderTextureFormat.ARGB32 },
  77. #endif
  78. #if !UNITY_2018_3_OR_NEWER
  79. { (int)TextureFormat.ETC_RGB4_3DS, RenderTextureFormat.ARGB32 },
  80. { (int)TextureFormat.ETC_RGBA8_3DS, RenderTextureFormat.ARGB32 }
  81. #endif
  82. };
  83. // TODO: refactor the next two scopes in a generic function once we have support for enum constraints on generics
  84. // In 2018.1 SystemInfo.SupportsRenderTextureFormat() generates garbage so we need to
  85. // cache its calls to avoid that...
  86. {
  87. s_SupportedRenderTextureFormats = new Dictionary<int, bool>();
  88. var values = Enum.GetValues(typeof(RenderTextureFormat));
  89. foreach (var format in values)
  90. {
  91. if ((int)format < 0) // Safe guard, negative values are deprecated stuff
  92. continue;
  93. if (IsObsolete(format))
  94. continue;
  95. bool supported = SystemInfo.SupportsRenderTextureFormat((RenderTextureFormat)format);
  96. s_SupportedRenderTextureFormats[(int)format] = supported;
  97. }
  98. }
  99. // Same for TextureFormat
  100. {
  101. s_SupportedTextureFormats = new Dictionary<int, bool>();
  102. var values = Enum.GetValues(typeof(TextureFormat));
  103. foreach (var format in values)
  104. {
  105. if ((int)format < 0) // Crashes the runtime otherwise (!)
  106. continue;
  107. if (IsObsolete(format))
  108. continue;
  109. bool supported = SystemInfo.SupportsTextureFormat((TextureFormat)format);
  110. s_SupportedTextureFormats[(int)format] = supported;
  111. }
  112. }
  113. }
  114. static bool IsObsolete(object value)
  115. {
  116. var fieldInfo = value.GetType().GetField(value.ToString());
  117. var attributes = (ObsoleteAttribute[])fieldInfo.GetCustomAttributes(typeof(ObsoleteAttribute), false);
  118. return attributes != null && attributes.Length > 0;
  119. }
  120. /// <summary>
  121. /// Returns a <see cref="RenderTextureFormat"/> compatible with the given texture's format.
  122. /// </summary>
  123. /// <param name="texture">A texture to get a compatible format from</param>
  124. /// <returns>A compatible render texture format</returns>
  125. public static RenderTextureFormat GetUncompressedRenderTextureFormat(Texture texture)
  126. {
  127. Assert.IsNotNull(texture);
  128. if (texture is RenderTexture)
  129. return (texture as RenderTexture).format;
  130. if (texture is Texture2D)
  131. {
  132. var inFormat = ((Texture2D)texture).format;
  133. RenderTextureFormat outFormat;
  134. if (!s_FormatAliasMap.TryGetValue((int)inFormat, out outFormat))
  135. throw new NotSupportedException("Texture format not supported");
  136. return outFormat;
  137. }
  138. return RenderTextureFormat.Default;
  139. }
  140. internal static bool IsSupported(this RenderTextureFormat format)
  141. {
  142. bool supported;
  143. s_SupportedRenderTextureFormats.TryGetValue((int)format, out supported);
  144. return supported;
  145. }
  146. internal static bool IsSupported(this TextureFormat format)
  147. {
  148. bool supported;
  149. s_SupportedTextureFormats.TryGetValue((int)format, out supported);
  150. return supported;
  151. }
  152. }
  153. }