VkGrManager.cpp 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Gr/Vulkan/VkGrManager.h>
  6. #include <AnKi/Util/StringList.h>
  7. #include <AnKi/Core/App.h>
  8. #include <AnKi/Gr/Vulkan/VkBuffer.h>
  9. #include <AnKi/Gr/Vulkan/VkTexture.h>
  10. #include <AnKi/Gr/Vulkan/VkSampler.h>
  11. #include <AnKi/Gr/Vulkan/VkShader.h>
  12. #include <AnKi/Gr/Vulkan/VkShaderProgram.h>
  13. #include <AnKi/Gr/Vulkan/VkCommandBuffer.h>
  14. #include <AnKi/Gr/Vulkan/VkOcclusionQuery.h>
  15. #include <AnKi/Gr/Vulkan/VkTimestampQuery.h>
  16. #include <AnKi/Gr/Vulkan/VkPipelineQuery.h>
  17. #include <AnKi/Gr/RenderGraph.h>
  18. #include <AnKi/Gr/Vulkan/VkAccelerationStructure.h>
  19. #include <AnKi/Gr/Vulkan/VkGrUpscaler.h>
  20. #include <AnKi/Gr/Vulkan/VkFence.h>
  21. #include <AnKi/Gr/Vulkan/VkGpuMemoryManager.h>
  22. #include <AnKi/Gr/Vulkan/VkDescriptor.h>
  23. #include <AnKi/Window/NativeWindow.h>
  24. #if ANKI_WINDOWING_SYSTEM_SDL
  25. # include <AnKi/Window/NativeWindowSdl.h>
  26. # include <SDL3/SDL_vulkan.h>
  27. #elif ANKI_WINDOWING_SYSTEM_ANDROID
  28. # include <AnKi/Window/NativeWindowAndroid.h>
  29. #elif ANKI_WINDOWING_SYSTEM_HEADLESS
  30. // Nothing extra
  31. #else
  32. # error "Unsupported"
  33. #endif
  34. namespace anki {
  35. // DLSS related
  36. #define ANKI_VK_NVX_BINARY_IMPORT "VK_NVX_binary_import"
  37. template<>
  38. template<>
  39. GrManager& MakeSingletonPtr<GrManager>::allocateSingleton<>()
  40. {
  41. ANKI_ASSERT(m_global == nullptr);
  42. m_global = new GrManagerImpl;
  43. #if ANKI_ASSERTIONS_ENABLED
  44. ++g_singletonsAllocated;
  45. #endif
  46. return *m_global;
  47. }
  48. template<>
  49. void MakeSingletonPtr<GrManager>::freeSingleton()
  50. {
  51. if(m_global)
  52. {
  53. delete static_cast<GrManagerImpl*>(m_global);
  54. m_global = nullptr;
  55. #if ANKI_ASSERTIONS_ENABLED
  56. --g_singletonsAllocated;
  57. #endif
  58. }
  59. }
  60. GrManager::GrManager()
  61. {
  62. }
  63. GrManager::~GrManager()
  64. {
  65. }
  66. Error GrManager::init(GrManagerInitInfo& inf)
  67. {
  68. ANKI_VK_SELF(GrManagerImpl);
  69. return self.init(inf);
  70. }
  71. void GrManager::beginFrame()
  72. {
  73. ANKI_VK_SELF(GrManagerImpl);
  74. self.beginFrameInternal();
  75. }
  76. TexturePtr GrManager::acquireNextPresentableTexture()
  77. {
  78. ANKI_VK_SELF(GrManagerImpl);
  79. return self.acquireNextPresentableTexture();
  80. }
  81. void GrManager::endFrame()
  82. {
  83. ANKI_VK_SELF(GrManagerImpl);
  84. self.endFrameInternal();
  85. }
  86. void GrManager::finish()
  87. {
  88. ANKI_VK_SELF(GrManagerImpl);
  89. self.finishInternal();
  90. }
  91. #define ANKI_NEW_GR_OBJECT(type) \
  92. type##Ptr GrManager::new##type(const type##InitInfo& init) \
  93. { \
  94. type##Ptr ptr(type::newInstance(init)); \
  95. if(!ptr.isCreated()) [[unlikely]] \
  96. { \
  97. ANKI_VK_LOGF("Failed to create a " ANKI_STRINGIZE(type) " object"); \
  98. } \
  99. return ptr; \
  100. }
  101. #define ANKI_NEW_GR_OBJECT_NO_INIT_INFO(type) \
  102. type##Ptr GrManager::new##type() \
  103. { \
  104. type##Ptr ptr(type::newInstance()); \
  105. if(!ptr.isCreated()) [[unlikely]] \
  106. { \
  107. ANKI_VK_LOGF("Failed to create a " ANKI_STRINGIZE(type) " object"); \
  108. } \
  109. return ptr; \
  110. }
  111. ANKI_NEW_GR_OBJECT(Buffer)
  112. ANKI_NEW_GR_OBJECT(Texture)
  113. ANKI_NEW_GR_OBJECT(Sampler)
  114. ANKI_NEW_GR_OBJECT(Shader)
  115. ANKI_NEW_GR_OBJECT(ShaderProgram)
  116. ANKI_NEW_GR_OBJECT(CommandBuffer)
  117. ANKI_NEW_GR_OBJECT_NO_INIT_INFO(OcclusionQuery)
  118. ANKI_NEW_GR_OBJECT_NO_INIT_INFO(TimestampQuery)
  119. ANKI_NEW_GR_OBJECT(PipelineQuery)
  120. ANKI_NEW_GR_OBJECT_NO_INIT_INFO(RenderGraph)
  121. ANKI_NEW_GR_OBJECT(AccelerationStructure)
  122. ANKI_NEW_GR_OBJECT(GrUpscaler)
  123. #undef ANKI_NEW_GR_OBJECT
  124. #undef ANKI_NEW_GR_OBJECT_NO_INIT_INFO
  125. void GrManager::submit(WeakArray<CommandBuffer*> cmdbs, WeakArray<Fence*> waitFences, FencePtr* signalFence)
  126. {
  127. ANKI_VK_SELF(GrManagerImpl);
  128. self.submitInternal(cmdbs, waitFences, signalFence);
  129. }
  130. PtrSize GrManager::getAccelerationStructureMemoryRequirement(const AccelerationStructureInitInfo& init) const
  131. {
  132. ANKI_VK_SELF_CONST(GrManagerImpl);
  133. PtrSize asSize, unused;
  134. AccelerationStructureImpl::getMemoryRequirement(init, asSize, unused);
  135. return asSize + self.m_caps.m_asBufferAlignment;
  136. }
  137. GrManagerImpl::~GrManagerImpl()
  138. {
  139. ANKI_VK_LOGI("Destroying Vulkan backend");
  140. // 1st THING: wait for the GPU
  141. finishInternal();
  142. // 2nd THING: Destroy everything that has a reference to GrObjects.
  143. m_crntSwapchain.reset(nullptr);
  144. SwapchainFactory::freeSingleton();
  145. for(U32 frame = 0; frame < m_perFrame.getSize(); ++frame)
  146. {
  147. m_frame = frame;
  148. deleteObjectsMarkedForDeletion();
  149. }
  150. // 3rd THING: Continue with the rest
  151. CommandBufferFactory::freeSingleton();
  152. OcclusionQueryFactory::freeSingleton();
  153. TimestampQueryFactory::freeSingleton();
  154. PrimitivesPassedClippingFactory::freeSingleton();
  155. SemaphoreFactory::freeSingleton();
  156. SamplerFactory::freeSingleton();
  157. GpuMemoryManager::freeSingleton();
  158. PipelineLayoutFactory2::freeSingleton();
  159. BindlessDescriptorSet::freeSingleton();
  160. PipelineCache::freeSingleton();
  161. FenceFactory::freeSingleton();
  162. if(m_device)
  163. {
  164. vkDestroyDevice(m_device, nullptr);
  165. }
  166. if(m_surface)
  167. {
  168. vkDestroySurfaceKHR(m_instance, m_surface, nullptr);
  169. }
  170. if(m_debugUtilsMessager)
  171. {
  172. vkDestroyDebugUtilsMessengerEXT(m_instance, m_debugUtilsMessager, nullptr);
  173. }
  174. if(m_instance)
  175. {
  176. #if ANKI_GR_MANAGER_DEBUG_MEMMORY
  177. VkAllocationCallbacks* pallocCbs = &m_debugAllocCbs;
  178. #else
  179. VkAllocationCallbacks* pallocCbs = nullptr;
  180. #endif
  181. vkDestroyInstance(m_instance, pallocCbs);
  182. }
  183. m_cacheDir.destroy();
  184. GrMemoryPool::freeSingleton();
  185. }
  186. Error GrManagerImpl::init(const GrManagerInitInfo& init)
  187. {
  188. const Error err = initInternal(init);
  189. if(err)
  190. {
  191. ANKI_VK_LOGE("Vulkan initialization failed");
  192. return Error::kFunctionFailed;
  193. }
  194. return Error::kNone;
  195. }
  196. Error GrManagerImpl::initInternal(const GrManagerInitInfo& init)
  197. {
  198. ANKI_VK_LOGI("Initializing Vulkan backend");
  199. GrMemoryPool::allocateSingleton(init.m_allocCallback, init.m_allocCallbackUserData);
  200. m_cacheDir = init.m_cacheDirectory;
  201. ANKI_CHECK(initInstance());
  202. ANKI_CHECK(initSurface());
  203. ANKI_CHECK(initDevice());
  204. PipelineCache::allocateSingleton();
  205. ANKI_CHECK(PipelineCache::getSingleton().init(init.m_cacheDirectory));
  206. ANKI_CHECK(initMemory());
  207. CommandBufferFactory::allocateSingleton();
  208. FenceFactory::allocateSingleton();
  209. SemaphoreFactory::allocateSingleton();
  210. OcclusionQueryFactory::allocateSingleton();
  211. TimestampQueryFactory::allocateSingleton();
  212. PrimitivesPassedClippingFactory::allocateSingleton();
  213. SamplerFactory::allocateSingleton();
  214. SwapchainFactory::allocateSingleton(U32(g_cvarGrVsync));
  215. m_crntSwapchain = SwapchainFactory::getSingleton().newInstance();
  216. // See if unaligned formats are supported
  217. {
  218. m_capabilities.m_unalignedBbpTextureFormats = true;
  219. VkImageFormatProperties props = {};
  220. VkResult res = vkGetPhysicalDeviceImageFormatProperties(m_physicalDevice, VK_FORMAT_R8G8B8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
  221. VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &props);
  222. if(res == VK_ERROR_FORMAT_NOT_SUPPORTED)
  223. {
  224. m_capabilities.m_unalignedBbpTextureFormats = false;
  225. }
  226. res = vkGetPhysicalDeviceImageFormatProperties(m_physicalDevice, VK_FORMAT_R32G32B32_SFLOAT, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
  227. VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &props);
  228. if(res == VK_ERROR_FORMAT_NOT_SUPPORTED)
  229. {
  230. m_capabilities.m_unalignedBbpTextureFormats = false;
  231. }
  232. if(!m_capabilities.m_unalignedBbpTextureFormats)
  233. {
  234. ANKI_VK_LOGV("R8G8B8, R32G32B32 image formats are not supported");
  235. }
  236. }
  237. BindlessDescriptorSet::allocateSingleton();
  238. ANKI_CHECK(BindlessDescriptorSet::getSingleton().init());
  239. PipelineLayoutFactory2::allocateSingleton();
  240. return Error::kNone;
  241. }
  242. Error GrManagerImpl::initInstance()
  243. {
  244. // Init VOLK
  245. //
  246. ANKI_VK_CHECK(volkInitialize());
  247. // Create the instance
  248. //
  249. const U8 vulkanMinor = 1;
  250. const U8 vulkanMajor = 3;
  251. VkApplicationInfo app = {};
  252. app.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
  253. app.pApplicationName = "unamed";
  254. app.applicationVersion = 1;
  255. app.pEngineName = "AnKi 3D Engine";
  256. app.engineVersion = (ANKI_VERSION_MAJOR << 16) | ANKI_VERSION_MINOR;
  257. app.apiVersion = VK_MAKE_VERSION(vulkanMajor, vulkanMinor, 0);
  258. VkInstanceCreateInfo ci = {};
  259. ci.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
  260. ci.pApplicationInfo = &app;
  261. // Instance layers
  262. GrDynamicArray<const char*> layersToEnable;
  263. GrList<GrString> layersToEnableStrings;
  264. {
  265. U32 layerCount;
  266. vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
  267. if(layerCount)
  268. {
  269. GrDynamicArray<VkLayerProperties> layerProps;
  270. layerProps.resize(layerCount);
  271. vkEnumerateInstanceLayerProperties(&layerCount, &layerProps[0]);
  272. ANKI_VK_LOGV("Found the following instance layers:");
  273. for(const VkLayerProperties& layer : layerProps)
  274. {
  275. ANKI_VK_LOGV("\t%s", layer.layerName);
  276. CString layerName = layer.layerName;
  277. Bool enableLayer = (g_cvarGrValidation || g_cvarGrDebugPrintf) && layerName == "VK_LAYER_KHRONOS_validation";
  278. enableLayer = enableLayer || (!CString(g_cvarGrVkLayers).isEmpty() && CString(g_cvarGrVkLayers).find(layerName) != CString::kNpos);
  279. if(enableLayer)
  280. {
  281. layersToEnableStrings.emplaceBack(layer.layerName);
  282. layersToEnable.emplaceBack(layersToEnableStrings.getBack().cstr());
  283. }
  284. }
  285. }
  286. if(layersToEnable.getSize())
  287. {
  288. ANKI_VK_LOGI("Will enable the following instance layers:");
  289. for(const char* name : layersToEnable)
  290. {
  291. ANKI_VK_LOGI("\t%s", name);
  292. }
  293. ci.enabledLayerCount = layersToEnable.getSize();
  294. ci.ppEnabledLayerNames = &layersToEnable[0];
  295. }
  296. }
  297. // Validation features
  298. GrDynamicArray<VkValidationFeatureEnableEXT> enabledValidationFeatures;
  299. GrDynamicArray<VkValidationFeatureDisableEXT> disabledValidationFeatures;
  300. if(g_cvarGrDebugPrintf)
  301. {
  302. enabledValidationFeatures.emplaceBack(VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT);
  303. }
  304. if(g_cvarGrDebugPrintf && !g_cvarGrValidation)
  305. {
  306. disabledValidationFeatures.emplaceBack(VK_VALIDATION_FEATURE_DISABLE_ALL_EXT);
  307. }
  308. if(g_cvarGrValidation && g_cvarGrGpuValidation)
  309. {
  310. enabledValidationFeatures.emplaceBack(VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT);
  311. }
  312. VkValidationFeaturesEXT validationFeatures = {};
  313. if(enabledValidationFeatures.getSize() || disabledValidationFeatures.getSize())
  314. {
  315. validationFeatures.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT;
  316. validationFeatures.disabledValidationFeatureCount = disabledValidationFeatures.getSize();
  317. validationFeatures.enabledValidationFeatureCount = enabledValidationFeatures.getSize();
  318. validationFeatures.pDisabledValidationFeatures = disabledValidationFeatures.getBegin();
  319. validationFeatures.pEnabledValidationFeatures = enabledValidationFeatures.getBegin();
  320. validationFeatures.pNext = ci.pNext;
  321. ci.pNext = &validationFeatures;
  322. }
  323. // Extensions
  324. GrDynamicArray<const char*> instExtensions;
  325. GrDynamicArray<VkExtensionProperties> instExtensionInf;
  326. U32 extCount = 0;
  327. vkEnumerateInstanceExtensionProperties(nullptr, &extCount, nullptr);
  328. if(extCount)
  329. {
  330. instExtensions.resize(extCount);
  331. instExtensionInf.resize(extCount);
  332. vkEnumerateInstanceExtensionProperties(nullptr, &extCount, &instExtensionInf[0]);
  333. ANKI_VK_LOGV("Found the following instance extensions:");
  334. for(U32 i = 0; i < extCount; ++i)
  335. {
  336. ANKI_VK_LOGV("\t%s", instExtensionInf[i].extensionName);
  337. }
  338. U32 instExtensionCount = 0;
  339. for(U32 i = 0; i < extCount; ++i)
  340. {
  341. const CString extensionName = instExtensionInf[i].extensionName;
  342. #if ANKI_WINDOWING_SYSTEM_HEADLESS
  343. if(extensionName == VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME)
  344. {
  345. m_extensions |= VulkanExtensions::kEXT_headless_surface;
  346. instExtensions[instExtensionCount++] = VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME;
  347. }
  348. #elif ANKI_OS_LINUX
  349. if(extensionName == VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME)
  350. {
  351. m_extensions |= VulkanExtensions::kKHR_wayland_surface;
  352. instExtensions[instExtensionCount++] = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME;
  353. }
  354. else if(extensionName == VK_KHR_XCB_SURFACE_EXTENSION_NAME)
  355. {
  356. m_extensions |= VulkanExtensions::kKHR_xcb_surface;
  357. instExtensions[instExtensionCount++] = VK_KHR_XCB_SURFACE_EXTENSION_NAME;
  358. }
  359. else if(extensionName == VK_KHR_XLIB_SURFACE_EXTENSION_NAME)
  360. {
  361. m_extensions |= VulkanExtensions::kKHR_xlib_surface;
  362. instExtensions[instExtensionCount++] = VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
  363. }
  364. #elif ANKI_OS_WINDOWS
  365. if(extensionName == VK_KHR_WIN32_SURFACE_EXTENSION_NAME)
  366. {
  367. m_extensions |= VulkanExtensions::kKHR_win32_surface;
  368. instExtensions[instExtensionCount++] = VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
  369. }
  370. #elif ANKI_OS_ANDROID
  371. if(extensionName == VK_KHR_ANDROID_SURFACE_EXTENSION_NAME)
  372. {
  373. m_extensions |= VulkanExtensions::kKHR_android_surface;
  374. instExtensions[instExtensionCount++] = VK_KHR_ANDROID_SURFACE_EXTENSION_NAME;
  375. }
  376. #else
  377. # error Not implemented
  378. #endif
  379. else if(extensionName == VK_KHR_SURFACE_EXTENSION_NAME)
  380. {
  381. m_extensions |= VulkanExtensions::kKHR_surface;
  382. instExtensions[instExtensionCount++] = VK_KHR_SURFACE_EXTENSION_NAME;
  383. }
  384. else if(extensionName == VK_EXT_DEBUG_UTILS_EXTENSION_NAME && (g_cvarGrDebugMarkers || g_cvarGrValidation || g_cvarGrDebugPrintf))
  385. {
  386. m_extensions |= VulkanExtensions::kEXT_debug_utils;
  387. instExtensions[instExtensionCount++] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
  388. }
  389. }
  390. if(!(m_extensions
  391. & (VulkanExtensions::kEXT_headless_surface | VulkanExtensions::kKHR_wayland_surface | VulkanExtensions::kKHR_xcb_surface
  392. | VulkanExtensions::kKHR_xlib_surface | VulkanExtensions::kKHR_win32_surface | VulkanExtensions::kKHR_android_surface)))
  393. {
  394. ANKI_VK_LOGE("Couldn't find suitable surface extension");
  395. return Error::kFunctionFailed;
  396. }
  397. if(instExtensionCount)
  398. {
  399. ANKI_VK_LOGI("Will enable the following instance extensions:");
  400. for(U32 i = 0; i < instExtensionCount; ++i)
  401. {
  402. ANKI_VK_LOGI("\t%s", instExtensions[i]);
  403. }
  404. ci.enabledExtensionCount = instExtensionCount;
  405. ci.ppEnabledExtensionNames = &instExtensions[0];
  406. }
  407. }
  408. #if ANKI_GR_MANAGER_DEBUG_MEMMORY
  409. m_debugAllocCbs = {};
  410. m_debugAllocCbs.pUserData = this;
  411. m_debugAllocCbs.pfnAllocation = allocateCallback;
  412. m_debugAllocCbs.pfnReallocation = reallocateCallback;
  413. m_debugAllocCbs.pfnFree = freeCallback;
  414. VkAllocationCallbacks* pallocCbs = &m_debugAllocCbs;
  415. #else
  416. VkAllocationCallbacks* pallocCbs = nullptr;
  417. #endif
  418. ANKI_VK_CHECK(vkCreateInstance(&ci, pallocCbs, &m_instance));
  419. // Get symbolx
  420. //
  421. volkLoadInstance(m_instance);
  422. // Set debug callbacks
  423. if(!!(m_extensions & VulkanExtensions::kEXT_debug_utils))
  424. {
  425. VkDebugUtilsMessengerCreateInfoEXT info = {};
  426. info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
  427. info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
  428. | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
  429. info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT
  430. | VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
  431. info.pfnUserCallback = debugReportCallbackEXT;
  432. info.pUserData = this;
  433. vkCreateDebugUtilsMessengerEXT(m_instance, &info, nullptr, &m_debugUtilsMessager);
  434. }
  435. // Create the physical device
  436. //
  437. {
  438. uint32_t count = 0;
  439. ANKI_VK_CHECK(vkEnumeratePhysicalDevices(m_instance, &count, nullptr));
  440. if(count < 1)
  441. {
  442. ANKI_VK_LOGE("Wrong number of physical devices");
  443. return Error::kFunctionFailed;
  444. }
  445. GrDynamicArray<VkPhysicalDevice> physicalDevices;
  446. physicalDevices.resize(count);
  447. ANKI_VK_CHECK(vkEnumeratePhysicalDevices(m_instance, &count, &physicalDevices[0]));
  448. class Dev
  449. {
  450. public:
  451. VkPhysicalDevice m_pdev;
  452. VkPhysicalDeviceProperties2 m_vkProps;
  453. };
  454. GrDynamicArray<Dev> devs;
  455. devs.resize(count);
  456. for(U32 devIdx = 0; devIdx < count; ++devIdx)
  457. {
  458. devs[devIdx].m_pdev = physicalDevices[devIdx];
  459. devs[devIdx].m_vkProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
  460. vkGetPhysicalDeviceProperties2(physicalDevices[devIdx], &devs[devIdx].m_vkProps);
  461. }
  462. // Sort the devices with the most powerful first
  463. std::sort(devs.getBegin(), devs.getEnd(), [](const Dev& a, const Dev& b) {
  464. if(a.m_vkProps.properties.deviceType != b.m_vkProps.properties.deviceType)
  465. {
  466. auto findDeviceTypeWeight = [](VkPhysicalDeviceType type) {
  467. switch(type)
  468. {
  469. case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
  470. return 1.0;
  471. case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
  472. return 2.0;
  473. default:
  474. return 0.0;
  475. }
  476. };
  477. // Put descrete GPUs first
  478. return findDeviceTypeWeight(a.m_vkProps.properties.deviceType) > findDeviceTypeWeight(b.m_vkProps.properties.deviceType);
  479. }
  480. else
  481. {
  482. return a.m_vkProps.properties.apiVersion >= b.m_vkProps.properties.apiVersion;
  483. }
  484. });
  485. const U32 chosenPhysDevIdx = min<U32>(g_cvarGrDevice, devs.getSize() - 1);
  486. ANKI_VK_LOGI("Physical devices:");
  487. for(U32 devIdx = 0; devIdx < count; ++devIdx)
  488. {
  489. ANKI_VK_LOGI((devIdx == chosenPhysDevIdx) ? "\t(Selected) %s" : "\t%s", devs[devIdx].m_vkProps.properties.deviceName);
  490. }
  491. m_capabilities.m_discreteGpu = devs[chosenPhysDevIdx].m_vkProps.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
  492. m_physicalDevice = devs[chosenPhysDevIdx].m_pdev;
  493. }
  494. VkPhysicalDeviceProperties2 props2 = {};
  495. props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
  496. vkGetPhysicalDeviceProperties2(m_physicalDevice, &props2);
  497. VkPhysicalDeviceVulkan12Properties props12 = {};
  498. props12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES;
  499. getPhysicalDeviceProperties2(props12);
  500. VkPhysicalDeviceVulkan13Properties props13 = {};
  501. props13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES;
  502. getPhysicalDeviceProperties2(props13);
  503. m_capabilities.m_minWaveSize = props13.minSubgroupSize;
  504. m_capabilities.m_maxWaveSize = props13.maxSubgroupSize;
  505. if(props2.properties.limits.maxComputeWorkGroupInvocations < 1024)
  506. {
  507. ANKI_VK_LOGE("GPU doesn't support at least 1024 workgroup invocations");
  508. return Error::kFunctionFailed;
  509. }
  510. if(props2.properties.limits.maxPushConstantsSize < kMaxFastConstantsSize)
  511. {
  512. ANKI_VK_LOGE("GPU doesn't support at least %u push constants size", kMaxFastConstantsSize);
  513. return Error::kFunctionFailed;
  514. }
  515. // Find vendor
  516. switch(props2.properties.vendorID)
  517. {
  518. case 0x13B5:
  519. m_capabilities.m_gpuVendor = GpuVendor::kArm;
  520. break;
  521. case 0x10DE:
  522. m_capabilities.m_gpuVendor = GpuVendor::kNvidia;
  523. break;
  524. case 0x1002:
  525. case 0x1022:
  526. m_capabilities.m_gpuVendor = GpuVendor::kAMD;
  527. break;
  528. case 0x8086:
  529. m_capabilities.m_gpuVendor = GpuVendor::kIntel;
  530. break;
  531. case 0x5143:
  532. m_capabilities.m_gpuVendor = GpuVendor::kQualcomm;
  533. break;
  534. default:
  535. m_capabilities.m_gpuVendor = GpuVendor::kUnknown;
  536. }
  537. ANKI_VK_LOGI("GPU is %s. Vendor identified as %s, Driver %s", props2.properties.deviceName, &kGPUVendorStrings[m_capabilities.m_gpuVendor][0],
  538. props12.driverInfo);
  539. // Set limits
  540. m_capabilities.m_constantBufferBindOffsetAlignment =
  541. computeCompoundAlignment<U32>(ANKI_SAFE_ALIGNMENT, U32(props2.properties.limits.minUniformBufferOffsetAlignment));
  542. m_capabilities.m_structuredBufferBindOffsetAlignment =
  543. computeCompoundAlignment<U32>(ANKI_SAFE_ALIGNMENT, U32(props2.properties.limits.minStorageBufferOffsetAlignment));
  544. m_capabilities.m_structuredBufferNaturalAlignment = false;
  545. m_capabilities.m_texelBufferBindOffsetAlignment = max<U32>(ANKI_SAFE_ALIGNMENT, U32(props2.properties.limits.minTexelBufferOffsetAlignment));
  546. m_capabilities.m_computeSharedMemorySize = props2.properties.limits.maxComputeSharedMemorySize;
  547. m_capabilities.m_maxDrawIndirectCount = props2.properties.limits.maxDrawIndirectCount;
  548. m_capabilities.m_majorApiVersion = vulkanMajor;
  549. m_capabilities.m_minorApiVersion = vulkanMinor;
  550. m_caps.m_nonCoherentAtomSize = props2.properties.limits.nonCoherentAtomSize;
  551. m_caps.m_maxTexelBufferElements = props2.properties.limits.maxTexelBufferElements;
  552. m_caps.m_timestampPeriod = props2.properties.limits.timestampPeriod;
  553. // DLSS checks
  554. m_capabilities.m_dlss = ANKI_DLSS && m_capabilities.m_gpuVendor == GpuVendor::kNvidia;
  555. return Error::kNone;
  556. }
  557. Error GrManagerImpl::initDevice()
  558. {
  559. uint32_t count = 0;
  560. vkGetPhysicalDeviceQueueFamilyProperties(m_physicalDevice, &count, nullptr);
  561. ANKI_VK_LOGI("Number of queue families: %u", count);
  562. GrDynamicArray<VkQueueFamilyProperties> queueInfos;
  563. queueInfos.resize(count);
  564. vkGetPhysicalDeviceQueueFamilyProperties(m_physicalDevice, &count, &queueInfos[0]);
  565. Bool generalQueueFamilySupportsMultipleQueues = false;
  566. const VkQueueFlags generalQueueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
  567. for(U32 i = 0; i < count; ++i)
  568. {
  569. VkBool32 supportsPresent = false;
  570. ANKI_VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(m_physicalDevice, i, m_surface, &supportsPresent));
  571. if(!supportsPresent)
  572. {
  573. continue;
  574. }
  575. if((queueInfos[i].queueFlags & generalQueueFlags) == generalQueueFlags)
  576. {
  577. m_queueFamilyIndices[GpuQueueType::kGeneral] = i;
  578. if(queueInfos[i].queueCount > 1)
  579. {
  580. generalQueueFamilySupportsMultipleQueues = true;
  581. }
  582. }
  583. else if((queueInfos[i].queueFlags & VK_QUEUE_COMPUTE_BIT) && !(queueInfos[i].queueFlags & VK_QUEUE_GRAPHICS_BIT))
  584. {
  585. // This must be the async compute
  586. m_queueFamilyIndices[GpuQueueType::kCompute] = i;
  587. }
  588. }
  589. if(m_queueFamilyIndices[GpuQueueType::kGeneral] == kMaxU32)
  590. {
  591. ANKI_VK_LOGE("Couldn't find a queue family with graphics+compute+transfer+present. Something is wrong");
  592. return Error::kFunctionFailed;
  593. }
  594. const Bool pureAsyncCompute = m_queueFamilyIndices[GpuQueueType::kCompute] != kMaxU32 && g_cvarGrAsyncCompute == 0;
  595. const Bool lowPriorityQueueAsyncCompute = !pureAsyncCompute && generalQueueFamilySupportsMultipleQueues && g_cvarGrAsyncCompute <= 1;
  596. Array<F32, U32(GpuQueueType::kCount)> priorities = {1.0f, 0.5f};
  597. Array<VkDeviceQueueCreateInfo, U32(GpuQueueType::kCount)> q = {};
  598. VkDeviceQueueCreateInfo queueCreateInfo = {};
  599. queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
  600. q.fill(queueCreateInfo);
  601. VkDeviceCreateInfo ci = {};
  602. ci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
  603. ci.pQueueCreateInfos = &q[0];
  604. CString asyncComputeMsg;
  605. if(pureAsyncCompute)
  606. {
  607. asyncComputeMsg = "Using pure async compute queue";
  608. q[GpuQueueType::kGeneral].queueFamilyIndex = m_queueFamilyIndices[GpuQueueType::kGeneral];
  609. q[GpuQueueType::kGeneral].queueCount = 1;
  610. q[GpuQueueType::kGeneral].pQueuePriorities = &priorities[0];
  611. q[GpuQueueType::kCompute].queueFamilyIndex = m_queueFamilyIndices[GpuQueueType::kCompute];
  612. q[GpuQueueType::kCompute].queueCount = 1;
  613. q[GpuQueueType::kCompute].pQueuePriorities = &priorities[0];
  614. ci.queueCreateInfoCount = 2;
  615. }
  616. else if(lowPriorityQueueAsyncCompute)
  617. {
  618. asyncComputeMsg = "Using low priority queue in same family as general queue (fallback #1)";
  619. m_queueFamilyIndices[GpuQueueType::kCompute] = m_queueFamilyIndices[GpuQueueType::kGeneral];
  620. q[0].queueFamilyIndex = m_queueFamilyIndices[GpuQueueType::kGeneral];
  621. q[0].queueCount = 2;
  622. q[0].pQueuePriorities = &priorities[0];
  623. ci.queueCreateInfoCount = 1;
  624. }
  625. else
  626. {
  627. asyncComputeMsg = "Can't do much, using general queue (fallback #2)";
  628. m_queueFamilyIndices[GpuQueueType::kCompute] = m_queueFamilyIndices[GpuQueueType::kGeneral];
  629. q[0].queueFamilyIndex = m_queueFamilyIndices[GpuQueueType::kGeneral];
  630. q[0].queueCount = 1;
  631. q[0].pQueuePriorities = &priorities[0];
  632. ci.queueCreateInfoCount = 1;
  633. }
  634. ANKI_VK_LOGI("Async compute: %s", asyncComputeMsg.cstr());
  635. // Extensions
  636. U32 extCount = 0;
  637. vkEnumerateDeviceExtensionProperties(m_physicalDevice, nullptr, &extCount, nullptr);
  638. GrDynamicArray<VkExtensionProperties> extensionInfos; // Keep it alive in the stack
  639. GrDynamicArray<const char*> extensionsToEnable;
  640. if(extCount)
  641. {
  642. extensionInfos.resize(extCount);
  643. extensionsToEnable.resize(extCount);
  644. U32 extensionsToEnableCount = 0;
  645. vkEnumerateDeviceExtensionProperties(m_physicalDevice, nullptr, &extCount, &extensionInfos[0]);
  646. ANKI_VK_LOGV("Found the following device extensions:");
  647. for(U32 i = 0; i < extCount; ++i)
  648. {
  649. ANKI_VK_LOGV("\t%s", extensionInfos[i].extensionName);
  650. }
  651. while(extCount-- != 0)
  652. {
  653. const CString extensionName(&extensionInfos[extCount].extensionName[0]);
  654. if(extensionName == VK_KHR_SWAPCHAIN_EXTENSION_NAME)
  655. {
  656. m_extensions |= VulkanExtensions::kKHR_swapchain;
  657. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  658. }
  659. else if(extensionName == VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME && g_cvarGrRayTracing)
  660. {
  661. m_extensions |= VulkanExtensions::kKHR_ray_tracing;
  662. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  663. m_capabilities.m_rayTracingEnabled = true;
  664. }
  665. else if(extensionName == VK_KHR_RAY_QUERY_EXTENSION_NAME && g_cvarGrRayTracing)
  666. {
  667. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  668. }
  669. else if(extensionName == VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME && g_cvarGrRayTracing)
  670. {
  671. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  672. }
  673. else if(extensionName == VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME && g_cvarGrRayTracing)
  674. {
  675. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  676. }
  677. else if(extensionName == VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME && g_cvarGrRayTracing)
  678. {
  679. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  680. }
  681. else if(extensionName == VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME && g_cvarCoreDisplayStats > 1)
  682. {
  683. m_extensions |= VulkanExtensions::kKHR_pipeline_executable_properties;
  684. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  685. }
  686. else if(extensionName == VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME && g_cvarGrDebugPrintf)
  687. {
  688. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  689. }
  690. else if(extensionName == VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME && g_cvarGrVrs)
  691. {
  692. m_extensions |= VulkanExtensions::kKHR_fragment_shading_rate;
  693. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  694. }
  695. else if(extensionName == VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME)
  696. {
  697. m_extensions |= VulkanExtensions::kEXT_astc_decode_mode;
  698. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  699. }
  700. else if(extensionName == VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME)
  701. {
  702. m_extensions |= VulkanExtensions::kEXT_texture_compression_astc_hdr;
  703. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  704. }
  705. else if(m_capabilities.m_dlss && extensionName == VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)
  706. {
  707. m_extensions |= VulkanExtensions::kKHR_push_descriptor;
  708. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  709. }
  710. else if(m_capabilities.m_dlss && extensionName == ANKI_VK_NVX_BINARY_IMPORT)
  711. {
  712. m_extensions |= VulkanExtensions::kNVX_binary_import;
  713. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  714. }
  715. else if(m_capabilities.m_dlss && extensionName == VK_NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME)
  716. {
  717. m_extensions |= VulkanExtensions::kNVX_image_view_handle;
  718. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  719. }
  720. else if(extensionName == VK_EXT_MESH_SHADER_EXTENSION_NAME && g_cvarGrMeshShaders)
  721. {
  722. m_extensions |= VulkanExtensions::kEXT_mesh_shader;
  723. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  724. }
  725. else if(extensionName == VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME)
  726. {
  727. m_extensions |= VulkanExtensions::kKHR_fragment_shader_barycentric;
  728. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  729. }
  730. else if(extensionName == VK_KHR_RAY_TRACING_POSITION_FETCH_EXTENSION_NAME && g_cvarGrRayTracing)
  731. {
  732. m_extensions |= VulkanExtensions::kKHR_ray_tracing_position_fetch;
  733. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  734. }
  735. }
  736. ANKI_VK_LOGI("Will enable the following device extensions:");
  737. for(U32 i = 0; i < extensionsToEnableCount; ++i)
  738. {
  739. ANKI_VK_LOGI("\t%s", extensionsToEnable[i]);
  740. }
  741. ci.enabledExtensionCount = extensionsToEnableCount;
  742. ci.ppEnabledExtensionNames = &extensionsToEnable[0];
  743. }
  744. // Enable/disable generic features
  745. VkPhysicalDeviceFeatures2 devFeatures = {};
  746. {
  747. devFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  748. vkGetPhysicalDeviceFeatures2(m_physicalDevice, &devFeatures);
  749. devFeatures.features.robustBufferAccess = (g_cvarGrValidation && devFeatures.features.robustBufferAccess) ? true : false;
  750. ANKI_VK_LOGI("Robust buffer access is %s", (devFeatures.features.robustBufferAccess) ? "enabled" : "disabled");
  751. if(devFeatures.features.pipelineStatisticsQuery)
  752. {
  753. m_capabilities.m_pipelineQuery = true;
  754. ANKI_VK_LOGV("GPU supports pipeline statistics queries");
  755. }
  756. appendPNextList(ci, &devFeatures);
  757. }
  758. // 1.1 features
  759. VkPhysicalDeviceVulkan11Features features11 = {};
  760. {
  761. features11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
  762. getPhysicalDevicaFeatures2(features11);
  763. appendPNextList(ci, &features11);
  764. }
  765. #define ANKI_ASSERT_SUPPORTED(features, feature) \
  766. if(!features.feature) \
  767. { \
  768. ANKI_VK_LOGE(#feature " not supported"); \
  769. return Error::kFunctionFailed; \
  770. }
  771. // 1.2 features
  772. VkPhysicalDeviceVulkan12Features features12 = {};
  773. {
  774. features12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
  775. getPhysicalDevicaFeatures2(features12);
  776. ANKI_ASSERT_SUPPORTED(features12, descriptorIndexing)
  777. ANKI_ASSERT_SUPPORTED(features12, shaderSampledImageArrayNonUniformIndexing)
  778. ANKI_ASSERT_SUPPORTED(features12, shaderStorageImageArrayNonUniformIndexing)
  779. ANKI_ASSERT_SUPPORTED(features12, descriptorBindingSampledImageUpdateAfterBind)
  780. ANKI_ASSERT_SUPPORTED(features12, descriptorBindingStorageImageUpdateAfterBind)
  781. ANKI_ASSERT_SUPPORTED(features12, descriptorBindingUpdateUnusedWhilePending)
  782. ANKI_ASSERT_SUPPORTED(features12, samplerFilterMinmax)
  783. ANKI_ASSERT_SUPPORTED(features12, hostQueryReset)
  784. ANKI_ASSERT_SUPPORTED(features12, timelineSemaphore)
  785. ANKI_ASSERT_SUPPORTED(features12, drawIndirectCount)
  786. ANKI_ASSERT_SUPPORTED(features12, bufferDeviceAddress)
  787. features12.bufferDeviceAddressCaptureReplay = !!features12.bufferDeviceAddressCaptureReplay && g_cvarGrDebugMarkers;
  788. features12.bufferDeviceAddressMultiDevice = false;
  789. ANKI_ASSERT_SUPPORTED(features12, shaderFloat16)
  790. ANKI_ASSERT_SUPPORTED(features12, scalarBlockLayout)
  791. ANKI_ASSERT_SUPPORTED(features12, shaderBufferInt64Atomics)
  792. appendPNextList(ci, &features12);
  793. }
  794. // 1.3 features
  795. VkPhysicalDeviceVulkan13Features features13 = {};
  796. {
  797. features13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
  798. getPhysicalDevicaFeatures2(features13);
  799. ANKI_ASSERT_SUPPORTED(features13, dynamicRendering)
  800. ANKI_ASSERT_SUPPORTED(features13, maintenance4)
  801. #if ANKI_PLATFORM_MOBILE
  802. ANKI_ASSERT_SUPPORTED(features13, textureCompressionASTC_HDR)
  803. #endif
  804. appendPNextList(ci, &features13);
  805. }
  806. // Set RT features
  807. VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeatures = {};
  808. VkPhysicalDeviceRayQueryFeaturesKHR rayQueryFeatures = {};
  809. VkPhysicalDeviceAccelerationStructureFeaturesKHR accelerationStructureFeatures = {};
  810. VkPhysicalDeviceRayTracingPositionFetchFeaturesKHR positionFetchFeatures = {};
  811. if(!!(m_extensions & VulkanExtensions::kKHR_ray_tracing))
  812. {
  813. if(!(m_extensions & VulkanExtensions::kKHR_ray_tracing_position_fetch))
  814. {
  815. ANKI_VK_LOGE(VK_KHR_RAY_TRACING_POSITION_FETCH_EXTENSION_NAME " is required");
  816. return Error::kFunctionFailed;
  817. }
  818. rtPipelineFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR;
  819. rayQueryFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR;
  820. accelerationStructureFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR;
  821. positionFetchFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_POSITION_FETCH_FEATURES_KHR;
  822. VkPhysicalDeviceFeatures2 features = {};
  823. features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  824. features.pNext = &rtPipelineFeatures;
  825. rtPipelineFeatures.pNext = &rayQueryFeatures;
  826. rayQueryFeatures.pNext = &accelerationStructureFeatures;
  827. accelerationStructureFeatures.pNext = &positionFetchFeatures;
  828. vkGetPhysicalDeviceFeatures2(m_physicalDevice, &features);
  829. if(!rtPipelineFeatures.rayTracingPipeline || !rayQueryFeatures.rayQuery || !accelerationStructureFeatures.accelerationStructure)
  830. {
  831. ANKI_VK_LOGE("Ray tracing and ray query are both required");
  832. return Error::kFunctionFailed;
  833. }
  834. if(!positionFetchFeatures.rayTracingPositionFetch)
  835. {
  836. ANKI_VK_LOGE(VK_KHR_RAY_TRACING_POSITION_FETCH_EXTENSION_NAME " should be really really supported");
  837. return Error::kFunctionFailed;
  838. }
  839. // Only enable what's necessary
  840. rtPipelineFeatures.rayTracingPipelineShaderGroupHandleCaptureReplay = false;
  841. rtPipelineFeatures.rayTracingPipelineShaderGroupHandleCaptureReplayMixed = false;
  842. rtPipelineFeatures.rayTraversalPrimitiveCulling = false;
  843. accelerationStructureFeatures.accelerationStructureCaptureReplay = false;
  844. accelerationStructureFeatures.accelerationStructureHostCommands = false;
  845. accelerationStructureFeatures.descriptorBindingAccelerationStructureUpdateAfterBind = false;
  846. appendPNextList(ci, &accelerationStructureFeatures);
  847. appendPNextList(ci, &rayQueryFeatures);
  848. appendPNextList(ci, &rtPipelineFeatures);
  849. appendPNextList(ci, &positionFetchFeatures);
  850. // Get some more stuff
  851. VkPhysicalDeviceAccelerationStructurePropertiesKHR props = {};
  852. props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR;
  853. getPhysicalDeviceProperties2(props);
  854. m_caps.m_asBuildScratchAlignment = props.minAccelerationStructureScratchOffsetAlignment;
  855. VkPhysicalDeviceRayTracingPipelinePropertiesKHR rtprops = {};
  856. rtprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR;
  857. getPhysicalDeviceProperties2(rtprops);
  858. m_capabilities.m_shaderGroupHandleSize = rtprops.shaderGroupHandleSize;
  859. m_capabilities.m_sbtRecordAlignment = rtprops.shaderGroupBaseAlignment;
  860. }
  861. // Pipeline features
  862. VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR pplineExecutablePropertiesFeatures = {};
  863. if(!!(m_extensions & VulkanExtensions::kKHR_pipeline_executable_properties))
  864. {
  865. pplineExecutablePropertiesFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR;
  866. pplineExecutablePropertiesFeatures.pipelineExecutableInfo = true;
  867. appendPNextList(ci, &pplineExecutablePropertiesFeatures);
  868. }
  869. // VRS
  870. VkPhysicalDeviceFragmentShadingRateFeaturesKHR fragmentShadingRateFeatures = {};
  871. if(!(m_extensions & VulkanExtensions::kKHR_fragment_shading_rate))
  872. {
  873. ANKI_VK_LOGI(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME " is not supported or disabled");
  874. m_capabilities.m_vrs = false;
  875. }
  876. else
  877. {
  878. m_capabilities.m_vrs = true;
  879. fragmentShadingRateFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR;
  880. getPhysicalDevicaFeatures2(fragmentShadingRateFeatures);
  881. // Some checks
  882. if(!fragmentShadingRateFeatures.attachmentFragmentShadingRate || !fragmentShadingRateFeatures.pipelineFragmentShadingRate)
  883. {
  884. ANKI_VK_LOGW(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME " doesn't support attachment and/or pipeline rates. Will disable VRS");
  885. m_capabilities.m_vrs = false;
  886. }
  887. else
  888. {
  889. // Disable some things
  890. fragmentShadingRateFeatures.primitiveFragmentShadingRate = false;
  891. }
  892. if(m_capabilities.m_vrs)
  893. {
  894. VkPhysicalDeviceFragmentShadingRatePropertiesKHR fragmentShadingRateProperties = {};
  895. fragmentShadingRateProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR;
  896. getPhysicalDeviceProperties2(fragmentShadingRateProperties);
  897. if(fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.width > 16
  898. || fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.height > 16
  899. || fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.width < 8
  900. || fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.height < 8)
  901. {
  902. ANKI_VK_LOGW(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME
  903. " doesn't support 8x8 or 16x16 shading rate attachment texel size. Will disable VRS");
  904. m_capabilities.m_vrs = false;
  905. }
  906. else
  907. {
  908. m_capabilities.m_minShadingRateImageTexelSize = max(fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.width,
  909. fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.height);
  910. }
  911. }
  912. if(m_capabilities.m_vrs)
  913. {
  914. appendPNextList(ci, &fragmentShadingRateFeatures);
  915. }
  916. }
  917. // Mesh shaders
  918. VkPhysicalDeviceMeshShaderFeaturesEXT meshShadersFeatures = {};
  919. if(!!(m_extensions & VulkanExtensions::kEXT_mesh_shader))
  920. {
  921. m_capabilities.m_meshShaders = true;
  922. meshShadersFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT;
  923. getPhysicalDevicaFeatures2(meshShadersFeatures);
  924. if(meshShadersFeatures.taskShader == false)
  925. {
  926. ANKI_LOGE(VK_EXT_MESH_SHADER_EXTENSION_NAME " doesn't support task shaders");
  927. return Error::kFunctionFailed;
  928. }
  929. meshShadersFeatures.multiviewMeshShader = false;
  930. meshShadersFeatures.primitiveFragmentShadingRateMeshShader = false;
  931. appendPNextList(ci, &meshShadersFeatures);
  932. ANKI_VK_LOGI(VK_EXT_MESH_SHADER_EXTENSION_NAME " is supported and enabled");
  933. }
  934. else
  935. {
  936. ANKI_VK_LOGI(VK_EXT_MESH_SHADER_EXTENSION_NAME " is not supported or disabled ");
  937. }
  938. // Barycentrics
  939. VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR baryFeatures = {};
  940. if(!!(m_extensions & VulkanExtensions::kKHR_fragment_shader_barycentric))
  941. {
  942. baryFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR;
  943. getPhysicalDevicaFeatures2(baryFeatures);
  944. if(baryFeatures.fragmentShaderBarycentric == false)
  945. {
  946. ANKI_VK_LOGE("VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR::fragmentShaderBarycentric is false");
  947. return Error::kFunctionFailed;
  948. }
  949. appendPNextList(ci, &baryFeatures);
  950. m_capabilities.m_barycentrics = true;
  951. }
  952. ANKI_VK_CHECK(vkCreateDevice(m_physicalDevice, &ci, nullptr, &m_device));
  953. // Get the queues
  954. vkGetDeviceQueue(m_device, m_queueFamilyIndices[GpuQueueType::kGeneral], 0, &m_queues[GpuQueueType::kGeneral]);
  955. trySetVulkanHandleName("General", VK_OBJECT_TYPE_QUEUE, m_queues[GpuQueueType::kGeneral]);
  956. if(pureAsyncCompute)
  957. {
  958. vkGetDeviceQueue(m_device, m_queueFamilyIndices[GpuQueueType::kCompute], 0, &m_queues[GpuQueueType::kCompute]);
  959. trySetVulkanHandleName("AsyncCompute", VK_OBJECT_TYPE_QUEUE, m_queues[GpuQueueType::kGeneral]);
  960. }
  961. else if(lowPriorityQueueAsyncCompute)
  962. {
  963. vkGetDeviceQueue(m_device, m_queueFamilyIndices[GpuQueueType::kGeneral], 1, &m_queues[GpuQueueType::kCompute]);
  964. trySetVulkanHandleName("GeneralLowPriority", VK_OBJECT_TYPE_QUEUE, m_queues[GpuQueueType::kCompute]);
  965. }
  966. else
  967. {
  968. m_queues[GpuQueueType::kCompute] = nullptr;
  969. }
  970. return Error::kNone;
  971. }
  972. Error GrManagerImpl::initMemory()
  973. {
  974. vkGetPhysicalDeviceMemoryProperties(m_physicalDevice, &m_memoryProperties);
  975. // Print some info
  976. ANKI_VK_LOGV("Vulkan memory info:");
  977. for(U32 i = 0; i < m_memoryProperties.memoryHeapCount; ++i)
  978. {
  979. ANKI_VK_LOGV("\tHeap %u size %zu", i, m_memoryProperties.memoryHeaps[i].size);
  980. }
  981. for(U32 i = 0; i < m_memoryProperties.memoryTypeCount; ++i)
  982. {
  983. ANKI_VK_LOGV("\tMem type %u points to heap %u, flags %" ANKI_PRIb32, i, m_memoryProperties.memoryTypes[i].heapIndex,
  984. ANKI_FORMAT_U32(m_memoryProperties.memoryTypes[i].propertyFlags));
  985. }
  986. GpuMemoryManager::allocateSingleton();
  987. return Error::kNone;
  988. }
  989. #if ANKI_GR_MANAGER_DEBUG_MEMMORY
  990. void* GrManagerImpl::allocateCallback(void* userData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
  991. {
  992. if(size == 0) [[unlikely]]
  993. {
  994. return nullptr;
  995. }
  996. ANKI_ASSERT(userData);
  997. ANKI_ASSERT(size);
  998. ANKI_ASSERT(isPowerOfTwo(alignment));
  999. ANKI_ASSERT(alignment <= MAX_ALLOC_ALIGNMENT);
  1000. auto alloc = static_cast<GrManagerImpl*>(userData)->getAllocator();
  1001. PtrSize newSize = size + sizeof(AllocHeader);
  1002. AllocHeader* header = static_cast<AllocHeader*>(alloc.getMemoryPool().allocate(newSize, MAX_ALLOC_ALIGNMENT));
  1003. header->m_sig = ALLOC_SIG;
  1004. header->m_size = size;
  1005. ++header;
  1006. return static_cast<AllocHeader*>(header);
  1007. }
  1008. void* GrManagerImpl::reallocateCallback(void* userData, void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
  1009. {
  1010. if(original && size == 0)
  1011. {
  1012. freeCallback(userData, original);
  1013. return nullptr;
  1014. }
  1015. void* mem = allocateCallback(userData, size, alignment, allocationScope);
  1016. if(original)
  1017. {
  1018. // Move the data
  1019. AllocHeader* header = static_cast<AllocHeader*>(original);
  1020. --header;
  1021. ANKI_ASSERT(header->m_sig == ALLOC_SIG);
  1022. memcpy(mem, original, header->m_size);
  1023. }
  1024. return mem;
  1025. }
  1026. void GrManagerImpl::freeCallback(void* userData, void* ptr)
  1027. {
  1028. if(ptr)
  1029. {
  1030. ANKI_ASSERT(userData);
  1031. auto alloc = static_cast<GrManagerImpl*>(userData)->getAllocator();
  1032. AllocHeader* header = static_cast<AllocHeader*>(ptr);
  1033. --header;
  1034. ANKI_ASSERT(header->m_sig == ALLOC_SIG);
  1035. alloc.getMemoryPool().free(header);
  1036. }
  1037. }
  1038. #endif
  1039. void GrManagerImpl::beginFrameInternal()
  1040. {
  1041. ANKI_TRACE_FUNCTION();
  1042. LockGuard<Mutex> lock(m_globalMtx);
  1043. // Do that at begin frame, ALWAYS
  1044. ++m_frame;
  1045. PerFrame& frame = m_perFrame[m_frame % m_perFrame.getSize()];
  1046. ANKI_ASSERT(m_frameState == kFrameEnded);
  1047. m_frameState = kFrameStarted;
  1048. // Wait for the oldest frame because we don't want to start the new one too early
  1049. {
  1050. ANKI_TRACE_SCOPED_EVENT(WaitFences);
  1051. for(MicroFencePtr& fence : frame.m_fences)
  1052. {
  1053. if(fence)
  1054. {
  1055. const Bool signaled = fence->clientWait(kMaxSecond);
  1056. if(!signaled)
  1057. {
  1058. ANKI_VK_LOGF("Timeout detected");
  1059. }
  1060. }
  1061. }
  1062. }
  1063. frame.m_fences.destroy();
  1064. frame.m_queueWroteToSwapchainImage = GpuQueueType::kCount;
  1065. // Clear garbage
  1066. deleteObjectsMarkedForDeletion();
  1067. }
  1068. TexturePtr GrManagerImpl::acquireNextPresentableTexture()
  1069. {
  1070. ANKI_TRACE_FUNCTION();
  1071. // Create some objets outside the lock
  1072. Array<Char, 16> name;
  1073. snprintf(name.getBegin(), name.getSize(), "Acquire %" PRIu64, m_frame);
  1074. MicroFencePtr fence = FenceFactory::getSingleton().newInstance(name.getBegin());
  1075. LockGuard<Mutex> lock(m_globalMtx);
  1076. ANKI_ASSERT(m_frameState == kFrameStarted);
  1077. m_frameState = kPresentableAcquired;
  1078. PerFrame& frame = m_perFrame[m_frame % m_perFrame.getSize()];
  1079. frame.m_fences.emplaceBack(fence);
  1080. // Get new image
  1081. const MicroSemaphore& acquireSemaphore = *m_crntSwapchain->m_acquireSemaphores[m_frame % m_crntSwapchain->m_acquireSemaphores.getSize()];
  1082. uint32_t imageIdx;
  1083. const VkResult res = vkAcquireNextImageKHR(m_device, m_crntSwapchain->m_swapchain, UINT64_MAX, acquireSemaphore.getHandle(),
  1084. fence->getImplementation().m_handle, &imageIdx);
  1085. if(res == VK_ERROR_OUT_OF_DATE_KHR)
  1086. {
  1087. ANKI_VK_LOGW("Swapchain is out of date. Will wait for the queue and create a new one");
  1088. for(VkQueue queue : m_queues)
  1089. {
  1090. if(queue)
  1091. {
  1092. vkQueueWaitIdle(queue);
  1093. }
  1094. }
  1095. m_crntSwapchain.reset(nullptr);
  1096. m_crntSwapchain = SwapchainFactory::getSingleton().newInstance();
  1097. const MicroSemaphore& acquireSemaphore = *m_crntSwapchain->m_acquireSemaphores[m_frame % m_crntSwapchain->m_acquireSemaphores.getSize()];
  1098. // Can't fail a second time
  1099. ANKI_VK_CHECKF(vkAcquireNextImageKHR(m_device, m_crntSwapchain->m_swapchain, UINT64_MAX, acquireSemaphore.getHandle(),
  1100. fence->getImplementation().m_handle, &imageIdx));
  1101. }
  1102. else
  1103. {
  1104. ANKI_VK_CHECKF(res);
  1105. }
  1106. ANKI_ASSERT(m_acquiredImageIdx == kMaxU8 && "Tried to acquire multiple times in a frame?");
  1107. m_acquiredImageIdx = U8(imageIdx);
  1108. return TexturePtr(m_crntSwapchain->m_textures[imageIdx].get());
  1109. }
  1110. void GrManagerImpl::endFrameInternal()
  1111. {
  1112. ANKI_TRACE_FUNCTION();
  1113. LockGuard<Mutex> lock(m_globalMtx);
  1114. PerFrame& frame = m_perFrame[m_frame % m_perFrame.getSize()];
  1115. const Bool imageAcquired = m_acquiredImageIdx < kMaxU8;
  1116. // Present
  1117. if(imageAcquired)
  1118. {
  1119. ANKI_ASSERT(m_frameState == kPresentableDrawn && "Acquired an image but didn't draw to it?");
  1120. ANKI_ASSERT(m_acquiredImageIdx < kMaxU8);
  1121. VkResult res;
  1122. VkPresentInfoKHR present = {};
  1123. present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
  1124. present.waitSemaphoreCount = 1;
  1125. present.pWaitSemaphores = &m_crntSwapchain->m_renderSemaphores[m_acquiredImageIdx]->getHandle();
  1126. present.swapchainCount = 1;
  1127. present.pSwapchains = &m_crntSwapchain->m_swapchain;
  1128. const U32 idx = m_acquiredImageIdx;
  1129. present.pImageIndices = &idx;
  1130. present.pResults = &res;
  1131. const VkResult res1 = vkQueuePresentKHR(m_queues[frame.m_queueWroteToSwapchainImage], &present);
  1132. if(res1 == VK_ERROR_OUT_OF_DATE_KHR)
  1133. {
  1134. ANKI_VK_LOGW("Swapchain is out of date. Will wait for the queues and create a new one");
  1135. for(VkQueue queue : m_queues)
  1136. {
  1137. if(queue)
  1138. {
  1139. vkQueueWaitIdle(queue);
  1140. }
  1141. }
  1142. vkDeviceWaitIdle(m_device);
  1143. m_crntSwapchain.reset(nullptr);
  1144. m_crntSwapchain = SwapchainFactory::getSingleton().newInstance();
  1145. }
  1146. else
  1147. {
  1148. ANKI_VK_CHECKF(res1);
  1149. ANKI_VK_CHECKF(res);
  1150. }
  1151. m_acquiredImageIdx = kMaxU8;
  1152. }
  1153. else
  1154. {
  1155. ANKI_ASSERT(m_frameState == kFrameStarted);
  1156. }
  1157. m_frameState = kFrameEnded;
  1158. GpuMemoryManager::getSingleton().updateStats();
  1159. }
  1160. void GrManagerImpl::submitInternal(WeakArray<CommandBuffer*> cmdbs, WeakArray<Fence*> waitFences, FencePtr* signalFence)
  1161. {
  1162. // First thing, create a fence
  1163. MicroFencePtr fence = FenceFactory::getSingleton().newInstance("Submit");
  1164. // Gather command buffers
  1165. GrDynamicArray<VkCommandBuffer> vkCmdbs;
  1166. vkCmdbs.resizeStorage(cmdbs.getSize());
  1167. Bool renderedToDefaultFb = false;
  1168. GpuQueueType queueType = GpuQueueType::kCount;
  1169. for(U32 i = 0; i < cmdbs.getSize(); ++i)
  1170. {
  1171. CommandBufferImpl& cmdb = *static_cast<CommandBufferImpl*>(cmdbs[i]);
  1172. ANKI_ASSERT(cmdb.isFinalized());
  1173. renderedToDefaultFb = renderedToDefaultFb || cmdb.renderedToDefaultFramebuffer();
  1174. #if ANKI_ASSERTIONS_ENABLED
  1175. cmdb.setSubmitted();
  1176. #endif
  1177. const MicroCommandBuffer& mcmdb = *cmdb.getMicroCommandBuffer();
  1178. if(i == 0)
  1179. {
  1180. queueType = mcmdb.getVulkanQueueType();
  1181. }
  1182. else
  1183. {
  1184. ANKI_ASSERT(queueType == mcmdb.getVulkanQueueType() && "All cmdbs should be for the same queue");
  1185. }
  1186. vkCmdbs.emplaceBack(cmdb.getHandle());
  1187. }
  1188. // Gather wait semaphores
  1189. GrDynamicArray<VkSemaphore> waitSemaphores;
  1190. GrDynamicArray<VkPipelineStageFlags> waitStages;
  1191. GrDynamicArray<U64> waitTimelineValues;
  1192. waitSemaphores.resizeStorage(waitFences.getSize());
  1193. waitStages.resizeStorage(waitFences.getSize());
  1194. waitTimelineValues.resizeStorage(waitFences.getSize());
  1195. for(U32 i = 0; i < waitFences.getSize(); ++i)
  1196. {
  1197. FenceImpl& impl = static_cast<FenceImpl&>(*waitFences[i]);
  1198. MicroSemaphore& msem = *impl.m_semaphore;
  1199. ANKI_ASSERT(msem.isTimeline());
  1200. waitSemaphores.emplaceBack(msem.getHandle());
  1201. waitStages.emplaceBack(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
  1202. waitTimelineValues.emplaceBack(msem.getSemaphoreValue());
  1203. }
  1204. // Signal semaphore
  1205. GrDynamicArray<VkSemaphore> signalSemaphores;
  1206. GrDynamicArray<U64> signalTimelineValues;
  1207. if(signalFence)
  1208. {
  1209. FenceImpl* fenceImpl = anki::newInstance<FenceImpl>(GrMemoryPool::getSingleton(), "SignalFence");
  1210. fenceImpl->m_semaphore = SemaphoreFactory::getSingleton().newInstance(true, "SubmitSignal");
  1211. signalFence->reset(fenceImpl);
  1212. signalSemaphores.emplaceBack(fenceImpl->m_semaphore->getHandle());
  1213. signalTimelineValues.emplaceBack(fenceImpl->m_semaphore->getNextSemaphoreValue());
  1214. }
  1215. // Submit
  1216. {
  1217. // Protect the class, the queue and other stuff
  1218. LockGuard<Mutex> lock(m_globalMtx);
  1219. // Do some special stuff for the last command buffer
  1220. GrManagerImpl::PerFrame& frame = m_perFrame[m_frame % m_perFrame.getSize()];
  1221. if(renderedToDefaultFb)
  1222. {
  1223. ANKI_ASSERT(m_frameState == kPresentableAcquired);
  1224. m_frameState = kPresentableDrawn;
  1225. const MicroSemaphore& acquireSemaphore = *m_crntSwapchain->m_acquireSemaphores[m_frame % m_crntSwapchain->m_acquireSemaphores.getSize()];
  1226. // Wait semaphore
  1227. waitSemaphores.emplaceBack(acquireSemaphore.getHandle());
  1228. // That depends on how we use the swapchain img. Be a bit conservative
  1229. waitStages.emplaceBack(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
  1230. // Set something
  1231. waitTimelineValues.emplaceBack(0);
  1232. // Get the semaphore to signal and then wait on present
  1233. const MicroSemaphore& renderSemaphore = *m_crntSwapchain->m_renderSemaphores[m_acquiredImageIdx];
  1234. signalSemaphores.emplaceBack(renderSemaphore.getHandle());
  1235. // Increment the timeline values as well because the spec wants a dummy value even for non-timeline semaphores
  1236. signalTimelineValues.emplaceBack(0);
  1237. frame.m_queueWroteToSwapchainImage = queueType;
  1238. }
  1239. frame.m_fences.emplaceBack(fence);
  1240. // Submit
  1241. VkSubmitInfo submit = {};
  1242. submit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
  1243. submit.waitSemaphoreCount = waitSemaphores.getSize();
  1244. submit.pWaitSemaphores = (waitSemaphores.getSize()) ? waitSemaphores.getBegin() : nullptr;
  1245. submit.signalSemaphoreCount = signalSemaphores.getSize();
  1246. submit.pSignalSemaphores = (signalSemaphores.getSize()) ? signalSemaphores.getBegin() : nullptr;
  1247. submit.pWaitDstStageMask = (waitStages.getSize()) ? waitStages.getBegin() : nullptr;
  1248. submit.commandBufferCount = vkCmdbs.getSize();
  1249. submit.pCommandBuffers = (vkCmdbs.getSize()) ? vkCmdbs.getBegin() : nullptr;
  1250. VkTimelineSemaphoreSubmitInfo timelineInfo = {};
  1251. timelineInfo.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
  1252. timelineInfo.waitSemaphoreValueCount = waitSemaphores.getSize();
  1253. timelineInfo.pWaitSemaphoreValues = (waitSemaphores.getSize()) ? waitTimelineValues.getBegin() : nullptr;
  1254. timelineInfo.signalSemaphoreValueCount = signalTimelineValues.getSize();
  1255. timelineInfo.pSignalSemaphoreValues = (signalTimelineValues.getSize()) ? signalTimelineValues.getBegin() : nullptr;
  1256. appendPNextList(submit, &timelineInfo);
  1257. ANKI_TRACE_SCOPED_EVENT(VkQueueSubmit);
  1258. ANKI_VK_CHECKF(vkQueueSubmit(m_queues[queueType], 1, &submit, fence->getImplementation().m_handle));
  1259. // Throttle the number of fences
  1260. Bool fencesThrottled = false;
  1261. while(frame.m_fences.getSize() > 64)
  1262. {
  1263. fencesThrottled = true;
  1264. auto it = frame.m_fences.getBegin();
  1265. for(; it != frame.m_fences.getEnd(); ++it)
  1266. {
  1267. if((*it)->signaled())
  1268. {
  1269. frame.m_fences.erase(it);
  1270. break;
  1271. }
  1272. }
  1273. }
  1274. if(fencesThrottled)
  1275. {
  1276. ANKI_VK_LOGV("Had to throttle the number of fences");
  1277. }
  1278. }
  1279. }
  1280. void GrManagerImpl::finishInternal()
  1281. {
  1282. LockGuard<Mutex> lock(m_globalMtx);
  1283. for(VkQueue queue : m_queues)
  1284. {
  1285. if(queue)
  1286. {
  1287. vkQueueWaitIdle(queue);
  1288. }
  1289. }
  1290. for(PerFrame& frame : m_perFrame)
  1291. {
  1292. for(MicroFencePtr& fence : frame.m_fences)
  1293. {
  1294. const Bool signaled = fence->clientWait(kMaxSecond);
  1295. if(!signaled)
  1296. {
  1297. ANKI_VK_LOGF("Timeout detected");
  1298. }
  1299. }
  1300. frame.m_fences.destroy();
  1301. }
  1302. // Since we waited for the GPU do a cleanup as well
  1303. const U64 oldFrame = m_frame;
  1304. for(U32 frame = 0; frame < m_perFrame.getSize(); ++frame)
  1305. {
  1306. m_frame = frame;
  1307. deleteObjectsMarkedForDeletion();
  1308. }
  1309. m_frame = oldFrame;
  1310. }
  1311. void GrManagerImpl::trySetVulkanHandleName(CString name, VkObjectType type, U64 handle) const
  1312. {
  1313. if(name && name.getLength() && !!(m_extensions & VulkanExtensions::kEXT_debug_utils))
  1314. {
  1315. VkDebugUtilsObjectNameInfoEXT info = {};
  1316. info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
  1317. info.objectHandle = handle;
  1318. info.objectType = type;
  1319. info.pObjectName = name.cstr();
  1320. vkSetDebugUtilsObjectNameEXT(m_device, &info);
  1321. }
  1322. }
  1323. void GrManagerImpl::printPipelineShaderInfo(VkPipeline ppline, CString name, U64 hash) const
  1324. {
  1325. if(printPipelineShaderInfoInternal(ppline, name, hash))
  1326. {
  1327. ANKI_VK_LOGE("Ignoring previous errors");
  1328. }
  1329. }
  1330. Error GrManagerImpl::printPipelineShaderInfoInternal(VkPipeline ppline, CString name, U64 hash) const
  1331. {
  1332. if(!!(m_extensions & VulkanExtensions::kKHR_pipeline_executable_properties) && Logger::getSingleton().verbosityEnabled())
  1333. {
  1334. VkPipelineInfoKHR pplineInf = {};
  1335. pplineInf.sType = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR;
  1336. pplineInf.pipeline = ppline;
  1337. U32 executableCount = 0;
  1338. ANKI_VK_CHECK(vkGetPipelineExecutablePropertiesKHR(m_device, &pplineInf, &executableCount, nullptr));
  1339. GrDynamicArray<VkPipelineExecutablePropertiesKHR> executableProps;
  1340. LockGuard lock(m_shaderStatsMtx); // Lock so that all messages appear together
  1341. ANKI_VK_LOGV("Pipeline info \"%s\" (0x%016" PRIx64 "):", name.cstr(), hash);
  1342. if(executableCount > 0)
  1343. {
  1344. executableProps.resize(executableCount);
  1345. for(VkPipelineExecutablePropertiesKHR& prop : executableProps)
  1346. {
  1347. prop = {};
  1348. prop.sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR;
  1349. }
  1350. ANKI_VK_CHECK(vkGetPipelineExecutablePropertiesKHR(m_device, &pplineInf, &executableCount, &executableProps[0]));
  1351. }
  1352. else
  1353. {
  1354. ANKI_VK_LOGV("\tNo executable count!!!");
  1355. }
  1356. for(U32 i = 0; i < executableCount; ++i)
  1357. {
  1358. const VkPipelineExecutablePropertiesKHR& p = executableProps[i];
  1359. ANKI_VK_LOGV("\tDescription: %s, stages: 0x%X:", p.description, p.stages);
  1360. // Get stats
  1361. VkPipelineExecutableInfoKHR exeInf = {};
  1362. exeInf.sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR;
  1363. exeInf.executableIndex = i;
  1364. exeInf.pipeline = ppline;
  1365. U32 statCount = 0;
  1366. vkGetPipelineExecutableStatisticsKHR(m_device, &exeInf, &statCount, nullptr);
  1367. GrDynamicArray<VkPipelineExecutableStatisticKHR> stats;
  1368. stats.resize(statCount);
  1369. for(VkPipelineExecutableStatisticKHR& s : stats)
  1370. {
  1371. s = {};
  1372. s.sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR;
  1373. }
  1374. vkGetPipelineExecutableStatisticsKHR(m_device, &exeInf, &statCount, &stats[0]);
  1375. for(U32 s = 0; s < statCount; ++s)
  1376. {
  1377. const VkPipelineExecutableStatisticKHR& ss = stats[s];
  1378. switch(ss.format)
  1379. {
  1380. case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR:
  1381. ANKI_VK_LOGV("\t\t%s: %u", ss.name, ss.value.b32);
  1382. break;
  1383. case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR:
  1384. ANKI_VK_LOGV("\t\t%s: %" PRId64, ss.name, ss.value.i64);
  1385. break;
  1386. case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR:
  1387. ANKI_VK_LOGV("\t\t%s: %" PRIu64, ss.name, ss.value.u64);
  1388. break;
  1389. case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR:
  1390. ANKI_VK_LOGV("\t\t%s: %f", ss.name, ss.value.f64);
  1391. break;
  1392. default:
  1393. ANKI_ASSERT(0);
  1394. }
  1395. }
  1396. ANKI_VK_LOGV("\t\tSubgroup size: %u", p.subgroupSize);
  1397. }
  1398. }
  1399. return Error::kNone;
  1400. }
  1401. Error GrManagerImpl::initSurface()
  1402. {
  1403. #if ANKI_WINDOWING_SYSTEM_SDL
  1404. if(!SDL_Vulkan_CreateSurface(static_cast<NativeWindowSdl&>(NativeWindow::getSingleton()).m_sdlWindow, m_instance, nullptr, &m_surface))
  1405. {
  1406. ANKI_VK_LOGE("SDL_Vulkan_CreateSurface() failed: %s", SDL_GetError());
  1407. return Error::kFunctionFailed;
  1408. }
  1409. #elif ANKI_WINDOWING_SYSTEM_ANDROID
  1410. VkAndroidSurfaceCreateInfoKHR createInfo = {};
  1411. createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
  1412. createInfo.window = static_cast<NativeWindowAndroid&>(NativeWindow::getSingleton()).m_nativeWindowAndroid;
  1413. ANKI_VK_CHECK(vkCreateAndroidSurfaceKHR(m_instance, &createInfo, nullptr, &m_surface));
  1414. #elif ANKI_WINDOWING_SYSTEM_HEADLESS
  1415. VkHeadlessSurfaceCreateInfoEXT createInfo = {};
  1416. createInfo.sType = VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT;
  1417. ANKI_VK_CHECK(vkCreateHeadlessSurfaceEXT(m_instance, &createInfo, nullptr, &m_surface));
  1418. #else
  1419. # error Unsupported
  1420. #endif
  1421. m_nativeWindowWidth = NativeWindow::getSingleton().getWidth();
  1422. m_nativeWindowHeight = NativeWindow::getSingleton().getHeight();
  1423. return Error::kNone;
  1424. }
  1425. VkBool32 GrManagerImpl::debugReportCallbackEXT(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
  1426. [[maybe_unused]] VkDebugUtilsMessageTypeFlagsEXT messageTypes,
  1427. const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, [[maybe_unused]] void* pUserData)
  1428. {
  1429. #if ANKI_PLATFORM_MOBILE
  1430. if(pCallbackData->messageIdNumber == 101294395)
  1431. {
  1432. // Interface mismatch error. Eg vert shader is writing to varying that is not consumed by frag. Ignore this
  1433. // stupid error because I'm not going to create more shader variants to fix it. Especially when mobile drivers
  1434. // do linking anyway. On desktop just enable the maintenance4 extension
  1435. return false;
  1436. }
  1437. #endif
  1438. if(pCallbackData->messageIdNumber == 20145586 || pCallbackData->messageIdNumber == 979140054)
  1439. {
  1440. // Mismatch of the format of the storage image (or the storage texel buffer) in SPIR-V and the actual VkImage. Ignore it because DXC puts
  1441. // almost random shit as formats
  1442. return false;
  1443. }
  1444. if(pCallbackData->messageIdNumber == 1944932341 || pCallbackData->messageIdNumber == 1303270965)
  1445. {
  1446. // Not sure why I'm getting that
  1447. return false;
  1448. }
  1449. if(pCallbackData->messageIdNumber == -1094381206)
  1450. {
  1451. // Complains that CullPrimitiveEXT is not a bool array, which is wrong
  1452. return false;
  1453. }
  1454. // Get all names of affected objects
  1455. GrString objectNames;
  1456. if(pCallbackData->objectCount)
  1457. {
  1458. for(U32 i = 0; i < pCallbackData->objectCount; ++i)
  1459. {
  1460. const Char* name = pCallbackData->pObjects[i].pObjectName;
  1461. objectNames += (name) ? name : "?";
  1462. if(i < pCallbackData->objectCount - 1)
  1463. {
  1464. objectNames += ", ";
  1465. }
  1466. }
  1467. }
  1468. else
  1469. {
  1470. objectNames = "N/A";
  1471. }
  1472. if(CString(pCallbackData->pMessage).find("Assertion failed") != CString::kNpos)
  1473. {
  1474. messageSeverity = VkDebugUtilsMessageSeverityFlagBitsEXT(messageSeverity | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT);
  1475. }
  1476. if(messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
  1477. {
  1478. ANKI_VK_LOGE("VK debug report: %s. Affected objects: %s", pCallbackData->pMessage, objectNames.cstr());
  1479. }
  1480. else if(messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
  1481. {
  1482. ANKI_VK_LOGW("VK debug report: %s. Affected objects: %s", pCallbackData->pMessage, objectNames.cstr());
  1483. }
  1484. else
  1485. {
  1486. ANKI_VK_LOGI("VK debug report: %s. Affected objects: %s", pCallbackData->pMessage, objectNames.cstr());
  1487. }
  1488. return false;
  1489. }
  1490. } // end namespace anki