TextureCompatibility.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using Ryujinx.Graphics.GAL;
  2. namespace Ryujinx.Graphics.Gpu.Image
  3. {
  4. /// <summary>
  5. /// Texture format compatibility checks.
  6. /// </summary>
  7. static class TextureCompatibility
  8. {
  9. private enum FormatClass
  10. {
  11. Unclassified,
  12. BCn64,
  13. BCn128,
  14. Bc1Rgb,
  15. Bc1Rgba,
  16. Bc2,
  17. Bc3,
  18. Bc4,
  19. Bc5,
  20. Bc6,
  21. Bc7
  22. }
  23. /// <summary>
  24. /// Checks if two formats are compatible, according to the host API copy format compatibility rules.
  25. /// </summary>
  26. /// <param name="lhs">First comparand</param>
  27. /// <param name="rhs">Second comparand</param>
  28. /// <returns>True if the formats are compatible, false otherwise</returns>
  29. public static bool FormatCompatible(FormatInfo lhs, FormatInfo rhs)
  30. {
  31. if (IsDsFormat(lhs.Format) || IsDsFormat(rhs.Format))
  32. {
  33. return lhs.Format == rhs.Format;
  34. }
  35. if (lhs.Format.IsAstc() || rhs.Format.IsAstc())
  36. {
  37. return lhs.Format == rhs.Format;
  38. }
  39. if (lhs.IsCompressed && rhs.IsCompressed)
  40. {
  41. FormatClass lhsClass = GetFormatClass(lhs.Format);
  42. FormatClass rhsClass = GetFormatClass(rhs.Format);
  43. return lhsClass == rhsClass;
  44. }
  45. else
  46. {
  47. return lhs.BytesPerPixel == rhs.BytesPerPixel;
  48. }
  49. }
  50. /// <summary>
  51. /// Gets the texture format class, for compressed textures, or Unclassified otherwise.
  52. /// </summary>
  53. /// <param name="format">The format</param>
  54. /// <returns>Format class</returns>
  55. private static FormatClass GetFormatClass(Format format)
  56. {
  57. switch (format)
  58. {
  59. case Format.Bc1RgbSrgb:
  60. case Format.Bc1RgbUnorm:
  61. return FormatClass.Bc1Rgb;
  62. case Format.Bc1RgbaSrgb:
  63. case Format.Bc1RgbaUnorm:
  64. return FormatClass.Bc1Rgba;
  65. case Format.Bc2Srgb:
  66. case Format.Bc2Unorm:
  67. return FormatClass.Bc2;
  68. case Format.Bc3Srgb:
  69. case Format.Bc3Unorm:
  70. return FormatClass.Bc3;
  71. case Format.Bc4Snorm:
  72. case Format.Bc4Unorm:
  73. return FormatClass.Bc4;
  74. case Format.Bc5Snorm:
  75. case Format.Bc5Unorm:
  76. return FormatClass.Bc5;
  77. case Format.Bc6HSfloat:
  78. case Format.Bc6HUfloat:
  79. return FormatClass.Bc6;
  80. case Format.Bc7Srgb:
  81. case Format.Bc7Unorm:
  82. return FormatClass.Bc7;
  83. }
  84. return FormatClass.Unclassified;
  85. }
  86. /// <summary>
  87. /// Checks if the format is a depth-stencil texture format.
  88. /// </summary>
  89. /// <param name="format">Format to check</param>
  90. /// <returns>True if the format is a depth-stencil format (including depth only), false otherwise</returns>
  91. private static bool IsDsFormat(Format format)
  92. {
  93. switch (format)
  94. {
  95. case Format.D16Unorm:
  96. case Format.D24X8Unorm:
  97. case Format.D24UnormS8Uint:
  98. case Format.D32Float:
  99. case Format.D32FloatS8Uint:
  100. case Format.S8Uint:
  101. return true;
  102. }
  103. return false;
  104. }
  105. }
  106. }