GrManagerImpl.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966
  1. // Copyright (C) 2009-2016, 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/Pipeline.h>
  8. #include <anki/gr/vulkan/CommandBufferImpl.h>
  9. #include <anki/gr/CommandBuffer.h>
  10. #include <anki/util/HashMap.h>
  11. #include <anki/util/Hash.h>
  12. #include <anki/core/Config.h>
  13. #include <glslang/Public/ShaderLang.h>
  14. namespace anki
  15. {
  16. #define ANKI_GR_MANAGER_DEBUG_MEMMORY ANKI_DEBUG
  17. //==============================================================================
  18. // GrManagerImpl::CompatibleRenderPassHashMap =
  19. //==============================================================================
  20. class RenderPassKey
  21. {
  22. public:
  23. Array<PixelFormat, MAX_COLOR_ATTACHMENTS> m_colorAttachments;
  24. PixelFormat m_depthStencilAttachment;
  25. RenderPassKey()
  26. {
  27. // Zero because we compute hashes
  28. memset(this, 0, sizeof(*this));
  29. }
  30. RenderPassKey& operator=(const RenderPassKey& b) = default;
  31. };
  32. class RenderPassHasher
  33. {
  34. public:
  35. U64 operator()(const RenderPassKey& b) const
  36. {
  37. return computeHash(&b, sizeof(b));
  38. }
  39. };
  40. class RenderPassCompare
  41. {
  42. public:
  43. Bool operator()(const RenderPassKey& a, const RenderPassKey& b) const
  44. {
  45. for(U i = 0; i < a.m_colorAttachments.getSize(); ++i)
  46. {
  47. if(a.m_colorAttachments[i] != b.m_colorAttachments[i])
  48. {
  49. return false;
  50. }
  51. }
  52. return a.m_depthStencilAttachment == b.m_depthStencilAttachment;
  53. }
  54. };
  55. class GrManagerImpl::CompatibleRenderPassHashMap
  56. {
  57. public:
  58. Mutex m_mtx;
  59. HashMap<RenderPassKey, VkRenderPass, RenderPassHasher, RenderPassCompare>
  60. m_hashmap;
  61. };
  62. //==============================================================================
  63. // GrManagerImpl =
  64. //==============================================================================
  65. //==============================================================================
  66. GrManagerImpl::~GrManagerImpl()
  67. {
  68. // FIRST THING: wait for the GPU
  69. if(m_queue)
  70. {
  71. LockGuard<Mutex> lock(m_queueSubmitMtx);
  72. vkQueueWaitIdle(m_queue);
  73. m_queue = VK_NULL_HANDLE;
  74. }
  75. if(m_renderPasses)
  76. {
  77. auto it = m_renderPasses->m_hashmap.getBegin();
  78. auto end = m_renderPasses->m_hashmap.getEnd();
  79. while(it != end)
  80. {
  81. VkRenderPass pass = (*it);
  82. vkDestroyRenderPass(m_device, pass, nullptr);
  83. ++it;
  84. }
  85. m_renderPasses->m_hashmap.destroy(getAllocator());
  86. getAllocator().deleteInstance(m_renderPasses);
  87. }
  88. if(m_globalPipelineLayout)
  89. {
  90. vkDestroyPipelineLayout(m_device, m_globalPipelineLayout, nullptr);
  91. }
  92. if(m_globalDescriptorPool)
  93. {
  94. vkDestroyDescriptorPool(m_device, m_globalDescriptorPool, nullptr);
  95. }
  96. if(m_globalDescriptorSetLayout)
  97. {
  98. vkDestroyDescriptorSetLayout(
  99. m_device, m_globalDescriptorSetLayout, nullptr);
  100. }
  101. for(auto& x : m_perFrame)
  102. {
  103. if(x.m_imageView)
  104. {
  105. vkDestroyImageView(m_device, x.m_imageView, nullptr);
  106. x.m_imageView = VK_NULL_HANDLE;
  107. }
  108. x.m_presentFence.reset(nullptr);
  109. x.m_acquireSemaphore.reset(nullptr);
  110. x.m_renderSemaphore.reset(nullptr);
  111. x.m_cmdbsSubmitted.destroy(getAllocator());
  112. }
  113. m_perThread.destroy(getAllocator());
  114. m_gpuMemAllocs.destroy(getAllocator());
  115. m_semaphores.destroy(); // Destroy before fences
  116. m_fences.destroy();
  117. if(m_swapchain)
  118. {
  119. vkDestroySwapchainKHR(m_device, m_swapchain, nullptr);
  120. }
  121. if(m_device)
  122. {
  123. vkDestroyDevice(m_device, nullptr);
  124. }
  125. if(m_surface)
  126. {
  127. vkDestroySurfaceKHR(m_instance, m_surface, nullptr);
  128. }
  129. if(m_instance)
  130. {
  131. vkDestroyInstance(m_instance, nullptr);
  132. }
  133. }
  134. //==============================================================================
  135. GrAllocator<U8> GrManagerImpl::getAllocator() const
  136. {
  137. return m_manager->getAllocator();
  138. }
  139. //==============================================================================
  140. Error GrManagerImpl::init(const GrManagerInitInfo& init)
  141. {
  142. Error err = initInternal(init);
  143. if(err)
  144. {
  145. ANKI_LOGE("Vulkan initialization failed");
  146. return ErrorCode::FUNCTION_FAILED;
  147. }
  148. return ErrorCode::NONE;
  149. }
  150. //==============================================================================
  151. Error GrManagerImpl::initInternal(const GrManagerInitInfo& init)
  152. {
  153. ANKI_LOGI("Initializing Vulkan backend");
  154. ANKI_CHECK(initInstance(init));
  155. ANKI_CHECK(initSurface(init));
  156. ANKI_CHECK(initDevice(init));
  157. vkGetDeviceQueue(m_device, m_queueIdx, 0, &m_queue);
  158. ANKI_CHECK(initSwapchain(init));
  159. initMemory();
  160. ANKI_CHECK(initGlobalDsetLayout());
  161. ANKI_CHECK(initGlobalDsetPool());
  162. ANKI_CHECK(initGlobalPplineLayout());
  163. m_renderPasses = getAllocator().newInstance<CompatibleRenderPassHashMap>();
  164. for(PerFrame& f : m_perFrame)
  165. {
  166. resetFrame(f);
  167. }
  168. glslang::InitializeProcess();
  169. m_fences.init(getAllocator(), m_device);
  170. m_semaphores.init(getAllocator(), m_device);
  171. return ErrorCode::NONE;
  172. }
  173. //==============================================================================
  174. Error GrManagerImpl::initInstance(const GrManagerInitInfo& init)
  175. {
  176. // Create the instance
  177. //
  178. static Array<const char*, 9> LAYERS = {{"VK_LAYER_LUNARG_core_validation",
  179. "VK_LAYER_LUNARG_device_limits",
  180. "VK_LAYER_LUNARG_swapchain",
  181. "VK_LAYER_LUNARG_image",
  182. "VK_LAYER_GOOGLE_threading",
  183. "VK_LAYER_LUNARG_parameter_validation",
  184. "VK_LAYER_GOOGLE_unique_objects",
  185. "VK_LAYER_LUNARG_object_tracker",
  186. "VK_LAYER_LUNARG_standard_validation"}};
  187. static Array<const char*, 2> EXTENSIONS = {
  188. {VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME}};
  189. VkApplicationInfo app = {};
  190. app.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
  191. app.pApplicationName = "unamed";
  192. app.applicationVersion = 1;
  193. app.pEngineName = "AnKi 3D Engine";
  194. app.engineVersion = (ANKI_VERSION_MAJOR << 1) | ANKI_VERSION_MINOR;
  195. app.apiVersion = VK_MAKE_VERSION(1, 0, 3);
  196. VkInstanceCreateInfo ci = {};
  197. ci.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
  198. ci.pApplicationInfo = &app;
  199. if(init.m_config->getNumber("debugContext"))
  200. {
  201. ANKI_LOGI("VK: Will enable debug layers");
  202. ci.enabledLayerCount = LAYERS.getSize();
  203. ci.ppEnabledLayerNames = &LAYERS[0];
  204. }
  205. ci.enabledExtensionCount = EXTENSIONS.getSize();
  206. ci.ppEnabledExtensionNames = &EXTENSIONS[0];
  207. #if ANKI_GR_MANAGER_DEBUG_MEMMORY
  208. VkAllocationCallbacks allocCbs = {};
  209. VkAllocationCallbacks* pallocCbs = &allocCbs;
  210. allocCbs.pUserData = this;
  211. allocCbs.pfnAllocation = allocateCallback;
  212. allocCbs.pfnReallocation = reallocateCallback;
  213. allocCbs.pfnFree = freeCallback;
  214. #else
  215. VkAllocationCallbacks* pallocCbs = nullptr;
  216. #endif
  217. ANKI_VK_CHECK(vkCreateInstance(&ci, pallocCbs, &m_instance));
  218. // Create the physical device
  219. //
  220. uint32_t count = 0;
  221. ANKI_VK_CHECK(vkEnumeratePhysicalDevices(m_instance, &count, nullptr));
  222. ANKI_LOGI("VK: Number of physical devices: %u", count);
  223. if(count < 1)
  224. {
  225. ANKI_LOGE("Wrong number of physical devices");
  226. return ErrorCode::FUNCTION_FAILED;
  227. }
  228. count = 1;
  229. ANKI_VK_CHECK(
  230. vkEnumeratePhysicalDevices(m_instance, &count, &m_physicalDevice));
  231. vkGetPhysicalDeviceProperties(m_physicalDevice, &m_devProps);
  232. return ErrorCode::NONE;
  233. }
  234. //==============================================================================
  235. Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
  236. {
  237. uint32_t count = 0;
  238. vkGetPhysicalDeviceQueueFamilyProperties(m_physicalDevice, &count, nullptr);
  239. ANKI_LOGI("VK: Number of queue families: %u\n", count);
  240. DynamicArrayAuto<VkQueueFamilyProperties> queueInfos(getAllocator());
  241. queueInfos.create(count);
  242. vkGetPhysicalDeviceQueueFamilyProperties(
  243. m_physicalDevice, &count, &queueInfos[0]);
  244. uint32_t desiredFamilyIdx = MAX_U32;
  245. const VkQueueFlags DESITED_QUEUE_FLAGS =
  246. VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
  247. for(U i = 0; i < count; ++i)
  248. {
  249. if((queueInfos[i].queueFlags & (DESITED_QUEUE_FLAGS))
  250. == DESITED_QUEUE_FLAGS)
  251. {
  252. VkBool32 supportsPresent = false;
  253. ANKI_VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(
  254. m_physicalDevice, i, m_surface, &supportsPresent));
  255. if(supportsPresent)
  256. {
  257. desiredFamilyIdx = i;
  258. break;
  259. }
  260. }
  261. }
  262. if(desiredFamilyIdx == MAX_U32)
  263. {
  264. ANKI_LOGE("Couldn't find a queue family with graphics+compute+present."
  265. "The assumption was wrong. The code needs rework");
  266. return ErrorCode::FUNCTION_FAILED;
  267. }
  268. m_queueIdx = desiredFamilyIdx;
  269. F32 priority = 1.0;
  270. VkDeviceQueueCreateInfo q = {};
  271. q.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
  272. q.queueFamilyIndex = desiredFamilyIdx;
  273. q.queueCount = 1;
  274. q.pQueuePriorities = &priority;
  275. static Array<const char*, 1> DEV_EXTENSIONS = {
  276. {VK_KHR_SWAPCHAIN_EXTENSION_NAME}};
  277. VkDeviceCreateInfo ci = {};
  278. ci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
  279. ci.queueCreateInfoCount = 1;
  280. ci.pQueueCreateInfos = &q;
  281. ci.enabledExtensionCount = DEV_EXTENSIONS.getSize();
  282. ci.ppEnabledExtensionNames = &DEV_EXTENSIONS[0];
  283. ANKI_VK_CHECK(vkCreateDevice(m_physicalDevice, &ci, nullptr, &m_device));
  284. return ErrorCode::NONE;
  285. }
  286. //==============================================================================
  287. Error GrManagerImpl::initSwapchain(const GrManagerInitInfo& init)
  288. {
  289. VkSurfaceCapabilitiesKHR surfaceProperties;
  290. ANKI_VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
  291. m_physicalDevice, m_surface, &surfaceProperties));
  292. if(surfaceProperties.currentExtent.width == MAX_U32
  293. || surfaceProperties.currentExtent.height == MAX_U32)
  294. {
  295. ANKI_LOGE("Wrong surface size");
  296. return ErrorCode::FUNCTION_FAILED;
  297. }
  298. m_surfaceWidth = surfaceProperties.currentExtent.width;
  299. m_surfaceHeight = surfaceProperties.currentExtent.height;
  300. uint32_t formatCount;
  301. ANKI_VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(
  302. m_physicalDevice, m_surface, &formatCount, nullptr));
  303. DynamicArrayAuto<VkSurfaceFormatKHR> formats(getAllocator());
  304. formats.create(formatCount);
  305. ANKI_VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(
  306. m_physicalDevice, m_surface, &formatCount, &formats[0]));
  307. VkColorSpaceKHR colorspace = VK_COLOR_SPACE_MAX_ENUM_KHR;
  308. while(formatCount--)
  309. {
  310. if(formats[formatCount].format == VK_FORMAT_B8G8R8A8_SRGB)
  311. {
  312. m_surfaceFormat = formats[formatCount].format;
  313. colorspace = formats[formatCount].colorSpace;
  314. break;
  315. }
  316. }
  317. if(m_surfaceFormat == VK_FORMAT_UNDEFINED)
  318. {
  319. ANKI_LOGE("Surface format not found");
  320. return ErrorCode::FUNCTION_FAILED;
  321. }
  322. VkSwapchainCreateInfoKHR ci = {};
  323. ci.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
  324. ci.surface = m_surface;
  325. ci.minImageCount = MAX_FRAMES_IN_FLIGHT;
  326. ci.imageFormat = m_surfaceFormat;
  327. ci.imageColorSpace = colorspace;
  328. ci.imageExtent = surfaceProperties.currentExtent;
  329. ci.imageArrayLayers = 1;
  330. ci.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
  331. ci.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
  332. ci.queueFamilyIndexCount = 1;
  333. ci.pQueueFamilyIndices = &m_queueIdx;
  334. ci.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
  335. ci.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
  336. ci.presentMode = VK_PRESENT_MODE_FIFO_KHR;
  337. ci.clipped = false;
  338. ci.oldSwapchain = VK_NULL_HANDLE;
  339. ANKI_VK_CHECK(vkCreateSwapchainKHR(m_device, &ci, nullptr, &m_swapchain));
  340. // Get images
  341. uint32_t count = 0;
  342. ANKI_VK_CHECK(
  343. vkGetSwapchainImagesKHR(m_device, m_swapchain, &count, nullptr));
  344. if(count != MAX_FRAMES_IN_FLIGHT)
  345. {
  346. ANKI_LOGE("Requested a swapchain with %u images but got one with %u",
  347. MAX_FRAMES_IN_FLIGHT,
  348. count);
  349. return ErrorCode::FUNCTION_FAILED;
  350. }
  351. ANKI_LOGI("VK: Swapchain images count %u", count);
  352. Array<VkImage, MAX_FRAMES_IN_FLIGHT> images;
  353. ANKI_VK_CHECK(
  354. vkGetSwapchainImagesKHR(m_device, m_swapchain, &count, &images[0]));
  355. for(U i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i)
  356. {
  357. m_perFrame[i].m_image = images[i];
  358. ANKI_ASSERT(images[i]);
  359. }
  360. // Create img views
  361. for(U i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i)
  362. {
  363. PerFrame& perFrame = m_perFrame[i];
  364. VkImageViewCreateInfo ci = {};
  365. ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
  366. ci.flags = 0;
  367. ci.image = perFrame.m_image;
  368. ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
  369. ci.format = m_surfaceFormat;
  370. ci.components = {VK_COMPONENT_SWIZZLE_R,
  371. VK_COMPONENT_SWIZZLE_G,
  372. VK_COMPONENT_SWIZZLE_B,
  373. VK_COMPONENT_SWIZZLE_A};
  374. ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  375. ci.subresourceRange.baseMipLevel = 0;
  376. ci.subresourceRange.levelCount = 1;
  377. ci.subresourceRange.baseArrayLayer = 0;
  378. ci.subresourceRange.layerCount = 1;
  379. ANKI_VK_CHECK(
  380. vkCreateImageView(m_device, &ci, nullptr, &perFrame.m_imageView));
  381. }
  382. return ErrorCode::NONE;
  383. }
  384. //==============================================================================
  385. Error GrManagerImpl::initGlobalDsetLayout()
  386. {
  387. VkDescriptorSetLayoutCreateInfo ci = {};
  388. ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
  389. const U BINDING_COUNT = MAX_TEXTURE_BINDINGS + MAX_UNIFORM_BUFFER_BINDINGS
  390. + MAX_STORAGE_BUFFER_BINDINGS;
  391. ci.bindingCount = BINDING_COUNT;
  392. Array<VkDescriptorSetLayoutBinding, BINDING_COUNT> bindings;
  393. memset(&bindings[0], 0, sizeof(bindings));
  394. ci.pBindings = &bindings[0];
  395. U count = 0;
  396. // Combined image samplers
  397. for(U i = 0; i < MAX_TEXTURE_BINDINGS; ++i)
  398. {
  399. VkDescriptorSetLayoutBinding& binding = bindings[count];
  400. binding.binding = count;
  401. binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
  402. binding.descriptorCount = 1;
  403. binding.stageFlags = VK_SHADER_STAGE_ALL;
  404. ++count;
  405. }
  406. // Uniform buffers
  407. for(U i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
  408. {
  409. VkDescriptorSetLayoutBinding& binding = bindings[count];
  410. binding.binding = count;
  411. binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
  412. binding.descriptorCount = 1;
  413. binding.stageFlags = VK_SHADER_STAGE_ALL;
  414. ++count;
  415. }
  416. // Storage buffers
  417. for(U i = 0; i < MAX_STORAGE_BUFFER_BINDINGS; ++i)
  418. {
  419. VkDescriptorSetLayoutBinding& binding = bindings[count];
  420. binding.binding = count;
  421. binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
  422. binding.descriptorCount = 1;
  423. binding.stageFlags = VK_SHADER_STAGE_ALL;
  424. ++count;
  425. }
  426. ANKI_ASSERT(count == BINDING_COUNT);
  427. ANKI_VK_CHECK(vkCreateDescriptorSetLayout(
  428. m_device, &ci, nullptr, &m_globalDescriptorSetLayout));
  429. return ErrorCode::NONE;
  430. }
  431. //==============================================================================
  432. Error GrManagerImpl::initGlobalDsetPool()
  433. {
  434. Array<VkDescriptorPoolSize, 3> pools = {{}};
  435. pools[0] = VkDescriptorPoolSize{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
  436. MAX_TEXTURE_BINDINGS * MAX_RESOURCE_GROUPS};
  437. pools[1] = VkDescriptorPoolSize{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
  438. MAX_UNIFORM_BUFFER_BINDINGS * MAX_RESOURCE_GROUPS};
  439. pools[2] = VkDescriptorPoolSize{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
  440. MAX_STORAGE_BUFFER_BINDINGS * MAX_RESOURCE_GROUPS};
  441. VkDescriptorPoolCreateInfo ci = {};
  442. ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
  443. ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
  444. ci.maxSets = MAX_RESOURCE_GROUPS;
  445. ci.poolSizeCount = pools.getSize();
  446. ci.pPoolSizes = &pools[0];
  447. ANKI_VK_CHECK(vkCreateDescriptorPool(
  448. m_device, &ci, nullptr, &m_globalDescriptorPool));
  449. return ErrorCode::NONE;
  450. }
  451. //==============================================================================
  452. Error GrManagerImpl::initGlobalPplineLayout()
  453. {
  454. Array<VkDescriptorSetLayout, MAX_BOUND_RESOURCE_GROUPS> sets = {
  455. {m_globalDescriptorSetLayout, m_globalDescriptorSetLayout}};
  456. VkPipelineLayoutCreateInfo ci;
  457. ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
  458. ci.pNext = nullptr;
  459. ci.flags = 0;
  460. ci.setLayoutCount = MAX_BOUND_RESOURCE_GROUPS;
  461. ci.pSetLayouts = &sets[0];
  462. ci.pushConstantRangeCount = 0;
  463. ci.pPushConstantRanges = nullptr;
  464. ANKI_VK_CHECK(vkCreatePipelineLayout(
  465. m_device, &ci, nullptr, &m_globalPipelineLayout));
  466. return ErrorCode::NONE;
  467. }
  468. //==============================================================================
  469. VkRenderPass GrManagerImpl::getOrCreateCompatibleRenderPass(
  470. const PipelineInitInfo& init)
  471. {
  472. VkRenderPass out = VK_NULL_HANDLE;
  473. // Create the key
  474. RenderPassKey key;
  475. for(U i = 0; i < init.m_color.m_attachmentCount; ++i)
  476. {
  477. key.m_colorAttachments[i] = init.m_color.m_attachments[i].m_format;
  478. }
  479. key.m_depthStencilAttachment = init.m_depthStencil.m_format;
  480. // Lock
  481. LockGuard<Mutex> lock(m_renderPasses->m_mtx);
  482. auto it = m_renderPasses->m_hashmap.find(key);
  483. if(it != m_renderPasses->m_hashmap.getEnd())
  484. {
  485. // Found the key
  486. out = *it;
  487. }
  488. else
  489. {
  490. // Not found, create one
  491. VkRenderPassCreateInfo ci = {};
  492. ci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
  493. Array<VkAttachmentDescription, MAX_COLOR_ATTACHMENTS + 1>
  494. attachmentDescriptions;
  495. memset(&attachmentDescriptions[0], 0, sizeof(attachmentDescriptions));
  496. Array<VkAttachmentReference, MAX_COLOR_ATTACHMENTS> references;
  497. memset(&references[0], 0, sizeof(references));
  498. for(U i = 0; i < init.m_color.m_attachmentCount; ++i)
  499. {
  500. // We only care about samples and format
  501. VkAttachmentDescription& desc = attachmentDescriptions[i];
  502. desc.format = (!init.m_color.m_drawsToDefaultFramebuffer)
  503. ? convertFormat(init.m_color.m_attachments[i].m_format)
  504. : m_surfaceFormat;
  505. desc.samples = VK_SAMPLE_COUNT_1_BIT;
  506. desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  507. desc.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  508. desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  509. desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  510. desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL;
  511. desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
  512. references[i].attachment = i;
  513. references[i].layout = VK_IMAGE_LAYOUT_GENERAL;
  514. }
  515. ci.attachmentCount = init.m_color.m_attachmentCount;
  516. Bool hasDepthStencil =
  517. init.m_depthStencil.m_format.m_components != ComponentFormat::NONE;
  518. VkAttachmentReference dsReference = {0, VK_IMAGE_LAYOUT_GENERAL};
  519. if(hasDepthStencil)
  520. {
  521. VkAttachmentDescription& desc =
  522. attachmentDescriptions[ci.attachmentCount];
  523. desc.format = convertFormat(init.m_depthStencil.m_format);
  524. desc.samples = VK_SAMPLE_COUNT_1_BIT;
  525. desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  526. desc.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  527. desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  528. desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  529. desc.initialLayout = VK_IMAGE_LAYOUT_GENERAL;
  530. desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
  531. dsReference.attachment = ci.attachmentCount;
  532. dsReference.layout = VK_IMAGE_LAYOUT_GENERAL;
  533. ++ci.attachmentCount;
  534. }
  535. VkSubpassDescription desc = {};
  536. desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
  537. desc.colorAttachmentCount = init.m_color.m_attachmentCount;
  538. desc.pColorAttachments =
  539. (init.m_color.m_attachmentCount) ? &references[0] : nullptr;
  540. desc.pDepthStencilAttachment =
  541. (hasDepthStencil) ? &dsReference : nullptr;
  542. ANKI_ASSERT(ci.attachmentCount);
  543. ci.pAttachments = &attachmentDescriptions[0];
  544. ci.subpassCount = 1;
  545. ci.pSubpasses = &desc;
  546. VkRenderPass rpass;
  547. ANKI_VK_CHECKF(vkCreateRenderPass(m_device, &ci, nullptr, &rpass));
  548. m_renderPasses->m_hashmap.pushBack(getAllocator(), key, rpass);
  549. out = rpass;
  550. }
  551. ANKI_ASSERT(out);
  552. return out;
  553. }
  554. //==============================================================================
  555. void GrManagerImpl::initMemory()
  556. {
  557. vkGetPhysicalDeviceMemoryProperties(m_physicalDevice, &m_memoryProperties);
  558. m_gpuMemAllocs.create(getAllocator(), m_memoryProperties.memoryTypeCount);
  559. U idx = 0;
  560. for(GpuMemoryAllocator& alloc : m_gpuMemAllocs)
  561. {
  562. alloc.init(getAllocator(), m_device, idx++);
  563. }
  564. }
  565. //==============================================================================
  566. U GrManagerImpl::findMemoryType(U resourceMemTypeBits,
  567. VkMemoryPropertyFlags preferFlags,
  568. VkMemoryPropertyFlags avoidFlags) const
  569. {
  570. U preferedHigh = MAX_U32;
  571. U preferedMed = MAX_U32;
  572. // Iterate all mem types
  573. for(U i = 0; i < m_memoryProperties.memoryTypeCount; i++)
  574. {
  575. if(resourceMemTypeBits & (1u << i))
  576. {
  577. VkMemoryPropertyFlags flags =
  578. m_memoryProperties.memoryTypes[i].propertyFlags;
  579. if((flags & preferFlags) == preferFlags)
  580. {
  581. preferedMed = i;
  582. if((flags & avoidFlags) != avoidFlags)
  583. {
  584. preferedHigh = i;
  585. }
  586. }
  587. }
  588. }
  589. if(preferedHigh < MAX_U32)
  590. {
  591. return preferedHigh;
  592. }
  593. else
  594. {
  595. return preferedMed;
  596. }
  597. }
  598. //==============================================================================
  599. void* GrManagerImpl::allocateCallback(void* userData,
  600. size_t size,
  601. size_t alignment,
  602. VkSystemAllocationScope allocationScope)
  603. {
  604. ANKI_ASSERT(userData);
  605. GrManagerImpl* self = static_cast<GrManagerImpl*>(userData);
  606. return self->getAllocator().getMemoryPool().allocate(size, alignment);
  607. }
  608. //==============================================================================
  609. void* GrManagerImpl::reallocateCallback(void* userData,
  610. void* original,
  611. size_t size,
  612. size_t alignment,
  613. VkSystemAllocationScope allocationScope)
  614. {
  615. ANKI_ASSERT(0 && "TODO");
  616. return nullptr;
  617. }
  618. //==============================================================================
  619. void GrManagerImpl::freeCallback(void* userData, void* ptr)
  620. {
  621. if(ptr)
  622. {
  623. ANKI_ASSERT(userData);
  624. GrManagerImpl* self = static_cast<GrManagerImpl*>(userData);
  625. self->getAllocator().getMemoryPool().free(ptr);
  626. }
  627. }
  628. //==============================================================================
  629. void GrManagerImpl::beginFrame()
  630. {
  631. PerFrame& frame = m_perFrame[m_frame % MAX_FRAMES_IN_FLIGHT];
  632. // Create a semaphore
  633. frame.m_acquireSemaphore = newSemaphore();
  634. // Get new image
  635. uint32_t imageIdx;
  636. ANKI_VK_CHECKF(vkAcquireNextImageKHR(m_device,
  637. m_swapchain,
  638. UINT64_MAX,
  639. frame.m_acquireSemaphore->getHandle(),
  640. 0,
  641. &imageIdx));
  642. ANKI_ASSERT(
  643. imageIdx == (m_frame % MAX_FRAMES_IN_FLIGHT) && "Wrong assumption");
  644. }
  645. //==============================================================================
  646. void GrManagerImpl::endFrame()
  647. {
  648. PerFrame& frame = m_perFrame[m_frame % MAX_FRAMES_IN_FLIGHT];
  649. // Wait for the fence of N-2 frame
  650. U waitFrameIdx = (m_frame + 1) % MAX_FRAMES_IN_FLIGHT;
  651. PerFrame& waitFrame = m_perFrame[waitFrameIdx];
  652. if(waitFrame.m_presentFence)
  653. {
  654. waitFrame.m_presentFence->wait();
  655. }
  656. resetFrame(waitFrame);
  657. if(!frame.m_renderSemaphore)
  658. {
  659. ANKI_LOGW("Nobody draw to the default framebuffer");
  660. }
  661. // Present
  662. uint32_t imageIdx = m_frame % MAX_FRAMES_IN_FLIGHT;
  663. VkPresentInfoKHR present = {};
  664. present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
  665. present.waitSemaphoreCount = (frame.m_renderSemaphore) ? 1 : 0;
  666. present.pWaitSemaphores = (frame.m_renderSemaphore)
  667. ? &frame.m_renderSemaphore->getHandle()
  668. : nullptr;
  669. present.swapchainCount = 1;
  670. present.pSwapchains = &m_swapchain;
  671. present.pImageIndices = &imageIdx;
  672. {
  673. LockGuard<Mutex> lock(m_queueSubmitMtx);
  674. ANKI_VK_CHECKF(vkQueuePresentKHR(m_queue, &present));
  675. }
  676. // Finalize
  677. ++m_frame;
  678. #if ANKI_ASSERTIONS
  679. ANKI_ASSERT(m_cmdbWithIndicationThatIsFirstSubmitted
  680. && m_cmdbWithIndicationThatIsLastSubmitted
  681. && "Forgot to set some command buffer flags");
  682. m_cmdbWithIndicationThatIsFirstSubmitted = false;
  683. m_cmdbWithIndicationThatIsLastSubmitted = false;
  684. #endif
  685. }
  686. //==============================================================================
  687. void GrManagerImpl::resetFrame(PerFrame& frame)
  688. {
  689. frame.m_presentFence.reset(nullptr);
  690. frame.m_acquireSemaphore.reset(nullptr);
  691. frame.m_renderSemaphore.reset(nullptr);
  692. frame.m_cmdbsSubmitted.destroy(getAllocator());
  693. }
  694. //==============================================================================
  695. GrManagerImpl::PerThread& GrManagerImpl::getPerThreadCache(Thread::Id tid)
  696. {
  697. PerThread* thread = nullptr;
  698. LockGuard<SpinLock> lock(m_perThreadMtx);
  699. // Find or create a record
  700. auto it = m_perThread.find(tid);
  701. if(it != m_perThread.getEnd())
  702. {
  703. thread = &(*it);
  704. }
  705. else
  706. {
  707. m_perThread.emplaceBack(getAllocator(), tid);
  708. it = m_perThread.find(tid);
  709. thread = &(*it);
  710. }
  711. return *thread;
  712. }
  713. //==============================================================================
  714. VkCommandBuffer GrManagerImpl::newCommandBuffer(
  715. Thread::Id tid, Bool secondLevel)
  716. {
  717. // Get the per thread cache
  718. PerThread& thread = getPerThreadCache(tid);
  719. // Try initialize the recycler
  720. if(ANKI_UNLIKELY(!thread.m_cmdbs.isCreated()))
  721. {
  722. Error err = thread.m_cmdbs.init(getAllocator(), m_device, m_queueIdx);
  723. if(err)
  724. {
  725. ANKI_LOGF("Cannot recover");
  726. }
  727. }
  728. return thread.m_cmdbs.newCommandBuffer(secondLevel);
  729. }
  730. //==============================================================================
  731. void GrManagerImpl::deleteCommandBuffer(
  732. VkCommandBuffer cmdb, Bool secondLevel, Thread::Id tid)
  733. {
  734. // Get the per thread cache
  735. PerThread& thread = getPerThreadCache(tid);
  736. thread.m_cmdbs.deleteCommandBuffer(cmdb, secondLevel);
  737. }
  738. //==============================================================================
  739. void GrManagerImpl::flushCommandBuffer(CommandBufferPtr cmdb,
  740. SemaphorePtr signalSemaphore,
  741. WeakArray<SemaphorePtr> waitSemaphores,
  742. WeakArray<VkPipelineStageFlags> waitPplineStages)
  743. {
  744. CommandBufferImpl& impl = cmdb->getImplementation();
  745. VkCommandBuffer handle = impl.getHandle();
  746. VkSubmitInfo submit = {};
  747. submit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
  748. FencePtr fence = newFence();
  749. PerFrame& frame = m_perFrame[m_frame % MAX_FRAMES_IN_FLIGHT];
  750. if(signalSemaphore)
  751. {
  752. submit.pSignalSemaphores = &signalSemaphore->getHandle();
  753. submit.signalSemaphoreCount = 1;
  754. signalSemaphore->setFence(fence);
  755. }
  756. Array<VkSemaphore, 16> allWaitSemaphores;
  757. Array<VkPipelineStageFlags, 16> allWaitPplineStages;
  758. for(U i = 0; i < waitSemaphores.getSize(); ++i)
  759. {
  760. ANKI_ASSERT(waitSemaphores[i]);
  761. allWaitSemaphores[submit.waitSemaphoreCount] =
  762. waitSemaphores[i]->getHandle();
  763. allWaitPplineStages[submit.waitSemaphoreCount] = waitPplineStages[i];
  764. ++submit.waitSemaphoreCount;
  765. }
  766. // Do some special stuff for the last command buffer
  767. if(impl.renderedToDefaultFramebuffer())
  768. {
  769. allWaitSemaphores[submit.waitSemaphoreCount] =
  770. frame.m_acquireSemaphore->getHandle();
  771. allWaitPplineStages[submit.waitSemaphoreCount] =
  772. VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  773. ++submit.waitSemaphoreCount;
  774. // Create the semaphore to signal
  775. ANKI_ASSERT(!frame.m_renderSemaphore
  776. && "Only one begin/end render pass is allowed with the default fb");
  777. frame.m_renderSemaphore = newSemaphore();
  778. submit.signalSemaphoreCount = 1;
  779. submit.pSignalSemaphores = &frame.m_renderSemaphore->getHandle();
  780. frame.m_presentFence = fence;
  781. }
  782. submit.pWaitSemaphores = &allWaitSemaphores[0];
  783. submit.pWaitDstStageMask = &allWaitPplineStages[0];
  784. submit.commandBufferCount = 1;
  785. submit.pCommandBuffers = &handle;
  786. // Lock to submit
  787. LockGuard<Mutex> lock(m_queueSubmitMtx);
  788. frame.m_cmdbsSubmitted.pushBack(getAllocator(), cmdb);
  789. #if ANKI_ASSERTIONS
  790. if(impl.isTheFirstFramebufferOfTheFrame())
  791. {
  792. ANKI_ASSERT(m_cmdbWithIndicationThatIsFirstSubmitted == false);
  793. m_cmdbWithIndicationThatIsFirstSubmitted = true;
  794. }
  795. if(impl.isTheLastFramebufferOfTheFrame())
  796. {
  797. ANKI_ASSERT(m_cmdbWithIndicationThatIsLastSubmitted == false);
  798. m_cmdbWithIndicationThatIsLastSubmitted = true;
  799. }
  800. #endif
  801. ANKI_VK_CHECKF(vkQueueSubmit(m_queue, 1, &submit, fence->getHandle()));
  802. }
  803. } // end namespace anki