ImageUtils.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. using ChocolArm64.Memory;
  2. using Ryujinx.Graphics.Gal;
  3. using Ryujinx.Graphics.Memory;
  4. using System;
  5. using System.Collections.Generic;
  6. namespace Ryujinx.Graphics.Texture
  7. {
  8. public static class ImageUtils
  9. {
  10. [Flags]
  11. private enum TargetBuffer
  12. {
  13. Color = 1 << 0,
  14. Depth = 1 << 1,
  15. Stencil = 1 << 2,
  16. DepthStencil = Depth | Stencil
  17. }
  18. private struct ImageDescriptor
  19. {
  20. public int BytesPerPixel { get; private set; }
  21. public int BlockWidth { get; private set; }
  22. public int BlockHeight { get; private set; }
  23. public TargetBuffer Target { get; private set; }
  24. public ImageDescriptor(int BytesPerPixel, int BlockWidth, int BlockHeight, TargetBuffer Target)
  25. {
  26. this.BytesPerPixel = BytesPerPixel;
  27. this.BlockWidth = BlockWidth;
  28. this.BlockHeight = BlockHeight;
  29. this.Target = Target;
  30. }
  31. }
  32. private const GalImageFormat Snorm = GalImageFormat.Snorm;
  33. private const GalImageFormat Unorm = GalImageFormat.Unorm;
  34. private const GalImageFormat Sint = GalImageFormat.Sint;
  35. private const GalImageFormat Uint = GalImageFormat.Uint;
  36. private const GalImageFormat Float = GalImageFormat.Float;
  37. private const GalImageFormat Srgb = GalImageFormat.Srgb;
  38. private static readonly Dictionary<GalTextureFormat, GalImageFormat> s_TextureTable =
  39. new Dictionary<GalTextureFormat, GalImageFormat>()
  40. {
  41. { GalTextureFormat.RGBA32, GalImageFormat.RGBA32 | Sint | Uint | Float },
  42. { GalTextureFormat.RGBA16, GalImageFormat.RGBA16 | Snorm | Unorm | Sint | Uint | Float },
  43. { GalTextureFormat.RG32, GalImageFormat.RG32 | Sint | Uint | Float },
  44. { GalTextureFormat.RGBA8, GalImageFormat.RGBA8 | Snorm | Unorm | Sint | Uint | Srgb },
  45. { GalTextureFormat.RGB10A2, GalImageFormat.RGB10A2 | Snorm | Unorm | Sint | Uint },
  46. { GalTextureFormat.RG8, GalImageFormat.RG8 | Snorm | Unorm | Sint | Uint },
  47. { GalTextureFormat.R16, GalImageFormat.R16 | Snorm | Unorm | Sint | Uint | Float },
  48. { GalTextureFormat.R8, GalImageFormat.R8 | Snorm | Unorm | Sint | Uint },
  49. { GalTextureFormat.RG16, GalImageFormat.RG16 | Snorm | Unorm | Float },
  50. { GalTextureFormat.R32, GalImageFormat.R32 | Sint | Uint | Float },
  51. { GalTextureFormat.RGBA4, GalImageFormat.RGBA4 | Unorm },
  52. { GalTextureFormat.RGB5A1, GalImageFormat.RGB5A1 | Unorm },
  53. { GalTextureFormat.RGB565, GalImageFormat.RGB565 | Unorm },
  54. { GalTextureFormat.R11G11B10F, GalImageFormat.R11G11B10 | Float },
  55. { GalTextureFormat.D24S8, GalImageFormat.D24S8 | Unorm | Uint },
  56. { GalTextureFormat.D32F, GalImageFormat.D32 | Float },
  57. { GalTextureFormat.D32FX24S8, GalImageFormat.D32S8 | Float },
  58. { GalTextureFormat.D16, GalImageFormat.D16 | Unorm },
  59. //Compressed formats
  60. { GalTextureFormat.BptcSfloat, GalImageFormat.BptcSfloat | Float },
  61. { GalTextureFormat.BptcUfloat, GalImageFormat.BptcUfloat | Float },
  62. { GalTextureFormat.BptcUnorm, GalImageFormat.BptcUnorm | Unorm | Srgb },
  63. { GalTextureFormat.BC1, GalImageFormat.BC1 | Unorm | Srgb },
  64. { GalTextureFormat.BC2, GalImageFormat.BC2 | Unorm | Srgb },
  65. { GalTextureFormat.BC3, GalImageFormat.BC3 | Unorm | Srgb },
  66. { GalTextureFormat.BC4, GalImageFormat.BC4 | Unorm | Snorm },
  67. { GalTextureFormat.BC5, GalImageFormat.BC5 | Unorm | Snorm },
  68. { GalTextureFormat.Astc2D4x4, GalImageFormat.Astc2D4x4 | Unorm | Srgb },
  69. { GalTextureFormat.Astc2D5x5, GalImageFormat.Astc2D5x5 | Unorm | Srgb },
  70. { GalTextureFormat.Astc2D6x6, GalImageFormat.Astc2D6x6 | Unorm | Srgb },
  71. { GalTextureFormat.Astc2D8x8, GalImageFormat.Astc2D8x8 | Unorm | Srgb },
  72. { GalTextureFormat.Astc2D10x10, GalImageFormat.Astc2D10x10 | Unorm | Srgb },
  73. { GalTextureFormat.Astc2D12x12, GalImageFormat.Astc2D12x12 | Unorm | Srgb },
  74. { GalTextureFormat.Astc2D5x4, GalImageFormat.Astc2D5x4 | Unorm | Srgb },
  75. { GalTextureFormat.Astc2D6x5, GalImageFormat.Astc2D6x5 | Unorm | Srgb },
  76. { GalTextureFormat.Astc2D8x6, GalImageFormat.Astc2D8x6 | Unorm | Srgb },
  77. { GalTextureFormat.Astc2D10x8, GalImageFormat.Astc2D10x8 | Unorm | Srgb },
  78. { GalTextureFormat.Astc2D12x10, GalImageFormat.Astc2D12x10 | Unorm | Srgb },
  79. { GalTextureFormat.Astc2D8x5, GalImageFormat.Astc2D8x5 | Unorm | Srgb },
  80. { GalTextureFormat.Astc2D10x5, GalImageFormat.Astc2D10x5 | Unorm | Srgb },
  81. { GalTextureFormat.Astc2D10x6, GalImageFormat.Astc2D10x6 | Unorm | Srgb }
  82. };
  83. private static readonly Dictionary<GalImageFormat, ImageDescriptor> s_ImageTable =
  84. new Dictionary<GalImageFormat, ImageDescriptor>()
  85. {
  86. { GalImageFormat.RGBA32, new ImageDescriptor(16, 1, 1, TargetBuffer.Color) },
  87. { GalImageFormat.RGBA16, new ImageDescriptor(8, 1, 1, TargetBuffer.Color) },
  88. { GalImageFormat.RG32, new ImageDescriptor(8, 1, 1, TargetBuffer.Color) },
  89. { GalImageFormat.RGBX8, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
  90. { GalImageFormat.RGBA8, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
  91. { GalImageFormat.BGRA8, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
  92. { GalImageFormat.RGB10A2, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
  93. { GalImageFormat.R32, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
  94. { GalImageFormat.RGBA4, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
  95. { GalImageFormat.BptcSfloat, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
  96. { GalImageFormat.BptcUfloat, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
  97. { GalImageFormat.BGR5A1, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
  98. { GalImageFormat.RGB5A1, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
  99. { GalImageFormat.RGB565, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
  100. { GalImageFormat.BptcUnorm, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
  101. { GalImageFormat.RG16, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
  102. { GalImageFormat.RG8, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
  103. { GalImageFormat.R16, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
  104. { GalImageFormat.R8, new ImageDescriptor(1, 1, 1, TargetBuffer.Color) },
  105. { GalImageFormat.R11G11B10, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
  106. { GalImageFormat.BC1, new ImageDescriptor(8, 4, 4, TargetBuffer.Color) },
  107. { GalImageFormat.BC2, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
  108. { GalImageFormat.BC3, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
  109. { GalImageFormat.BC4, new ImageDescriptor(8, 4, 4, TargetBuffer.Color) },
  110. { GalImageFormat.BC5, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
  111. { GalImageFormat.Astc2D4x4, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
  112. { GalImageFormat.Astc2D5x5, new ImageDescriptor(16, 5, 5, TargetBuffer.Color) },
  113. { GalImageFormat.Astc2D6x6, new ImageDescriptor(16, 6, 6, TargetBuffer.Color) },
  114. { GalImageFormat.Astc2D8x8, new ImageDescriptor(16, 8, 8, TargetBuffer.Color) },
  115. { GalImageFormat.Astc2D10x10, new ImageDescriptor(16, 10, 10, TargetBuffer.Color) },
  116. { GalImageFormat.Astc2D12x12, new ImageDescriptor(16, 12, 12, TargetBuffer.Color) },
  117. { GalImageFormat.Astc2D5x4, new ImageDescriptor(16, 5, 4, TargetBuffer.Color) },
  118. { GalImageFormat.Astc2D6x5, new ImageDescriptor(16, 6, 5, TargetBuffer.Color) },
  119. { GalImageFormat.Astc2D8x6, new ImageDescriptor(16, 8, 6, TargetBuffer.Color) },
  120. { GalImageFormat.Astc2D10x8, new ImageDescriptor(16, 10, 8, TargetBuffer.Color) },
  121. { GalImageFormat.Astc2D12x10, new ImageDescriptor(16, 12, 10, TargetBuffer.Color) },
  122. { GalImageFormat.Astc2D8x5, new ImageDescriptor(16, 8, 5, TargetBuffer.Color) },
  123. { GalImageFormat.Astc2D10x5, new ImageDescriptor(16, 10, 5, TargetBuffer.Color) },
  124. { GalImageFormat.Astc2D10x6, new ImageDescriptor(16, 10, 6, TargetBuffer.Color) },
  125. { GalImageFormat.D16, new ImageDescriptor(2, 1, 1, TargetBuffer.Depth) },
  126. { GalImageFormat.D24, new ImageDescriptor(4, 1, 1, TargetBuffer.Depth) },
  127. { GalImageFormat.D24S8, new ImageDescriptor(4, 1, 1, TargetBuffer.DepthStencil) },
  128. { GalImageFormat.D32, new ImageDescriptor(4, 1, 1, TargetBuffer.Depth) },
  129. { GalImageFormat.D32S8, new ImageDescriptor(8, 1, 1, TargetBuffer.DepthStencil) }
  130. };
  131. public static GalImageFormat ConvertTexture(
  132. GalTextureFormat Format,
  133. GalTextureType RType,
  134. GalTextureType GType,
  135. GalTextureType BType,
  136. GalTextureType AType,
  137. bool ConvSrgb)
  138. {
  139. if (RType != GType || RType != BType || RType != AType)
  140. {
  141. throw new NotImplementedException("Per component types are not implemented!");
  142. }
  143. if (!s_TextureTable.TryGetValue(Format, out GalImageFormat ImageFormat))
  144. {
  145. throw new NotImplementedException($"Format 0x{((int)Format):x} not implemented!");
  146. }
  147. GalImageFormat FormatType = ConvSrgb ? Srgb : GetFormatType(RType);
  148. GalImageFormat CombinedFormat = (ImageFormat & GalImageFormat.FormatMask) | FormatType;
  149. if (!ImageFormat.HasFlag(FormatType))
  150. {
  151. throw new NotImplementedException($"Format \"{CombinedFormat}\" not implemented!");
  152. }
  153. return CombinedFormat;
  154. }
  155. public static GalImageFormat ConvertSurface(GalSurfaceFormat Format)
  156. {
  157. switch (Format)
  158. {
  159. case GalSurfaceFormat.RGBA32Float: return GalImageFormat.RGBA32 | Float;
  160. case GalSurfaceFormat.RGBA32Uint: return GalImageFormat.RGBA32 | Uint;
  161. case GalSurfaceFormat.RGBA16Float: return GalImageFormat.RGBA16 | Float;
  162. case GalSurfaceFormat.RG32Float: return GalImageFormat.RG32 | Float;
  163. case GalSurfaceFormat.RG32Sint: return GalImageFormat.RG32 | Sint;
  164. case GalSurfaceFormat.RG32Uint: return GalImageFormat.RG32 | Uint;
  165. case GalSurfaceFormat.BGRA8Unorm: return GalImageFormat.BGRA8 | Unorm;
  166. case GalSurfaceFormat.BGRA8Srgb: return GalImageFormat.BGRA8 | Srgb;
  167. case GalSurfaceFormat.RGB10A2Unorm: return GalImageFormat.RGB10A2 | Unorm;
  168. case GalSurfaceFormat.RGBA8Unorm: return GalImageFormat.RGBA8 | Unorm;
  169. case GalSurfaceFormat.RGBA8Srgb: return GalImageFormat.RGBA8 | Srgb;
  170. case GalSurfaceFormat.RGBA8Snorm: return GalImageFormat.RGBA8 | Snorm;
  171. case GalSurfaceFormat.RG16Snorm: return GalImageFormat.RG16 | Snorm;
  172. case GalSurfaceFormat.RG16Unorm: return GalImageFormat.RG16 | Unorm;
  173. case GalSurfaceFormat.RG16Float: return GalImageFormat.RG16 | Float;
  174. case GalSurfaceFormat.R11G11B10Float: return GalImageFormat.R11G11B10 | Float;
  175. case GalSurfaceFormat.R32Float: return GalImageFormat.R32 | Float;
  176. case GalSurfaceFormat.R32Uint: return GalImageFormat.R32 | Uint;
  177. case GalSurfaceFormat.RG8Unorm: return GalImageFormat.RG8 | Unorm;
  178. case GalSurfaceFormat.RG8Snorm: return GalImageFormat.RG8 | Snorm;
  179. case GalSurfaceFormat.R16Float: return GalImageFormat.R16 | Float;
  180. case GalSurfaceFormat.R16Unorm: return GalImageFormat.R16 | Unorm;
  181. case GalSurfaceFormat.R16Uint: return GalImageFormat.R16 | Uint;
  182. case GalSurfaceFormat.R8Unorm: return GalImageFormat.R8 | Unorm;
  183. case GalSurfaceFormat.R8Uint: return GalImageFormat.R8 | Uint;
  184. case GalSurfaceFormat.B5G6R5Unorm: return GalImageFormat.RGB565 | Unorm;
  185. case GalSurfaceFormat.BGR5A1Unorm: return GalImageFormat.BGR5A1 | Unorm;
  186. case GalSurfaceFormat.RGBX8Unorm: return GalImageFormat.RGBX8 | Unorm;
  187. }
  188. throw new NotImplementedException(Format.ToString());
  189. }
  190. public static GalImageFormat ConvertZeta(GalZetaFormat Format)
  191. {
  192. switch (Format)
  193. {
  194. case GalZetaFormat.D32Float: return GalImageFormat.D32 | Float;
  195. case GalZetaFormat.S8D24Unorm: return GalImageFormat.D24S8 | Unorm;
  196. case GalZetaFormat.D16Unorm: return GalImageFormat.D16 | Unorm;
  197. case GalZetaFormat.D24X8Unorm: return GalImageFormat.D24 | Unorm;
  198. case GalZetaFormat.D24S8Unorm: return GalImageFormat.D24S8 | Unorm;
  199. case GalZetaFormat.D32S8X24Float: return GalImageFormat.D32S8 | Float;
  200. }
  201. throw new NotImplementedException(Format.ToString());
  202. }
  203. public static byte[] ReadTexture(IMemory Memory, GalImage Image, long Position)
  204. {
  205. MemoryManager CpuMemory;
  206. if (Memory is NvGpuVmm Vmm)
  207. {
  208. CpuMemory = Vmm.Memory;
  209. }
  210. else
  211. {
  212. CpuMemory = (MemoryManager)Memory;
  213. }
  214. ISwizzle Swizzle = TextureHelper.GetSwizzle(Image);
  215. ImageDescriptor Desc = GetImageDescriptor(Image.Format);
  216. (int Width, int Height) = GetImageSizeInBlocks(Image);
  217. int BytesPerPixel = Desc.BytesPerPixel;
  218. //Note: Each row of the texture needs to be aligned to 4 bytes.
  219. int Pitch = (Width * BytesPerPixel + 3) & ~3;
  220. byte[] Data = new byte[Height * Pitch];
  221. for (int Y = 0; Y < Height; Y++)
  222. {
  223. int OutOffs = Y * Pitch;
  224. for (int X = 0; X < Width; X++)
  225. {
  226. long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);
  227. CpuMemory.ReadBytes(Position + Offset, Data, OutOffs, BytesPerPixel);
  228. OutOffs += BytesPerPixel;
  229. }
  230. }
  231. return Data;
  232. }
  233. public static void WriteTexture(NvGpuVmm Vmm, GalImage Image, long Position, byte[] Data)
  234. {
  235. ISwizzle Swizzle = TextureHelper.GetSwizzle(Image);
  236. ImageDescriptor Desc = GetImageDescriptor(Image.Format);
  237. (int Width, int Height) = ImageUtils.GetImageSizeInBlocks(Image);
  238. int BytesPerPixel = Desc.BytesPerPixel;
  239. int InOffs = 0;
  240. for (int Y = 0; Y < Height; Y++)
  241. for (int X = 0; X < Width; X++)
  242. {
  243. long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);
  244. Vmm.Memory.WriteBytes(Position + Offset, Data, InOffs, BytesPerPixel);
  245. InOffs += BytesPerPixel;
  246. }
  247. }
  248. public static bool CopyTexture(
  249. NvGpuVmm Vmm,
  250. GalImage SrcImage,
  251. GalImage DstImage,
  252. long SrcAddress,
  253. long DstAddress,
  254. int SrcX,
  255. int SrcY,
  256. int DstX,
  257. int DstY,
  258. int Width,
  259. int Height)
  260. {
  261. ISwizzle SrcSwizzle = TextureHelper.GetSwizzle(SrcImage);
  262. ISwizzle DstSwizzle = TextureHelper.GetSwizzle(DstImage);
  263. ImageDescriptor Desc = GetImageDescriptor(SrcImage.Format);
  264. if (GetImageDescriptor(DstImage.Format).BytesPerPixel != Desc.BytesPerPixel)
  265. {
  266. return false;
  267. }
  268. int BytesPerPixel = Desc.BytesPerPixel;
  269. for (int Y = 0; Y < Height; Y++)
  270. for (int X = 0; X < Width; X++)
  271. {
  272. long SrcOffset = (uint)SrcSwizzle.GetSwizzleOffset(SrcX + X, SrcY + Y);
  273. long DstOffset = (uint)DstSwizzle.GetSwizzleOffset(DstX + X, DstY + Y);
  274. byte[] Texel = Vmm.ReadBytes(SrcAddress + SrcOffset, BytesPerPixel);
  275. Vmm.WriteBytes(DstAddress + DstOffset, Texel);
  276. }
  277. return true;
  278. }
  279. public static int GetSize(GalImage Image)
  280. {
  281. ImageDescriptor Desc = GetImageDescriptor(Image.Format);
  282. int Width = DivRoundUp(Image.Width, Desc.BlockWidth);
  283. int Height = DivRoundUp(Image.Height, Desc.BlockHeight);
  284. return Desc.BytesPerPixel * Width * Height;
  285. }
  286. public static int GetPitch(GalImageFormat Format, int Width)
  287. {
  288. ImageDescriptor Desc = GetImageDescriptor(Format);
  289. int Pitch = Desc.BytesPerPixel * DivRoundUp(Width, Desc.BlockWidth);
  290. Pitch = (Pitch + 0x1f) & ~0x1f;
  291. return Pitch;
  292. }
  293. public static int GetBlockWidth(GalImageFormat Format)
  294. {
  295. return GetImageDescriptor(Format).BlockWidth;
  296. }
  297. public static int GetBlockHeight(GalImageFormat Format)
  298. {
  299. return GetImageDescriptor(Format).BlockHeight;
  300. }
  301. public static int GetAlignedWidth(GalImage Image)
  302. {
  303. ImageDescriptor Desc = GetImageDescriptor(Image.Format);
  304. int AlignMask;
  305. if (Image.Layout == GalMemoryLayout.BlockLinear)
  306. {
  307. AlignMask = Image.TileWidth * (64 / Desc.BytesPerPixel) - 1;
  308. }
  309. else
  310. {
  311. AlignMask = (32 / Desc.BytesPerPixel) - 1;
  312. }
  313. return (Image.Width + AlignMask) & ~AlignMask;
  314. }
  315. public static (int Width, int Height) GetImageSizeInBlocks(GalImage Image)
  316. {
  317. ImageDescriptor Desc = GetImageDescriptor(Image.Format);
  318. return (DivRoundUp(Image.Width, Desc.BlockWidth),
  319. DivRoundUp(Image.Height, Desc.BlockHeight));
  320. }
  321. public static int GetBytesPerPixel(GalImageFormat Format)
  322. {
  323. return GetImageDescriptor(Format).BytesPerPixel;
  324. }
  325. private static int DivRoundUp(int LHS, int RHS)
  326. {
  327. return (LHS + (RHS - 1)) / RHS;
  328. }
  329. public static bool HasColor(GalImageFormat Format)
  330. {
  331. return (GetImageDescriptor(Format).Target & TargetBuffer.Color) != 0;
  332. }
  333. public static bool HasDepth(GalImageFormat Format)
  334. {
  335. return (GetImageDescriptor(Format).Target & TargetBuffer.Depth) != 0;
  336. }
  337. public static bool HasStencil(GalImageFormat Format)
  338. {
  339. return (GetImageDescriptor(Format).Target & TargetBuffer.Stencil) != 0;
  340. }
  341. public static bool IsCompressed(GalImageFormat Format)
  342. {
  343. ImageDescriptor Desc = GetImageDescriptor(Format);
  344. return (Desc.BlockWidth | Desc.BlockHeight) != 1;
  345. }
  346. private static ImageDescriptor GetImageDescriptor(GalImageFormat Format)
  347. {
  348. GalImageFormat PixelFormat = Format & GalImageFormat.FormatMask;
  349. if (s_ImageTable.TryGetValue(PixelFormat, out ImageDescriptor Descriptor))
  350. {
  351. return Descriptor;
  352. }
  353. throw new NotImplementedException($"Format \"{PixelFormat}\" not implemented!");
  354. }
  355. private static GalImageFormat GetFormatType(GalTextureType Type)
  356. {
  357. switch (Type)
  358. {
  359. case GalTextureType.Snorm: return Snorm;
  360. case GalTextureType.Unorm: return Unorm;
  361. case GalTextureType.Sint: return Sint;
  362. case GalTextureType.Uint: return Uint;
  363. case GalTextureType.Float: return Float;
  364. default: throw new NotImplementedException(((int)Type).ToString());
  365. }
  366. }
  367. }
  368. }