Conversion.cpp 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  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/Vulkan/Conversion.h>
  9. #include <Atom/RHI.Reflect/ImageDescriptor.h>
  10. #include <Atom/RHI.Reflect/ImageSubresource.h>
  11. #include <Atom/RHI.Reflect/RenderAttachmentLayout.h>
  12. #include <Atom/RHI.Reflect/ShaderResourceGroupLayout.h>
  13. #include <AzCore/std/algorithm.h>
  14. #include <AzCore/std/containers/bitset.h>
  15. namespace AZ
  16. {
  17. namespace Vulkan
  18. {
  19. RHI::ResultCode ConvertResult(VkResult vkResult)
  20. {
  21. switch (vkResult)
  22. {
  23. case VK_SUCCESS:
  24. case VK_INCOMPLETE:
  25. return RHI::ResultCode::Success;
  26. case VK_ERROR_OUT_OF_HOST_MEMORY:
  27. case VK_ERROR_OUT_OF_DEVICE_MEMORY:
  28. case VK_ERROR_OUT_OF_POOL_MEMORY:
  29. return RHI::ResultCode::OutOfMemory;
  30. case VK_ERROR_INVALID_SHADER_NV:
  31. case VK_ERROR_INVALID_EXTERNAL_HANDLE:
  32. return RHI::ResultCode::InvalidArgument;
  33. case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
  34. case VK_ERROR_FRAGMENTATION_EXT:
  35. case VK_ERROR_FRAGMENTED_POOL:
  36. case VK_ERROR_TOO_MANY_OBJECTS:
  37. case VK_ERROR_DEVICE_LOST:
  38. case VK_ERROR_SURFACE_LOST_KHR:
  39. return RHI::ResultCode::InvalidOperation;
  40. case VK_NOT_READY:
  41. return RHI::ResultCode::NotReady;
  42. default:
  43. return RHI::ResultCode::Fail;
  44. }
  45. }
  46. // definition of the macro "RHIVK_EXPAND_FOR_FORMATS" containing formats' names and aspect flags.
  47. #include "Formats.inl"
  48. VkFormat ConvertFormat(RHI::Format format, [[maybe_unused]] bool raiseAsserts)
  49. {
  50. #define RHIVK_RHI_TO_VK(_FormatID, _VKFormat, _Color, _Depth, _Stencil) \
  51. case RHI::Format::_FormatID: \
  52. return _VKFormat;
  53. switch (format)
  54. {
  55. case RHI::Format::Unknown:
  56. return VK_FORMAT_UNDEFINED;
  57. RHIVK_EXPAND_FOR_FORMATS(RHIVK_RHI_TO_VK)
  58. default:
  59. AZ_Assert(!raiseAsserts, "unhandled conversion in ConvertFormat");
  60. return VK_FORMAT_UNDEFINED;
  61. }
  62. #undef RHIVK_RHI_TO_VK
  63. }
  64. RHI::Format ConvertFormat(VkFormat format)
  65. {
  66. #define RHIVK_VK_TO_RHI(_FormatID, _VKFormat, _Color, _Depth, _Stencil) \
  67. case _VKFormat: \
  68. return RHI::Format::_FormatID;
  69. switch (format)
  70. {
  71. case VK_FORMAT_UNDEFINED:
  72. return RHI::Format::Unknown;
  73. RHIVK_EXPAND_FOR_FORMATS(RHIVK_VK_TO_RHI)
  74. default:
  75. AZ_Assert(false, "unhandled conversion in ConvertFormat");
  76. return RHI::Format::Unknown;
  77. }
  78. #undef RHIVK_VK_TO_RHI
  79. }
  80. #undef RHIVK_EXPAND_FOR_FORMATS
  81. VkImageAspectFlagBits ConvertImageAspect(RHI::ImageAspect imageAspect)
  82. {
  83. switch (imageAspect)
  84. {
  85. case RHI::ImageAspect::Color:
  86. return VK_IMAGE_ASPECT_COLOR_BIT;
  87. case RHI::ImageAspect::Depth:
  88. return VK_IMAGE_ASPECT_DEPTH_BIT;
  89. case RHI::ImageAspect::Stencil:
  90. return VK_IMAGE_ASPECT_STENCIL_BIT;
  91. default:
  92. AZ_Assert(false, "Invalid image aspect %d", imageAspect);
  93. return VK_IMAGE_ASPECT_COLOR_BIT;
  94. }
  95. }
  96. VkImageAspectFlags ConvertImageAspectFlags(RHI::ImageAspectFlags aspectFlagMask)
  97. {
  98. VkImageAspectFlags flags = 0;
  99. for (uint32_t i = 0; i < RHI::ImageAspectCount; ++i)
  100. {
  101. if (!RHI::CheckBitsAll(aspectFlagMask, static_cast<RHI::ImageAspectFlags>(AZ_BIT(i))))
  102. {
  103. continue;
  104. }
  105. flags |= ConvertImageAspect(static_cast<RHI::ImageAspect>(i));
  106. }
  107. return flags;
  108. }
  109. RHI::ImageAspectFlags ConvertImageAspectFlags(VkImageAspectFlags imageAspect)
  110. {
  111. RHI::ImageAspectFlags flags = {};
  112. if (RHI::CheckBitsAll(imageAspect, static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT)))
  113. {
  114. flags |= RHI::ImageAspectFlags::Color;
  115. }
  116. if (RHI::CheckBitsAll(imageAspect, static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT)))
  117. {
  118. flags |= RHI::ImageAspectFlags::Depth;
  119. }
  120. if (RHI::CheckBitsAll(imageAspect, static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_STENCIL_BIT)))
  121. {
  122. flags |= RHI::ImageAspectFlags::Stencil;
  123. }
  124. return flags;
  125. }
  126. VkPrimitiveTopology ConvertTopology(RHI::PrimitiveTopology topology)
  127. {
  128. switch (topology)
  129. {
  130. case RHI::PrimitiveTopology::PointList:
  131. return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
  132. case RHI::PrimitiveTopology::LineList:
  133. return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
  134. case RHI::PrimitiveTopology::LineListAdj:
  135. return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY;
  136. case RHI::PrimitiveTopology::LineStrip:
  137. return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
  138. case RHI::PrimitiveTopology::LineStripAdj:
  139. return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
  140. case RHI::PrimitiveTopology::TriangleList:
  141. return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
  142. case RHI::PrimitiveTopology::TriangleListAdj:
  143. return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY;
  144. case RHI::PrimitiveTopology::TriangleStrip:
  145. return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
  146. case RHI::PrimitiveTopology::TriangleStripAdj:
  147. return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
  148. default:
  149. AZ_Assert(false, "Unknown primitive topology.");
  150. }
  151. return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
  152. }
  153. VkQueueFlags ConvertQueueClass(RHI::HardwareQueueClass queueClass)
  154. {
  155. switch (queueClass)
  156. {
  157. case RHI::HardwareQueueClass::Graphics:
  158. return VK_QUEUE_GRAPHICS_BIT;
  159. case RHI::HardwareQueueClass::Compute:
  160. return VK_QUEUE_COMPUTE_BIT;
  161. case RHI::HardwareQueueClass::Copy:
  162. return VK_QUEUE_TRANSFER_BIT|VK_QUEUE_SPARSE_BINDING_BIT;
  163. default:
  164. AZ_Assert(false, "Hardware queue class is invalid.");
  165. return VK_QUEUE_GRAPHICS_BIT;
  166. }
  167. }
  168. VkMemoryPropertyFlags ConvertHeapMemoryLevel(RHI::HeapMemoryLevel heapMemoryLevel)
  169. {
  170. switch (heapMemoryLevel)
  171. {
  172. case RHI::HeapMemoryLevel::Host:
  173. return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
  174. case RHI::HeapMemoryLevel::Device:
  175. return VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
  176. default:
  177. AZ_Assert(false, "illegal case");
  178. }
  179. return VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
  180. }
  181. void FillStencilOpState(const RHI::StencilOpState& stencilOpState, VkStencilOpState& vkStencilOpState)
  182. {
  183. VkStencilOpState& state = vkStencilOpState;
  184. state.failOp = ConvertStencilOp(stencilOpState.m_failOp);
  185. state.passOp = ConvertStencilOp(stencilOpState.m_passOp);
  186. state.depthFailOp = ConvertStencilOp(stencilOpState.m_depthFailOp);
  187. state.compareOp = ConvertComparisonFunction(stencilOpState.m_func);
  188. }
  189. VkStencilOp ConvertStencilOp(RHI::StencilOp op)
  190. {
  191. switch (op)
  192. {
  193. case RHI::StencilOp::Keep:
  194. return VK_STENCIL_OP_KEEP;
  195. case RHI::StencilOp::Zero:
  196. return VK_STENCIL_OP_ZERO;
  197. case RHI::StencilOp::Replace:
  198. return VK_STENCIL_OP_REPLACE;
  199. case RHI::StencilOp::IncrementSaturate:
  200. return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
  201. case RHI::StencilOp::DecrementSaturate:
  202. return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
  203. case RHI::StencilOp::Invert:
  204. return VK_STENCIL_OP_INVERT;
  205. case RHI::StencilOp::Increment:
  206. return VK_STENCIL_OP_INCREMENT_AND_WRAP;
  207. case RHI::StencilOp::Decrement:
  208. return VK_STENCIL_OP_DECREMENT_AND_WRAP;
  209. default:
  210. AZ_Assert(false, "Stencil Op is invalid.");
  211. return VK_STENCIL_OP_KEEP;
  212. }
  213. }
  214. VkCompareOp ConvertComparisonFunction(RHI::ComparisonFunc func)
  215. {
  216. switch (func)
  217. {
  218. case RHI::ComparisonFunc::Never:
  219. return VK_COMPARE_OP_NEVER;
  220. case RHI::ComparisonFunc::Less:
  221. return VK_COMPARE_OP_LESS;
  222. case RHI::ComparisonFunc::Equal:
  223. return VK_COMPARE_OP_EQUAL;
  224. case RHI::ComparisonFunc::LessEqual:
  225. return VK_COMPARE_OP_LESS_OR_EQUAL;
  226. case RHI::ComparisonFunc::Greater:
  227. return VK_COMPARE_OP_GREATER;
  228. case RHI::ComparisonFunc::NotEqual:
  229. return VK_COMPARE_OP_NOT_EQUAL;
  230. case RHI::ComparisonFunc::GreaterEqual:
  231. return VK_COMPARE_OP_GREATER_OR_EQUAL;
  232. case RHI::ComparisonFunc::Always:
  233. return VK_COMPARE_OP_ALWAYS;
  234. default:
  235. AZ_Assert(false, "Comparison function is invalid.");
  236. }
  237. return VK_COMPARE_OP_LESS;
  238. }
  239. void FillColorBlendAttachmentState(const RHI::TargetBlendState& targetBlendState, VkPipelineColorBlendAttachmentState& colorBlendAttachmentState)
  240. {
  241. VkPipelineColorBlendAttachmentState& state = colorBlendAttachmentState;
  242. state.blendEnable = (targetBlendState.m_enable != 0);
  243. state.srcColorBlendFactor = ConvertBlendFactor(targetBlendState.m_blendSource);
  244. state.dstColorBlendFactor = ConvertBlendFactor(targetBlendState.m_blendDest);
  245. state.colorBlendOp = ConvertBlendOp(targetBlendState.m_blendOp);
  246. state.srcAlphaBlendFactor = ConvertBlendFactor(targetBlendState.m_blendAlphaSource);
  247. state.dstAlphaBlendFactor = ConvertBlendFactor(targetBlendState.m_blendAlphaDest);
  248. state.alphaBlendOp = ConvertBlendOp(targetBlendState.m_blendAlphaOp);
  249. state.colorWriteMask = ConvertComponentFlags(static_cast<uint8_t>(targetBlendState.m_writeMask));
  250. }
  251. VkBlendFactor ConvertBlendFactor(const RHI::BlendFactor& blendFactor)
  252. {
  253. switch (blendFactor)
  254. {
  255. case RHI::BlendFactor::Zero:
  256. return VK_BLEND_FACTOR_ZERO;
  257. case RHI::BlendFactor::One:
  258. return VK_BLEND_FACTOR_ONE;
  259. case RHI::BlendFactor::ColorSource:
  260. return VK_BLEND_FACTOR_SRC_COLOR;
  261. case RHI::BlendFactor::ColorSourceInverse:
  262. return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
  263. case RHI::BlendFactor::AlphaSource:
  264. return VK_BLEND_FACTOR_SRC_ALPHA;
  265. case RHI::BlendFactor::AlphaSourceInverse:
  266. return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
  267. case RHI::BlendFactor::AlphaDest:
  268. return VK_BLEND_FACTOR_DST_ALPHA;
  269. case RHI::BlendFactor::AlphaDestInverse:
  270. return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
  271. case RHI::BlendFactor::ColorDest:
  272. return VK_BLEND_FACTOR_DST_COLOR;
  273. case RHI::BlendFactor::ColorDestInverse:
  274. return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
  275. case RHI::BlendFactor::AlphaSourceSaturate:
  276. return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
  277. case RHI::BlendFactor::Factor:
  278. return VK_BLEND_FACTOR_CONSTANT_COLOR;
  279. case RHI::BlendFactor::FactorInverse:
  280. return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
  281. case RHI::BlendFactor::ColorSource1:
  282. return VK_BLEND_FACTOR_SRC1_COLOR;
  283. case RHI::BlendFactor::ColorSource1Inverse:
  284. return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
  285. case RHI::BlendFactor::AlphaSource1:
  286. return VK_BLEND_FACTOR_SRC1_ALPHA;
  287. case RHI::BlendFactor::AlphaSource1Inverse:
  288. return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
  289. default:
  290. AZ_Assert(false, "Blend factor is invalid.");
  291. break;
  292. }
  293. return VK_BLEND_FACTOR_SRC_COLOR;
  294. }
  295. VkBlendOp ConvertBlendOp(const RHI::BlendOp blendOp)
  296. {
  297. switch (blendOp)
  298. {
  299. case RHI::BlendOp::Add:
  300. return VK_BLEND_OP_ADD;
  301. case RHI::BlendOp::Subtract:
  302. return VK_BLEND_OP_SUBTRACT;
  303. case RHI::BlendOp::SubtractReverse:
  304. return VK_BLEND_OP_REVERSE_SUBTRACT;
  305. case RHI::BlendOp::Minimum:
  306. return VK_BLEND_OP_MIN;
  307. case RHI::BlendOp::Maximum:
  308. return VK_BLEND_OP_MAX;
  309. default:
  310. AZ_Assert(false, "Blend op is invalid.");
  311. break;
  312. }
  313. return VK_BLEND_OP_ADD;
  314. }
  315. VkColorComponentFlags ConvertComponentFlags(uint8_t sflags)
  316. {
  317. VkColorComponentFlags dflags = 0;
  318. if(sflags == 0)
  319. {
  320. return dflags;
  321. }
  322. if(RHI::CheckBitsAll(sflags, static_cast<uint8_t>(RHI::WriteChannelMask::ColorWriteMaskAll)))
  323. {
  324. return VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
  325. }
  326. if (RHI::CheckBitsAny(sflags, static_cast<uint8_t>(RHI::WriteChannelMask::ColorWriteMaskRed)))
  327. {
  328. dflags |= VK_COLOR_COMPONENT_R_BIT;
  329. }
  330. if (RHI::CheckBitsAny(sflags, static_cast<uint8_t>(RHI::WriteChannelMask::ColorWriteMaskGreen)))
  331. {
  332. dflags |= VK_COLOR_COMPONENT_G_BIT;
  333. }
  334. if (RHI::CheckBitsAny(sflags, static_cast<uint8_t>(RHI::WriteChannelMask::ColorWriteMaskBlue)))
  335. {
  336. dflags |= VK_COLOR_COMPONENT_B_BIT;
  337. }
  338. if (RHI::CheckBitsAny(sflags, static_cast<uint8_t>(RHI::WriteChannelMask::ColorWriteMaskAlpha)))
  339. {
  340. dflags |= VK_COLOR_COMPONENT_A_BIT;
  341. }
  342. return dflags;
  343. }
  344. VkSampleCountFlagBits ConvertSampleCount(uint16_t samples)
  345. {
  346. switch (samples)
  347. {
  348. case 1:
  349. return VK_SAMPLE_COUNT_1_BIT;
  350. case 2:
  351. return VK_SAMPLE_COUNT_2_BIT;
  352. case 4:
  353. return VK_SAMPLE_COUNT_4_BIT;
  354. case 8:
  355. return VK_SAMPLE_COUNT_8_BIT;
  356. case 16:
  357. return VK_SAMPLE_COUNT_16_BIT;
  358. case 32:
  359. return VK_SAMPLE_COUNT_32_BIT;
  360. case 64:
  361. return VK_SAMPLE_COUNT_64_BIT;
  362. default:
  363. AZ_Assert(false, "SampleCount is invalid.");
  364. return VK_SAMPLE_COUNT_1_BIT;
  365. }
  366. }
  367. VkAttachmentLoadOp ConvertAttachmentLoadAction(RHI::AttachmentLoadAction loadAction)
  368. {
  369. switch (loadAction)
  370. {
  371. case RHI::AttachmentLoadAction::Load:
  372. return VK_ATTACHMENT_LOAD_OP_LOAD;
  373. case RHI::AttachmentLoadAction::Clear:
  374. return VK_ATTACHMENT_LOAD_OP_CLEAR;
  375. case RHI::AttachmentLoadAction::DontCare:
  376. return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  377. default:
  378. AZ_Assert(false, "AttachmentLoadAction is illegal.");
  379. return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  380. }
  381. }
  382. VkAttachmentStoreOp ConvertAttachmentStoreAction(RHI::AttachmentStoreAction storeAction)
  383. {
  384. switch (storeAction)
  385. {
  386. case RHI::AttachmentStoreAction::Store:
  387. return VK_ATTACHMENT_STORE_OP_STORE;
  388. case RHI::AttachmentStoreAction::DontCare:
  389. return VK_ATTACHMENT_STORE_OP_DONT_CARE;
  390. default:
  391. AZ_Assert(false, "AttachmentStoreAction is illegal.");
  392. return VK_ATTACHMENT_STORE_OP_DONT_CARE;
  393. }
  394. }
  395. void FillClearValue(const RHI::ClearValue& rhiClearValue, VkClearValue& vulkanClearValue)
  396. {
  397. switch (rhiClearValue.m_type)
  398. {
  399. case RHI::ClearValueType::Vector4Float:
  400. vulkanClearValue.color.float32[0] = rhiClearValue.m_vector4Float[0];
  401. vulkanClearValue.color.float32[1] = rhiClearValue.m_vector4Float[1];
  402. vulkanClearValue.color.float32[2] = rhiClearValue.m_vector4Float[2];
  403. vulkanClearValue.color.float32[3] = rhiClearValue.m_vector4Float[3];
  404. return;
  405. case RHI::ClearValueType::Vector4Uint:
  406. vulkanClearValue.color.uint32[0] = rhiClearValue.m_vector4Uint[0];
  407. vulkanClearValue.color.uint32[1] = rhiClearValue.m_vector4Uint[1];
  408. vulkanClearValue.color.uint32[2] = rhiClearValue.m_vector4Uint[2];
  409. vulkanClearValue.color.uint32[3] = rhiClearValue.m_vector4Uint[3];
  410. return;
  411. case RHI::ClearValueType::DepthStencil:
  412. vulkanClearValue.depthStencil.depth = rhiClearValue.m_depthStencil.m_depth;
  413. vulkanClearValue.depthStencil.stencil = rhiClearValue.m_depthStencil.m_stencil;
  414. return;
  415. default:
  416. AZ_Assert(false, "ClearValueType is invalid.");
  417. }
  418. }
  419. VkFilter ConvertFilterMode(RHI::FilterMode filterMode)
  420. {
  421. switch (filterMode)
  422. {
  423. case RHI::FilterMode::Point:
  424. return VK_FILTER_NEAREST;
  425. case RHI::FilterMode::Linear:
  426. return VK_FILTER_LINEAR;
  427. default:
  428. AZ_Assert(false, "SamplerFilterMode is illegal.");
  429. return VK_FILTER_NEAREST;
  430. }
  431. }
  432. VkSamplerAddressMode ConvertAddressMode(RHI::AddressMode addressMode)
  433. {
  434. switch (addressMode)
  435. {
  436. case RHI::AddressMode::Wrap:
  437. return VK_SAMPLER_ADDRESS_MODE_REPEAT;
  438. case RHI::AddressMode::Mirror:
  439. return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
  440. case RHI::AddressMode::Clamp:
  441. return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
  442. case RHI::AddressMode::Border:
  443. return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
  444. case RHI::AddressMode::MirrorOnce:
  445. return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
  446. default:
  447. AZ_Assert(false, "SamplerAddressMode is illegal.");
  448. return VK_SAMPLER_ADDRESS_MODE_REPEAT;
  449. }
  450. }
  451. VkImageType ConvertToImageType(RHI::ImageDimension dimension)
  452. {
  453. switch (dimension)
  454. {
  455. case RHI::ImageDimension::Image1D:
  456. return VK_IMAGE_TYPE_1D;
  457. case RHI::ImageDimension::Image2D:
  458. return VK_IMAGE_TYPE_2D;
  459. case RHI::ImageDimension::Image3D:
  460. return VK_IMAGE_TYPE_3D;
  461. default:
  462. AZ_Assert(false, "Invalid dimension type.");
  463. return VK_IMAGE_TYPE_2D;
  464. }
  465. }
  466. VkExtent3D ConvertToExtent3D(const RHI::Size& size)
  467. {
  468. VkExtent3D extent{};
  469. extent.width = size.m_width;
  470. extent.height = size.m_height;
  471. extent.depth = size.m_depth;
  472. return extent;
  473. }
  474. VkQueryType ConvertQueryType(const RHI::QueryType type)
  475. {
  476. switch (type)
  477. {
  478. case RHI::QueryType::Occlusion:
  479. return VK_QUERY_TYPE_OCCLUSION;
  480. case RHI::QueryType::PipelineStatistics:
  481. return VK_QUERY_TYPE_PIPELINE_STATISTICS;
  482. case RHI::QueryType::Timestamp:
  483. return VK_QUERY_TYPE_TIMESTAMP;
  484. default:
  485. AZ_Assert(false, "Invalid query type");
  486. return VK_QUERY_TYPE_OCCLUSION;
  487. }
  488. }
  489. VkQueryPipelineStatisticFlags ConvertQueryPipelineStatisticMask(RHI::PipelineStatisticsFlags mask)
  490. {
  491. VkQueryPipelineStatisticFlags flags = 0;
  492. if (RHI::CheckBitsAll(mask, RHI::PipelineStatisticsFlags::IAVertices))
  493. {
  494. flags |= VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT;
  495. }
  496. if (RHI::CheckBitsAll(mask, RHI::PipelineStatisticsFlags::IAPrimitives))
  497. {
  498. flags |= VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT;
  499. }
  500. if (RHI::CheckBitsAll(mask, RHI::PipelineStatisticsFlags::VSInvocations))
  501. {
  502. flags |= VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT;
  503. }
  504. if (RHI::CheckBitsAll(mask, RHI::PipelineStatisticsFlags::GSInvocations))
  505. {
  506. flags |= VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT;
  507. }
  508. if (RHI::CheckBitsAll(mask, RHI::PipelineStatisticsFlags::GSPrimitives))
  509. {
  510. flags |= VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT;
  511. }
  512. if (RHI::CheckBitsAll(mask, RHI::PipelineStatisticsFlags::CInvocations))
  513. {
  514. flags |= VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT;
  515. }
  516. if (RHI::CheckBitsAll(mask, RHI::PipelineStatisticsFlags::CPrimitives))
  517. {
  518. flags |= VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT;
  519. }
  520. if (RHI::CheckBitsAll(mask, RHI::PipelineStatisticsFlags::PSInvocations))
  521. {
  522. flags |= VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT;
  523. }
  524. if (RHI::CheckBitsAll(mask, RHI::PipelineStatisticsFlags::HSInvocations))
  525. {
  526. flags |= VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT;
  527. }
  528. if (RHI::CheckBitsAll(mask, RHI::PipelineStatisticsFlags::DSInvocations))
  529. {
  530. flags |= VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT;
  531. }
  532. if (RHI::CheckBitsAll(mask, RHI::PipelineStatisticsFlags::CSInvocations))
  533. {
  534. flags |= VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT;
  535. }
  536. return flags;
  537. }
  538. VkShaderStageFlagBits ConvertShaderStage(RHI::ShaderStage stage, [[maybe_unused]] uint32_t subStageIndex /* = 0 */)
  539. {
  540. switch (stage)
  541. {
  542. case RHI::ShaderStage::Vertex:
  543. return VK_SHADER_STAGE_VERTEX_BIT;
  544. case RHI::ShaderStage::Fragment:
  545. return VK_SHADER_STAGE_FRAGMENT_BIT;
  546. case RHI::ShaderStage::Compute:
  547. return VK_SHADER_STAGE_COMPUTE_BIT;
  548. case RHI::ShaderStage::Geometry:
  549. return VK_SHADER_STAGE_GEOMETRY_BIT;
  550. default:
  551. AZ_Assert(false, "Invalid shader stage %d", stage);
  552. return VkShaderStageFlagBits(0);
  553. }
  554. }
  555. VkShaderStageFlags ConvertShaderStageMask(uint32_t shaderStageMask)
  556. {
  557. VkShaderStageFlags flags = 0;
  558. for (uint32_t i = 0; i < RHI::ShaderStageCount; ++i)
  559. {
  560. if (RHI::CheckBitsAll(shaderStageMask, AZ_BIT(i)))
  561. {
  562. flags |= ConvertShaderStage(static_cast<RHI::ShaderStage>(i));
  563. }
  564. }
  565. return flags;
  566. }
  567. VkBufferUsageFlags GetBufferUsageFlagBits(RHI::BufferBindFlags bindFlags)
  568. {
  569. using BindFlags = RHI::BufferBindFlags;
  570. VkBufferUsageFlags usageFlags{ 0 };
  571. if (RHI::CheckBitsAny(bindFlags, BindFlags::InputAssembly | BindFlags::DynamicInputAssembly))
  572. {
  573. usageFlags |=
  574. VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
  575. VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
  576. VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR;
  577. }
  578. if (RHI::CheckBitsAny(bindFlags, BindFlags::Constant))
  579. {
  580. usageFlags |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
  581. }
  582. if (RHI::CheckBitsAny(bindFlags, BindFlags::ShaderRead))
  583. {
  584. usageFlags |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
  585. }
  586. if (RHI::CheckBitsAny(bindFlags, BindFlags::ShaderWrite))
  587. {
  588. usageFlags |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
  589. }
  590. if (RHI::CheckBitsAny(bindFlags, BindFlags::CopyRead))
  591. {
  592. usageFlags |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
  593. }
  594. if (RHI::CheckBitsAny(bindFlags, BindFlags::CopyWrite))
  595. {
  596. usageFlags |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
  597. }
  598. if (RHI::CheckBitsAny(bindFlags, BindFlags::Predication))
  599. {
  600. usageFlags |= VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT;
  601. }
  602. if (RHI::CheckBitsAny(bindFlags, BindFlags::Indirect))
  603. {
  604. usageFlags |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
  605. }
  606. if (RHI::CheckBitsAny(bindFlags, BindFlags::RayTracingAccelerationStructure))
  607. {
  608. usageFlags |= VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR;
  609. }
  610. if (RHI::CheckBitsAny(bindFlags, BindFlags::RayTracingShaderTable))
  611. {
  612. usageFlags |= VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR;
  613. }
  614. if (RHI::CheckBitsAny(
  615. bindFlags,
  616. RHI::BufferBindFlags::InputAssembly | RHI::BufferBindFlags::DynamicInputAssembly |
  617. RHI::BufferBindFlags::RayTracingShaderTable | RHI::BufferBindFlags::RayTracingAccelerationStructure |
  618. RHI::BufferBindFlags::RayTracingScratchBuffer | RHI::BufferBindFlags::Indirect))
  619. {
  620. usageFlags |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
  621. }
  622. return usageFlags;
  623. }
  624. VkSampleLocationEXT ConvertSampleLocation(const RHI::SamplePosition& position)
  625. {
  626. const static float cellSize = 1.0f / RHI::Limits::Pipeline::MultiSampleCustomLocationGridSize;
  627. return VkSampleLocationEXT{ position.m_x * cellSize, position.m_y * cellSize };
  628. }
  629. VkFragmentShadingRateCombinerOpKHR ConvertShadingRateCombiner(const RHI::ShadingRateCombinerOp op)
  630. {
  631. switch (op)
  632. {
  633. case RHI::ShadingRateCombinerOp::Max: return VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR;
  634. case RHI::ShadingRateCombinerOp::Min: return VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR;
  635. case RHI::ShadingRateCombinerOp::Override: return VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR;
  636. case RHI::ShadingRateCombinerOp::Passthrough: return VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR;
  637. default:
  638. AZ_Assert(false, "Invalid ShadingRateCombinerOp %d", op);
  639. return VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR;
  640. }
  641. }
  642. VkExtent2D ConvertFragmentShadingRate(const RHI::ShadingRate rate)
  643. {
  644. VkExtent2D fragmentSize;
  645. switch (rate)
  646. {
  647. case RHI::ShadingRate::Rate1x1:
  648. fragmentSize.width = fragmentSize.height = 1;
  649. break;
  650. case RHI::ShadingRate::Rate1x2:
  651. fragmentSize.width = 1;
  652. fragmentSize.height = 2;
  653. break;
  654. case RHI::ShadingRate::Rate2x1:
  655. fragmentSize.width = 2;
  656. fragmentSize.height = 1;
  657. break;
  658. case RHI::ShadingRate::Rate2x2:
  659. fragmentSize.width = fragmentSize.height = 2;
  660. break;
  661. case RHI::ShadingRate::Rate2x4:
  662. fragmentSize.width = 2;
  663. fragmentSize.height = 4;
  664. break;
  665. case RHI::ShadingRate::Rate4x2:
  666. fragmentSize.width = 4;
  667. fragmentSize.height = 2;
  668. break;
  669. case RHI::ShadingRate::Rate4x1:
  670. fragmentSize.width = 4;
  671. fragmentSize.height = 1;
  672. break;
  673. case RHI::ShadingRate::Rate1x4:
  674. fragmentSize.width = 1;
  675. fragmentSize.height = 4;
  676. break;
  677. case RHI::ShadingRate::Rate4x4:
  678. fragmentSize.width = fragmentSize.height = 4;
  679. break;
  680. default:
  681. AZ_Assert(false, "Invalid shading rate %d", rate);
  682. fragmentSize.width = fragmentSize.height = 1;
  683. break;
  684. }
  685. return fragmentSize;
  686. }
  687. RHI::ShadingRate ConvertFragmentShadingRate(const VkExtent2D rate)
  688. {
  689. switch (rate.width)
  690. {
  691. case 1:
  692. switch (rate.height)
  693. {
  694. case 1: return RHI::ShadingRate::Rate1x1;
  695. case 2: return RHI::ShadingRate::Rate1x2;
  696. case 4: return RHI::ShadingRate::Rate1x4;
  697. default:
  698. break;
  699. }
  700. case 2:
  701. switch (rate.height)
  702. {
  703. case 1: return RHI::ShadingRate::Rate2x1;
  704. case 2: return RHI::ShadingRate::Rate2x2;
  705. case 4: return RHI::ShadingRate::Rate2x4;
  706. default:
  707. break;
  708. }
  709. case 4:
  710. switch (rate.height)
  711. {
  712. case 1: return RHI::ShadingRate::Rate4x1;
  713. case 2: return RHI::ShadingRate::Rate4x2;
  714. case 4: return RHI::ShadingRate::Rate4x4;
  715. default:
  716. break;
  717. }
  718. }
  719. AZ_Assert(false, "Invalid rate for conversion (%d, %d)", rate.width, rate.height);
  720. return RHI::ShadingRate::Rate1x1;
  721. }
  722. VkImageUsageFlags ImageUsageFlagsOfFormatFeatureFlags(VkFormatFeatureFlags formatFeatureFlags)
  723. {
  724. VkImageUsageFlags usageFlags{};
  725. if (RHI::CheckBitsAny(formatFeatureFlags, static_cast<VkFormatFeatureFlags>(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)))
  726. {
  727. usageFlags |= VK_IMAGE_USAGE_SAMPLED_BIT;
  728. }
  729. if (RHI::CheckBitsAny(formatFeatureFlags, static_cast<VkFormatFeatureFlags>(VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)))
  730. {
  731. usageFlags |= VK_IMAGE_USAGE_STORAGE_BIT;
  732. }
  733. if (RHI::CheckBitsAny(formatFeatureFlags, static_cast<VkFormatFeatureFlags>(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)))
  734. {
  735. usageFlags |= (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
  736. }
  737. if (RHI::CheckBitsAny(formatFeatureFlags, static_cast<VkFormatFeatureFlags>(VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)))
  738. {
  739. usageFlags |= (VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
  740. }
  741. if (RHI::CheckBitsAny(formatFeatureFlags, static_cast<VkFormatFeatureFlags>(VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)))
  742. {
  743. usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
  744. }
  745. if (RHI::CheckBitsAny(formatFeatureFlags, static_cast<VkFormatFeatureFlags>(VK_FORMAT_FEATURE_TRANSFER_DST_BIT)))
  746. {
  747. usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
  748. }
  749. if (RHI::CheckBitsAny(formatFeatureFlags, static_cast<VkFormatFeatureFlags>(VK_FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT)))
  750. {
  751. usageFlags |= VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT;
  752. }
  753. if (RHI::CheckBitsAny(
  754. formatFeatureFlags, static_cast<VkFormatFeatureFlags>(VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR)))
  755. {
  756. usageFlags |= VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
  757. }
  758. return usageFlags;
  759. }
  760. VkAccessFlags GetSupportedAccessFlags(VkPipelineStageFlags pipelineStageFlags)
  761. {
  762. if (RHI::CheckBitsAny(pipelineStageFlags, static_cast<VkPipelineStageFlags>(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)) ||
  763. RHI::CheckBitsAny(pipelineStageFlags, static_cast<VkPipelineStageFlags>(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT)))
  764. {
  765. return VK_ACCESS_NONE;
  766. }
  767. // The initial access flags don't need special stages.
  768. VkAccessFlags accessFlagBits = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
  769. if (RHI::CheckBitsAny(pipelineStageFlags, static_cast<VkPipelineStageFlags>(VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT)))
  770. {
  771. accessFlagBits |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
  772. }
  773. if (RHI::CheckBitsAny(pipelineStageFlags, static_cast<VkPipelineStageFlags>(VK_PIPELINE_STAGE_VERTEX_INPUT_BIT)))
  774. {
  775. accessFlagBits |= VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
  776. }
  777. if (RHI::CheckBitsAny(
  778. pipelineStageFlags,
  779. static_cast<VkPipelineStageFlags>(VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
  780. VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
  781. VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV | VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV)))
  782. {
  783. accessFlagBits |= VK_ACCESS_UNIFORM_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
  784. }
  785. if (RHI::CheckBitsAny(pipelineStageFlags, static_cast<VkPipelineStageFlags>(VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT)))
  786. {
  787. accessFlagBits |= VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
  788. }
  789. if (RHI::CheckBitsAny(pipelineStageFlags, static_cast<VkPipelineStageFlags>(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT)))
  790. {
  791. accessFlagBits |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
  792. }
  793. if (RHI::CheckBitsAny(pipelineStageFlags, static_cast<VkPipelineStageFlags>(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)))
  794. {
  795. accessFlagBits |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT;
  796. }
  797. if (RHI::CheckBitsAny(pipelineStageFlags, static_cast<VkPipelineStageFlags>(VK_PIPELINE_STAGE_TRANSFER_BIT)))
  798. {
  799. accessFlagBits |= VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
  800. }
  801. if (RHI::CheckBitsAny(pipelineStageFlags, static_cast<VkPipelineStageFlags>(VK_PIPELINE_STAGE_HOST_BIT)))
  802. {
  803. accessFlagBits |= VK_ACCESS_HOST_READ_BIT | VK_ACCESS_HOST_WRITE_BIT;
  804. }
  805. if (RHI::CheckBitsAny(pipelineStageFlags, static_cast<VkPipelineStageFlags>(VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT)))
  806. {
  807. accessFlagBits |= VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT;
  808. }
  809. if (RHI::CheckBitsAny(pipelineStageFlags, static_cast<VkPipelineStageFlags>(VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT)))
  810. {
  811. accessFlagBits |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
  812. }
  813. if (RHI::CheckBitsAny(
  814. pipelineStageFlags, static_cast<VkPipelineStageFlags>(VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT)))
  815. {
  816. accessFlagBits |= VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT;
  817. }
  818. if (RHI::CheckBitsAny(
  819. pipelineStageFlags, static_cast<VkPipelineStageFlags>(VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR)))
  820. {
  821. accessFlagBits |= VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR;
  822. }
  823. return accessFlagBits;
  824. }
  825. VkComponentSwizzle ConvertComponentSwizzle(const ImageComponentMapping::Swizzle swizzle)
  826. {
  827. switch (swizzle)
  828. {
  829. case ImageComponentMapping::Swizzle::Identity:
  830. return VkComponentSwizzle::VK_COMPONENT_SWIZZLE_IDENTITY;
  831. case ImageComponentMapping::Swizzle::Zero:
  832. return VkComponentSwizzle::VK_COMPONENT_SWIZZLE_ZERO;
  833. case ImageComponentMapping::Swizzle::One:
  834. return VkComponentSwizzle::VK_COMPONENT_SWIZZLE_ONE;
  835. case ImageComponentMapping::Swizzle::R:
  836. return VkComponentSwizzle::VK_COMPONENT_SWIZZLE_R;
  837. case ImageComponentMapping::Swizzle::G:
  838. return VkComponentSwizzle::VK_COMPONENT_SWIZZLE_G;
  839. case ImageComponentMapping::Swizzle::B:
  840. return VkComponentSwizzle::VK_COMPONENT_SWIZZLE_B;
  841. case ImageComponentMapping::Swizzle::A:
  842. return VkComponentSwizzle::VK_COMPONENT_SWIZZLE_A;
  843. default:
  844. AZ_Assert(false, "Invalid component swizzle %d", swizzle);
  845. return VkComponentSwizzle::VK_COMPONENT_SWIZZLE_IDENTITY;
  846. }
  847. }
  848. VkComponentMapping ConvertComponentMapping(const ImageComponentMapping& mapping)
  849. {
  850. VkComponentMapping vkMapping;
  851. vkMapping.r = ConvertComponentSwizzle(mapping.m_red);
  852. vkMapping.g = ConvertComponentSwizzle(mapping.m_green);
  853. vkMapping.b = ConvertComponentSwizzle(mapping.m_blue);
  854. vkMapping.a = ConvertComponentSwizzle(mapping.m_alpha);
  855. return vkMapping;
  856. }
  857. RHI::ImageSubresourceRange ConvertSubresourceRange(const VkImageSubresourceRange& range)
  858. {
  859. RHI::ImageSubresourceRange rhiRange;
  860. rhiRange.m_aspectFlags = ConvertImageAspectFlags(range.aspectMask);
  861. rhiRange.m_mipSliceMin = static_cast<uint16_t>(range.baseMipLevel);
  862. rhiRange.m_mipSliceMax = static_cast<uint16_t>(range.baseMipLevel + range.levelCount - 1);
  863. rhiRange.m_arraySliceMin = static_cast<uint16_t>(range.baseArrayLayer);
  864. rhiRange.m_arraySliceMax = static_cast<uint16_t>(range.baseArrayLayer + range.layerCount - 1);
  865. return rhiRange;
  866. }
  867. VkPipelineStageFlags ConvertScopeAttachmentStage(const RHI::ScopeAttachmentStage& stage)
  868. {
  869. VkPipelineStageFlags flags = {};
  870. if (RHI::CheckBitsAll(stage, RHI::ScopeAttachmentStage::VertexShader))
  871. {
  872. flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
  873. }
  874. if (RHI::CheckBitsAll(stage, RHI::ScopeAttachmentStage::FragmentShader))
  875. {
  876. flags |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  877. }
  878. if (RHI::CheckBitsAll(stage, RHI::ScopeAttachmentStage::ComputeShader))
  879. {
  880. flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
  881. }
  882. if (RHI::CheckBitsAll(stage, RHI::ScopeAttachmentStage::RayTracingShader))
  883. {
  884. flags |= VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR;
  885. }
  886. if (RHI::CheckBitsAll(stage, RHI::ScopeAttachmentStage::EarlyFragmentTest))
  887. {
  888. flags |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
  889. }
  890. if (RHI::CheckBitsAll(stage, RHI::ScopeAttachmentStage::LateFragmentTest))
  891. {
  892. flags |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
  893. }
  894. if (RHI::CheckBitsAll(stage, RHI::ScopeAttachmentStage::ColorAttachmentOutput))
  895. {
  896. flags |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  897. }
  898. if (RHI::CheckBitsAll(stage, RHI::ScopeAttachmentStage::Copy))
  899. {
  900. flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
  901. }
  902. if (RHI::CheckBitsAll(stage, RHI::ScopeAttachmentStage::Predication))
  903. {
  904. flags |= VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT;
  905. }
  906. if (RHI::CheckBitsAll(stage, RHI::ScopeAttachmentStage::DrawIndirect))
  907. {
  908. flags |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
  909. }
  910. if (RHI::CheckBitsAll(stage, RHI::ScopeAttachmentStage::VertexInput))
  911. {
  912. flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
  913. }
  914. if (RHI::CheckBitsAll(stage, RHI::ScopeAttachmentStage::ShadingRate))
  915. {
  916. flags |= VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT | VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
  917. }
  918. return flags;
  919. }
  920. }
  921. }