GrManagerImpl.cpp 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685
  1. // Copyright (C) 2009-2023, 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/GrManagerImpl.h>
  6. #include <AnKi/Gr/GrManager.h>
  7. #include <AnKi/Gr/Vulkan/CommandBufferImpl.h>
  8. #include <AnKi/Gr/CommandBuffer.h>
  9. #include <AnKi/Gr/Fence.h>
  10. #include <AnKi/Gr/Vulkan/FenceImpl.h>
  11. #include <AnKi/Util/Functions.h>
  12. #include <AnKi/Util/StringList.h>
  13. #include <AnKi/Core/ConfigSet.h>
  14. namespace anki {
  15. // DLSS related
  16. #define ANKI_VK_NVX_BINARY_IMPORT "VK_NVX_binary_import"
  17. GrManagerImpl::~GrManagerImpl()
  18. {
  19. ANKI_VK_LOGI("Destroying Vulkan backend");
  20. // 1st THING: wait for the present fences because I don't know if waiting on queue will cover this
  21. for(PerFrame& frame : m_perFrame)
  22. {
  23. if(frame.m_presentFence.isCreated())
  24. {
  25. frame.m_presentFence->wait();
  26. }
  27. }
  28. // 2nd THING: wait for the GPU
  29. for(VkQueue& queue : m_queues)
  30. {
  31. LockGuard<Mutex> lock(m_globalMtx);
  32. if(queue)
  33. {
  34. vkQueueWaitIdle(queue);
  35. queue = VK_NULL_HANDLE;
  36. }
  37. }
  38. // 3rd THING: The destroy everything that has a reference to GrObjects.
  39. m_cmdbFactory.destroy();
  40. for(PerFrame& frame : m_perFrame)
  41. {
  42. frame.m_presentFence.reset(nullptr);
  43. frame.m_acquireSemaphore.reset(nullptr);
  44. frame.m_renderSemaphore.reset(nullptr);
  45. }
  46. m_crntSwapchain.reset(nullptr);
  47. // 4th THING: Continue with the rest
  48. m_barrierFactory.destroy(); // Destroy before fences
  49. m_semaphoreFactory.destroy(); // Destroy before fences
  50. m_swapchainFactory.destroy(); // Destroy before fences
  51. m_frameGarbageCollector.destroy();
  52. m_gpuMemManager.destroy();
  53. m_pplineLayoutFactory.destroy();
  54. m_descrFactory.destroy();
  55. m_pplineCache.destroy(m_device, m_physicalDevice, m_pool);
  56. m_fenceFactory.destroy();
  57. m_samplerFactory.destroy();
  58. if(m_device)
  59. {
  60. vkDestroyDevice(m_device, nullptr);
  61. }
  62. if(m_surface)
  63. {
  64. vkDestroySurfaceKHR(m_instance, m_surface, nullptr);
  65. }
  66. if(m_debugUtilsMessager)
  67. {
  68. vkDestroyDebugUtilsMessengerEXT(m_instance, m_debugUtilsMessager, nullptr);
  69. }
  70. if(m_instance)
  71. {
  72. #if ANKI_GR_MANAGER_DEBUG_MEMMORY
  73. VkAllocationCallbacks* pallocCbs = &m_debugAllocCbs;
  74. #else
  75. VkAllocationCallbacks* pallocCbs = nullptr;
  76. #endif
  77. vkDestroyInstance(m_instance, pallocCbs);
  78. }
  79. #if ANKI_PLATFORM_MOBILE
  80. anki::deleteInstance(m_pool, m_globalCreatePipelineMtx);
  81. #endif
  82. }
  83. Error GrManagerImpl::init(const GrManagerInitInfo& init)
  84. {
  85. const Error err = initInternal(init);
  86. if(err)
  87. {
  88. ANKI_VK_LOGE("Vulkan initialization failed");
  89. return Error::kFunctionFailed;
  90. }
  91. return Error::kNone;
  92. }
  93. Error GrManagerImpl::initInternal(const GrManagerInitInfo& init)
  94. {
  95. ANKI_VK_LOGI("Initializing Vulkan backend");
  96. ANKI_CHECK(initInstance());
  97. ANKI_CHECK(initSurface(init));
  98. ANKI_CHECK(initDevice(init));
  99. for(VulkanQueueType qtype : EnumIterable<VulkanQueueType>())
  100. {
  101. if(m_queueFamilyIndices[qtype] != kMaxU32)
  102. {
  103. vkGetDeviceQueue(m_device, m_queueFamilyIndices[qtype], 0, &m_queues[qtype]);
  104. }
  105. else
  106. {
  107. m_queues[qtype] = VK_NULL_HANDLE;
  108. }
  109. }
  110. m_swapchainFactory.init(this, ConfigSet::getSingleton().getGrVsync());
  111. m_crntSwapchain = m_swapchainFactory.newInstance();
  112. ANKI_CHECK(m_pplineCache.init(m_device, m_physicalDevice, init.m_cacheDirectory, m_pool));
  113. ANKI_CHECK(initMemory());
  114. ANKI_CHECK(m_cmdbFactory.init(&m_pool, m_device, m_queueFamilyIndices));
  115. for(PerFrame& f : m_perFrame)
  116. {
  117. resetFrame(f);
  118. }
  119. m_fenceFactory.init(&m_pool, m_device);
  120. m_semaphoreFactory.init(&m_pool, m_device);
  121. m_samplerFactory.init(this);
  122. m_barrierFactory.init(&m_pool, m_device);
  123. m_occlusionQueryFactory.init(&m_pool, m_device, VK_QUERY_TYPE_OCCLUSION);
  124. m_timestampQueryFactory.init(&m_pool, m_device, VK_QUERY_TYPE_TIMESTAMP);
  125. // See if unaligned formats are supported
  126. {
  127. m_capabilities.m_unalignedBbpTextureFormats = true;
  128. VkImageFormatProperties props = {};
  129. VkResult res = vkGetPhysicalDeviceImageFormatProperties(
  130. m_physicalDevice, VK_FORMAT_R8G8B8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
  131. VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &props);
  132. if(res == VK_ERROR_FORMAT_NOT_SUPPORTED)
  133. {
  134. m_capabilities.m_unalignedBbpTextureFormats = false;
  135. }
  136. res = vkGetPhysicalDeviceImageFormatProperties(
  137. m_physicalDevice, VK_FORMAT_R16G16B16_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
  138. VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &props);
  139. if(res == VK_ERROR_FORMAT_NOT_SUPPORTED)
  140. {
  141. m_capabilities.m_unalignedBbpTextureFormats = false;
  142. }
  143. res = vkGetPhysicalDeviceImageFormatProperties(
  144. m_physicalDevice, VK_FORMAT_R32G32B32_SFLOAT, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
  145. VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &props);
  146. if(res == VK_ERROR_FORMAT_NOT_SUPPORTED)
  147. {
  148. m_capabilities.m_unalignedBbpTextureFormats = false;
  149. }
  150. if(!m_capabilities.m_unalignedBbpTextureFormats)
  151. {
  152. ANKI_VK_LOGI("R8G8B8, R16G16B16 and R32G32B32 image formats are not supported");
  153. }
  154. }
  155. ANKI_CHECK(m_descrFactory.init(&m_pool, m_device, kMaxBindlessTextures, kMaxBindlessReadonlyTextureBuffers));
  156. m_pplineLayoutFactory.init(&m_pool, m_device);
  157. m_frameGarbageCollector.init(this);
  158. return Error::kNone;
  159. }
  160. Error GrManagerImpl::initInstance()
  161. {
  162. // Init VOLK
  163. //
  164. ANKI_VK_CHECK(volkInitialize());
  165. // Create the instance
  166. //
  167. const U8 vulkanMinor = ConfigSet::getSingleton().getGrVkMinor();
  168. const U8 vulkanMajor = ConfigSet::getSingleton().getGrVkMajor();
  169. VkApplicationInfo app = {};
  170. app.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
  171. app.pApplicationName = "unamed";
  172. app.applicationVersion = 1;
  173. app.pEngineName = "AnKi 3D Engine";
  174. app.engineVersion = (ANKI_VERSION_MAJOR << 16) | ANKI_VERSION_MINOR;
  175. app.apiVersion = VK_MAKE_VERSION(vulkanMajor, vulkanMinor, 0);
  176. VkInstanceCreateInfo ci = {};
  177. ci.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
  178. ci.pApplicationInfo = &app;
  179. // Instance layers
  180. DynamicArrayRaii<const char*> layersToEnable(&m_pool);
  181. {
  182. U32 layerCount;
  183. vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
  184. if(layerCount)
  185. {
  186. DynamicArrayRaii<VkLayerProperties> layerProps(&m_pool, layerCount);
  187. vkEnumerateInstanceLayerProperties(&layerCount, &layerProps[0]);
  188. ANKI_VK_LOGV("Found the following instance layers:");
  189. for(const VkLayerProperties& layer : layerProps)
  190. {
  191. ANKI_VK_LOGV("\t%s", layer.layerName);
  192. CString layerName = layer.layerName;
  193. static constexpr const Char* kValidationName = "VK_LAYER_KHRONOS_validation";
  194. if((ConfigSet::getSingleton().getGrValidation() || ConfigSet::getSingleton().getGrDebugPrintf())
  195. && layerName == kValidationName)
  196. {
  197. layersToEnable.emplaceBack(kValidationName);
  198. }
  199. }
  200. }
  201. if(layersToEnable.getSize())
  202. {
  203. ANKI_VK_LOGI("Will enable the following instance layers:");
  204. for(const char* name : layersToEnable)
  205. {
  206. ANKI_VK_LOGI("\t%s", name);
  207. }
  208. ci.enabledLayerCount = layersToEnable.getSize();
  209. ci.ppEnabledLayerNames = &layersToEnable[0];
  210. }
  211. }
  212. // Validation features
  213. DynamicArrayRaii<VkValidationFeatureEnableEXT> enabledValidationFeatures(&m_pool);
  214. DynamicArrayRaii<VkValidationFeatureDisableEXT> disabledValidationFeatures(&m_pool);
  215. if(ConfigSet::getSingleton().getGrDebugPrintf())
  216. {
  217. enabledValidationFeatures.emplaceBack(VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT);
  218. }
  219. if(!ConfigSet::getSingleton().getGrValidation())
  220. {
  221. disabledValidationFeatures.emplaceBack(VK_VALIDATION_FEATURE_DISABLE_ALL_EXT);
  222. }
  223. VkValidationFeaturesEXT validationFeatures = {};
  224. if(enabledValidationFeatures.getSize() || disabledValidationFeatures.getSize())
  225. {
  226. validationFeatures.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT;
  227. validationFeatures.disabledValidationFeatureCount = disabledValidationFeatures.getSize();
  228. validationFeatures.enabledValidationFeatureCount = enabledValidationFeatures.getSize();
  229. validationFeatures.pDisabledValidationFeatures = disabledValidationFeatures.getBegin();
  230. validationFeatures.pEnabledValidationFeatures = enabledValidationFeatures.getBegin();
  231. validationFeatures.pNext = ci.pNext;
  232. ci.pNext = &validationFeatures;
  233. }
  234. // Extensions
  235. DynamicArrayRaii<const char*> instExtensions(&m_pool);
  236. DynamicArrayRaii<VkExtensionProperties> instExtensionInf(&m_pool);
  237. U32 extCount = 0;
  238. vkEnumerateInstanceExtensionProperties(nullptr, &extCount, nullptr);
  239. if(extCount)
  240. {
  241. instExtensions.create(extCount);
  242. instExtensionInf.create(extCount);
  243. vkEnumerateInstanceExtensionProperties(nullptr, &extCount, &instExtensionInf[0]);
  244. ANKI_VK_LOGV("Found the following instance extensions:");
  245. for(U32 i = 0; i < extCount; ++i)
  246. {
  247. ANKI_VK_LOGV("\t%s", instExtensionInf[i].extensionName);
  248. }
  249. U32 instExtensionCount = 0;
  250. for(U32 i = 0; i < extCount; ++i)
  251. {
  252. const CString extensionName = instExtensionInf[i].extensionName;
  253. #if ANKI_WINDOWING_SYSTEM_HEADLESS
  254. if(extensionName == VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME)
  255. {
  256. m_extensions |= VulkanExtensions::kEXT_headless_surface;
  257. instExtensions[instExtensionCount++] = VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME;
  258. }
  259. #elif ANKI_OS_LINUX
  260. if(extensionName == VK_KHR_XCB_SURFACE_EXTENSION_NAME)
  261. {
  262. m_extensions |= VulkanExtensions::kKHR_xcb_surface;
  263. instExtensions[instExtensionCount++] = VK_KHR_XCB_SURFACE_EXTENSION_NAME;
  264. }
  265. else if(extensionName == VK_KHR_XLIB_SURFACE_EXTENSION_NAME)
  266. {
  267. m_extensions |= VulkanExtensions::kKHR_xlib_surface;
  268. instExtensions[instExtensionCount++] = VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
  269. }
  270. #elif ANKI_OS_WINDOWS
  271. if(extensionName == VK_KHR_WIN32_SURFACE_EXTENSION_NAME)
  272. {
  273. m_extensions |= VulkanExtensions::kKHR_win32_surface;
  274. instExtensions[instExtensionCount++] = VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
  275. }
  276. #elif ANKI_OS_ANDROID
  277. if(extensionName == VK_KHR_ANDROID_SURFACE_EXTENSION_NAME)
  278. {
  279. m_extensions |= VulkanExtensions::kKHR_android_surface;
  280. instExtensions[instExtensionCount++] = VK_KHR_ANDROID_SURFACE_EXTENSION_NAME;
  281. }
  282. #else
  283. # error Not implemented
  284. #endif
  285. else if(extensionName == VK_KHR_SURFACE_EXTENSION_NAME)
  286. {
  287. m_extensions |= VulkanExtensions::kKHR_surface;
  288. instExtensions[instExtensionCount++] = VK_KHR_SURFACE_EXTENSION_NAME;
  289. }
  290. else if(extensionName == VK_EXT_DEBUG_UTILS_EXTENSION_NAME
  291. && (ConfigSet::getSingleton().getGrDebugMarkers() || ConfigSet::getSingleton().getGrValidation()
  292. || ConfigSet::getSingleton().getGrDebugPrintf()))
  293. {
  294. m_extensions |= VulkanExtensions::kEXT_debug_utils;
  295. instExtensions[instExtensionCount++] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
  296. }
  297. }
  298. if(!(m_extensions
  299. & (VulkanExtensions::kEXT_headless_surface | VulkanExtensions::kKHR_xcb_surface
  300. | VulkanExtensions::kKHR_xlib_surface | VulkanExtensions::kKHR_win32_surface
  301. | VulkanExtensions::kKHR_android_surface)))
  302. {
  303. ANKI_VK_LOGE("Couldn't find suitable surface extension");
  304. return Error::kFunctionFailed;
  305. }
  306. if(instExtensionCount)
  307. {
  308. ANKI_VK_LOGI("Will enable the following instance extensions:");
  309. for(U32 i = 0; i < instExtensionCount; ++i)
  310. {
  311. ANKI_VK_LOGI("\t%s", instExtensions[i]);
  312. }
  313. ci.enabledExtensionCount = instExtensionCount;
  314. ci.ppEnabledExtensionNames = &instExtensions[0];
  315. }
  316. }
  317. #if ANKI_GR_MANAGER_DEBUG_MEMMORY
  318. m_debugAllocCbs = {};
  319. m_debugAllocCbs.pUserData = this;
  320. m_debugAllocCbs.pfnAllocation = allocateCallback;
  321. m_debugAllocCbs.pfnReallocation = reallocateCallback;
  322. m_debugAllocCbs.pfnFree = freeCallback;
  323. VkAllocationCallbacks* pallocCbs = &m_debugAllocCbs;
  324. #else
  325. VkAllocationCallbacks* pallocCbs = nullptr;
  326. #endif
  327. ANKI_VK_CHECK(vkCreateInstance(&ci, pallocCbs, &m_instance));
  328. // Get symbolx
  329. //
  330. volkLoadInstance(m_instance);
  331. // Set debug callbacks
  332. if(!!(m_extensions & VulkanExtensions::kEXT_debug_utils))
  333. {
  334. VkDebugUtilsMessengerCreateInfoEXT info = {};
  335. info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
  336. info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT
  337. | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
  338. | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
  339. info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
  340. | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT
  341. | VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
  342. info.pfnUserCallback = debugReportCallbackEXT;
  343. info.pUserData = this;
  344. vkCreateDebugUtilsMessengerEXT(m_instance, &info, nullptr, &m_debugUtilsMessager);
  345. }
  346. // Create the physical device
  347. //
  348. {
  349. uint32_t count = 0;
  350. ANKI_VK_CHECK(vkEnumeratePhysicalDevices(m_instance, &count, nullptr));
  351. if(count < 1)
  352. {
  353. ANKI_VK_LOGE("Wrong number of physical devices");
  354. return Error::kFunctionFailed;
  355. }
  356. DynamicArrayRaii<VkPhysicalDevice> physicalDevices(&m_pool, count);
  357. ANKI_VK_CHECK(vkEnumeratePhysicalDevices(m_instance, &count, &physicalDevices[0]));
  358. class Dev
  359. {
  360. public:
  361. VkPhysicalDevice m_pdev;
  362. VkPhysicalDeviceProperties2 m_vkProps;
  363. };
  364. DynamicArrayRaii<Dev> devs(&m_pool, count);
  365. for(U32 devIdx = 0; devIdx < count; ++devIdx)
  366. {
  367. devs[devIdx].m_pdev = physicalDevices[devIdx];
  368. devs[devIdx].m_vkProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
  369. vkGetPhysicalDeviceProperties2(physicalDevices[devIdx], &devs[devIdx].m_vkProps);
  370. }
  371. // Sort the devices with the most powerful first
  372. std::sort(devs.getBegin(), devs.getEnd(), [](const Dev& a, const Dev& b) {
  373. if(a.m_vkProps.properties.deviceType != b.m_vkProps.properties.deviceType)
  374. {
  375. auto findDeviceTypeWeight = [](VkPhysicalDeviceType type) {
  376. switch(type)
  377. {
  378. case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
  379. return 1.0;
  380. case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
  381. return 2.0;
  382. default:
  383. return 0.0;
  384. }
  385. };
  386. // Put descrete GPUs first
  387. return findDeviceTypeWeight(a.m_vkProps.properties.deviceType)
  388. > findDeviceTypeWeight(b.m_vkProps.properties.deviceType);
  389. }
  390. else
  391. {
  392. return a.m_vkProps.properties.apiVersion >= b.m_vkProps.properties.apiVersion;
  393. }
  394. });
  395. const U32 chosenPhysDevIdx = min<U32>(ConfigSet::getSingleton().getGrDevice(), devs.getSize() - 1);
  396. ANKI_VK_LOGI("Physical devices:");
  397. for(U32 devIdx = 0; devIdx < count; ++devIdx)
  398. {
  399. ANKI_VK_LOGI((devIdx == chosenPhysDevIdx) ? "\t(Selected) %s" : "\t%s",
  400. devs[devIdx].m_vkProps.properties.deviceName);
  401. }
  402. m_capabilities.m_discreteGpu =
  403. devs[chosenPhysDevIdx].m_vkProps.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
  404. m_physicalDevice = devs[chosenPhysDevIdx].m_pdev;
  405. }
  406. m_rtPipelineProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR;
  407. m_accelerationStructureProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR;
  408. m_devProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
  409. m_devProps.pNext = &m_rtPipelineProps;
  410. m_rtPipelineProps.pNext = &m_accelerationStructureProps;
  411. vkGetPhysicalDeviceProperties2(m_physicalDevice, &m_devProps);
  412. // Find vendor
  413. switch(m_devProps.properties.vendorID)
  414. {
  415. case 0x13B5:
  416. m_capabilities.m_gpuVendor = GpuVendor::kArm;
  417. m_capabilities.m_minSubgroupSize = 16;
  418. m_capabilities.m_maxSubgroupSize = 16;
  419. break;
  420. case 0x10DE:
  421. m_capabilities.m_gpuVendor = GpuVendor::kNvidia;
  422. m_capabilities.m_minSubgroupSize = 32;
  423. m_capabilities.m_maxSubgroupSize = 32;
  424. break;
  425. case 0x1002:
  426. case 0x1022:
  427. m_capabilities.m_gpuVendor = GpuVendor::kAMD;
  428. m_capabilities.m_minSubgroupSize = 32;
  429. m_capabilities.m_maxSubgroupSize = 64;
  430. break;
  431. case 0x8086:
  432. m_capabilities.m_gpuVendor = GpuVendor::kIntel;
  433. m_capabilities.m_minSubgroupSize = 8;
  434. m_capabilities.m_maxSubgroupSize = 32;
  435. break;
  436. case 0x5143:
  437. m_capabilities.m_gpuVendor = GpuVendor::kQualcomm;
  438. m_capabilities.m_minSubgroupSize = 64;
  439. m_capabilities.m_maxSubgroupSize = 128;
  440. break;
  441. default:
  442. m_capabilities.m_gpuVendor = GpuVendor::kUnknown;
  443. // Choose something really low
  444. m_capabilities.m_minSubgroupSize = 8;
  445. m_capabilities.m_maxSubgroupSize = 8;
  446. }
  447. ANKI_VK_LOGI("GPU is %s. Vendor identified as %s", m_devProps.properties.deviceName,
  448. &kGPUVendorStrings[m_capabilities.m_gpuVendor][0]);
  449. // Set limits
  450. m_capabilities.m_uniformBufferBindOffsetAlignment =
  451. max<U32>(ANKI_SAFE_ALIGNMENT, U32(m_devProps.properties.limits.minUniformBufferOffsetAlignment));
  452. m_capabilities.m_uniformBufferMaxRange = m_devProps.properties.limits.maxUniformBufferRange;
  453. m_capabilities.m_storageBufferBindOffsetAlignment =
  454. max<U32>(ANKI_SAFE_ALIGNMENT, U32(m_devProps.properties.limits.minStorageBufferOffsetAlignment));
  455. m_capabilities.m_storageBufferMaxRange = m_devProps.properties.limits.maxStorageBufferRange;
  456. m_capabilities.m_textureBufferBindOffsetAlignment =
  457. max<U32>(ANKI_SAFE_ALIGNMENT, U32(m_devProps.properties.limits.minTexelBufferOffsetAlignment));
  458. m_capabilities.m_textureBufferMaxRange = kMaxU32;
  459. m_capabilities.m_computeSharedMemorySize = m_devProps.properties.limits.maxComputeSharedMemorySize;
  460. m_capabilities.m_majorApiVersion = vulkanMajor;
  461. m_capabilities.m_minorApiVersion = vulkanMinor;
  462. m_capabilities.m_shaderGroupHandleSize = m_rtPipelineProps.shaderGroupHandleSize;
  463. m_capabilities.m_sbtRecordAlignment = m_rtPipelineProps.shaderGroupBaseAlignment;
  464. #if ANKI_PLATFORM_MOBILE
  465. if(m_capabilities.m_gpuVendor == GpuVendor::kQualcomm)
  466. {
  467. // Calling vkCreateGraphicsPipeline from multiple threads crashes qualcomm's compiler
  468. ANKI_VK_LOGI("Enabling workaround for vkCreateGraphicsPipeline crashing when called from multiple threads");
  469. m_globalCreatePipelineMtx = anki::newInstance<Mutex>(m_pool);
  470. }
  471. #endif
  472. // DLSS checks
  473. m_capabilities.m_dlss = ANKI_DLSS && m_capabilities.m_gpuVendor == GpuVendor::kNvidia;
  474. return Error::kNone;
  475. }
  476. Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
  477. {
  478. uint32_t count = 0;
  479. vkGetPhysicalDeviceQueueFamilyProperties(m_physicalDevice, &count, nullptr);
  480. ANKI_VK_LOGI("Number of queue families: %u", count);
  481. DynamicArrayRaii<VkQueueFamilyProperties> queueInfos(&m_pool);
  482. queueInfos.create(count);
  483. vkGetPhysicalDeviceQueueFamilyProperties(m_physicalDevice, &count, &queueInfos[0]);
  484. const VkQueueFlags GENERAL_QUEUE_FLAGS = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
  485. for(U32 i = 0; i < count; ++i)
  486. {
  487. VkBool32 supportsPresent = false;
  488. ANKI_VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(m_physicalDevice, i, m_surface, &supportsPresent));
  489. if(supportsPresent)
  490. {
  491. if((queueInfos[i].queueFlags & GENERAL_QUEUE_FLAGS) == GENERAL_QUEUE_FLAGS)
  492. {
  493. m_queueFamilyIndices[VulkanQueueType::kGeneral] = i;
  494. }
  495. else if((queueInfos[i].queueFlags & VK_QUEUE_COMPUTE_BIT)
  496. && !(queueInfos[i].queueFlags & VK_QUEUE_GRAPHICS_BIT))
  497. {
  498. // This must be the async compute
  499. m_queueFamilyIndices[VulkanQueueType::kCompute] = i;
  500. }
  501. }
  502. }
  503. if(m_queueFamilyIndices[VulkanQueueType::kGeneral] == kMaxU32)
  504. {
  505. ANKI_VK_LOGE("Couldn't find a queue family with graphics+compute+transfer+present. "
  506. "Something is wrong");
  507. return Error::kFunctionFailed;
  508. }
  509. if(!ConfigSet::getSingleton().getGrAsyncCompute())
  510. {
  511. m_queueFamilyIndices[VulkanQueueType::kCompute] = kMaxU32;
  512. }
  513. if(m_queueFamilyIndices[VulkanQueueType::kCompute] == kMaxU32)
  514. {
  515. ANKI_VK_LOGW("Couldn't find an async compute queue. Will try to use the general queue instead");
  516. }
  517. else
  518. {
  519. ANKI_VK_LOGI("Async compute is enabled");
  520. }
  521. const F32 priority = 1.0f;
  522. Array<VkDeviceQueueCreateInfo, U32(VulkanQueueType::kCount)> q = {};
  523. VkDeviceCreateInfo ci = {};
  524. ci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
  525. ci.pQueueCreateInfos = &q[0];
  526. for(VulkanQueueType qtype : EnumIterable<VulkanQueueType>())
  527. {
  528. if(m_queueFamilyIndices[qtype] != kMaxU32)
  529. {
  530. q[qtype].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
  531. q[qtype].queueFamilyIndex = m_queueFamilyIndices[qtype];
  532. q[qtype].queueCount = 1;
  533. q[qtype].pQueuePriorities = &priority;
  534. ++ci.queueCreateInfoCount;
  535. }
  536. }
  537. // Extensions
  538. U32 extCount = 0;
  539. vkEnumerateDeviceExtensionProperties(m_physicalDevice, nullptr, &extCount, nullptr);
  540. DynamicArrayRaii<VkExtensionProperties> extensionInfos(&m_pool); // Keep it alive in the stack
  541. DynamicArrayRaii<const char*> extensionsToEnable(&m_pool);
  542. if(extCount)
  543. {
  544. extensionInfos.create(extCount);
  545. extensionsToEnable.create(extCount);
  546. U32 extensionsToEnableCount = 0;
  547. vkEnumerateDeviceExtensionProperties(m_physicalDevice, nullptr, &extCount, &extensionInfos[0]);
  548. ANKI_VK_LOGV("Found the following device extensions:");
  549. for(U32 i = 0; i < extCount; ++i)
  550. {
  551. ANKI_VK_LOGV("\t%s", extensionInfos[i].extensionName);
  552. }
  553. while(extCount-- != 0)
  554. {
  555. const CString extensionName(&extensionInfos[extCount].extensionName[0]);
  556. if(extensionName == VK_KHR_SWAPCHAIN_EXTENSION_NAME)
  557. {
  558. m_extensions |= VulkanExtensions::kKHR_swapchain;
  559. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  560. }
  561. else if(extensionName == VK_AMD_SHADER_INFO_EXTENSION_NAME
  562. && ConfigSet::getSingleton().getCoreDisplayStats())
  563. {
  564. m_extensions |= VulkanExtensions::kAMD_shader_info;
  565. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  566. }
  567. else if(extensionName == VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME)
  568. {
  569. m_extensions |= VulkanExtensions::kAMD_rasterization_order;
  570. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  571. }
  572. else if(extensionName == VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME
  573. && ConfigSet::getSingleton().getGrRayTracing())
  574. {
  575. m_extensions |= VulkanExtensions::kKHR_ray_tracing;
  576. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  577. m_capabilities.m_rayTracingEnabled = true;
  578. }
  579. else if(extensionName == VK_KHR_RAY_QUERY_EXTENSION_NAME && ConfigSet::getSingleton().getGrRayTracing())
  580. {
  581. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  582. }
  583. else if(extensionName == VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME
  584. && ConfigSet::getSingleton().getGrRayTracing())
  585. {
  586. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  587. }
  588. else if(extensionName == VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME
  589. && ConfigSet::getSingleton().getGrRayTracing())
  590. {
  591. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  592. }
  593. else if(extensionName == VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME
  594. && ConfigSet::getSingleton().getGrRayTracing())
  595. {
  596. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  597. }
  598. else if(extensionName == VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME
  599. && ConfigSet::getSingleton().getCoreDisplayStats() > 1)
  600. {
  601. m_extensions |= VulkanExtensions::kKHR_pipeline_executable_properties;
  602. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  603. }
  604. else if(extensionName == VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME
  605. && ConfigSet::getSingleton().getGrDebugPrintf())
  606. {
  607. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  608. }
  609. else if(extensionName == VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)
  610. {
  611. m_extensions |= VulkanExtensions::kEXT_descriptor_indexing;
  612. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  613. }
  614. else if(extensionName == VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)
  615. {
  616. m_extensions |= VulkanExtensions::kKHR_buffer_device_address;
  617. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  618. }
  619. else if(extensionName == VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME)
  620. {
  621. m_extensions |= VulkanExtensions::kEXT_scalar_block_layout;
  622. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  623. }
  624. else if(extensionName == VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME)
  625. {
  626. m_extensions |= VulkanExtensions::kKHR_timeline_semaphore;
  627. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  628. }
  629. else if(extensionName == VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME)
  630. {
  631. m_extensions |= VulkanExtensions::kKHR_shader_float16_int8;
  632. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  633. }
  634. else if(extensionName == VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME
  635. && ConfigSet::getSingleton().getGr64bitAtomics())
  636. {
  637. m_extensions |= VulkanExtensions::kKHR_shader_atomic_int64;
  638. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  639. }
  640. else if(extensionName == VK_KHR_SPIRV_1_4_EXTENSION_NAME)
  641. {
  642. m_extensions |= VulkanExtensions::kKHR_spirv_1_4;
  643. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  644. }
  645. else if(extensionName == VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME)
  646. {
  647. m_extensions |= VulkanExtensions::kKHR_shader_float_controls;
  648. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  649. }
  650. else if(extensionName == VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME
  651. && ConfigSet::getSingleton().getGrSamplerFilterMinMax())
  652. {
  653. m_extensions |= VulkanExtensions::kKHR_sampler_filter_min_max;
  654. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  655. }
  656. else if(extensionName == VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)
  657. {
  658. m_extensions |= VulkanExtensions::kKHR_create_renderpass_2;
  659. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  660. }
  661. else if(extensionName == VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME
  662. && ConfigSet::getSingleton().getGrVrs())
  663. {
  664. m_extensions |= VulkanExtensions::kKHR_fragment_shading_rate;
  665. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  666. }
  667. else if(extensionName == VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME)
  668. {
  669. m_extensions |= VulkanExtensions::kEXT_astc_decode_mode;
  670. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  671. }
  672. else if(extensionName == VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME)
  673. {
  674. m_extensions |= VulkanExtensions::kEXT_texture_compression_astc_hdr;
  675. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  676. }
  677. else if(m_capabilities.m_dlss && extensionName == VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)
  678. {
  679. m_extensions |= VulkanExtensions::kKHR_push_descriptor;
  680. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  681. }
  682. else if(m_capabilities.m_dlss && extensionName == ANKI_VK_NVX_BINARY_IMPORT)
  683. {
  684. m_extensions |= VulkanExtensions::kNVX_binary_import;
  685. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  686. }
  687. else if(m_capabilities.m_dlss && extensionName == VK_NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME)
  688. {
  689. m_extensions |= VulkanExtensions::kNVX_image_view_handle;
  690. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  691. }
  692. else if(extensionName == VK_KHR_MAINTENANCE_4_EXTENSION_NAME)
  693. {
  694. m_extensions |= VulkanExtensions::kKHR_maintenance_4;
  695. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  696. }
  697. }
  698. ANKI_VK_LOGI("Will enable the following device extensions:");
  699. for(U32 i = 0; i < extensionsToEnableCount; ++i)
  700. {
  701. ANKI_VK_LOGI("\t%s", extensionsToEnable[i]);
  702. }
  703. ci.enabledExtensionCount = extensionsToEnableCount;
  704. ci.ppEnabledExtensionNames = &extensionsToEnable[0];
  705. }
  706. // Enable/disable generic features
  707. {
  708. VkPhysicalDeviceFeatures2 devFeatures = {};
  709. devFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  710. vkGetPhysicalDeviceFeatures2(m_physicalDevice, &devFeatures);
  711. m_devFeatures = devFeatures.features;
  712. m_devFeatures.robustBufferAccess =
  713. (ConfigSet::getSingleton().getGrValidation() && m_devFeatures.robustBufferAccess) ? true : false;
  714. ANKI_VK_LOGI("Robust buffer access is %s", (m_devFeatures.robustBufferAccess) ? "enabled" : "disabled");
  715. ci.pEnabledFeatures = &m_devFeatures;
  716. }
  717. #if ANKI_PLATFORM_MOBILE
  718. if(!(m_extensions & VulkanExtensions::kEXT_texture_compression_astc_hdr))
  719. {
  720. ANKI_VK_LOGE(VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME " is not supported");
  721. return Error::kFunctionFailed;
  722. }
  723. #endif
  724. if(!(m_extensions & VulkanExtensions::kKHR_create_renderpass_2))
  725. {
  726. ANKI_VK_LOGE(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME " is not supported");
  727. return Error::kFunctionFailed;
  728. }
  729. if(!!(m_extensions & VulkanExtensions::kKHR_sampler_filter_min_max))
  730. {
  731. m_capabilities.m_samplingFilterMinMax = true;
  732. }
  733. else
  734. {
  735. m_capabilities.m_samplingFilterMinMax = false;
  736. ANKI_VK_LOGI(VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME " is not supported or disabled");
  737. }
  738. // Descriptor indexing
  739. if(!(m_extensions & VulkanExtensions::kEXT_descriptor_indexing))
  740. {
  741. ANKI_VK_LOGE(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME " is not supported");
  742. return Error::kFunctionFailed;
  743. }
  744. else
  745. {
  746. m_descriptorIndexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
  747. VkPhysicalDeviceFeatures2 features = {};
  748. features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  749. features.pNext = &m_descriptorIndexingFeatures;
  750. vkGetPhysicalDeviceFeatures2(m_physicalDevice, &features);
  751. if(!m_descriptorIndexingFeatures.shaderSampledImageArrayNonUniformIndexing
  752. || !m_descriptorIndexingFeatures.shaderStorageImageArrayNonUniformIndexing)
  753. {
  754. ANKI_VK_LOGE("Non uniform indexing is not supported by the device");
  755. return Error::kFunctionFailed;
  756. }
  757. if(!m_descriptorIndexingFeatures.descriptorBindingSampledImageUpdateAfterBind
  758. || !m_descriptorIndexingFeatures.descriptorBindingStorageImageUpdateAfterBind)
  759. {
  760. ANKI_VK_LOGE("Update descriptors after bind is not supported by the device");
  761. return Error::kFunctionFailed;
  762. }
  763. if(!m_descriptorIndexingFeatures.descriptorBindingUpdateUnusedWhilePending)
  764. {
  765. ANKI_VK_LOGE("Update descriptors while cmd buffer is pending is not supported by the device");
  766. return Error::kFunctionFailed;
  767. }
  768. m_descriptorIndexingFeatures.pNext = const_cast<void*>(ci.pNext);
  769. ci.pNext = &m_descriptorIndexingFeatures;
  770. }
  771. // Buffer address
  772. if(!(m_extensions & VulkanExtensions::kKHR_buffer_device_address))
  773. {
  774. ANKI_VK_LOGW(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME " is not supported");
  775. }
  776. else
  777. {
  778. m_deviceBufferFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR;
  779. VkPhysicalDeviceFeatures2 features = {};
  780. features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  781. features.pNext = &m_deviceBufferFeatures;
  782. vkGetPhysicalDeviceFeatures2(m_physicalDevice, &features);
  783. m_deviceBufferFeatures.bufferDeviceAddressCaptureReplay =
  784. m_deviceBufferFeatures.bufferDeviceAddressCaptureReplay && ConfigSet::getSingleton().getGrDebugMarkers();
  785. m_deviceBufferFeatures.bufferDeviceAddressMultiDevice = false;
  786. m_deviceBufferFeatures.pNext = const_cast<void*>(ci.pNext);
  787. ci.pNext = &m_deviceBufferFeatures;
  788. }
  789. // Scalar block layout
  790. if(!(m_extensions & VulkanExtensions::kEXT_scalar_block_layout))
  791. {
  792. ANKI_VK_LOGE(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME " is not supported");
  793. return Error::kFunctionFailed;
  794. }
  795. else
  796. {
  797. m_scalarBlockLayout.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT;
  798. VkPhysicalDeviceFeatures2 features = {};
  799. features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  800. features.pNext = &m_scalarBlockLayout;
  801. vkGetPhysicalDeviceFeatures2(m_physicalDevice, &features);
  802. if(!m_scalarBlockLayout.scalarBlockLayout)
  803. {
  804. ANKI_VK_LOGE("Scalar block layout is not supported by the device");
  805. return Error::kFunctionFailed;
  806. }
  807. m_scalarBlockLayout.pNext = const_cast<void*>(ci.pNext);
  808. ci.pNext = &m_scalarBlockLayout;
  809. }
  810. // Timeline semaphore
  811. if(!(m_extensions & VulkanExtensions::kKHR_timeline_semaphore))
  812. {
  813. ANKI_VK_LOGE(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME " is not supported");
  814. return Error::kFunctionFailed;
  815. }
  816. else
  817. {
  818. m_timelineSemaphoreFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR;
  819. VkPhysicalDeviceFeatures2 features = {};
  820. features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  821. features.pNext = &m_timelineSemaphoreFeatures;
  822. vkGetPhysicalDeviceFeatures2(m_physicalDevice, &features);
  823. if(!m_timelineSemaphoreFeatures.timelineSemaphore)
  824. {
  825. ANKI_VK_LOGE("Timeline semaphores are not supported by the device");
  826. return Error::kFunctionFailed;
  827. }
  828. m_timelineSemaphoreFeatures.pNext = const_cast<void*>(ci.pNext);
  829. ci.pNext = &m_timelineSemaphoreFeatures;
  830. }
  831. // Set RT features
  832. if(!!(m_extensions & VulkanExtensions::kKHR_ray_tracing))
  833. {
  834. m_rtPipelineFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR;
  835. m_rayQueryFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR;
  836. m_accelerationStructureFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR;
  837. VkPhysicalDeviceFeatures2 features = {};
  838. features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  839. features.pNext = &m_rtPipelineFeatures;
  840. m_rtPipelineFeatures.pNext = &m_rayQueryFeatures;
  841. m_rayQueryFeatures.pNext = &m_accelerationStructureFeatures;
  842. vkGetPhysicalDeviceFeatures2(m_physicalDevice, &features);
  843. if(!m_rtPipelineFeatures.rayTracingPipeline || !m_rayQueryFeatures.rayQuery
  844. || !m_accelerationStructureFeatures.accelerationStructure)
  845. {
  846. ANKI_VK_LOGE("Ray tracing and ray query are both required");
  847. return Error::kFunctionFailed;
  848. }
  849. // Only enable what's necessary
  850. m_rtPipelineFeatures.rayTracingPipelineShaderGroupHandleCaptureReplay = false;
  851. m_rtPipelineFeatures.rayTracingPipelineShaderGroupHandleCaptureReplayMixed = false;
  852. m_rtPipelineFeatures.rayTraversalPrimitiveCulling = false;
  853. m_accelerationStructureFeatures.accelerationStructureCaptureReplay = false;
  854. m_accelerationStructureFeatures.accelerationStructureHostCommands = false;
  855. m_accelerationStructureFeatures.descriptorBindingAccelerationStructureUpdateAfterBind = false;
  856. ANKI_ASSERT(m_accelerationStructureFeatures.pNext == nullptr);
  857. m_accelerationStructureFeatures.pNext = const_cast<void*>(ci.pNext);
  858. ci.pNext = &m_rtPipelineFeatures;
  859. }
  860. // Pipeline features
  861. if(!!(m_extensions & VulkanExtensions::kKHR_pipeline_executable_properties))
  862. {
  863. m_pplineExecutablePropertiesFeatures.sType =
  864. VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR;
  865. m_pplineExecutablePropertiesFeatures.pipelineExecutableInfo = true;
  866. m_pplineExecutablePropertiesFeatures.pNext = const_cast<void*>(ci.pNext);
  867. ci.pNext = &m_pplineExecutablePropertiesFeatures;
  868. }
  869. // F16 I8
  870. if(!(m_extensions & VulkanExtensions::kKHR_shader_float16_int8))
  871. {
  872. ANKI_VK_LOGE(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME " is not supported");
  873. return Error::kFunctionFailed;
  874. }
  875. else
  876. {
  877. m_float16Int8Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR;
  878. VkPhysicalDeviceFeatures2 features = {};
  879. features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  880. features.pNext = &m_float16Int8Features;
  881. vkGetPhysicalDeviceFeatures2(m_physicalDevice, &features);
  882. m_float16Int8Features.pNext = const_cast<void*>(ci.pNext);
  883. ci.pNext = &m_float16Int8Features;
  884. }
  885. // 64bit atomics
  886. if(!(m_extensions & VulkanExtensions::kKHR_shader_atomic_int64))
  887. {
  888. ANKI_VK_LOGW(VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME " is not supported or disabled");
  889. m_capabilities.m_64bitAtomics = false;
  890. }
  891. else
  892. {
  893. m_capabilities.m_64bitAtomics = true;
  894. m_atomicInt64Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR;
  895. VkPhysicalDeviceFeatures2 features = {};
  896. features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  897. features.pNext = &m_atomicInt64Features;
  898. vkGetPhysicalDeviceFeatures2(m_physicalDevice, &features);
  899. m_atomicInt64Features.pNext = const_cast<void*>(ci.pNext);
  900. ci.pNext = &m_atomicInt64Features;
  901. }
  902. // VRS
  903. if(!(m_extensions & VulkanExtensions::kKHR_fragment_shading_rate))
  904. {
  905. ANKI_VK_LOGI(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME " is not supported or disabled");
  906. m_capabilities.m_vrs = false;
  907. }
  908. else
  909. {
  910. m_capabilities.m_vrs = true;
  911. m_fragmentShadingRateFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR;
  912. VkPhysicalDeviceFeatures2 features = {};
  913. features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  914. features.pNext = &m_fragmentShadingRateFeatures;
  915. vkGetPhysicalDeviceFeatures2(m_physicalDevice, &features);
  916. // Some checks
  917. if(!m_fragmentShadingRateFeatures.attachmentFragmentShadingRate
  918. || !m_fragmentShadingRateFeatures.pipelineFragmentShadingRate)
  919. {
  920. ANKI_VK_LOGW(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME
  921. " doesn't support attachment and/or pipeline rates. Will disable VRS");
  922. m_capabilities.m_vrs = false;
  923. }
  924. else
  925. {
  926. // Disable some things
  927. m_fragmentShadingRateFeatures.primitiveFragmentShadingRate = false;
  928. }
  929. if(m_capabilities.m_vrs)
  930. {
  931. VkPhysicalDeviceFragmentShadingRatePropertiesKHR fragmentShadingRateProperties = {};
  932. fragmentShadingRateProperties.sType =
  933. VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR;
  934. VkPhysicalDeviceProperties2 properties = {};
  935. properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
  936. properties.pNext = &fragmentShadingRateProperties;
  937. vkGetPhysicalDeviceProperties2(m_physicalDevice, &properties);
  938. if(fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.width > 16
  939. || fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.height > 16
  940. || fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.width < 8
  941. || fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.height < 8)
  942. {
  943. ANKI_VK_LOGW(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME
  944. " doesn't support 8x8 or 16x16 shading rate attachment texel size. Will disable VRS");
  945. m_capabilities.m_vrs = false;
  946. }
  947. else
  948. {
  949. m_capabilities.m_minShadingRateImageTexelSize =
  950. max(fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.width,
  951. fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.height);
  952. }
  953. }
  954. if(m_capabilities.m_vrs)
  955. {
  956. m_fragmentShadingRateFeatures.pNext = const_cast<void*>(ci.pNext);
  957. ci.pNext = &m_fragmentShadingRateFeatures;
  958. }
  959. }
  960. VkPhysicalDeviceMaintenance4FeaturesKHR maintenance4Features = {};
  961. maintenance4Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR;
  962. if(!!(m_extensions & VulkanExtensions::kKHR_maintenance_4))
  963. {
  964. maintenance4Features.maintenance4 = true;
  965. maintenance4Features.pNext = const_cast<void*>(ci.pNext);
  966. ci.pNext = &maintenance4Features;
  967. }
  968. ANKI_VK_CHECK(vkCreateDevice(m_physicalDevice, &ci, nullptr, &m_device));
  969. // Get VK_AMD_shader_info entry points
  970. if(!!(m_extensions & VulkanExtensions::kAMD_shader_info))
  971. {
  972. m_pfnGetShaderInfoAMD =
  973. reinterpret_cast<PFN_vkGetShaderInfoAMD>(vkGetDeviceProcAddr(m_device, "vkGetShaderInfoAMD"));
  974. if(!m_pfnGetShaderInfoAMD)
  975. {
  976. ANKI_VK_LOGW("VK_AMD_shader_info is present but vkGetShaderInfoAMD is not there");
  977. }
  978. }
  979. if(!(m_extensions & VulkanExtensions::kKHR_spirv_1_4))
  980. {
  981. ANKI_VK_LOGE(VK_KHR_SPIRV_1_4_EXTENSION_NAME " is not supported");
  982. return Error::kFunctionFailed;
  983. }
  984. if(!(m_extensions & VulkanExtensions::kKHR_shader_float_controls))
  985. {
  986. ANKI_VK_LOGE(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME " is not supported");
  987. return Error::kFunctionFailed;
  988. }
  989. return Error::kNone;
  990. }
  991. Error GrManagerImpl::initMemory()
  992. {
  993. vkGetPhysicalDeviceMemoryProperties(m_physicalDevice, &m_memoryProperties);
  994. // Print some info
  995. ANKI_VK_LOGV("Vulkan memory info:");
  996. for(U32 i = 0; i < m_memoryProperties.memoryHeapCount; ++i)
  997. {
  998. ANKI_VK_LOGV("\tHeap %u size %zu", i, m_memoryProperties.memoryHeaps[i].size);
  999. }
  1000. for(U32 i = 0; i < m_memoryProperties.memoryTypeCount; ++i)
  1001. {
  1002. ANKI_VK_LOGV("\tMem type %u points to heap %u, flags %" ANKI_PRIb32, i,
  1003. m_memoryProperties.memoryTypes[i].heapIndex,
  1004. ANKI_FORMAT_U32(m_memoryProperties.memoryTypes[i].propertyFlags));
  1005. }
  1006. m_gpuMemManager.init(m_physicalDevice, m_device, &m_pool,
  1007. !!(m_extensions & VulkanExtensions::kKHR_buffer_device_address));
  1008. return Error::kNone;
  1009. }
  1010. #if ANKI_GR_MANAGER_DEBUG_MEMMORY
  1011. void* GrManagerImpl::allocateCallback(void* userData, size_t size, size_t alignment,
  1012. VkSystemAllocationScope allocationScope)
  1013. {
  1014. if(size == 0) [[unlikely]]
  1015. {
  1016. return nullptr;
  1017. }
  1018. ANKI_ASSERT(userData);
  1019. ANKI_ASSERT(size);
  1020. ANKI_ASSERT(isPowerOfTwo(alignment));
  1021. ANKI_ASSERT(alignment <= MAX_ALLOC_ALIGNMENT);
  1022. auto alloc = static_cast<GrManagerImpl*>(userData)->getAllocator();
  1023. PtrSize newSize = size + sizeof(AllocHeader);
  1024. AllocHeader* header = static_cast<AllocHeader*>(alloc.getMemoryPool().allocate(newSize, MAX_ALLOC_ALIGNMENT));
  1025. header->m_sig = ALLOC_SIG;
  1026. header->m_size = size;
  1027. ++header;
  1028. return static_cast<AllocHeader*>(header);
  1029. }
  1030. void* GrManagerImpl::reallocateCallback(void* userData, void* original, size_t size, size_t alignment,
  1031. VkSystemAllocationScope allocationScope)
  1032. {
  1033. if(original && size == 0)
  1034. {
  1035. freeCallback(userData, original);
  1036. return nullptr;
  1037. }
  1038. void* mem = allocateCallback(userData, size, alignment, allocationScope);
  1039. if(original)
  1040. {
  1041. // Move the data
  1042. AllocHeader* header = static_cast<AllocHeader*>(original);
  1043. --header;
  1044. ANKI_ASSERT(header->m_sig == ALLOC_SIG);
  1045. memcpy(mem, original, header->m_size);
  1046. }
  1047. return mem;
  1048. }
  1049. void GrManagerImpl::freeCallback(void* userData, void* ptr)
  1050. {
  1051. if(ptr)
  1052. {
  1053. ANKI_ASSERT(userData);
  1054. auto alloc = static_cast<GrManagerImpl*>(userData)->getAllocator();
  1055. AllocHeader* header = static_cast<AllocHeader*>(ptr);
  1056. --header;
  1057. ANKI_ASSERT(header->m_sig == ALLOC_SIG);
  1058. alloc.getMemoryPool().free(header);
  1059. }
  1060. }
  1061. #endif
  1062. TexturePtr GrManagerImpl::acquireNextPresentableTexture()
  1063. {
  1064. ANKI_TRACE_SCOPED_EVENT(VkAcquireImage);
  1065. LockGuard<Mutex> lock(m_globalMtx);
  1066. PerFrame& frame = m_perFrame[m_frame % kMaxFramesInFlight];
  1067. // Create sync objects
  1068. MicroFencePtr fence = m_fenceFactory.newInstance();
  1069. frame.m_acquireSemaphore = m_semaphoreFactory.newInstance(fence, false);
  1070. // Get new image
  1071. uint32_t imageIdx;
  1072. VkResult res = vkAcquireNextImageKHR(m_device, m_crntSwapchain->m_swapchain, UINT64_MAX,
  1073. frame.m_acquireSemaphore->getHandle(), fence->getHandle(), &imageIdx);
  1074. if(res == VK_ERROR_OUT_OF_DATE_KHR)
  1075. {
  1076. ANKI_VK_LOGW("Swapchain is out of date. Will wait for the queue and create a new one");
  1077. for(VkQueue queue : m_queues)
  1078. {
  1079. if(queue)
  1080. {
  1081. vkQueueWaitIdle(queue);
  1082. }
  1083. }
  1084. m_crntSwapchain.reset(nullptr);
  1085. m_crntSwapchain = m_swapchainFactory.newInstance();
  1086. // Can't fail a second time
  1087. ANKI_VK_CHECKF(vkAcquireNextImageKHR(m_device, m_crntSwapchain->m_swapchain, UINT64_MAX,
  1088. frame.m_acquireSemaphore->getHandle(), fence->getHandle(), &imageIdx));
  1089. }
  1090. else
  1091. {
  1092. ANKI_VK_CHECKF(res);
  1093. }
  1094. m_acquiredImageIdx = U8(imageIdx);
  1095. return m_crntSwapchain->m_textures[imageIdx];
  1096. }
  1097. void GrManagerImpl::endFrame()
  1098. {
  1099. ANKI_TRACE_SCOPED_EVENT(VkPresent);
  1100. LockGuard<Mutex> lock(m_globalMtx);
  1101. PerFrame& frame = m_perFrame[m_frame % kMaxFramesInFlight];
  1102. // Wait for the fence of N-2 frame
  1103. const U waitFrameIdx = (m_frame + 1) % kMaxFramesInFlight;
  1104. PerFrame& waitFrame = m_perFrame[waitFrameIdx];
  1105. if(waitFrame.m_presentFence)
  1106. {
  1107. waitFrame.m_presentFence->wait();
  1108. }
  1109. resetFrame(waitFrame);
  1110. if(!frame.m_renderSemaphore)
  1111. {
  1112. ANKI_VK_LOGW("Nobody draw to the default framebuffer");
  1113. }
  1114. // Present
  1115. VkResult res;
  1116. VkPresentInfoKHR present = {};
  1117. present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
  1118. present.waitSemaphoreCount = (frame.m_renderSemaphore) ? 1 : 0;
  1119. present.pWaitSemaphores = (frame.m_renderSemaphore) ? &frame.m_renderSemaphore->getHandle() : nullptr;
  1120. present.swapchainCount = 1;
  1121. present.pSwapchains = &m_crntSwapchain->m_swapchain;
  1122. const U32 idx = m_acquiredImageIdx;
  1123. present.pImageIndices = &idx;
  1124. present.pResults = &res;
  1125. const VkResult res1 = vkQueuePresentKHR(m_queues[frame.m_queueWroteToSwapchainImage], &present);
  1126. if(res1 == VK_ERROR_OUT_OF_DATE_KHR)
  1127. {
  1128. ANKI_VK_LOGW("Swapchain is out of date. Will wait for the queues and create a new one");
  1129. for(VkQueue queue : m_queues)
  1130. {
  1131. if(queue)
  1132. {
  1133. vkQueueWaitIdle(queue);
  1134. }
  1135. }
  1136. vkDeviceWaitIdle(m_device);
  1137. m_crntSwapchain.reset(nullptr);
  1138. m_crntSwapchain = m_swapchainFactory.newInstance();
  1139. }
  1140. else
  1141. {
  1142. ANKI_VK_CHECKF(res1);
  1143. ANKI_VK_CHECKF(res);
  1144. }
  1145. m_descrFactory.endFrame();
  1146. // Finalize
  1147. ++m_frame;
  1148. }
  1149. void GrManagerImpl::resetFrame(PerFrame& frame)
  1150. {
  1151. frame.m_presentFence.reset(nullptr);
  1152. frame.m_acquireSemaphore.reset(nullptr);
  1153. frame.m_renderSemaphore.reset(nullptr);
  1154. }
  1155. void GrManagerImpl::flushCommandBuffer(MicroCommandBufferPtr cmdb, Bool cmdbRenderedToSwapchain,
  1156. WeakArray<MicroSemaphorePtr> userWaitSemaphores,
  1157. MicroSemaphorePtr* userSignalSemaphore, Bool wait)
  1158. {
  1159. constexpr U32 maxSemaphores = 8;
  1160. VkSubmitInfo submit = {};
  1161. submit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
  1162. Array<VkSemaphore, maxSemaphores> waitSemaphores;
  1163. submit.pWaitSemaphores = &waitSemaphores[0];
  1164. Array<VkSemaphore, maxSemaphores> signalSemaphores;
  1165. submit.pSignalSemaphores = &signalSemaphores[0];
  1166. Array<VkPipelineStageFlags, maxSemaphores> waitStages;
  1167. submit.pWaitDstStageMask = &waitStages[0];
  1168. // First thing, create a fence
  1169. MicroFencePtr fence = m_fenceFactory.newInstance();
  1170. // Command buffer
  1171. const VkCommandBuffer handle = cmdb->getHandle();
  1172. cmdb->setFence(fence);
  1173. submit.commandBufferCount = 1;
  1174. submit.pCommandBuffers = &handle;
  1175. // Handle user semaphores
  1176. Array<U64, maxSemaphores> waitTimelineValues;
  1177. Array<U64, maxSemaphores> signalTimelineValues;
  1178. VkTimelineSemaphoreSubmitInfo timelineInfo = {};
  1179. timelineInfo.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
  1180. timelineInfo.waitSemaphoreValueCount = userWaitSemaphores.getSize();
  1181. timelineInfo.pWaitSemaphoreValues = &waitTimelineValues[0];
  1182. timelineInfo.signalSemaphoreValueCount = (userSignalSemaphore != nullptr);
  1183. timelineInfo.pSignalSemaphoreValues = &signalTimelineValues[0];
  1184. submit.pNext = &timelineInfo;
  1185. for(MicroSemaphorePtr& userWaitSemaphore : userWaitSemaphores)
  1186. {
  1187. ANKI_ASSERT(userWaitSemaphore.isCreated());
  1188. ANKI_ASSERT(userWaitSemaphore->isTimeline());
  1189. waitSemaphores[submit.waitSemaphoreCount] = userWaitSemaphore->getHandle();
  1190. waitTimelineValues[submit.waitSemaphoreCount] = userWaitSemaphore->getSemaphoreValue();
  1191. // Be a bit conservative
  1192. waitStages[submit.waitSemaphoreCount] = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
  1193. ++submit.waitSemaphoreCount;
  1194. // Refresh the fence because the semaphore can't be recycled until the current submission is done
  1195. userWaitSemaphore->setFence(fence);
  1196. }
  1197. if(userSignalSemaphore)
  1198. {
  1199. *userSignalSemaphore = m_semaphoreFactory.newInstance(fence, true);
  1200. signalSemaphores[submit.signalSemaphoreCount] = (*userSignalSemaphore)->getHandle();
  1201. signalTimelineValues[submit.signalSemaphoreCount] = (*userSignalSemaphore)->getNextSemaphoreValue();
  1202. ++submit.signalSemaphoreCount;
  1203. }
  1204. // Submit
  1205. {
  1206. // Protect the class, the queue and other stuff
  1207. LockGuard<Mutex> lock(m_globalMtx);
  1208. // Do some special stuff for the last command buffer
  1209. PerFrame& frame = m_perFrame[m_frame % kMaxFramesInFlight];
  1210. if(cmdbRenderedToSwapchain)
  1211. {
  1212. // Wait semaphore
  1213. waitSemaphores[submit.waitSemaphoreCount] = frame.m_acquireSemaphore->getHandle();
  1214. // That depends on how we use the swapchain img. Be a bit conservative
  1215. waitStages[submit.waitSemaphoreCount] =
  1216. VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
  1217. ++submit.waitSemaphoreCount;
  1218. // Refresh the fence because the semaphore can't be recycled until the current submission is done
  1219. frame.m_acquireSemaphore->setFence(fence);
  1220. // Create the semaphore to signal
  1221. ANKI_ASSERT(!frame.m_renderSemaphore && "Only one begin/end render pass is allowed with the default fb");
  1222. frame.m_renderSemaphore = m_semaphoreFactory.newInstance(fence, false);
  1223. signalSemaphores[submit.signalSemaphoreCount++] = frame.m_renderSemaphore->getHandle();
  1224. // Update the frame fence
  1225. frame.m_presentFence = fence;
  1226. // Update the swapchain's fence
  1227. m_crntSwapchain->setFence(fence);
  1228. frame.m_queueWroteToSwapchainImage = cmdb->getVulkanQueueType();
  1229. }
  1230. // Submit
  1231. ANKI_TRACE_SCOPED_EVENT(VkQueueSubmit);
  1232. ANKI_VK_CHECKF(vkQueueSubmit(m_queues[cmdb->getVulkanQueueType()], 1, &submit, fence->getHandle()));
  1233. if(wait)
  1234. {
  1235. vkQueueWaitIdle(m_queues[cmdb->getVulkanQueueType()]);
  1236. }
  1237. }
  1238. // Garbage work
  1239. if(cmdbRenderedToSwapchain)
  1240. {
  1241. m_frameGarbageCollector.setNewFrame(fence);
  1242. }
  1243. }
  1244. void GrManagerImpl::finish()
  1245. {
  1246. LockGuard<Mutex> lock(m_globalMtx);
  1247. for(VkQueue queue : m_queues)
  1248. {
  1249. if(queue)
  1250. {
  1251. vkQueueWaitIdle(queue);
  1252. }
  1253. }
  1254. }
  1255. void GrManagerImpl::trySetVulkanHandleName(CString name, VkObjectType type, U64 handle) const
  1256. {
  1257. if(name && name.getLength() && !!(m_extensions & VulkanExtensions::kEXT_debug_utils))
  1258. {
  1259. VkDebugUtilsObjectNameInfoEXT info = {};
  1260. info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
  1261. info.objectHandle = handle;
  1262. info.objectType = type;
  1263. info.pObjectName = name.cstr();
  1264. vkSetDebugUtilsObjectNameEXT(m_device, &info);
  1265. }
  1266. }
  1267. VkBool32 GrManagerImpl::debugReportCallbackEXT(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
  1268. [[maybe_unused]] VkDebugUtilsMessageTypeFlagsEXT messageTypes,
  1269. const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
  1270. void* pUserData)
  1271. {
  1272. #if ANKI_PLATFORM_MOBILE
  1273. if(pCallbackData->messageIdNumber == 101294395)
  1274. {
  1275. // Interface mismatch error. Eg vert shader is writing to varying that is not consumed by frag. Ignore this
  1276. // stupid error because I'm not going to create more shader variants to fix it. Especially when mobile drivers
  1277. // do linking anyway. On desktop just enable the maintenance4 extension
  1278. return false;
  1279. }
  1280. #endif
  1281. // Get all names of affected objects
  1282. GrManagerImpl* self = static_cast<GrManagerImpl*>(pUserData);
  1283. StringRaii objectNames(&self->m_pool);
  1284. if(pCallbackData->objectCount)
  1285. {
  1286. for(U32 i = 0; i < pCallbackData->objectCount; ++i)
  1287. {
  1288. const Char* name = pCallbackData->pObjects[i].pObjectName;
  1289. objectNames.append((name) ? name : "?");
  1290. if(i < pCallbackData->objectCount - 1)
  1291. {
  1292. objectNames.append(", ");
  1293. }
  1294. }
  1295. }
  1296. else
  1297. {
  1298. objectNames.create("N/A");
  1299. }
  1300. if(messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
  1301. {
  1302. ANKI_VK_LOGE("VK debug report: %s. Affected objects: %s", pCallbackData->pMessage, objectNames.cstr());
  1303. }
  1304. else if(messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
  1305. {
  1306. ANKI_VK_LOGW("VK debug report: %s. Affected objects: %s", pCallbackData->pMessage, objectNames.cstr());
  1307. }
  1308. else
  1309. {
  1310. ANKI_VK_LOGI("VK debug report: %s. Affected objects: %s", pCallbackData->pMessage, objectNames.cstr());
  1311. }
  1312. return false;
  1313. }
  1314. void GrManagerImpl::printPipelineShaderInfo(VkPipeline ppline, CString name, ShaderTypeBit stages, U64 hash) const
  1315. {
  1316. if(printPipelineShaderInfoInternal(ppline, name, stages, hash))
  1317. {
  1318. ANKI_VK_LOGE("Ignoring previous errors");
  1319. }
  1320. }
  1321. Error GrManagerImpl::printPipelineShaderInfoInternal(VkPipeline ppline, CString name, ShaderTypeBit stages,
  1322. U64 hash) const
  1323. {
  1324. if(m_pfnGetShaderInfoAMD)
  1325. {
  1326. VkShaderStatisticsInfoAMD stats = {};
  1327. LockGuard<SpinLock> lock(m_shaderStatsFileMtx);
  1328. // Open the file
  1329. if(!m_shaderStatsFile.isOpen())
  1330. {
  1331. ANKI_CHECK(m_shaderStatsFile.open(
  1332. StringRaii(&m_pool).sprintf("%s/../ppline_stats.csv", m_cacheDir.cstr()).toCString(),
  1333. FileOpenFlag::kWrite));
  1334. ANKI_CHECK(m_shaderStatsFile.writeText("ppline name,hash,"
  1335. "stage 0 VGPR,stage 0 SGPR,"
  1336. "stage 1 VGPR,stage 1 SGPR,"
  1337. "stage 2 VGPR,stage 2 SGPR,"
  1338. "stage 3 VGPR,stage 3 SGPR,"
  1339. "stage 4 VGPR,stage 4 SGPR,"
  1340. "stage 5 VGPR,stage 5 SGPR\n"));
  1341. }
  1342. ANKI_CHECK(m_shaderStatsFile.writeTextf("%s,0x%" PRIx64 ",", name.cstr(), hash));
  1343. StringRaii str(&m_pool);
  1344. for(ShaderType type = ShaderType::kFirst; type < ShaderType::kCount; ++type)
  1345. {
  1346. ShaderTypeBit stage = stages & ShaderTypeBit(1 << type);
  1347. if(!stage)
  1348. {
  1349. ANKI_CHECK(m_shaderStatsFile.writeText((type != ShaderType::kLast) ? "0,0," : "0,0\n"));
  1350. continue;
  1351. }
  1352. size_t size = sizeof(stats);
  1353. ANKI_VK_CHECK(m_pfnGetShaderInfoAMD(m_device, ppline, VkShaderStageFlagBits(convertShaderTypeBit(stage)),
  1354. VK_SHADER_INFO_TYPE_STATISTICS_AMD, &size, &stats));
  1355. str.append(StringRaii(&m_pool).sprintf("Stage %u: VGRPS %02u, SGRPS %02u ", U32(type),
  1356. stats.resourceUsage.numUsedVgprs, stats.resourceUsage.numUsedSgprs));
  1357. ANKI_CHECK(m_shaderStatsFile.writeTextf((type != ShaderType::kLast) ? "%u,%u," : "%u,%u\n",
  1358. stats.resourceUsage.numUsedVgprs,
  1359. stats.resourceUsage.numUsedSgprs));
  1360. }
  1361. ANKI_VK_LOGV("Pipeline \"%s\" (0x%016" PRIx64 ") stats: %s", name.cstr(), hash, str.cstr());
  1362. // Flush the file just in case
  1363. ANKI_CHECK(m_shaderStatsFile.flush());
  1364. }
  1365. if(!!(m_extensions & VulkanExtensions::kKHR_pipeline_executable_properties))
  1366. {
  1367. StringListRaii log(&m_pool);
  1368. VkPipelineInfoKHR pplineInf = {};
  1369. pplineInf.sType = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR;
  1370. pplineInf.pipeline = ppline;
  1371. U32 executableCount = 0;
  1372. ANKI_VK_CHECK(vkGetPipelineExecutablePropertiesKHR(m_device, &pplineInf, &executableCount, nullptr));
  1373. DynamicArrayRaii<VkPipelineExecutablePropertiesKHR> executableProps(&m_pool, executableCount);
  1374. for(VkPipelineExecutablePropertiesKHR& prop : executableProps)
  1375. {
  1376. prop = {};
  1377. prop.sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR;
  1378. }
  1379. ANKI_VK_CHECK(
  1380. vkGetPipelineExecutablePropertiesKHR(m_device, &pplineInf, &executableCount, &executableProps[0]));
  1381. log.pushBackSprintf("Pipeline info \"%s\" (0x%016" PRIx64 "): ", name.cstr(), hash);
  1382. for(U32 i = 0; i < executableCount; ++i)
  1383. {
  1384. const VkPipelineExecutablePropertiesKHR& p = executableProps[i];
  1385. log.pushBackSprintf("%s: ", p.description);
  1386. // Get stats
  1387. VkPipelineExecutableInfoKHR exeInf = {};
  1388. exeInf.sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR;
  1389. exeInf.executableIndex = i;
  1390. exeInf.pipeline = ppline;
  1391. U32 statCount = 0;
  1392. vkGetPipelineExecutableStatisticsKHR(m_device, &exeInf, &statCount, nullptr);
  1393. DynamicArrayRaii<VkPipelineExecutableStatisticKHR> stats(&m_pool, statCount);
  1394. for(VkPipelineExecutableStatisticKHR& s : stats)
  1395. {
  1396. s = {};
  1397. s.sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR;
  1398. }
  1399. vkGetPipelineExecutableStatisticsKHR(m_device, &exeInf, &statCount, &stats[0]);
  1400. for(U32 s = 0; s < statCount; ++s)
  1401. {
  1402. const VkPipelineExecutableStatisticKHR& ss = stats[s];
  1403. switch(ss.format)
  1404. {
  1405. case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR:
  1406. log.pushBackSprintf("%s: %u, ", ss.name, ss.value.b32);
  1407. break;
  1408. case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR:
  1409. log.pushBackSprintf("%s: %" PRId64 ", ", ss.name, ss.value.i64);
  1410. break;
  1411. case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR:
  1412. log.pushBackSprintf("%s: %" PRIu64 ", ", ss.name, ss.value.u64);
  1413. break;
  1414. case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR:
  1415. log.pushBackSprintf("%s: %f, ", ss.name, ss.value.f64);
  1416. break;
  1417. default:
  1418. ANKI_ASSERT(0);
  1419. }
  1420. }
  1421. log.pushBackSprintf("Subgroup size: %u", p.subgroupSize);
  1422. if(i < executableCount - 1)
  1423. {
  1424. log.pushBack(", ");
  1425. }
  1426. }
  1427. StringRaii finalLog(&m_pool);
  1428. log.join("", finalLog);
  1429. ANKI_VK_LOGV("%s", finalLog.cstr());
  1430. }
  1431. return Error::kNone;
  1432. }
  1433. } // end namespace anki