VkGrManager.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Gr/GrManager.h>
  7. #include <AnKi/Gr/Vulkan/VkCommon.h>
  8. #include <AnKi/Gr/Vulkan/VkSemaphoreFactory.h>
  9. #include <AnKi/Gr/Vulkan/VkFenceFactory.h>
  10. #include <AnKi/Gr/Vulkan/VkSwapchainFactory.h>
  11. #include <AnKi/Util/File.h>
  12. namespace anki {
  13. /// @note Disable that because it crashes Intel drivers
  14. #define ANKI_GR_MANAGER_DEBUG_MEMMORY ANKI_EXTRA_CHECKS && 0
  15. // Forward
  16. class TextureFallbackUploader;
  17. class MicroCommandBuffer;
  18. /// @addtogroup vulkan
  19. /// @{
  20. enum class AsyncComputeType
  21. {
  22. kProper,
  23. kLowPriorityQueue,
  24. kDisabled
  25. };
  26. /// A small struct with all the caps we need.
  27. class VulkanCapabilities
  28. {
  29. public:
  30. VkDeviceAddress m_nonCoherentAtomSize = 0;
  31. U64 m_maxTexelBufferElements = 0;
  32. F32 m_timestampPeriod = 0.0f;
  33. U32 m_asBuildScratchAlignment = 0;
  34. U32 m_asBufferAlignment = 256; // Spec says 256
  35. };
  36. /// Vulkan implementation of GrManager.
  37. class GrManagerImpl : public GrManager
  38. {
  39. friend class GrManager;
  40. public:
  41. GrManagerImpl()
  42. {
  43. }
  44. ~GrManagerImpl();
  45. Error init(const GrManagerInitInfo& cfg);
  46. ConstWeakArray<U32> getQueueFamilies() const
  47. {
  48. const Bool hasAsyncCompute = m_queueFamilyIndices[GpuQueueType::kGeneral] != m_queueFamilyIndices[GpuQueueType::kCompute];
  49. return (hasAsyncCompute) ? m_queueFamilyIndices : ConstWeakArray<U32>(&m_queueFamilyIndices[0], 1);
  50. }
  51. AsyncComputeType getAsyncComputeType() const
  52. {
  53. if(m_queues[GpuQueueType::kCompute] == nullptr)
  54. {
  55. return AsyncComputeType::kDisabled;
  56. }
  57. else if(m_queueFamilyIndices[GpuQueueType::kCompute] == m_queueFamilyIndices[GpuQueueType::kGeneral])
  58. {
  59. return AsyncComputeType::kLowPriorityQueue;
  60. }
  61. else
  62. {
  63. return AsyncComputeType::kProper;
  64. }
  65. }
  66. const VulkanCapabilities& getVulkanCapabilities() const
  67. {
  68. return m_caps;
  69. }
  70. TexturePtr acquireNextPresentableTexture();
  71. void beginFrameInternal();
  72. void endFrameInternal();
  73. void submitInternal(WeakArray<CommandBuffer*> cmdbs, WeakArray<Fence*> waitFences, FencePtr* signalFence);
  74. void finishInternal();
  75. VkDevice getDevice() const
  76. {
  77. ANKI_ASSERT(m_device);
  78. return m_device;
  79. }
  80. VkPhysicalDevice getPhysicalDevice() const
  81. {
  82. ANKI_ASSERT(m_physicalDevice);
  83. return m_physicalDevice;
  84. }
  85. VkInstance getInstance() const
  86. {
  87. ANKI_ASSERT(m_instance);
  88. return m_instance;
  89. }
  90. const VkPhysicalDeviceMemoryProperties& getMemoryProperties() const
  91. {
  92. return m_memoryProperties;
  93. }
  94. VulkanExtensions getExtensions() const
  95. {
  96. return m_extensions;
  97. }
  98. MicroSwapchainPtr getSwapchain() const
  99. {
  100. return m_crntSwapchain;
  101. }
  102. VkSurfaceKHR getSurface() const
  103. {
  104. ANKI_ASSERT(m_surface);
  105. return m_surface;
  106. }
  107. void getNativeWindowSize(U32& width, U32& height) const
  108. {
  109. width = m_nativeWindowWidth;
  110. height = m_nativeWindowHeight;
  111. ANKI_ASSERT(width && height);
  112. }
  113. /// @name Debug report
  114. /// @{
  115. void trySetVulkanHandleName(CString name, VkObjectType type, U64 handle) const;
  116. void trySetVulkanHandleName(CString name, VkObjectType type, void* handle) const
  117. {
  118. trySetVulkanHandleName(name, type, U64(ptrToNumber(handle)));
  119. }
  120. /// @}
  121. /// @note It's thread-safe.
  122. void printPipelineShaderInfo(VkPipeline ppline, CString name, U64 hash = 0) const;
  123. /// @note It's thread-safe.
  124. void releaseObject(GrObject* object)
  125. {
  126. ANKI_ASSERT(object);
  127. LockGuard lock(m_globalMtx);
  128. m_perFrame[m_frame % m_perFrame.getSize()].m_objectsMarkedForDeletion.emplaceBack(object);
  129. }
  130. void releaseObjectDeleteLoop(GrObject* object)
  131. {
  132. ANKI_ASSERT(object);
  133. m_perFrame[m_frame % m_perFrame.getSize()].m_objectsMarkedForDeletion.emplaceBack(object);
  134. }
  135. private:
  136. enum FrameState : U8
  137. {
  138. kFrameStarted,
  139. kPresentableAcquired,
  140. kPresentableDrawn,
  141. kFrameEnded,
  142. };
  143. class PerFrame
  144. {
  145. public:
  146. GrDynamicArray<MicroFencePtr> m_fences;
  147. GpuQueueType m_queueWroteToSwapchainImage = GpuQueueType::kCount;
  148. GrDynamicArray<GrObject*> m_objectsMarkedForDeletion;
  149. };
  150. U64 m_frame = 0;
  151. #if ANKI_GR_MANAGER_DEBUG_MEMMORY
  152. VkAllocationCallbacks m_debugAllocCbs;
  153. static constexpr U32 MAX_ALLOC_ALIGNMENT = 64;
  154. static constexpr PtrSize ALLOC_SIG = 0xF00B00;
  155. struct alignas(MAX_ALLOC_ALIGNMENT) AllocHeader
  156. {
  157. PtrSize m_sig;
  158. PtrSize m_size;
  159. };
  160. #endif
  161. VkInstance m_instance = VK_NULL_HANDLE;
  162. VkPhysicalDevice m_physicalDevice = VK_NULL_HANDLE;
  163. VulkanExtensions m_extensions = VulkanExtensions::kNone;
  164. VkDevice m_device = VK_NULL_HANDLE;
  165. VulkanQueueFamilies m_queueFamilyIndices = {kMaxU32, kMaxU32};
  166. Array<VkQueue, U32(GpuQueueType::kCount)> m_queues = {nullptr, nullptr};
  167. Mutex m_globalMtx;
  168. VkDebugUtilsMessengerEXT m_debugUtilsMessager = VK_NULL_HANDLE;
  169. mutable SpinLock m_shaderStatsMtx;
  170. VkSurfaceKHR m_surface = VK_NULL_HANDLE;
  171. U32 m_nativeWindowWidth = 0;
  172. U32 m_nativeWindowHeight = 0;
  173. MicroSwapchainPtr m_crntSwapchain;
  174. U8 m_acquiredImageIdx = kMaxU8;
  175. FrameState m_frameState = kFrameEnded;
  176. VulkanCapabilities m_caps;
  177. Array<PerFrame, kMaxFramesInFlight> m_perFrame;
  178. VkPhysicalDeviceMemoryProperties m_memoryProperties;
  179. Error initInternal(const GrManagerInitInfo& init);
  180. Error initInstance();
  181. Error initSurface();
  182. Error initDevice();
  183. Error initMemory();
  184. #if ANKI_GR_MANAGER_DEBUG_MEMMORY
  185. static void* allocateCallback(void* userData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
  186. static void* reallocateCallback(void* userData, void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
  187. static void freeCallback(void* userData, void* ptr);
  188. #endif
  189. static VkBool32 debugReportCallbackEXT(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes,
  190. const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData);
  191. Error printPipelineShaderInfoInternal(VkPipeline ppline, CString name, U64 hash) const;
  192. template<typename TProps>
  193. void getPhysicalDeviceProperties2(TProps& props) const
  194. {
  195. VkPhysicalDeviceProperties2 properties = {};
  196. properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
  197. properties.pNext = &props;
  198. vkGetPhysicalDeviceProperties2(m_physicalDevice, &properties);
  199. }
  200. template<typename TFeatures>
  201. void getPhysicalDevicaFeatures2(TFeatures& features) const
  202. {
  203. VkPhysicalDeviceFeatures2 features2 = {};
  204. features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  205. features2.pNext = &features;
  206. vkGetPhysicalDeviceFeatures2(m_physicalDevice, &features2);
  207. }
  208. void deleteObjectsMarkedForDeletion()
  209. {
  210. ANKI_TRACE_FUNCTION();
  211. PerFrame& frame = m_perFrame[m_frame % m_perFrame.getSize()];
  212. while(!frame.m_objectsMarkedForDeletion.isEmpty())
  213. {
  214. GrDynamicArray<GrObject*> objects = std::move(frame.m_objectsMarkedForDeletion);
  215. for(GrObject* obj : objects)
  216. {
  217. deleteInstance(GrMemoryPool::getSingleton(), obj);
  218. }
  219. }
  220. }
  221. };
  222. /// @}
  223. } // end namespace anki