GrManagerImpl.cpp 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331
  1. // Copyright (C) 2009-2021, 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. #include <glslang/Public/ShaderLang.h>
  15. namespace anki
  16. {
  17. GrManagerImpl::~GrManagerImpl()
  18. {
  19. // 1st THING: wait for the present fences because I don't know if waiting on queue will cover this
  20. for(PerFrame& frame : m_perFrame)
  21. {
  22. if(frame.m_presentFence.isCreated())
  23. {
  24. frame.m_presentFence->wait();
  25. }
  26. }
  27. // 2nd THING: wait for the GPU
  28. for(VkQueue& queue : m_queues)
  29. {
  30. LockGuard<Mutex> lock(m_globalMtx);
  31. if(queue)
  32. {
  33. vkQueueWaitIdle(queue);
  34. queue = VK_NULL_HANDLE;
  35. }
  36. }
  37. m_cmdbFactory.destroy();
  38. // 3rd THING: The destroy everything that has a reference to GrObjects.
  39. for(PerFrame& frame : m_perFrame)
  40. {
  41. frame.m_presentFence.reset(nullptr);
  42. frame.m_acquireSemaphore.reset(nullptr);
  43. frame.m_renderSemaphore.reset(nullptr);
  44. }
  45. m_crntSwapchain.reset(nullptr);
  46. // 4th THING: Continue with the rest
  47. m_gpuMemManager.destroy();
  48. m_barrierFactory.destroy(); // Destroy before fences
  49. m_semaphoreFactory.destroy(); // Destroy before fences
  50. m_swapchainFactory.destroy(); // Destroy before fences
  51. m_pplineLayoutFactory.destroy();
  52. m_descrFactory.destroy();
  53. m_pplineCache.destroy(m_device, m_physicalDevice, getAllocator());
  54. m_fenceFactory.destroy();
  55. m_samplerFactory.destroy();
  56. if(m_device)
  57. {
  58. vkDestroyDevice(m_device, nullptr);
  59. }
  60. if(m_surface)
  61. {
  62. vkDestroySurfaceKHR(m_instance, m_surface, nullptr);
  63. }
  64. if(m_debugCallback)
  65. {
  66. vkDestroyDebugReportCallbackEXT(m_instance, m_debugCallback, nullptr);
  67. }
  68. if(m_instance)
  69. {
  70. #if ANKI_GR_MANAGER_DEBUG_MEMMORY
  71. VkAllocationCallbacks* pallocCbs = &m_debugAllocCbs;
  72. #else
  73. VkAllocationCallbacks* pallocCbs = nullptr;
  74. #endif
  75. vkDestroyInstance(m_instance, pallocCbs);
  76. }
  77. m_vkHandleToName.destroy(getAllocator());
  78. }
  79. Error GrManagerImpl::init(const GrManagerInitInfo& init)
  80. {
  81. Error err = initInternal(init);
  82. if(err)
  83. {
  84. ANKI_VK_LOGE("Vulkan initialization failed");
  85. return Error::FUNCTION_FAILED;
  86. }
  87. return Error::NONE;
  88. }
  89. Error GrManagerImpl::initInternal(const GrManagerInitInfo& init)
  90. {
  91. ANKI_VK_LOGI("Initializing Vulkan backend");
  92. ANKI_CHECK(initInstance(init));
  93. ANKI_CHECK(initSurface(init));
  94. ANKI_CHECK(initDevice(init));
  95. for(QueueType qtype : EnumIterable<QueueType>())
  96. {
  97. vkGetDeviceQueue(m_device, m_queueFamilyIndices[qtype], 0, &m_queues[qtype]);
  98. }
  99. m_swapchainFactory.init(this, init.m_config->getBool("gr_vsync"));
  100. m_crntSwapchain = m_swapchainFactory.newInstance();
  101. ANKI_CHECK(m_pplineCache.init(m_device, m_physicalDevice, init.m_cacheDirectory, *init.m_config, getAllocator()));
  102. ANKI_CHECK(initMemory(*init.m_config));
  103. ANKI_CHECK(m_cmdbFactory.init(getAllocator(), m_device, m_queueFamilyIndices));
  104. for(PerFrame& f : m_perFrame)
  105. {
  106. resetFrame(f);
  107. }
  108. glslang::InitializeProcess();
  109. m_fenceFactory.init(getAllocator(), m_device);
  110. m_semaphoreFactory.init(getAllocator(), m_device);
  111. m_samplerFactory.init(this);
  112. m_barrierFactory.init(getAllocator(), m_device);
  113. m_occlusionQueryFactory.init(getAllocator(), m_device, VK_QUERY_TYPE_OCCLUSION);
  114. m_timestampQueryFactory.init(getAllocator(), m_device, VK_QUERY_TYPE_TIMESTAMP);
  115. // Set m_r8g8b8ImagesSupported
  116. {
  117. VkImageFormatProperties props = {};
  118. VkResult res = vkGetPhysicalDeviceImageFormatProperties(
  119. m_physicalDevice, VK_FORMAT_R8G8B8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
  120. VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &props);
  121. if(res == VK_ERROR_FORMAT_NOT_SUPPORTED)
  122. {
  123. ANKI_VK_LOGI("R8G8B8 Images are not supported. Will workaround this");
  124. m_r8g8b8ImagesSupported = false;
  125. }
  126. else
  127. {
  128. ANKI_ASSERT(res == VK_SUCCESS);
  129. ANKI_VK_LOGI("R8G8B8 Images are supported");
  130. m_r8g8b8ImagesSupported = true;
  131. }
  132. }
  133. // Set m_s8ImagesSupported
  134. {
  135. VkImageFormatProperties props = {};
  136. VkResult res = vkGetPhysicalDeviceImageFormatProperties(
  137. m_physicalDevice, VK_FORMAT_S8_UINT, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
  138. VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 0, &props);
  139. if(res == VK_ERROR_FORMAT_NOT_SUPPORTED)
  140. {
  141. ANKI_VK_LOGI("S8 Images are not supported. Will workaround this");
  142. m_s8ImagesSupported = false;
  143. }
  144. else
  145. {
  146. ANKI_ASSERT(res == VK_SUCCESS);
  147. ANKI_VK_LOGI("S8 Images are supported");
  148. m_s8ImagesSupported = true;
  149. }
  150. }
  151. // Set m_d24S8ImagesSupported
  152. {
  153. VkImageFormatProperties props = {};
  154. VkResult res = vkGetPhysicalDeviceImageFormatProperties(
  155. m_physicalDevice, VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
  156. VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 0, &props);
  157. if(res == VK_ERROR_FORMAT_NOT_SUPPORTED)
  158. {
  159. ANKI_VK_LOGI("D24S8 Images are not supported. Will workaround this");
  160. m_d24S8ImagesSupported = false;
  161. }
  162. else
  163. {
  164. ANKI_ASSERT(res == VK_SUCCESS);
  165. ANKI_VK_LOGI("D24S8 Images are supported");
  166. m_d24S8ImagesSupported = true;
  167. }
  168. }
  169. m_bindlessLimits.m_bindlessTextureCount = init.m_config->getNumberU32("gr_maxBindlessTextures");
  170. m_bindlessLimits.m_bindlessImageCount = init.m_config->getNumberU32("gr_maxBindlessImages");
  171. ANKI_CHECK(m_descrFactory.init(getAllocator(), m_device, m_bindlessLimits));
  172. m_pplineLayoutFactory.init(getAllocator(), m_device);
  173. return Error::NONE;
  174. }
  175. Error GrManagerImpl::initInstance(const GrManagerInitInfo& init)
  176. {
  177. // Init VOLK
  178. //
  179. ANKI_VK_CHECK(volkInitialize());
  180. // Create the instance
  181. //
  182. const U8 vulkanMinor = init.m_config->getNumberU8("gr_vkminor");
  183. const U8 vulkanMajor = init.m_config->getNumberU8("gr_vkmajor");
  184. VkApplicationInfo app = {};
  185. app.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
  186. app.pApplicationName = "unamed";
  187. app.applicationVersion = 1;
  188. app.pEngineName = "AnKi 3D Engine";
  189. app.engineVersion = (ANKI_VERSION_MAJOR << 16) | ANKI_VERSION_MINOR;
  190. app.apiVersion = VK_MAKE_VERSION(vulkanMajor, vulkanMinor, 0);
  191. VkInstanceCreateInfo ci = {};
  192. ci.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
  193. ci.pApplicationInfo = &app;
  194. // Validation layers
  195. static Array<const char*, 1> LAYERS = {"VK_LAYER_KHRONOS_validation"};
  196. Array<const char*, LAYERS.getSize()> layersToEnable; // Keep it alive in the stack
  197. if(init.m_config->getBool("gr_validation") || init.m_config->getBool("gr_debugPrintf"))
  198. {
  199. uint32_t count;
  200. vkEnumerateInstanceLayerProperties(&count, nullptr);
  201. if(count)
  202. {
  203. DynamicArrayAuto<VkLayerProperties> layerProps(getAllocator());
  204. layerProps.create(count);
  205. vkEnumerateInstanceLayerProperties(&count, &layerProps[0]);
  206. U32 layersToEnableCount = 0;
  207. for(const char* c : LAYERS)
  208. {
  209. for(U32 i = 0; i < count; ++i)
  210. {
  211. if(CString(c) == layerProps[i].layerName)
  212. {
  213. layersToEnable[layersToEnableCount++] = c;
  214. break;
  215. }
  216. }
  217. }
  218. if(layersToEnableCount)
  219. {
  220. ANKI_VK_LOGI("Will enable the following layers:");
  221. for(U32 i = 0; i < layersToEnableCount; ++i)
  222. {
  223. ANKI_VK_LOGI("\t%s", layersToEnable[i]);
  224. }
  225. ci.enabledLayerCount = layersToEnableCount;
  226. ci.ppEnabledLayerNames = &layersToEnable[0];
  227. }
  228. }
  229. }
  230. // Validation features
  231. DynamicArrayAuto<VkValidationFeatureEnableEXT> enabledValidationFeatures(getAllocator());
  232. DynamicArrayAuto<VkValidationFeatureDisableEXT> disabledValidationFeatures(getAllocator());
  233. if(init.m_config->getBool("gr_debugPrintf"))
  234. {
  235. enabledValidationFeatures.emplaceBack(VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT);
  236. }
  237. if(!init.m_config->getBool("gr_validation"))
  238. {
  239. disabledValidationFeatures.emplaceBack(VK_VALIDATION_FEATURE_DISABLE_ALL_EXT);
  240. }
  241. VkValidationFeaturesEXT validationFeatures = {};
  242. if(enabledValidationFeatures.getSize() || disabledValidationFeatures.getSize())
  243. {
  244. validationFeatures.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT;
  245. validationFeatures.disabledValidationFeatureCount = disabledValidationFeatures.getSize();
  246. validationFeatures.enabledValidationFeatureCount = enabledValidationFeatures.getSize();
  247. validationFeatures.pDisabledValidationFeatures = disabledValidationFeatures.getBegin();
  248. validationFeatures.pEnabledValidationFeatures = enabledValidationFeatures.getBegin();
  249. validationFeatures.pNext = ci.pNext;
  250. ci.pNext = &validationFeatures;
  251. }
  252. // Extensions
  253. DynamicArrayAuto<const char*> instExtensions(getAllocator());
  254. DynamicArrayAuto<VkExtensionProperties> instExtensionInf(getAllocator());
  255. U32 extCount = 0;
  256. vkEnumerateInstanceExtensionProperties(nullptr, &extCount, nullptr);
  257. if(extCount)
  258. {
  259. instExtensions.create(extCount);
  260. instExtensionInf.create(extCount);
  261. vkEnumerateInstanceExtensionProperties(nullptr, &extCount, &instExtensionInf[0]);
  262. ANKI_VK_LOGI("Found the following instance extensions:");
  263. for(U32 i = 0; i < extCount; ++i)
  264. {
  265. ANKI_VK_LOGI("\t%s", instExtensionInf[i].extensionName);
  266. }
  267. U32 instExtensionCount = 0;
  268. for(U32 i = 0; i < extCount; ++i)
  269. {
  270. #if ANKI_OS_LINUX
  271. if(CString(instExtensionInf[i].extensionName) == VK_KHR_XCB_SURFACE_EXTENSION_NAME)
  272. {
  273. m_extensions |= VulkanExtensions::KHR_XCB_SURFACE;
  274. instExtensions[instExtensionCount++] = VK_KHR_XCB_SURFACE_EXTENSION_NAME;
  275. }
  276. else if(CString(instExtensionInf[i].extensionName) == VK_KHR_XLIB_SURFACE_EXTENSION_NAME)
  277. {
  278. m_extensions |= VulkanExtensions::KHR_XLIB_SURFACE;
  279. instExtensions[instExtensionCount++] = VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
  280. }
  281. #elif ANKI_OS_WINDOWS
  282. if(CString(instExtensionInf[i].extensionName) == VK_KHR_WIN32_SURFACE_EXTENSION_NAME)
  283. {
  284. m_extensions |= VulkanExtensions::KHR_WIN32_SURFACE;
  285. instExtensions[instExtensionCount++] = VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
  286. }
  287. #else
  288. # error TODO
  289. #endif
  290. else if(CString(instExtensionInf[i].extensionName) == VK_KHR_SURFACE_EXTENSION_NAME)
  291. {
  292. m_extensions |= VulkanExtensions::KHR_SURFACE;
  293. instExtensions[instExtensionCount++] = VK_KHR_SURFACE_EXTENSION_NAME;
  294. }
  295. else if(CString(instExtensionInf[i].extensionName) == VK_EXT_DEBUG_REPORT_EXTENSION_NAME
  296. && (init.m_config->getBool("gr_validation") || init.m_config->getBool("gr_debugPrintf")))
  297. {
  298. m_extensions |= VulkanExtensions::EXT_DEBUG_REPORT;
  299. instExtensions[instExtensionCount++] = VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
  300. }
  301. }
  302. if(instExtensionCount)
  303. {
  304. ANKI_VK_LOGI("Will enable the following instance extensions:");
  305. for(U32 i = 0; i < instExtensionCount; ++i)
  306. {
  307. ANKI_VK_LOGI("\t%s", instExtensions[i]);
  308. }
  309. ci.enabledExtensionCount = instExtensionCount;
  310. ci.ppEnabledExtensionNames = &instExtensions[0];
  311. }
  312. }
  313. #if ANKI_GR_MANAGER_DEBUG_MEMMORY
  314. m_debugAllocCbs = {};
  315. m_debugAllocCbs.pUserData = this;
  316. m_debugAllocCbs.pfnAllocation = allocateCallback;
  317. m_debugAllocCbs.pfnReallocation = reallocateCallback;
  318. m_debugAllocCbs.pfnFree = freeCallback;
  319. VkAllocationCallbacks* pallocCbs = &m_debugAllocCbs;
  320. #else
  321. VkAllocationCallbacks* pallocCbs = nullptr;
  322. #endif
  323. ANKI_VK_CHECK(vkCreateInstance(&ci, pallocCbs, &m_instance));
  324. // Get symbolx
  325. //
  326. volkLoadInstance(m_instance);
  327. // Set debug callbacks
  328. //
  329. if(!!(m_extensions & VulkanExtensions::EXT_DEBUG_REPORT))
  330. {
  331. VkDebugReportCallbackCreateInfoEXT ci = {};
  332. ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
  333. ci.pfnCallback = debugReportCallbackEXT;
  334. ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT
  335. | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
  336. if(init.m_config->getBool("gr_debugPrintf"))
  337. {
  338. ci.flags |= VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
  339. }
  340. ci.pUserData = this;
  341. vkCreateDebugReportCallbackEXT(m_instance, &ci, nullptr, &m_debugCallback);
  342. }
  343. // Create the physical device
  344. //
  345. uint32_t count = 0;
  346. ANKI_VK_CHECK(vkEnumeratePhysicalDevices(m_instance, &count, nullptr));
  347. ANKI_VK_LOGI("Number of physical devices: %u", count);
  348. if(count < 1)
  349. {
  350. ANKI_VK_LOGE("Wrong number of physical devices");
  351. return Error::FUNCTION_FAILED;
  352. }
  353. count = 1;
  354. ANKI_VK_CHECK(vkEnumeratePhysicalDevices(m_instance, &count, &m_physicalDevice));
  355. m_rtPipelineProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR;
  356. m_accelerationStructureProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR;
  357. m_devProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
  358. m_devProps.pNext = &m_rtPipelineProps;
  359. m_rtPipelineProps.pNext = &m_accelerationStructureProps;
  360. vkGetPhysicalDeviceProperties2(m_physicalDevice, &m_devProps);
  361. // Find vendor
  362. switch(m_devProps.properties.vendorID)
  363. {
  364. case 0x13B5:
  365. m_capabilities.m_gpuVendor = GpuVendor::ARM;
  366. break;
  367. case 0x10DE:
  368. m_capabilities.m_gpuVendor = GpuVendor::NVIDIA;
  369. break;
  370. case 0x1002:
  371. case 0x1022:
  372. m_capabilities.m_gpuVendor = GpuVendor::AMD;
  373. break;
  374. case 0x8086:
  375. m_capabilities.m_gpuVendor = GpuVendor::INTEL;
  376. break;
  377. default:
  378. m_capabilities.m_gpuVendor = GpuVendor::UNKNOWN;
  379. }
  380. ANKI_VK_LOGI("GPU is %s. Vendor identified as %s", m_devProps.properties.deviceName,
  381. &GPU_VENDOR_STR[m_capabilities.m_gpuVendor][0]);
  382. // Set limits
  383. m_capabilities.m_uniformBufferBindOffsetAlignment =
  384. max<U32>(ANKI_SAFE_ALIGNMENT, U32(m_devProps.properties.limits.minUniformBufferOffsetAlignment));
  385. m_capabilities.m_uniformBufferMaxRange = m_devProps.properties.limits.maxUniformBufferRange;
  386. m_capabilities.m_storageBufferBindOffsetAlignment =
  387. max<U32>(ANKI_SAFE_ALIGNMENT, U32(m_devProps.properties.limits.minStorageBufferOffsetAlignment));
  388. m_capabilities.m_storageBufferMaxRange = m_devProps.properties.limits.maxStorageBufferRange;
  389. m_capabilities.m_textureBufferBindOffsetAlignment =
  390. max<U32>(ANKI_SAFE_ALIGNMENT, U32(m_devProps.properties.limits.minTexelBufferOffsetAlignment));
  391. m_capabilities.m_textureBufferMaxRange = MAX_U32;
  392. m_capabilities.m_majorApiVersion = vulkanMajor;
  393. m_capabilities.m_minorApiVersion = vulkanMinor;
  394. m_capabilities.m_shaderGroupHandleSize = m_rtPipelineProps.shaderGroupHandleSize;
  395. m_capabilities.m_sbtRecordAlignment = m_rtPipelineProps.shaderGroupBaseAlignment;
  396. return Error::NONE;
  397. }
  398. Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
  399. {
  400. uint32_t count = 0;
  401. vkGetPhysicalDeviceQueueFamilyProperties(m_physicalDevice, &count, nullptr);
  402. ANKI_VK_LOGI("Number of queue families: %u", count);
  403. DynamicArrayAuto<VkQueueFamilyProperties> queueInfos(getAllocator());
  404. queueInfos.create(count);
  405. vkGetPhysicalDeviceQueueFamilyProperties(m_physicalDevice, &count, &queueInfos[0]);
  406. const VkQueueFlags GENERAL_QUEUE_FLAGS = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT;
  407. for(U32 i = 0; i < count; ++i)
  408. {
  409. VkBool32 supportsPresent = false;
  410. ANKI_VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(m_physicalDevice, i, m_surface, &supportsPresent));
  411. if(supportsPresent)
  412. {
  413. if((queueInfos[i].queueFlags & GENERAL_QUEUE_FLAGS) == GENERAL_QUEUE_FLAGS)
  414. {
  415. m_queueFamilyIndices[QueueType::GENERAL] = i;
  416. }
  417. else if((queueInfos[i].queueFlags & VK_QUEUE_COMPUTE_BIT)
  418. && !(queueInfos[i].queueFlags & VK_QUEUE_GRAPHICS_BIT))
  419. {
  420. // This must be the async compute
  421. m_queueFamilyIndices[QueueType::COMPUTE] = i;
  422. }
  423. }
  424. }
  425. if(m_queueFamilyIndices[QueueType::GENERAL] == MAX_U32)
  426. {
  427. ANKI_VK_LOGE("Couldn't find a queue family with graphics+compute+transfer+present. "
  428. "Something is wrong");
  429. return Error::FUNCTION_FAILED;
  430. }
  431. if(m_queueFamilyIndices[QueueType::COMPUTE] == MAX_U32)
  432. {
  433. ANKI_VK_LOGE("Couldn't find an async compute queue");
  434. return Error::FUNCTION_FAILED;
  435. }
  436. const F32 priority = 1.0;
  437. Array<VkDeviceQueueCreateInfo, U32(QueueType::COUNT)> q = {};
  438. for(QueueType qtype : EnumIterable<QueueType>())
  439. {
  440. q[qtype].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
  441. q[qtype].queueFamilyIndex = m_queueFamilyIndices[qtype];
  442. q[qtype].queueCount = 1;
  443. q[qtype].pQueuePriorities = &priority;
  444. }
  445. VkDeviceCreateInfo ci = {};
  446. ci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
  447. ci.queueCreateInfoCount = q.getSize();
  448. ci.pQueueCreateInfos = &q[0];
  449. // Extensions
  450. U32 extCount = 0;
  451. vkEnumerateDeviceExtensionProperties(m_physicalDevice, nullptr, &extCount, nullptr);
  452. DynamicArrayAuto<VkExtensionProperties> extensionInfos(getAllocator()); // Keep it alive in the stack
  453. DynamicArrayAuto<const char*> extensionsToEnable(getAllocator());
  454. if(extCount)
  455. {
  456. extensionInfos.create(extCount);
  457. extensionsToEnable.create(extCount);
  458. U32 extensionsToEnableCount = 0;
  459. vkEnumerateDeviceExtensionProperties(m_physicalDevice, nullptr, &extCount, &extensionInfos[0]);
  460. ANKI_VK_LOGI("Found the following device extensions:");
  461. for(U32 i = 0; i < extCount; ++i)
  462. {
  463. ANKI_VK_LOGI("\t%s", extensionInfos[i].extensionName);
  464. }
  465. while(extCount-- != 0)
  466. {
  467. const CString extensionName(&extensionInfos[extCount].extensionName[0]);
  468. if(extensionName == VK_KHR_SWAPCHAIN_EXTENSION_NAME)
  469. {
  470. m_extensions |= VulkanExtensions::KHR_SWAPCHAIN;
  471. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  472. }
  473. else if(extensionName == VK_EXT_DEBUG_MARKER_EXTENSION_NAME && init.m_config->getBool("gr_debugMarkers"))
  474. {
  475. m_extensions |= VulkanExtensions::EXT_DEBUG_MARKER;
  476. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  477. }
  478. else if(extensionName == VK_AMD_SHADER_INFO_EXTENSION_NAME && init.m_config->getBool("core_displayStats"))
  479. {
  480. m_extensions |= VulkanExtensions::AMD_SHADER_INFO;
  481. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  482. }
  483. else if(extensionName == VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME)
  484. {
  485. m_extensions |= VulkanExtensions::AMD_RASTERIZATION_ORDER;
  486. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  487. }
  488. else if(extensionName == VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME
  489. && init.m_config->getBool("gr_rayTracing"))
  490. {
  491. m_extensions |= VulkanExtensions::KHR_RAY_TRACING;
  492. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  493. m_capabilities.m_rayTracingEnabled = true;
  494. }
  495. else if(extensionName == VK_KHR_RAY_QUERY_EXTENSION_NAME && init.m_config->getBool("gr_rayTracing"))
  496. {
  497. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  498. }
  499. else if(extensionName == VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME
  500. && init.m_config->getBool("gr_rayTracing"))
  501. {
  502. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  503. }
  504. else if(extensionName == VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME
  505. && init.m_config->getBool("gr_rayTracing"))
  506. {
  507. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  508. }
  509. else if(extensionName == VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME && init.m_config->getBool("gr_rayTracing"))
  510. {
  511. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  512. }
  513. else if(extensionName == VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME
  514. && init.m_config->getBool("core_displayStats"))
  515. {
  516. m_extensions |= VulkanExtensions::PIPELINE_EXECUTABLE_PROPERTIES;
  517. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  518. }
  519. else if(extensionName == VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME
  520. && init.m_config->getBool("gr_debugPrintf"))
  521. {
  522. extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
  523. }
  524. }
  525. ANKI_VK_LOGI("Will enable the following device extensions:");
  526. for(U32 i = 0; i < extensionsToEnableCount; ++i)
  527. {
  528. ANKI_VK_LOGI("\t%s", extensionsToEnable[i]);
  529. }
  530. ci.enabledExtensionCount = extensionsToEnableCount;
  531. ci.ppEnabledExtensionNames = &extensionsToEnable[0];
  532. }
  533. // Enable/disable generic features
  534. {
  535. VkPhysicalDeviceFeatures2 devFeatures = {};
  536. devFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  537. vkGetPhysicalDeviceFeatures2(m_physicalDevice, &devFeatures);
  538. m_devFeatures = devFeatures.features;
  539. m_devFeatures.robustBufferAccess =
  540. (init.m_config->getBool("gr_validation") && m_devFeatures.robustBufferAccess) ? true : false;
  541. ANKI_VK_LOGI("Robust buffer access is %s", (m_devFeatures.robustBufferAccess) ? "enabled" : "disabled");
  542. ci.pEnabledFeatures = &m_devFeatures;
  543. }
  544. // Enable 1.1 features
  545. {
  546. m_11Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
  547. VkPhysicalDeviceFeatures2 features = {};
  548. features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  549. features.pNext = &m_11Features;
  550. vkGetPhysicalDeviceFeatures2(m_physicalDevice, &features);
  551. if(!m_11Features.storageBuffer16BitAccess || !m_11Features.uniformAndStorageBuffer16BitAccess)
  552. {
  553. ANKI_VK_LOGE("16bit buffer access is not supported");
  554. return Error::FUNCTION_FAILED;
  555. }
  556. // Disable a few things
  557. m_11Features.storagePushConstant16 = false; // Because AMD doesn't support it
  558. m_11Features.protectedMemory = false;
  559. m_11Features.multiview = false;
  560. m_11Features.multiviewGeometryShader = false;
  561. m_11Features.multiviewTessellationShader = false;
  562. m_11Features.samplerYcbcrConversion = false;
  563. m_11Features.pNext = const_cast<void*>(ci.pNext);
  564. ci.pNext = &m_11Features;
  565. }
  566. // Enable a few 1.2 features
  567. {
  568. m_12Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
  569. VkPhysicalDeviceFeatures2 features = {};
  570. features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  571. features.pNext = &m_12Features;
  572. vkGetPhysicalDeviceFeatures2(m_physicalDevice, &features);
  573. // Descriptor indexing
  574. if(!m_12Features.shaderSampledImageArrayNonUniformIndexing
  575. || !m_12Features.shaderStorageImageArrayNonUniformIndexing)
  576. {
  577. ANKI_VK_LOGE("Non uniform indexing is not supported by the device");
  578. return Error::FUNCTION_FAILED;
  579. }
  580. if(!m_12Features.descriptorBindingSampledImageUpdateAfterBind
  581. || !m_12Features.descriptorBindingStorageImageUpdateAfterBind)
  582. {
  583. ANKI_VK_LOGE("Update descriptors after bind is not supported by the device");
  584. return Error::FUNCTION_FAILED;
  585. }
  586. if(!m_12Features.descriptorBindingUpdateUnusedWhilePending)
  587. {
  588. ANKI_VK_LOGE("Update descriptors while cmd buffer is pending is not supported by the device");
  589. return Error::FUNCTION_FAILED;
  590. }
  591. // Buffer address
  592. if(!!(m_extensions & VulkanExtensions::KHR_RAY_TRACING))
  593. {
  594. if(!m_12Features.bufferDeviceAddress)
  595. {
  596. ANKI_VK_LOGE("Buffer device address is not supported by the device");
  597. return Error::FUNCTION_FAILED;
  598. }
  599. m_12Features.bufferDeviceAddressCaptureReplay =
  600. m_12Features.bufferDeviceAddressCaptureReplay && init.m_config->getBool("gr_debugMarkers");
  601. m_12Features.bufferDeviceAddressMultiDevice = false;
  602. }
  603. else
  604. {
  605. m_12Features.bufferDeviceAddress = false;
  606. m_12Features.bufferDeviceAddressCaptureReplay = false;
  607. m_12Features.bufferDeviceAddressMultiDevice = false;
  608. }
  609. // Scalar block layout
  610. if(!m_12Features.scalarBlockLayout)
  611. {
  612. ANKI_VK_LOGE("Scalar block layout is not supported by the device");
  613. return Error::FUNCTION_FAILED;
  614. }
  615. // Timeline semaphores
  616. if(!m_12Features.timelineSemaphore)
  617. {
  618. ANKI_VK_LOGE("Timeline semaphores are not supported by the device");
  619. return Error::FUNCTION_FAILED;
  620. }
  621. m_12Features.pNext = const_cast<void*>(ci.pNext);
  622. ci.pNext = &m_12Features;
  623. }
  624. // Set RT features
  625. if(!!(m_extensions & VulkanExtensions::KHR_RAY_TRACING))
  626. {
  627. m_rtPipelineFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR;
  628. m_rayQueryFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR;
  629. m_accelerationStructureFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR;
  630. VkPhysicalDeviceFeatures2 features = {};
  631. features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  632. features.pNext = &m_rtPipelineFeatures;
  633. m_rtPipelineFeatures.pNext = &m_rayQueryFeatures;
  634. m_rayQueryFeatures.pNext = &m_accelerationStructureFeatures;
  635. vkGetPhysicalDeviceFeatures2(m_physicalDevice, &features);
  636. if(!m_rtPipelineFeatures.rayTracingPipeline || !m_rayQueryFeatures.rayQuery
  637. || !m_accelerationStructureFeatures.accelerationStructure)
  638. {
  639. ANKI_VK_LOGE("Ray tracing and ray query are both required");
  640. return Error::FUNCTION_FAILED;
  641. }
  642. // Only enable what's necessary
  643. m_rtPipelineFeatures.rayTracingPipelineShaderGroupHandleCaptureReplay = false;
  644. m_rtPipelineFeatures.rayTracingPipelineShaderGroupHandleCaptureReplayMixed = false;
  645. m_rtPipelineFeatures.rayTraversalPrimitiveCulling = false;
  646. m_accelerationStructureFeatures.accelerationStructureCaptureReplay = false;
  647. m_accelerationStructureFeatures.accelerationStructureHostCommands = false;
  648. m_accelerationStructureFeatures.descriptorBindingAccelerationStructureUpdateAfterBind = false;
  649. ANKI_ASSERT(m_accelerationStructureFeatures.pNext == nullptr);
  650. m_accelerationStructureFeatures.pNext = const_cast<void*>(ci.pNext);
  651. ci.pNext = &m_rtPipelineFeatures;
  652. }
  653. // Pipeline features
  654. if(!!(m_extensions & VulkanExtensions::PIPELINE_EXECUTABLE_PROPERTIES))
  655. {
  656. m_pplineExecutablePropertiesFeatures.sType =
  657. VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR;
  658. m_pplineExecutablePropertiesFeatures.pipelineExecutableInfo = true;
  659. m_pplineExecutablePropertiesFeatures.pNext = const_cast<void*>(ci.pNext);
  660. ci.pNext = &m_pplineExecutablePropertiesFeatures;
  661. }
  662. ANKI_VK_CHECK(vkCreateDevice(m_physicalDevice, &ci, nullptr, &m_device));
  663. // Get debug marker
  664. if(!!(m_extensions & VulkanExtensions::EXT_DEBUG_MARKER))
  665. {
  666. m_pfnDebugMarkerSetObjectNameEXT = reinterpret_cast<PFN_vkDebugMarkerSetObjectNameEXT>(
  667. vkGetDeviceProcAddr(m_device, "vkDebugMarkerSetObjectNameEXT"));
  668. if(!m_pfnDebugMarkerSetObjectNameEXT)
  669. {
  670. ANKI_VK_LOGW("VK_EXT_debug_marker is present but vkDebugMarkerSetObjectNameEXT is not there");
  671. }
  672. m_pfnCmdDebugMarkerBeginEXT =
  673. reinterpret_cast<PFN_vkCmdDebugMarkerBeginEXT>(vkGetDeviceProcAddr(m_device, "vkCmdDebugMarkerBeginEXT"));
  674. if(!m_pfnCmdDebugMarkerBeginEXT)
  675. {
  676. ANKI_VK_LOGW("VK_EXT_debug_marker is present but vkCmdDebugMarkerBeginEXT is not there");
  677. }
  678. m_pfnCmdDebugMarkerEndEXT =
  679. reinterpret_cast<PFN_vkCmdDebugMarkerEndEXT>(vkGetDeviceProcAddr(m_device, "vkCmdDebugMarkerEndEXT"));
  680. if(!m_pfnCmdDebugMarkerEndEXT)
  681. {
  682. ANKI_VK_LOGW("VK_EXT_debug_marker is present but vkCmdDebugMarkerEndEXT is not there");
  683. }
  684. }
  685. // Get VK_AMD_shader_info entry points
  686. if(!!(m_extensions & VulkanExtensions::AMD_SHADER_INFO))
  687. {
  688. m_pfnGetShaderInfoAMD =
  689. reinterpret_cast<PFN_vkGetShaderInfoAMD>(vkGetDeviceProcAddr(m_device, "vkGetShaderInfoAMD"));
  690. if(!m_pfnGetShaderInfoAMD)
  691. {
  692. ANKI_VK_LOGW("VK_AMD_shader_info is present but vkGetShaderInfoAMD is not there");
  693. }
  694. }
  695. return Error::NONE;
  696. }
  697. Error GrManagerImpl::initMemory(const ConfigSet& cfg)
  698. {
  699. vkGetPhysicalDeviceMemoryProperties(m_physicalDevice, &m_memoryProperties);
  700. // Print some info
  701. ANKI_VK_LOGI("Vulkan memory info:");
  702. for(U32 i = 0; i < m_memoryProperties.memoryHeapCount; ++i)
  703. {
  704. ANKI_VK_LOGI("\tHeap %u size %zu", i, m_memoryProperties.memoryHeaps[i].size);
  705. }
  706. for(U32 i = 0; i < m_memoryProperties.memoryTypeCount; ++i)
  707. {
  708. ANKI_VK_LOGI("\tMem type %u points to heap %u, flags %" ANKI_PRIb32, i,
  709. m_memoryProperties.memoryTypes[i].heapIndex,
  710. ANKI_FORMAT_U32(m_memoryProperties.memoryTypes[i].propertyFlags));
  711. }
  712. m_gpuMemManager.init(m_physicalDevice, m_device, getAllocator(),
  713. !!(m_extensions & VulkanExtensions::KHR_RAY_TRACING));
  714. return Error::NONE;
  715. }
  716. #if ANKI_GR_MANAGER_DEBUG_MEMMORY
  717. void* GrManagerImpl::allocateCallback(void* userData, size_t size, size_t alignment,
  718. VkSystemAllocationScope allocationScope)
  719. {
  720. if(ANKI_UNLIKELY(size == 0))
  721. {
  722. return nullptr;
  723. }
  724. ANKI_ASSERT(userData);
  725. ANKI_ASSERT(size);
  726. ANKI_ASSERT(isPowerOfTwo(alignment));
  727. ANKI_ASSERT(alignment <= MAX_ALLOC_ALIGNMENT);
  728. auto alloc = static_cast<GrManagerImpl*>(userData)->getAllocator();
  729. PtrSize newSize = size + sizeof(AllocHeader);
  730. AllocHeader* header = static_cast<AllocHeader*>(alloc.getMemoryPool().allocate(newSize, MAX_ALLOC_ALIGNMENT));
  731. header->m_sig = ALLOC_SIG;
  732. header->m_size = size;
  733. ++header;
  734. return static_cast<AllocHeader*>(header);
  735. }
  736. void* GrManagerImpl::reallocateCallback(void* userData, void* original, size_t size, size_t alignment,
  737. VkSystemAllocationScope allocationScope)
  738. {
  739. if(original && size == 0)
  740. {
  741. freeCallback(userData, original);
  742. return nullptr;
  743. }
  744. void* mem = allocateCallback(userData, size, alignment, allocationScope);
  745. if(original)
  746. {
  747. // Move the data
  748. AllocHeader* header = static_cast<AllocHeader*>(original);
  749. --header;
  750. ANKI_ASSERT(header->m_sig == ALLOC_SIG);
  751. memcpy(mem, original, header->m_size);
  752. }
  753. return mem;
  754. }
  755. void GrManagerImpl::freeCallback(void* userData, void* ptr)
  756. {
  757. if(ptr)
  758. {
  759. ANKI_ASSERT(userData);
  760. auto alloc = static_cast<GrManagerImpl*>(userData)->getAllocator();
  761. AllocHeader* header = static_cast<AllocHeader*>(ptr);
  762. --header;
  763. ANKI_ASSERT(header->m_sig == ALLOC_SIG);
  764. alloc.getMemoryPool().free(header);
  765. }
  766. }
  767. #endif
  768. TexturePtr GrManagerImpl::acquireNextPresentableTexture()
  769. {
  770. ANKI_TRACE_SCOPED_EVENT(VK_ACQUIRE_IMAGE);
  771. LockGuard<Mutex> lock(m_globalMtx);
  772. PerFrame& frame = m_perFrame[m_frame % MAX_FRAMES_IN_FLIGHT];
  773. // Create sync objects
  774. MicroFencePtr fence = m_fenceFactory.newInstance();
  775. frame.m_acquireSemaphore = m_semaphoreFactory.newInstance(fence, false);
  776. // Get new image
  777. uint32_t imageIdx;
  778. VkResult res = vkAcquireNextImageKHR(m_device, m_crntSwapchain->m_swapchain, UINT64_MAX,
  779. frame.m_acquireSemaphore->getHandle(), fence->getHandle(), &imageIdx);
  780. if(res == VK_ERROR_OUT_OF_DATE_KHR)
  781. {
  782. ANKI_VK_LOGW("Swapchain is out of date. Will wait for the queue and create a new one");
  783. for(VkQueue queue : m_queues)
  784. {
  785. vkQueueWaitIdle(queue);
  786. }
  787. m_crntSwapchain = m_swapchainFactory.newInstance();
  788. // Can't fail a second time
  789. ANKI_VK_CHECKF(vkAcquireNextImageKHR(m_device, m_crntSwapchain->m_swapchain, UINT64_MAX,
  790. frame.m_acquireSemaphore->getHandle(), fence->getHandle(), &imageIdx));
  791. }
  792. else
  793. {
  794. ANKI_VK_CHECKF(res);
  795. }
  796. ANKI_ASSERT(imageIdx < MAX_FRAMES_IN_FLIGHT);
  797. m_acquiredImageIdx = U8(imageIdx);
  798. return m_crntSwapchain->m_textures[imageIdx];
  799. }
  800. void GrManagerImpl::endFrame()
  801. {
  802. ANKI_TRACE_SCOPED_EVENT(VK_PRESENT);
  803. LockGuard<Mutex> lock(m_globalMtx);
  804. PerFrame& frame = m_perFrame[m_frame % MAX_FRAMES_IN_FLIGHT];
  805. // Wait for the fence of N-2 frame
  806. const U waitFrameIdx = (m_frame + 1) % MAX_FRAMES_IN_FLIGHT;
  807. PerFrame& waitFrame = m_perFrame[waitFrameIdx];
  808. if(waitFrame.m_presentFence)
  809. {
  810. waitFrame.m_presentFence->wait();
  811. }
  812. resetFrame(waitFrame);
  813. if(!frame.m_renderSemaphore)
  814. {
  815. ANKI_VK_LOGW("Nobody draw to the default framebuffer");
  816. }
  817. // Present
  818. VkResult res;
  819. VkPresentInfoKHR present = {};
  820. present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
  821. present.waitSemaphoreCount = (frame.m_renderSemaphore) ? 1 : 0;
  822. present.pWaitSemaphores = (frame.m_renderSemaphore) ? &frame.m_renderSemaphore->getHandle() : nullptr;
  823. present.swapchainCount = 1;
  824. present.pSwapchains = &m_crntSwapchain->m_swapchain;
  825. const U32 idx = m_acquiredImageIdx;
  826. present.pImageIndices = &idx;
  827. present.pResults = &res;
  828. const VkResult res1 = vkQueuePresentKHR(m_queues[frame.m_queueWroteToSwapchainImage], &present);
  829. if(res1 == VK_ERROR_OUT_OF_DATE_KHR)
  830. {
  831. ANKI_VK_LOGW("Swapchain is out of date. Will wait for the queue and create a new one");
  832. for(VkQueue queue : m_queues)
  833. {
  834. vkQueueWaitIdle(queue);
  835. }
  836. m_crntSwapchain = m_swapchainFactory.newInstance();
  837. }
  838. else
  839. {
  840. ANKI_VK_CHECKF(res1);
  841. ANKI_VK_CHECKF(res);
  842. }
  843. m_descrFactory.endFrame();
  844. // Finalize
  845. ++m_frame;
  846. }
  847. void GrManagerImpl::resetFrame(PerFrame& frame)
  848. {
  849. frame.m_presentFence.reset(nullptr);
  850. frame.m_acquireSemaphore.reset(nullptr);
  851. frame.m_renderSemaphore.reset(nullptr);
  852. }
  853. void GrManagerImpl::flushCommandBuffer(MicroCommandBufferPtr cmdb, Bool cmdbRenderedToSwapchain,
  854. WeakArray<MicroSemaphorePtr> userWaitSemaphores,
  855. MicroSemaphorePtr* userSignalSemaphore, Bool wait)
  856. {
  857. constexpr U32 maxSemaphores = 8;
  858. VkSubmitInfo submit = {};
  859. submit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
  860. Array<VkSemaphore, maxSemaphores> waitSemaphores;
  861. submit.pWaitSemaphores = &waitSemaphores[0];
  862. Array<VkSemaphore, maxSemaphores> signalSemaphores;
  863. submit.pSignalSemaphores = &signalSemaphores[0];
  864. Array<VkPipelineStageFlags, maxSemaphores> waitStages;
  865. submit.pWaitDstStageMask = &waitStages[0];
  866. // First thing, create a fence
  867. MicroFencePtr fence = m_fenceFactory.newInstance();
  868. // Command buffer
  869. const VkCommandBuffer handle = cmdb->getHandle();
  870. cmdb->setFence(fence);
  871. submit.commandBufferCount = 1;
  872. submit.pCommandBuffers = &handle;
  873. // Handle user semaphores
  874. Array<U64, maxSemaphores> waitTimelineValues;
  875. Array<U64, maxSemaphores> signalTimelineValues;
  876. VkTimelineSemaphoreSubmitInfo timelineInfo = {};
  877. timelineInfo.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
  878. timelineInfo.waitSemaphoreValueCount = userWaitSemaphores.getSize();
  879. timelineInfo.pWaitSemaphoreValues = &waitTimelineValues[0];
  880. timelineInfo.signalSemaphoreValueCount = (userSignalSemaphore != nullptr);
  881. timelineInfo.pSignalSemaphoreValues = &signalTimelineValues[0];
  882. submit.pNext = &timelineInfo;
  883. for(MicroSemaphorePtr& userWaitSemaphore : userWaitSemaphores)
  884. {
  885. ANKI_ASSERT(userWaitSemaphore.isCreated());
  886. ANKI_ASSERT(userWaitSemaphore->isTimeline());
  887. waitSemaphores[submit.waitSemaphoreCount] = userWaitSemaphore->getHandle();
  888. waitTimelineValues[submit.waitSemaphoreCount] = userWaitSemaphore->getSemaphoreValue();
  889. // Be a bit conservative
  890. waitStages[submit.waitSemaphoreCount] = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
  891. ++submit.waitSemaphoreCount;
  892. // Refresh the fence because the semaphore can't be recycled until the current submission is done
  893. userWaitSemaphore->setFence(fence);
  894. }
  895. if(userSignalSemaphore)
  896. {
  897. *userSignalSemaphore = m_semaphoreFactory.newInstance(fence, true);
  898. signalSemaphores[submit.signalSemaphoreCount] = (*userSignalSemaphore)->getHandle();
  899. signalTimelineValues[submit.signalSemaphoreCount] = (*userSignalSemaphore)->getNextSemaphoreValue();
  900. ++submit.signalSemaphoreCount;
  901. }
  902. // Protect the class, the queue and other stuff
  903. LockGuard<Mutex> lock(m_globalMtx);
  904. // Do some special stuff for the last command buffer
  905. PerFrame& frame = m_perFrame[m_frame % MAX_FRAMES_IN_FLIGHT];
  906. if(cmdbRenderedToSwapchain)
  907. {
  908. // Wait semaphore
  909. waitSemaphores[submit.waitSemaphoreCount] = frame.m_acquireSemaphore->getHandle();
  910. // That depends on how we use the swapchain img. Be a bit conservative
  911. waitStages[submit.waitSemaphoreCount] =
  912. VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
  913. ++submit.waitSemaphoreCount;
  914. // Refresh the fence because the semaphore can't be recycled until the current submission is done
  915. frame.m_acquireSemaphore->setFence(fence);
  916. // Create the semaphore to signal
  917. ANKI_ASSERT(!frame.m_renderSemaphore && "Only one begin/end render pass is allowed with the default fb");
  918. frame.m_renderSemaphore = m_semaphoreFactory.newInstance(fence, false);
  919. signalSemaphores[submit.signalSemaphoreCount++] = frame.m_renderSemaphore->getHandle();
  920. // Update the frame fence
  921. frame.m_presentFence = fence;
  922. // Update the swapchain's fence
  923. m_crntSwapchain->setFence(fence);
  924. frame.m_queueWroteToSwapchainImage = getQueueTypeFromCommandBufferFlags(cmdb->getFlags());
  925. }
  926. // Submit
  927. {
  928. ANKI_TRACE_SCOPED_EVENT(VK_QUEUE_SUBMIT);
  929. ANKI_VK_CHECKF(vkQueueSubmit(m_queues[getQueueTypeFromCommandBufferFlags(cmdb->getFlags())], 1, &submit,
  930. fence->getHandle()));
  931. }
  932. if(wait)
  933. {
  934. vkQueueWaitIdle(m_queues[getQueueTypeFromCommandBufferFlags(cmdb->getFlags())]);
  935. }
  936. }
  937. void GrManagerImpl::finish()
  938. {
  939. LockGuard<Mutex> lock(m_globalMtx);
  940. for(VkQueue queue : m_queues)
  941. {
  942. vkQueueWaitIdle(queue);
  943. }
  944. }
  945. void GrManagerImpl::trySetVulkanHandleName(CString name, VkDebugReportObjectTypeEXT type, U64 handle) const
  946. {
  947. if(name && name.getLength())
  948. {
  949. if(m_pfnDebugMarkerSetObjectNameEXT)
  950. {
  951. VkDebugMarkerObjectNameInfoEXT inf = {};
  952. inf.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT;
  953. inf.objectType = type;
  954. inf.pObjectName = name.cstr();
  955. inf.object = handle;
  956. m_pfnDebugMarkerSetObjectNameEXT(m_device, &inf);
  957. }
  958. LockGuard<SpinLock> lock(m_vkHandleToNameLock);
  959. StringAuto newName(getAllocator());
  960. newName.create(name);
  961. m_vkHandleToName.emplace(getAllocator(), computeHash(&handle, sizeof(handle)), std::move(newName));
  962. }
  963. }
  964. StringAuto GrManagerImpl::tryGetVulkanHandleName(U64 handle) const
  965. {
  966. StringAuto out(getAllocator());
  967. LockGuard<SpinLock> lock(m_vkHandleToNameLock);
  968. auto it = m_vkHandleToName.find(computeHash(&handle, sizeof(handle)));
  969. CString objName;
  970. if(it != m_vkHandleToName.getEnd())
  971. {
  972. objName = it->toCString();
  973. }
  974. else
  975. {
  976. objName = "Unnamed";
  977. }
  978. out.create(objName);
  979. return out;
  980. }
  981. VkBool32 GrManagerImpl::debugReportCallbackEXT(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType,
  982. uint64_t object, size_t location, int32_t messageCode,
  983. const char* pLayerPrefix, const char* pMessage, void* pUserData)
  984. {
  985. // Get the object name
  986. GrManagerImpl* self = static_cast<GrManagerImpl*>(pUserData);
  987. StringAuto name = self->tryGetVulkanHandleName(object);
  988. if(flags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
  989. {
  990. ANKI_VK_LOGE("%s (handle: %s)", pMessage, name.cstr());
  991. }
  992. else if(flags & (VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT))
  993. {
  994. ANKI_VK_LOGW("%s (handle: %s)", pMessage, name.cstr());
  995. }
  996. else
  997. {
  998. ANKI_VK_LOGI("%s (handle: %s)", pMessage, name.cstr());
  999. }
  1000. return false;
  1001. }
  1002. void GrManagerImpl::printPipelineShaderInfo(VkPipeline ppline, CString name, ShaderTypeBit stages, U64 hash) const
  1003. {
  1004. if(printPipelineShaderInfoInternal(ppline, name, stages, hash))
  1005. {
  1006. ANKI_VK_LOGE("Ignoring previous errors");
  1007. }
  1008. }
  1009. Error GrManagerImpl::printPipelineShaderInfoInternal(VkPipeline ppline, CString name, ShaderTypeBit stages,
  1010. U64 hash) const
  1011. {
  1012. if(m_pfnGetShaderInfoAMD)
  1013. {
  1014. VkShaderStatisticsInfoAMD stats = {};
  1015. LockGuard<SpinLock> lock(m_shaderStatsFileMtx);
  1016. // Open the file
  1017. if(!m_shaderStatsFile.isOpen())
  1018. {
  1019. ANKI_CHECK(m_shaderStatsFile.open(
  1020. StringAuto(getAllocator()).sprintf("%s/../ppline_stats.csv", m_cacheDir.cstr()).toCString(),
  1021. FileOpenFlag::WRITE));
  1022. ANKI_CHECK(m_shaderStatsFile.writeText("ppline name,hash,"
  1023. "stage 0 VGPR,stage 0 SGPR,"
  1024. "stage 1 VGPR,stage 1 SGPR,"
  1025. "stage 2 VGPR,stage 2 SGPR,"
  1026. "stage 3 VGPR,stage 3 SGPR,"
  1027. "stage 4 VGPR,stage 4 SGPR,"
  1028. "stage 5 VGPR,stage 5 SGPR\n"));
  1029. }
  1030. ANKI_CHECK(m_shaderStatsFile.writeText("%s,0x%" PRIx64 ",", name.cstr(), hash));
  1031. StringAuto str(getAllocator());
  1032. for(ShaderType type = ShaderType::FIRST; type < ShaderType::COUNT; ++type)
  1033. {
  1034. ShaderTypeBit stage = stages & ShaderTypeBit(1 << type);
  1035. if(!stage)
  1036. {
  1037. ANKI_CHECK(m_shaderStatsFile.writeText((type != ShaderType::LAST) ? "0,0," : "0,0\n"));
  1038. continue;
  1039. }
  1040. size_t size = sizeof(stats);
  1041. ANKI_VK_CHECK(m_pfnGetShaderInfoAMD(m_device, ppline, VkShaderStageFlagBits(convertShaderTypeBit(stage)),
  1042. VK_SHADER_INFO_TYPE_STATISTICS_AMD, &size, &stats));
  1043. str.append(StringAuto(getAllocator())
  1044. .sprintf("Stage %u: VGRPS %02u, SGRPS %02u ", U32(type), stats.resourceUsage.numUsedVgprs,
  1045. stats.resourceUsage.numUsedSgprs));
  1046. ANKI_CHECK(m_shaderStatsFile.writeText((type != ShaderType::LAST) ? "%u,%u," : "%u,%u\n",
  1047. stats.resourceUsage.numUsedVgprs, stats.resourceUsage.numUsedSgprs));
  1048. }
  1049. ANKI_VK_LOGI("Pipeline \"%s\" (0x%016" PRIx64 ") stats: %s", name.cstr(), hash, str.cstr());
  1050. // Flush the file just in case
  1051. ANKI_CHECK(m_shaderStatsFile.flush());
  1052. }
  1053. if(!!(m_extensions & VulkanExtensions::PIPELINE_EXECUTABLE_PROPERTIES))
  1054. {
  1055. StringListAuto log(m_alloc);
  1056. VkPipelineInfoKHR pplineInf = {};
  1057. pplineInf.sType = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR;
  1058. pplineInf.pipeline = ppline;
  1059. U32 executableCount = 0;
  1060. ANKI_VK_CHECK(vkGetPipelineExecutablePropertiesKHR(m_device, &pplineInf, &executableCount, nullptr));
  1061. DynamicArrayAuto<VkPipelineExecutablePropertiesKHR> executableProps(m_alloc, executableCount);
  1062. ANKI_VK_CHECK(
  1063. vkGetPipelineExecutablePropertiesKHR(m_device, &pplineInf, &executableCount, &executableProps[0]));
  1064. log.pushBackSprintf("Pipeline info \"%s\" (0x%016" PRIx64 "): ", name.cstr(), hash);
  1065. for(U32 i = 0; i < executableCount; ++i)
  1066. {
  1067. const VkPipelineExecutablePropertiesKHR& p = executableProps[i];
  1068. log.pushBackSprintf("%s: ", p.description);
  1069. // Get stats
  1070. VkPipelineExecutableInfoKHR exeInf = {};
  1071. exeInf.sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR;
  1072. exeInf.executableIndex = i;
  1073. exeInf.pipeline = ppline;
  1074. U32 statCount = 0;
  1075. vkGetPipelineExecutableStatisticsKHR(m_device, &exeInf, &statCount, nullptr);
  1076. DynamicArrayAuto<VkPipelineExecutableStatisticKHR> stats(m_alloc, statCount);
  1077. vkGetPipelineExecutableStatisticsKHR(m_device, &exeInf, &statCount, &stats[0]);
  1078. for(U32 s = 0; s < statCount; ++s)
  1079. {
  1080. const VkPipelineExecutableStatisticKHR& ss = stats[s];
  1081. switch(ss.format)
  1082. {
  1083. case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR:
  1084. log.pushBackSprintf("%s: %u, ", ss.name, ss.value.b32);
  1085. break;
  1086. case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR:
  1087. log.pushBackSprintf("%s: %" PRId64 ", ", ss.name, ss.value.i64);
  1088. break;
  1089. case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR:
  1090. log.pushBackSprintf("%s: %" PRIu64 ", ", ss.name, ss.value.u64);
  1091. break;
  1092. case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR:
  1093. log.pushBackSprintf("%s: %f, ", ss.name, ss.value.f64);
  1094. break;
  1095. default:
  1096. ANKI_ASSERT(0);
  1097. }
  1098. }
  1099. log.pushBackSprintf("Subgroup size: %u", p.subgroupSize);
  1100. if(i < executableCount - 1)
  1101. {
  1102. log.pushBack(", ");
  1103. }
  1104. }
  1105. StringAuto finalLog(m_alloc);
  1106. log.join("", finalLog);
  1107. ANKI_VK_LOGI("%s", finalLog.cstr());
  1108. }
  1109. return Error::NONE;
  1110. }
  1111. } // end namespace anki