MTLVertexFormat.mm 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // Copyright 2022 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "VideoBackends/Metal/MTLVertexFormat.h"
  4. #include "VideoCommon/VertexShaderGen.h"
  5. static MTLVertexFormat ConvertFormat(ComponentFormat format, int count, bool int_format)
  6. {
  7. // clang-format off
  8. if (int_format)
  9. {
  10. switch (format)
  11. {
  12. case ComponentFormat::UByte:
  13. switch (count)
  14. {
  15. case 1: return MTLVertexFormatUChar;
  16. case 2: return MTLVertexFormatUChar2;
  17. case 3: return MTLVertexFormatUChar3;
  18. case 4: return MTLVertexFormatUChar4;
  19. default: return MTLVertexFormatInvalid;
  20. }
  21. case ComponentFormat::Byte:
  22. switch (count)
  23. {
  24. case 1: return MTLVertexFormatChar;
  25. case 2: return MTLVertexFormatChar2;
  26. case 3: return MTLVertexFormatChar3;
  27. case 4: return MTLVertexFormatChar4;
  28. default: return MTLVertexFormatInvalid;
  29. }
  30. case ComponentFormat::UShort:
  31. switch (count)
  32. {
  33. case 1: return MTLVertexFormatUShort;
  34. case 2: return MTLVertexFormatUShort2;
  35. case 3: return MTLVertexFormatUShort3;
  36. case 4: return MTLVertexFormatUShort4;
  37. default: return MTLVertexFormatInvalid;
  38. }
  39. case ComponentFormat::Short:
  40. switch (count)
  41. {
  42. case 1: return MTLVertexFormatShort;
  43. case 2: return MTLVertexFormatShort2;
  44. case 3: return MTLVertexFormatShort3;
  45. case 4: return MTLVertexFormatShort4;
  46. default: return MTLVertexFormatInvalid;
  47. }
  48. case ComponentFormat::Float:
  49. case ComponentFormat::InvalidFloat5:
  50. case ComponentFormat::InvalidFloat6:
  51. case ComponentFormat::InvalidFloat7:
  52. switch (count)
  53. {
  54. case 1: return MTLVertexFormatFloat;
  55. case 2: return MTLVertexFormatFloat2;
  56. case 3: return MTLVertexFormatFloat3;
  57. case 4: return MTLVertexFormatFloat4;
  58. default: return MTLVertexFormatInvalid;
  59. }
  60. }
  61. }
  62. else
  63. {
  64. switch (format)
  65. {
  66. case ComponentFormat::UByte:
  67. switch (count)
  68. {
  69. case 1: return MTLVertexFormatUCharNormalized;
  70. case 2: return MTLVertexFormatUChar2Normalized;
  71. case 3: return MTLVertexFormatUChar3Normalized;
  72. case 4: return MTLVertexFormatUChar4Normalized;
  73. default: return MTLVertexFormatInvalid;
  74. }
  75. case ComponentFormat::Byte:
  76. switch (count)
  77. {
  78. case 1: return MTLVertexFormatCharNormalized;
  79. case 2: return MTLVertexFormatChar2Normalized;
  80. case 3: return MTLVertexFormatChar3Normalized;
  81. case 4: return MTLVertexFormatChar4Normalized;
  82. default: return MTLVertexFormatInvalid;
  83. }
  84. case ComponentFormat::UShort:
  85. switch (count)
  86. {
  87. case 1: return MTLVertexFormatUShortNormalized;
  88. case 2: return MTLVertexFormatUShort2Normalized;
  89. case 3: return MTLVertexFormatUShort3Normalized;
  90. case 4: return MTLVertexFormatUShort4Normalized;
  91. default: return MTLVertexFormatInvalid;
  92. }
  93. case ComponentFormat::Short:
  94. switch (count)
  95. {
  96. case 1: return MTLVertexFormatShortNormalized;
  97. case 2: return MTLVertexFormatShort2Normalized;
  98. case 3: return MTLVertexFormatShort3Normalized;
  99. case 4: return MTLVertexFormatShort4Normalized;
  100. default: return MTLVertexFormatInvalid;
  101. }
  102. case ComponentFormat::Float:
  103. case ComponentFormat::InvalidFloat5:
  104. case ComponentFormat::InvalidFloat6:
  105. case ComponentFormat::InvalidFloat7:
  106. switch (count)
  107. {
  108. case 1: return MTLVertexFormatFloat;
  109. case 2: return MTLVertexFormatFloat2;
  110. case 3: return MTLVertexFormatFloat3;
  111. case 4: return MTLVertexFormatFloat4;
  112. default: return MTLVertexFormatInvalid;
  113. }
  114. }
  115. }
  116. // clang-format on
  117. }
  118. static void SetAttribute(MTLVertexDescriptor* desc, ShaderAttrib attribute,
  119. const AttributeFormat& format)
  120. {
  121. if (!format.enable)
  122. return;
  123. MTLVertexAttributeDescriptor* attr_desc =
  124. [[desc attributes] objectAtIndexedSubscript:(u32)attribute];
  125. [attr_desc setFormat:ConvertFormat(format.type, format.components, format.integer)];
  126. [attr_desc setOffset:format.offset];
  127. [attr_desc setBufferIndex:0];
  128. }
  129. template <size_t N>
  130. static void SetAttributes(MTLVertexDescriptor* desc, ShaderAttrib attribute,
  131. const std::array<AttributeFormat, N>& format)
  132. {
  133. for (size_t i = 0; i < N; ++i)
  134. SetAttribute(desc, attribute + i, format[i]);
  135. }
  136. Metal::VertexFormat::VertexFormat(const PortableVertexDeclaration& vtx_decl)
  137. : NativeVertexFormat(vtx_decl), m_desc(MRCTransfer([MTLVertexDescriptor new]))
  138. {
  139. [[[m_desc layouts] objectAtIndexedSubscript:0] setStride:vtx_decl.stride];
  140. SetAttribute(m_desc, ShaderAttrib::Position, vtx_decl.position);
  141. SetAttributes(m_desc, ShaderAttrib::Normal, vtx_decl.normals);
  142. SetAttributes(m_desc, ShaderAttrib::Color0, vtx_decl.colors);
  143. SetAttributes(m_desc, ShaderAttrib::TexCoord0, vtx_decl.texcoords);
  144. SetAttribute(m_desc, ShaderAttrib::PositionMatrix, vtx_decl.posmtx);
  145. }