GrManagerImpl.cpp 54 KB

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