BsVulkanUtility.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsVulkanUtility.h"
  4. #include "BsVulkanRenderAPI.h"
  5. #include "BsVulkanDevice.h"
  6. #include "BsException.h"
  7. namespace BansheeEngine
  8. {
  9. VkFormat VulkanUtility::getPixelFormat(PixelFormat format, bool sRGB)
  10. {
  11. switch (format)
  12. {
  13. case PF_R8:
  14. if(sRGB)
  15. return VK_FORMAT_R8_SRGB;
  16. return VK_FORMAT_R8_UNORM;
  17. case PF_R8G8:
  18. if (sRGB)
  19. return VK_FORMAT_R8G8_SRGB;
  20. return VK_FORMAT_R8G8_UNORM;
  21. case PF_R8G8B8:
  22. if (sRGB)
  23. return VK_FORMAT_R8G8B8_SRGB;
  24. return VK_FORMAT_R8G8B8_UNORM;
  25. case PF_R8G8B8A8:
  26. if (sRGB)
  27. return VK_FORMAT_R8G8B8A8_SRGB;
  28. return VK_FORMAT_R8G8B8A8_UNORM;
  29. case PF_B8G8R8A8:
  30. case PF_B8G8R8X8:
  31. if (sRGB)
  32. return VK_FORMAT_B8G8R8A8_SRGB;
  33. return VK_FORMAT_B8G8R8A8_UNORM;
  34. case PF_FLOAT16_R:
  35. return VK_FORMAT_R16_SFLOAT;
  36. case PF_FLOAT16_RG:
  37. return VK_FORMAT_R16G16_SFLOAT;
  38. case PF_FLOAT16_RGB:
  39. return VK_FORMAT_R16G16B16_SFLOAT;
  40. case PF_FLOAT16_RGBA:
  41. return VK_FORMAT_R16G16B16A16_SFLOAT;
  42. case PF_FLOAT32_R:
  43. return VK_FORMAT_R32_SFLOAT;
  44. case PF_FLOAT32_RG:
  45. return VK_FORMAT_R32G32_SFLOAT;
  46. case PF_FLOAT32_RGB:
  47. return VK_FORMAT_R32G32B32_SFLOAT;
  48. case PF_FLOAT32_RGBA:
  49. return VK_FORMAT_R32G32B32A32_SFLOAT;
  50. case PF_BC1:
  51. if (sRGB)
  52. return VK_FORMAT_BC1_RGB_SRGB_BLOCK;
  53. return VK_FORMAT_BC1_RGB_UNORM_BLOCK;
  54. case PF_BC1a:
  55. if (sRGB)
  56. return VK_FORMAT_BC1_RGBA_SRGB_BLOCK;
  57. return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
  58. case PF_BC2:
  59. if (sRGB)
  60. return VK_FORMAT_BC2_SRGB_BLOCK;
  61. return VK_FORMAT_BC2_UNORM_BLOCK;
  62. case PF_BC3:
  63. if (sRGB)
  64. return VK_FORMAT_BC3_SRGB_BLOCK;
  65. return VK_FORMAT_BC3_UNORM_BLOCK;
  66. case PF_BC4:
  67. return VK_FORMAT_BC4_SNORM_BLOCK;
  68. case PF_BC5:
  69. return VK_FORMAT_BC5_UNORM_BLOCK;
  70. case PF_BC6H:
  71. return VK_FORMAT_BC6H_SFLOAT_BLOCK;
  72. case PF_BC7:
  73. if (sRGB)
  74. return VK_FORMAT_BC7_SRGB_BLOCK;
  75. return VK_FORMAT_BC7_UNORM_BLOCK;
  76. case PF_D32_S8X24:
  77. return VK_FORMAT_D32_SFLOAT_S8_UINT;
  78. case PF_D24S8:
  79. return VK_FORMAT_D24_UNORM_S8_UINT;
  80. case PF_D32:
  81. return VK_FORMAT_D32_SFLOAT;
  82. case PF_D16:
  83. return VK_FORMAT_D16_UNORM;
  84. case PF_FLOAT_R11G11B10:
  85. return VK_FORMAT_B10G11R11_UFLOAT_PACK32;
  86. case PF_UNORM_R10G10B10A2:
  87. return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
  88. case PF_A8R8G8B8:
  89. case PF_A8B8G8R8:
  90. case PF_X8R8G8B8:
  91. case PF_X8B8G8R8:
  92. case PF_UNKNOWN:
  93. default:
  94. return VK_FORMAT_UNDEFINED;
  95. }
  96. }
  97. VkFormat VulkanUtility::getBufferFormat(GpuBufferFormat format)
  98. {
  99. static bool lookupInitialized = false;
  100. static VkFormat lookup[BF_COUNT];
  101. if (!lookupInitialized)
  102. {
  103. lookup[BF_16X1F] = VK_FORMAT_R16_SFLOAT;
  104. lookup[BF_16X2F] = VK_FORMAT_R16G16_SFLOAT;
  105. lookup[BF_16X4F] = VK_FORMAT_R16G16B16A16_SFLOAT;
  106. lookup[BF_32X1F] = VK_FORMAT_R32_SFLOAT;
  107. lookup[BF_32X2F] = VK_FORMAT_R32G32_SFLOAT;
  108. lookup[BF_32X3F] = VK_FORMAT_R32G32B32_SFLOAT;
  109. lookup[BF_32X4F] = VK_FORMAT_R32G32B32A32_SFLOAT;
  110. lookup[BF_8X1] = VK_FORMAT_R8_UNORM;
  111. lookup[BF_8X2] = VK_FORMAT_R8G8_UNORM;
  112. lookup[BF_8X4] = VK_FORMAT_R8G8B8A8_UNORM;
  113. lookup[BF_16X1] = VK_FORMAT_R16_UNORM;
  114. lookup[BF_16X2] = VK_FORMAT_R16G16_UNORM;
  115. lookup[BF_16X4] = VK_FORMAT_R16G16B16A16_UNORM;
  116. lookup[BF_8X1S] = VK_FORMAT_R8_SINT;
  117. lookup[BF_8X2S] = VK_FORMAT_R8G8_SINT;
  118. lookup[BF_8X4S] = VK_FORMAT_R8G8B8A8_SINT;
  119. lookup[BF_16X1S] = VK_FORMAT_R16_SINT;
  120. lookup[BF_16X2S] = VK_FORMAT_R16G16_SINT;
  121. lookup[BF_16X4S] = VK_FORMAT_R16G16B16A16_SINT;
  122. lookup[BF_32X1S] = VK_FORMAT_R32_SINT;
  123. lookup[BF_32X2S] = VK_FORMAT_R32G32_SINT;
  124. lookup[BF_32X3S] = VK_FORMAT_R32G32B32_SINT;
  125. lookup[BF_32X4S] = VK_FORMAT_R32G32B32A32_SINT;
  126. lookup[BF_8X1U] = VK_FORMAT_R8_UINT;
  127. lookup[BF_8X2U] = VK_FORMAT_R8G8_UINT;
  128. lookup[BF_8X4U] = VK_FORMAT_R8G8B8A8_UINT;
  129. lookup[BF_16X1U] = VK_FORMAT_R16_UINT;
  130. lookup[BF_16X2U] = VK_FORMAT_R16G16_UINT;
  131. lookup[BF_16X4U] = VK_FORMAT_R16G16B16A16_UINT;
  132. lookup[BF_32X1U] = VK_FORMAT_R32_UINT;
  133. lookup[BF_32X2U] = VK_FORMAT_R32G32_UINT;
  134. lookup[BF_32X3U] = VK_FORMAT_R32G32B32_UINT;
  135. lookup[BF_32X4U] = VK_FORMAT_R32G32B32A32_UINT;
  136. lookupInitialized = true;
  137. }
  138. if (format >= BF_COUNT)
  139. return VK_FORMAT_UNDEFINED;
  140. return lookup[(UINT32)format];
  141. }
  142. VkFormat VulkanUtility::getVertexType(VertexElementType type)
  143. {
  144. static bool lookupInitialized = false;
  145. static VkFormat lookup[VET_COUNT];
  146. if (!lookupInitialized)
  147. {
  148. lookup[VET_COLOR] = VK_FORMAT_R8G8B8A8_UNORM;
  149. lookup[VET_COLOR_ABGR] = VK_FORMAT_R8G8B8A8_UNORM;
  150. lookup[VET_COLOR_ARGB] = VK_FORMAT_R8G8B8A8_UNORM;
  151. lookup[VET_UBYTE4_NORM] = VK_FORMAT_R8G8B8A8_UNORM;
  152. lookup[VET_FLOAT1] = VK_FORMAT_R32_SFLOAT;
  153. lookup[VET_FLOAT2] = VK_FORMAT_R32G32_SFLOAT;
  154. lookup[VET_FLOAT3] = VK_FORMAT_R32G32B32_SFLOAT;
  155. lookup[VET_FLOAT4] = VK_FORMAT_R32G32B32A32_SFLOAT;
  156. lookup[VET_USHORT1] = VK_FORMAT_R16_UINT;
  157. lookup[VET_USHORT2] = VK_FORMAT_R16G16_UINT;
  158. lookup[VET_USHORT4] = VK_FORMAT_R16G16B16A16_UINT;
  159. lookup[VET_SHORT1] = VK_FORMAT_R16_SINT;
  160. lookup[VET_SHORT2] = VK_FORMAT_R16G16_SINT;
  161. lookup[VET_SHORT4] = VK_FORMAT_R16G16B16A16_SINT;
  162. lookup[VET_UINT1] = VK_FORMAT_R32_UINT;
  163. lookup[VET_UINT2] = VK_FORMAT_R32G32_UINT;
  164. lookup[VET_UINT3] = VK_FORMAT_R32G32B32_UINT;
  165. lookup[VET_UINT4] = VK_FORMAT_R32G32B32A32_UINT;
  166. lookup[VET_INT1] = VK_FORMAT_R32_SINT;
  167. lookup[VET_INT2] = VK_FORMAT_R32G32_SINT;
  168. lookup[VET_INT3] = VK_FORMAT_R32G32B32_SINT;
  169. lookup[VET_INT4] = VK_FORMAT_R32G32B32A32_SINT;
  170. lookup[VET_UBYTE4] = VK_FORMAT_R8G8B8A8_UINT;
  171. lookupInitialized = true;
  172. }
  173. if (type >= VET_COUNT)
  174. return VK_FORMAT_UNDEFINED;
  175. return lookup[(UINT32)type];
  176. }
  177. VkSampleCountFlagBits VulkanUtility::getSampleFlags(UINT32 numSamples)
  178. {
  179. switch(numSamples)
  180. {
  181. case 1:
  182. return VK_SAMPLE_COUNT_1_BIT;
  183. case 2:
  184. return VK_SAMPLE_COUNT_2_BIT;
  185. case 4:
  186. return VK_SAMPLE_COUNT_4_BIT;
  187. case 8:
  188. return VK_SAMPLE_COUNT_8_BIT;
  189. case 16:
  190. return VK_SAMPLE_COUNT_16_BIT;
  191. case 32:
  192. return VK_SAMPLE_COUNT_32_BIT;
  193. case 64:
  194. return VK_SAMPLE_COUNT_64_BIT;
  195. }
  196. BS_EXCEPT(RenderingAPIException, "Unsupported sample count: " + toString(numSamples));
  197. return VK_SAMPLE_COUNT_1_BIT;
  198. }
  199. VkSamplerAddressMode VulkanUtility::getAddressingMode(TextureAddressingMode mode)
  200. {
  201. switch (mode)
  202. {
  203. case TAM_WRAP:
  204. return VK_SAMPLER_ADDRESS_MODE_REPEAT;
  205. case TAM_MIRROR:
  206. return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
  207. case TAM_CLAMP:
  208. return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
  209. case TAM_BORDER:
  210. return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
  211. }
  212. return VK_SAMPLER_ADDRESS_MODE_REPEAT;
  213. }
  214. VkBlendFactor VulkanUtility::getBlendFactor(BlendFactor factor)
  215. {
  216. switch (factor)
  217. {
  218. case BF_ONE:
  219. return VK_BLEND_FACTOR_ONE;
  220. case BF_ZERO:
  221. return VK_BLEND_FACTOR_ZERO;
  222. case BF_DEST_COLOR:
  223. return VK_BLEND_FACTOR_DST_COLOR;
  224. case BF_SOURCE_COLOR:
  225. return VK_BLEND_FACTOR_SRC_COLOR;
  226. case BF_INV_DEST_COLOR:
  227. return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
  228. case BF_INV_SOURCE_COLOR:
  229. return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
  230. case BF_DEST_ALPHA:
  231. return VK_BLEND_FACTOR_DST_ALPHA;
  232. case BF_SOURCE_ALPHA:
  233. return VK_BLEND_FACTOR_SRC_ALPHA;
  234. case BF_INV_DEST_ALPHA:
  235. return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
  236. case BF_INV_SOURCE_ALPHA:
  237. return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
  238. }
  239. // Unsupported type
  240. return VK_BLEND_FACTOR_ZERO;
  241. }
  242. VkBlendOp VulkanUtility::getBlendOp(BlendOperation op)
  243. {
  244. switch (op)
  245. {
  246. case BO_ADD:
  247. return VK_BLEND_OP_ADD;
  248. case BO_SUBTRACT:
  249. return VK_BLEND_OP_SUBTRACT;
  250. case BO_REVERSE_SUBTRACT:
  251. return VK_BLEND_OP_REVERSE_SUBTRACT;
  252. case BO_MIN:
  253. return VK_BLEND_OP_MIN;
  254. case BO_MAX:
  255. return VK_BLEND_OP_MAX;
  256. }
  257. // Unsupported type
  258. return VK_BLEND_OP_ADD;
  259. }
  260. VkCompareOp VulkanUtility::getCompareOp(CompareFunction op)
  261. {
  262. switch (op)
  263. {
  264. case CMPF_ALWAYS_FAIL:
  265. return VK_COMPARE_OP_NEVER;
  266. case CMPF_ALWAYS_PASS:
  267. return VK_COMPARE_OP_ALWAYS;
  268. case CMPF_LESS:
  269. return VK_COMPARE_OP_LESS;
  270. case CMPF_LESS_EQUAL:
  271. return VK_COMPARE_OP_LESS_OR_EQUAL;
  272. case CMPF_EQUAL:
  273. return VK_COMPARE_OP_EQUAL;
  274. case CMPF_NOT_EQUAL:
  275. return VK_COMPARE_OP_NOT_EQUAL;
  276. case CMPF_GREATER_EQUAL:
  277. return VK_COMPARE_OP_GREATER_OR_EQUAL;
  278. case CMPF_GREATER:
  279. return VK_COMPARE_OP_GREATER;
  280. };
  281. // Unsupported type
  282. return VK_COMPARE_OP_ALWAYS;
  283. }
  284. VkCullModeFlagBits VulkanUtility::getCullMode(CullingMode mode)
  285. {
  286. switch (mode)
  287. {
  288. case CULL_NONE:
  289. return VK_CULL_MODE_NONE;
  290. case CULL_CLOCKWISE:
  291. return VK_CULL_MODE_BACK_BIT;
  292. case CULL_COUNTERCLOCKWISE:
  293. return VK_CULL_MODE_FRONT_BIT;
  294. }
  295. // Unsupported type
  296. return VK_CULL_MODE_NONE;
  297. }
  298. VkPolygonMode VulkanUtility::getPolygonMode(PolygonMode mode)
  299. {
  300. switch (mode)
  301. {
  302. case PM_WIREFRAME:
  303. return VK_POLYGON_MODE_LINE;
  304. case PM_SOLID:
  305. return VK_POLYGON_MODE_FILL;
  306. }
  307. return VK_POLYGON_MODE_FILL;
  308. }
  309. VkStencilOp VulkanUtility::getStencilOp(StencilOperation op)
  310. {
  311. switch (op)
  312. {
  313. case SOP_KEEP:
  314. return VK_STENCIL_OP_KEEP;
  315. case SOP_ZERO:
  316. return VK_STENCIL_OP_ZERO;
  317. case SOP_REPLACE:
  318. return VK_STENCIL_OP_REPLACE;
  319. case SOP_INCREMENT:
  320. return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
  321. case SOP_DECREMENT:
  322. return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
  323. case SOP_INCREMENT_WRAP:
  324. return VK_STENCIL_OP_INCREMENT_AND_WRAP;
  325. case SOP_DECREMENT_WRAP:
  326. return VK_STENCIL_OP_DECREMENT_AND_WRAP;
  327. case SOP_INVERT:
  328. return VK_STENCIL_OP_INVERT;
  329. }
  330. // Unsupported type
  331. return VK_STENCIL_OP_KEEP;
  332. }
  333. VkIndexType VulkanUtility::getIndexType(IndexType op)
  334. {
  335. switch(op)
  336. {
  337. case IT_16BIT:
  338. return VK_INDEX_TYPE_UINT16;
  339. case IT_32BIT:
  340. return VK_INDEX_TYPE_UINT32;
  341. }
  342. // Unsupported type
  343. return VK_INDEX_TYPE_UINT32;
  344. }
  345. VkPrimitiveTopology VulkanUtility::getDrawOp(DrawOperationType op)
  346. {
  347. switch (op)
  348. {
  349. case DOT_POINT_LIST:
  350. return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
  351. case DOT_LINE_LIST:
  352. return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
  353. case DOT_LINE_STRIP:
  354. return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
  355. case DOT_TRIANGLE_LIST:
  356. return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
  357. case DOT_TRIANGLE_STRIP:
  358. return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
  359. case DOT_TRIANGLE_FAN:
  360. return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
  361. }
  362. // Unsupported type
  363. return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
  364. }
  365. VkFilter VulkanUtility::getFilter(FilterOptions filter)
  366. {
  367. switch(filter)
  368. {
  369. case FO_LINEAR:
  370. case FO_ANISOTROPIC:
  371. return VK_FILTER_LINEAR;
  372. case FO_POINT:
  373. case FO_NONE:
  374. return VK_FILTER_NEAREST;
  375. }
  376. // Unsupported type
  377. return VK_FILTER_LINEAR;
  378. }
  379. VkSamplerMipmapMode VulkanUtility::getMipFilter(FilterOptions filter)
  380. {
  381. switch (filter)
  382. {
  383. case FO_LINEAR:
  384. case FO_ANISOTROPIC:
  385. return VK_SAMPLER_MIPMAP_MODE_LINEAR;
  386. case FO_POINT:
  387. case FO_NONE:
  388. return VK_SAMPLER_MIPMAP_MODE_NEAREST;
  389. }
  390. // Unsupported type
  391. return VK_SAMPLER_MIPMAP_MODE_LINEAR;
  392. }
  393. void VulkanUtility::getDevices(const VulkanRenderAPI& rapi, GpuDeviceFlags flags, VulkanDevice*(&devices)[BS_MAX_DEVICES])
  394. {
  395. UINT32 numDevices = std::min(BS_MAX_DEVICES, rapi._getNumDevices());
  396. for (UINT32 i = 0; i < numDevices; i++)
  397. {
  398. VulkanDevice* device = rapi._getDevice(i).get();
  399. if (isDeviceIdxSet(rapi, i, flags))
  400. devices[i] = device;
  401. else
  402. devices[i] = nullptr;
  403. }
  404. }
  405. bool VulkanUtility::isDeviceIdxSet(const VulkanRenderAPI& rapi, UINT32 idx, GpuDeviceFlags flags)
  406. {
  407. VulkanDevice* device = rapi._getDevice(idx).get();
  408. return ((flags & (1 << idx)) != 0 || (flags == GDF_DEFAULT && device->isPrimary()));
  409. }
  410. }