Vulkan.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  1. #include "Vulkan.h"
  2. #include <sstream>
  3. namespace love {
  4. namespace graphics {
  5. namespace vulkan {
  6. static uint32_t numShaderSwitches;
  7. void Vulkan::shaderSwitch() {
  8. numShaderSwitches++;
  9. }
  10. uint32_t Vulkan::getNumShaderSwitches() {
  11. return numShaderSwitches;
  12. }
  13. void Vulkan::resetShaderSwitches() {
  14. numShaderSwitches = 0;
  15. }
  16. VkFormat Vulkan::getVulkanVertexFormat(DataFormat format) {
  17. switch (format) {
  18. case DATAFORMAT_FLOAT:
  19. return VK_FORMAT_R32_SFLOAT;
  20. case DATAFORMAT_FLOAT_VEC2:
  21. return VK_FORMAT_R32G32_SFLOAT;
  22. case DATAFORMAT_FLOAT_VEC3:
  23. return VK_FORMAT_R32G32B32_SFLOAT;
  24. case DATAFORMAT_FLOAT_VEC4:
  25. return VK_FORMAT_R32G32B32A32_SFLOAT;
  26. case DATAFORMAT_FLOAT_MAT2X2:
  27. case DATAFORMAT_FLOAT_MAT2X3:
  28. case DATAFORMAT_FLOAT_MAT2X4:
  29. case DATAFORMAT_FLOAT_MAT3X2:
  30. case DATAFORMAT_FLOAT_MAT3X3:
  31. case DATAFORMAT_FLOAT_MAT3X4:
  32. case DATAFORMAT_FLOAT_MAT4X2:
  33. case DATAFORMAT_FLOAT_MAT4X3:
  34. case DATAFORMAT_FLOAT_MAT4X4:
  35. throw love::Exception("unimplemented data format (matnxm)");
  36. case DATAFORMAT_INT32:
  37. return VK_FORMAT_R32_SINT;
  38. case DATAFORMAT_INT32_VEC2:
  39. return VK_FORMAT_R32G32_SINT;
  40. case DATAFORMAT_INT32_VEC3:
  41. return VK_FORMAT_R32G32B32_SINT;
  42. case DATAFORMAT_INT32_VEC4:
  43. return VK_FORMAT_R32G32B32A32_SINT;
  44. case DATAFORMAT_UINT32:
  45. return VK_FORMAT_R32_UINT;
  46. case DATAFORMAT_UINT32_VEC2:
  47. return VK_FORMAT_R32G32_UINT;
  48. case DATAFORMAT_UINT32_VEC3:
  49. return VK_FORMAT_R32G32B32_UINT;
  50. case DATAFORMAT_UINT32_VEC4:
  51. return VK_FORMAT_R32G32B32A32_UINT;
  52. case DATAFORMAT_SNORM8_VEC4:
  53. return VK_FORMAT_R8G8B8A8_SNORM;
  54. case DATAFORMAT_UNORM8_VEC4:
  55. return VK_FORMAT_R8G8B8A8_UNORM;
  56. case DATAFORMAT_INT8_VEC4:
  57. return VK_FORMAT_R8G8B8A8_SINT;
  58. case DATAFORMAT_UINT8_VEC4:
  59. return VK_FORMAT_R8G8B8A8_UINT;
  60. case DATAFORMAT_SNORM16_VEC2:
  61. return VK_FORMAT_R16G16_SNORM;
  62. case DATAFORMAT_SNORM16_VEC4:
  63. return VK_FORMAT_R16G16B16A16_SNORM;
  64. case DATAFORMAT_UNORM16_VEC2:
  65. return VK_FORMAT_R16G16_UNORM;
  66. case DATAFORMAT_UNORM16_VEC4:
  67. return VK_FORMAT_R16G16B16A16_UNORM;
  68. case DATAFORMAT_INT16_VEC2:
  69. return VK_FORMAT_R16G16_SINT;
  70. case DATAFORMAT_INT16_VEC4:
  71. return VK_FORMAT_R16G16B16A16_SINT;
  72. case DATAFORMAT_UINT16:
  73. return VK_FORMAT_R16_UINT;
  74. case DATAFORMAT_UINT16_VEC2:
  75. return VK_FORMAT_R16G16_UINT;
  76. case DATAFORMAT_UINT16_VEC4:
  77. return VK_FORMAT_R16G16B16A16_UINT;
  78. case DATAFORMAT_BOOL:
  79. case DATAFORMAT_BOOL_VEC2:
  80. case DATAFORMAT_BOOL_VEC3:
  81. case DATAFORMAT_BOOL_VEC4:
  82. throw love::Exception("unimplemented data format (bool)");
  83. default:
  84. throw love::Exception("unknown data format");
  85. }
  86. }
  87. TextureFormat Vulkan::getTextureFormat(PixelFormat format) {
  88. TextureFormat textureFormat{};
  89. switch (format) {
  90. case PIXELFORMAT_UNKNOWN:
  91. throw love::Exception("unknown pixel format");
  92. case PIXELFORMAT_NORMAL:
  93. textureFormat.internalFormat = VK_FORMAT_R8G8B8A8_SRGB;
  94. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  95. break;
  96. case PIXELFORMAT_HDR:
  97. throw love::Exception("unimplemented pixel format: hdr");
  98. case PIXELFORMAT_R8_UNORM:
  99. textureFormat.internalFormat = VK_FORMAT_R8_UNORM;
  100. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  101. break;
  102. case PIXELFORMAT_R8_INT:
  103. textureFormat.internalFormat = VK_FORMAT_R8_SINT;
  104. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
  105. break;
  106. case PIXELFORMAT_R8_UINT:
  107. textureFormat.internalFormat = VK_FORMAT_R8_UINT;
  108. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
  109. break;
  110. case PIXELFORMAT_R16_UNORM:
  111. textureFormat.internalFormat = VK_FORMAT_R16_UNORM;
  112. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  113. break;
  114. case PIXELFORMAT_R16_FLOAT:
  115. textureFormat.internalFormat = VK_FORMAT_R16_SFLOAT;
  116. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  117. break;
  118. case PIXELFORMAT_R16_INT:
  119. textureFormat.internalFormat = VK_FORMAT_R16_SINT;
  120. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
  121. break;
  122. case PIXELFORMAT_R16_UINT:
  123. textureFormat.internalFormat = VK_FORMAT_R16_UINT;
  124. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
  125. break;
  126. case PIXELFORMAT_R32_FLOAT:
  127. textureFormat.internalFormat = VK_FORMAT_R32_SFLOAT;
  128. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  129. break;
  130. case PIXELFORMAT_R32_INT:
  131. textureFormat.internalFormat = VK_FORMAT_R32_SINT;
  132. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
  133. break;
  134. case PIXELFORMAT_R32_UINT:
  135. textureFormat.internalFormat = VK_FORMAT_R32_UINT;
  136. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
  137. break;
  138. case PIXELFORMAT_RG8_UNORM:
  139. textureFormat.internalFormat = VK_FORMAT_R8G8_UNORM;
  140. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  141. break;
  142. case PIXELFORMAT_RG8_INT:
  143. textureFormat.internalFormat = VK_FORMAT_R8G8_SINT;
  144. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
  145. break;
  146. case PIXELFORMAT_RG8_UINT:
  147. textureFormat.internalFormat = VK_FORMAT_R8G8_UINT;
  148. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
  149. break;
  150. case PIXELFORMAT_LA8_UNORM: // Same as RG8: but accessed as (L: L: L: A)
  151. textureFormat.internalFormat = VK_FORMAT_R8G8_UNORM;
  152. textureFormat.swizzleR = VK_COMPONENT_SWIZZLE_R;
  153. textureFormat.swizzleG = VK_COMPONENT_SWIZZLE_R;
  154. textureFormat.swizzleB = VK_COMPONENT_SWIZZLE_R;
  155. textureFormat.swizzleA = VK_COMPONENT_SWIZZLE_G;
  156. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  157. break;
  158. case PIXELFORMAT_RG16_UNORM:
  159. textureFormat.internalFormat = VK_FORMAT_R16G16_UNORM;
  160. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  161. break;
  162. case PIXELFORMAT_RG16_FLOAT:
  163. textureFormat.internalFormat = VK_FORMAT_R16G16_SFLOAT;
  164. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  165. break;
  166. case PIXELFORMAT_RG16_INT:
  167. textureFormat.internalFormat = VK_FORMAT_R16G16_SINT;
  168. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
  169. break;
  170. case PIXELFORMAT_RG16_UINT:
  171. textureFormat.internalFormat = VK_FORMAT_R16G16_UINT;
  172. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
  173. break;
  174. case PIXELFORMAT_RG32_FLOAT:
  175. textureFormat.internalFormat = VK_FORMAT_R32G32_SFLOAT;
  176. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  177. break;
  178. case PIXELFORMAT_RG32_INT:
  179. textureFormat.internalFormat = VK_FORMAT_R32G32_SINT;
  180. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
  181. break;
  182. case PIXELFORMAT_RG32_UINT:
  183. textureFormat.internalFormat = VK_FORMAT_R32G32_UINT;
  184. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
  185. break;
  186. case PIXELFORMAT_RGBA8_UNORM:
  187. textureFormat.internalFormat = VK_FORMAT_R8G8B8A8_UNORM;
  188. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  189. break;
  190. case PIXELFORMAT_RGBA8_UNORM_sRGB:
  191. textureFormat.internalFormat = VK_FORMAT_R8G8B8A8_SRGB;
  192. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  193. break;
  194. case PIXELFORMAT_BGRA8_UNORM:
  195. textureFormat.internalFormat = VK_FORMAT_B8G8R8A8_UNORM;
  196. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  197. break;
  198. case PIXELFORMAT_BGRA8_UNORM_sRGB:
  199. textureFormat.internalFormat = VK_FORMAT_B8G8R8A8_SRGB;
  200. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  201. break;
  202. case PIXELFORMAT_RGBA8_INT:
  203. textureFormat.internalFormat = VK_FORMAT_R8G8B8A8_SINT;
  204. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
  205. break;
  206. case PIXELFORMAT_RGBA8_UINT:
  207. textureFormat.internalFormat = VK_FORMAT_R8G8B8A8_UINT;
  208. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
  209. break;
  210. case PIXELFORMAT_RGBA16_UNORM:
  211. textureFormat.internalFormat = VK_FORMAT_R16G16B16A16_UNORM;
  212. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  213. break;
  214. case PIXELFORMAT_RGBA16_FLOAT:
  215. textureFormat.internalFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
  216. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  217. break;
  218. case PIXELFORMAT_RGBA16_INT:
  219. textureFormat.internalFormat = VK_FORMAT_R16G16B16A16_SINT;
  220. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
  221. break;
  222. case PIXELFORMAT_RGBA16_UINT:
  223. textureFormat.internalFormat = VK_FORMAT_R16G16B16A16_UINT;
  224. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
  225. break;
  226. case PIXELFORMAT_RGBA32_FLOAT:
  227. textureFormat.internalFormat = VK_FORMAT_R32G32B32A32_SFLOAT;
  228. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT;
  229. break;
  230. case PIXELFORMAT_RGBA32_INT:
  231. textureFormat.internalFormat = VK_FORMAT_R32G32B32A32_SINT;
  232. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
  233. break;
  234. case PIXELFORMAT_RGBA32_UINT:
  235. textureFormat.internalFormat = VK_FORMAT_R32G32B32A32_UINT;
  236. textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
  237. break;
  238. case PIXELFORMAT_RGBA4_UNORM: // LSB->MSB: [a: b: g: r]
  239. case PIXELFORMAT_RGB5A1_UNORM: // LSB->MSB: [a: b: g: r]
  240. case PIXELFORMAT_RGB565_UNORM: // LSB->MSB: [b: g: r]
  241. case PIXELFORMAT_RGB10A2_UNORM: // LSB->MSB: [r: g: b: a]
  242. case PIXELFORMAT_RG11B10_FLOAT: // LSB->MSB: [r: g: b]
  243. case PIXELFORMAT_STENCIL8:
  244. case PIXELFORMAT_DEPTH16_UNORM:
  245. case PIXELFORMAT_DEPTH24_UNORM:
  246. case PIXELFORMAT_DEPTH32_FLOAT:
  247. case PIXELFORMAT_DEPTH24_UNORM_STENCIL8:
  248. case PIXELFORMAT_DEPTH32_FLOAT_STENCIL8:
  249. case PIXELFORMAT_DXT1_UNORM:
  250. case PIXELFORMAT_DXT3_UNORM:
  251. case PIXELFORMAT_DXT5_UNORM:
  252. case PIXELFORMAT_BC4_UNORM:
  253. case PIXELFORMAT_BC4_SNORM:
  254. case PIXELFORMAT_BC5_UNORM:
  255. case PIXELFORMAT_BC5_SNORM:
  256. case PIXELFORMAT_BC6H_UFLOAT:
  257. case PIXELFORMAT_BC6H_FLOAT:
  258. case PIXELFORMAT_BC7_UNORM:
  259. case PIXELFORMAT_PVR1_RGB2_UNORM:
  260. case PIXELFORMAT_PVR1_RGB4_UNORM:
  261. case PIXELFORMAT_PVR1_RGBA2_UNORM:
  262. case PIXELFORMAT_PVR1_RGBA4_UNORM:
  263. case PIXELFORMAT_ETC1_UNORM:
  264. case PIXELFORMAT_ETC2_RGB_UNORM:
  265. case PIXELFORMAT_ETC2_RGBA_UNORM:
  266. case PIXELFORMAT_ETC2_RGBA1_UNORM:
  267. case PIXELFORMAT_EAC_R_UNORM:
  268. case PIXELFORMAT_EAC_R_SNORM:
  269. case PIXELFORMAT_EAC_RG_UNORM:
  270. case PIXELFORMAT_EAC_RG_SNORM:
  271. case PIXELFORMAT_ASTC_4x4:
  272. case PIXELFORMAT_ASTC_5x4:
  273. case PIXELFORMAT_ASTC_5x5:
  274. case PIXELFORMAT_ASTC_6x5:
  275. case PIXELFORMAT_ASTC_6x6:
  276. case PIXELFORMAT_ASTC_8x5:
  277. case PIXELFORMAT_ASTC_8x6:
  278. case PIXELFORMAT_ASTC_8x8:
  279. case PIXELFORMAT_ASTC_10x5:
  280. case PIXELFORMAT_ASTC_10x6:
  281. case PIXELFORMAT_ASTC_10x8:
  282. case PIXELFORMAT_ASTC_10x10:
  283. case PIXELFORMAT_ASTC_12x10:
  284. case PIXELFORMAT_ASTC_12x12:
  285. throw love::Exception("unimplemented pixel format");
  286. }
  287. return textureFormat;
  288. }
  289. // values taken from https://pcisig.com/membership/member-companies
  290. // as specified at https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkPhysicalDeviceProperties.html
  291. std::string Vulkan::getVendorName(uint32_t vendorId) {
  292. switch (vendorId) {
  293. case 4130:
  294. return "AMD";
  295. case 4318:
  296. return "Nvidia";
  297. case 8086:
  298. return "Intel";
  299. case 4203:
  300. return "Apple";
  301. case 5140:
  302. return "Microsoft";
  303. case 5045:
  304. return "ARM";
  305. case 20803:
  306. return "Qualcomm";
  307. case 5348:
  308. return "Broadcom";
  309. default:
  310. return "unknown";
  311. }
  312. }
  313. std::string Vulkan::getVulkanApiVersion(uint32_t version) {
  314. std::stringstream ss;
  315. ss << VK_API_VERSION_MAJOR(version)
  316. << "." << VK_API_VERSION_MINOR(version)
  317. << "." << VK_API_VERSION_PATCH(version);
  318. return ss.str();
  319. }
  320. VkPrimitiveTopology Vulkan::getPrimitiveTypeTopology(graphics::PrimitiveType primitiveType) {
  321. switch (primitiveType) {
  322. case PRIMITIVE_POINTS:
  323. return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
  324. case PRIMITIVE_TRIANGLES:
  325. return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
  326. case PRIMITIVE_TRIANGLE_FAN:
  327. return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
  328. case PRIMITIVE_TRIANGLE_STRIP:
  329. return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
  330. default:
  331. throw love::Exception("unknown primitive type");
  332. }
  333. }
  334. VkBlendFactor Vulkan::getBlendFactor(BlendFactor blendFactor) {
  335. switch (blendFactor) {
  336. case BLENDFACTOR_ZERO:
  337. return VK_BLEND_FACTOR_ZERO;
  338. case BLENDFACTOR_ONE:
  339. return VK_BLEND_FACTOR_ONE;
  340. case BLENDFACTOR_SRC_COLOR:
  341. return VK_BLEND_FACTOR_SRC_COLOR;
  342. case BLENDFACTOR_ONE_MINUS_SRC_COLOR:
  343. return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
  344. case BLENDFACTOR_SRC_ALPHA:
  345. return VK_BLEND_FACTOR_SRC_ALPHA;
  346. case BLENDFACTOR_ONE_MINUS_SRC_ALPHA:
  347. return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
  348. case BLENDFACTOR_DST_COLOR:
  349. return VK_BLEND_FACTOR_DST_COLOR;
  350. case BLENDFACTOR_ONE_MINUS_DST_COLOR:
  351. return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
  352. case BLENDFACTOR_DST_ALPHA:
  353. return VK_BLEND_FACTOR_DST_ALPHA;
  354. case BLENDFACTOR_ONE_MINUS_DST_ALPHA:
  355. return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
  356. case BLENDFACTOR_SRC_ALPHA_SATURATED:
  357. return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
  358. default:
  359. throw love::Exception("unknown blend factor");
  360. }
  361. }
  362. VkBlendOp Vulkan::getBlendOp(BlendOperation op) {
  363. switch (op) {
  364. case BLENDOP_ADD:
  365. return VK_BLEND_OP_ADD;
  366. case BLENDOP_MAX:
  367. return VK_BLEND_OP_MAX;
  368. case BLENDOP_MIN:
  369. return VK_BLEND_OP_MIN;
  370. case BLENDOP_SUBTRACT:
  371. return VK_BLEND_OP_SUBTRACT;
  372. case BLENDOP_REVERSE_SUBTRACT:
  373. return VK_BLEND_OP_REVERSE_SUBTRACT;
  374. default:
  375. throw love::Exception("unknown blend operation");
  376. }
  377. }
  378. VkBool32 Vulkan::getBool(bool b) {
  379. if (b) {
  380. return VK_TRUE;
  381. } else {
  382. return VK_FALSE;
  383. }
  384. }
  385. VkColorComponentFlags Vulkan::getColorMask(ColorChannelMask mask) {
  386. VkColorComponentFlags flags = 0;
  387. if (mask.r) {
  388. flags |= VK_COLOR_COMPONENT_R_BIT;
  389. }
  390. if (mask.g) {
  391. flags |= VK_COLOR_COMPONENT_G_BIT;
  392. }
  393. if (mask.b) {
  394. flags |= VK_COLOR_COMPONENT_B_BIT;
  395. }
  396. if (mask.a) {
  397. flags |= VK_COLOR_COMPONENT_A_BIT;
  398. }
  399. return flags;
  400. }
  401. VkFrontFace Vulkan::getFrontFace(Winding winding) {
  402. switch (winding) {
  403. case WINDING_CW:
  404. return VK_FRONT_FACE_CLOCKWISE;
  405. case WINDING_CCW:
  406. return VK_FRONT_FACE_COUNTER_CLOCKWISE;
  407. default:
  408. throw love::Exception("unknown winding");
  409. }
  410. }
  411. VkCullModeFlags Vulkan::getCullMode(CullMode cullmode) {
  412. switch (cullmode) {
  413. case CULL_BACK:
  414. return VK_CULL_MODE_BACK_BIT;
  415. case CULL_FRONT:
  416. return VK_CULL_MODE_FRONT_BIT;
  417. case CULL_NONE:
  418. return VK_CULL_MODE_NONE;
  419. default:
  420. throw love::Exception("unknown cull mode");
  421. }
  422. }
  423. void Vulkan::cmdTransitionImageLayout(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout) {
  424. VkImageMemoryBarrier barrier{};
  425. barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
  426. barrier.oldLayout = oldLayout;
  427. barrier.newLayout = newLayout;
  428. barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
  429. barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
  430. barrier.image = image;
  431. barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  432. barrier.subresourceRange.baseMipLevel = 0;
  433. barrier.subresourceRange.levelCount = 1;
  434. barrier.subresourceRange.baseArrayLayer = 0;
  435. barrier.subresourceRange.layerCount = 1;
  436. VkPipelineStageFlags sourceStage;
  437. VkPipelineStageFlags destinationStage;
  438. if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
  439. barrier.srcAccessMask = 0;
  440. barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
  441. sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
  442. destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
  443. }
  444. else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
  445. barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
  446. barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
  447. sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
  448. destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  449. }
  450. else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_GENERAL) {
  451. barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
  452. barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
  453. sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
  454. destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  455. }
  456. else if (oldLayout == VK_IMAGE_LAYOUT_GENERAL && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
  457. barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
  458. barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
  459. sourceStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  460. destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
  461. }
  462. else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_GENERAL) {
  463. barrier.srcAccessMask = 0;
  464. barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
  465. sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT;
  466. destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  467. }
  468. else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
  469. barrier.srcAccessMask = 0;
  470. barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
  471. sourceStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
  472. destinationStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  473. }
  474. else if (oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
  475. barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
  476. barrier.dstAccessMask = 0;
  477. sourceStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  478. destinationStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
  479. }
  480. else if (oldLayout == VK_IMAGE_LAYOUT_GENERAL && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
  481. barrier.srcAccessMask = 0;
  482. barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
  483. sourceStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
  484. destinationStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  485. }
  486. else if (oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_GENERAL) {
  487. barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
  488. barrier.dstAccessMask = 0;
  489. sourceStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  490. destinationStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
  491. }
  492. else {
  493. throw std::invalid_argument("unsupported layout transition!");
  494. }
  495. vkCmdPipelineBarrier(
  496. commandBuffer,
  497. sourceStage, destinationStage,
  498. 0,
  499. 0, nullptr,
  500. 0, nullptr,
  501. 1, &barrier
  502. );
  503. }
  504. }
  505. }
  506. }