BsVulkanUtility.cpp 11 KB

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