AttachmentEnums.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <Atom/RHI.Reflect/AttachmentEnums.h>
  9. #include <AzCore/std/containers/array.h>
  10. namespace AZ::RHI
  11. {
  12. HardwareQueueClassMask GetHardwareQueueClassMask(HardwareQueueClass hardwareQueueClass)
  13. {
  14. return static_cast<HardwareQueueClassMask>(AZ_BIT(static_cast<uint32_t>(hardwareQueueClass)));
  15. }
  16. const char* GetHardwareQueueClassName(HardwareQueueClass hardwareQueueClass)
  17. {
  18. AZStd::array<const char*, 3> nameTable =
  19. {{
  20. "Graphics",
  21. "Compute",
  22. "Copy"
  23. }};
  24. return nameTable[static_cast<size_t>(hardwareQueueClass)];
  25. }
  26. HardwareQueueClass GetMostCapableHardwareQueue(HardwareQueueClassMask queueMask)
  27. {
  28. if (CheckBitsAny(queueMask, HardwareQueueClassMask::Graphics))
  29. {
  30. return HardwareQueueClass::Graphics;
  31. }
  32. else if (CheckBitsAny(queueMask, HardwareQueueClassMask::Compute))
  33. {
  34. return HardwareQueueClass::Compute;
  35. }
  36. else
  37. {
  38. return HardwareQueueClass::Copy;
  39. }
  40. }
  41. bool IsHardwareQueueMoreCapable(HardwareQueueClass queueA, HardwareQueueClass queueB)
  42. {
  43. return queueA < queueB;
  44. }
  45. const char* ToString(ScopeAttachmentAccess attachmentAccess)
  46. {
  47. switch (attachmentAccess)
  48. {
  49. case ScopeAttachmentAccess::Read:
  50. return "Read";
  51. case ScopeAttachmentAccess::ReadWrite:
  52. return "ReadWrite";
  53. case ScopeAttachmentAccess::Write:
  54. return "Write";
  55. default:
  56. AZ_Assert(false, "Unkown ScopeAttachmentAccess: %d", static_cast<uint32_t>(attachmentAccess));
  57. return "Unknown";
  58. }
  59. }
  60. const char* ToString(ScopeAttachmentUsage attachmentUsage)
  61. {
  62. switch (attachmentUsage)
  63. {
  64. case ScopeAttachmentUsage::RenderTarget:
  65. return "RenderTarget";
  66. case ScopeAttachmentUsage::DepthStencil:
  67. return "DepthStencil";
  68. case ScopeAttachmentUsage::SubpassInput:
  69. return "SubpassInput";
  70. case ScopeAttachmentUsage::Shader:
  71. return "Shader";
  72. case ScopeAttachmentUsage::Copy:
  73. return "Copy";
  74. case ScopeAttachmentUsage::Resolve:
  75. return "Resolve";
  76. case ScopeAttachmentUsage::Predication:
  77. return "Predication";
  78. case ScopeAttachmentUsage::Indirect:
  79. return "Indirect";
  80. case ScopeAttachmentUsage::InputAssembly:
  81. return "InputAssembly";
  82. case ScopeAttachmentUsage::ShadingRate:
  83. return "ShadingRate";
  84. case ScopeAttachmentUsage::Uninitialized:
  85. return "Uninitialized";
  86. default:
  87. AZ_Assert(false, "Unkown ScopeAttachmentUsage: %d", static_cast<uint32_t>(attachmentUsage));
  88. return "Unknown";
  89. }
  90. }
  91. AZStd::string ToString(ScopeAttachmentStage attachmentStage)
  92. {
  93. if (attachmentStage == ScopeAttachmentStage::Uninitialized)
  94. {
  95. return "Uninitialized";
  96. }
  97. AZStd::string stages;
  98. if (CheckBitsAll(attachmentStage, ScopeAttachmentStage::VertexShader))
  99. {
  100. stages += "VertexShader|";
  101. }
  102. if (CheckBitsAll(attachmentStage, ScopeAttachmentStage::FragmentShader))
  103. {
  104. stages += "FragmentShader|";
  105. }
  106. if (CheckBitsAll(attachmentStage, ScopeAttachmentStage::ComputeShader))
  107. {
  108. stages += "ComputeShader|";
  109. }
  110. if (CheckBitsAll(attachmentStage, ScopeAttachmentStage::RayTracingShader))
  111. {
  112. stages += "RayTracingShader|";
  113. }
  114. if (CheckBitsAll(attachmentStage, ScopeAttachmentStage::EarlyFragmentTest))
  115. {
  116. stages += "EarlyFragmentTest|";
  117. }
  118. if (CheckBitsAll(attachmentStage, ScopeAttachmentStage::LateFragmentTest))
  119. {
  120. stages += "LateFragmentTest|";
  121. }
  122. if (CheckBitsAll(attachmentStage, ScopeAttachmentStage::ColorAttachmentOutput))
  123. {
  124. stages += "ColorAttachmentOutput|";
  125. }
  126. if (CheckBitsAll(attachmentStage, ScopeAttachmentStage::Copy))
  127. {
  128. stages += "Copy|";
  129. }
  130. if (CheckBitsAll(attachmentStage, ScopeAttachmentStage::Predication))
  131. {
  132. stages += "Predication|";
  133. }
  134. if (CheckBitsAll(attachmentStage, ScopeAttachmentStage::DrawIndirect))
  135. {
  136. stages += "DrawIndirect|";
  137. }
  138. if (CheckBitsAll(attachmentStage, ScopeAttachmentStage::VertexInput))
  139. {
  140. stages += "VertexInput|";
  141. }
  142. if (CheckBitsAll(attachmentStage, ScopeAttachmentStage::ShadingRate))
  143. {
  144. stages += "ShadingRate|";
  145. }
  146. if (!stages.empty())
  147. {
  148. stages.pop_back();
  149. }
  150. return stages;
  151. }
  152. const char* ToString(ScopeAttachmentUsage usage, ScopeAttachmentAccess acess)
  153. {
  154. switch (usage)
  155. {
  156. case ScopeAttachmentUsage::RenderTarget:
  157. return "RenderTarget";
  158. case ScopeAttachmentUsage::DepthStencil:
  159. return CheckBitsAny(acess, ScopeAttachmentAccess::Write) ? "DepthStencilReadWrite" : "DepthStencilRead";
  160. case ScopeAttachmentUsage::SubpassInput:
  161. return "SubpassInput";
  162. case ScopeAttachmentUsage::Shader:
  163. return CheckBitsAny(acess, ScopeAttachmentAccess::Write) ? "ShaderReadWrite" : "ShaderRead";
  164. case ScopeAttachmentUsage::Copy:
  165. return CheckBitsAny(acess, ScopeAttachmentAccess::Write) ? "CopyDest" : "CopySource";
  166. case ScopeAttachmentUsage::Predication:
  167. return "Predication";
  168. case ScopeAttachmentUsage::InputAssembly:
  169. return "InputAssembly";
  170. case ScopeAttachmentUsage::ShadingRate:
  171. return "ShadingRate";
  172. case ScopeAttachmentUsage::Resolve:
  173. return "Resolve";
  174. case ScopeAttachmentUsage::Indirect:
  175. return "Indirect";
  176. case ScopeAttachmentUsage::Uninitialized:
  177. return "Uninitialized";
  178. }
  179. return "Unknown";
  180. }
  181. ScopeAttachmentAccess AdjustAccessBasedOnUsage(ScopeAttachmentAccess access, ScopeAttachmentUsage usage)
  182. {
  183. switch (usage)
  184. {
  185. // Remap read/write to write for Color scope attachments. This is because from a user standpoint, an attachment
  186. // might be an input/output to a pass (which maps to read/write) but still be used as a render target (write).
  187. // We disallow read access and throw an error because having a read access on a render target is nonsensical.
  188. case ScopeAttachmentUsage::RenderTarget:
  189. AZ_Error("ScopeAttachment", access != ScopeAttachmentAccess::Read, "ScopeAttachmentAccess cannot be 'Read' when usage is 'RenderTarget'.");
  190. return ScopeAttachmentAccess::Write;
  191. // Remap read/write to write for DepthStencil scope attachments. This is because from a user standpoint, an attachment
  192. // might be an input/output to a pass (which maps to read/write) but still be used as a render target (write).
  193. case ScopeAttachmentUsage::DepthStencil:
  194. if (access == ScopeAttachmentAccess::ReadWrite)
  195. {
  196. return ScopeAttachmentAccess::Write;
  197. }
  198. return access;
  199. // Remap read/write to read for Subpass input scope attachments.
  200. // We disallow write access and throw an error because having a write access on an subpass input attachment is nonsensical.
  201. case ScopeAttachmentUsage::SubpassInput:
  202. AZ_Error("ScopeAttachment", access == ScopeAttachmentAccess::Read, "ScopeAttachmentAccess cannot be 'Write' when usage is 'SubpassInput'.");
  203. return ScopeAttachmentAccess::Read;
  204. // Remap write to read/write for Shader scope attachments. This is because
  205. // a write Shader scope is a UAV under the hood, and UAVs are read/write.
  206. case ScopeAttachmentUsage::Shader:
  207. if (access == ScopeAttachmentAccess::Write)
  208. {
  209. return ScopeAttachmentAccess::ReadWrite;
  210. }
  211. return access;
  212. // Disallow read/write access for Copy scope attachments as this is nonsensical, Copy operations
  213. // have only sources and destinations. We remap read/write to write as a fallback.
  214. case ScopeAttachmentUsage::Copy:
  215. AZ_Error("ScopeAttachment", access != ScopeAttachmentAccess::ReadWrite, "ScopeAttachmentAccess cannot be 'ReadWrite' when usage is 'Copy'.");
  216. if (access == ScopeAttachmentAccess::ReadWrite)
  217. {
  218. return ScopeAttachmentAccess::Write;
  219. }
  220. return access;
  221. case ScopeAttachmentUsage::InputAssembly:
  222. AZ_Error("ScopeAttachment", !RHI::CheckBitsAll(access, ScopeAttachmentAccess::Write), "ScopeAttachmentAccess cannot be 'Write' when usage is 'InputAssembly'.");
  223. return ScopeAttachmentAccess::Read;
  224. // Remap read/write to read for ShadingRate scope attachments.
  225. // We disallow write access and throw an error because having a write access on an ShadingRate input attachment is not allowed.
  226. case ScopeAttachmentUsage::ShadingRate:
  227. AZ_Error(
  228. "ScopeAttachment",
  229. access == ScopeAttachmentAccess::Read,
  230. "ScopeAttachmentAccess cannot be 'Write' when usage is 'ShadingRate'.");
  231. return ScopeAttachmentAccess::Read;
  232. // No access adjustment for Resolve or Predication
  233. case ScopeAttachmentUsage::Resolve:
  234. return access;
  235. case ScopeAttachmentUsage::Predication:
  236. return access;
  237. case ScopeAttachmentUsage::Indirect:
  238. AZ_Error(
  239. "ScopeAttachment",
  240. !RHI::CheckBitsAll(access, ScopeAttachmentAccess::Write),
  241. "ScopeAttachmentAccess cannot be 'Write' when usage is 'Indirect'.");
  242. return ScopeAttachmentAccess::Read;
  243. case ScopeAttachmentUsage::Uninitialized:
  244. return access;
  245. default:
  246. AZ_Assert(false, "Unkown ScopeAttachmentUsage: %d", static_cast<uint32_t>(usage));
  247. return access;
  248. }
  249. }
  250. const char* ToString(AZ::RHI::AttachmentType attachmentType)
  251. {
  252. switch (attachmentType)
  253. {
  254. case AZ::RHI::AttachmentType::Image:
  255. return "Image";
  256. case AZ::RHI::AttachmentType::Buffer:
  257. return "Buffer";
  258. case AZ::RHI::AttachmentType::Resolve:
  259. return "Resolve";
  260. case AZ::RHI::AttachmentType::Uninitialized:
  261. default:
  262. return "Uninitialized";
  263. }
  264. }
  265. const char* ToString(HardwareQueueClass hardwareClass)
  266. {
  267. switch (hardwareClass)
  268. {
  269. case HardwareQueueClass::Graphics:
  270. return "Graphics";
  271. case HardwareQueueClass::Compute:
  272. return "Compute";
  273. case HardwareQueueClass::Copy:
  274. return "Copy";
  275. default:
  276. return "Invalid";
  277. }
  278. }
  279. }